summaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
Diffstat (limited to 'gcc')
-rw-r--r--gcc/Makefile.in51
-rw-r--r--gcc/cppfiles.c111
-rw-r--r--gcc/cppinit.c129
-rw-r--r--gcc/cpplib.c520
-rw-r--r--gcc/cpplib.h18
5 files changed, 397 insertions, 432 deletions
diff --git a/gcc/Makefile.in b/gcc/Makefile.in
index bfbc42a07d2..c66b7784c19 100644
--- a/gcc/Makefile.in
+++ b/gcc/Makefile.in
@@ -873,10 +873,10 @@ stamp-objlist: $(OBJS)
# We call this executable `xgcc' rather than `gcc'
# to avoid confusion if the current directory is in the path
# and CC is `gcc'. It is renamed to `gcc' when it is installed.
-xgcc$(exeext): gcc.o version.o intl.o prefix.o \
- version.o $(LIBDEPS) $(EXTRA_GCC_OBJS)
+xgcc$(exeext): gcc.o version.o choose-temp.o intl.o pexecute.o prefix.o \
+ version.o mkstemp.o $(LIBDEPS) $(EXTRA_GCC_OBJS)
$(CC) $(ALL_CFLAGS) $(LDFLAGS) -o $@ gcc.o prefix.o version.o \
- $(EXTRA_GCC_OBJS) $(LIBS)
+ choose-temp.o pexecute.o mkstemp.o $(EXTRA_GCC_OBJS) $(LIBS)
# Dump a specs file to make -B./ read these specs over installed ones.
specs: xgcc$(exeext)
@@ -1337,11 +1337,11 @@ graph.o: graph.c $(CONFIG_H) system.h toplev.h flags.h output.h $(RTL_H) \
hard-reg-set.h $(BASIC_BLOCK_H)
sbitmap.o: sbitmap.c $(CONFIG_H) system.h $(RTL_H) flags.h $(BASIC_BLOCK_H)
-collect2$(exeext): collect2.o tlink.o hash.o underscore.o \
- version.o $(LIBDEPS)
+collect2$(exeext): collect2.o tlink.o hash.o cplus-dem.o underscore.o \
+ version.o choose-temp.o mkstemp.o $(LIBDEPS)
-COLLECT2_OBJS = collect2.o tlink.o hash.o \
- intl.o underscore.o version.o
+COLLECT2_OBJS = collect2.o tlink.o hash.o choose-temp.o cplus-dem.o \
+ intl.o underscore.o version.o mkstemp.o
collect2 : $(COLLECT2_OBJS) $(LIBDEPS)
# Don't try modifying collect2 (aka ld) in place--it might be linking this.
-rm -f collect2$(exeext)
@@ -1356,6 +1356,16 @@ collect2.o : collect2.c $(CONFIG_H) system.h gstab.h intl.h \
tlink.o: tlink.c $(DEMANGLE_H) hash.h $(CONFIG_H) system.h toplev.h collect2.h
hash.o: hash.c hash.h system.h toplev.h
+cplus-dem.o: $(srcdir)/../libiberty/cplus-dem.c $(DEMANGLE_H)
+ rm -f cplus-dem.c
+ $(LN_S) $(srcdir)/../libiberty/cplus-dem.c cplus-dem.c
+ $(CC) -c $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) cplus-dem.c
+
+pexecute.o: $(srcdir)/../libiberty/pexecute.c $(CONFIG_H) system.h
+ rm -f pexecute.c
+ $(LN_S) $(srcdir)/../libiberty/pexecute.c pexecute.c
+ $(CC) -c $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) pexecute.c
+
vfprintf.o: $(srcdir)/../libiberty/vfprintf.c $(CONFIG_H) system.h
rm -f vfprintf.c
$(LN_S) $(srcdir)/../libiberty/vfprintf.c vfprintf.c
@@ -1423,6 +1433,16 @@ obstack.o: $(srcdir)/../libiberty/obstack.c $(CONFIG_H)
$(LN_S) $(srcdir)/../libiberty/obstack.c obstack.c
$(CC) -c $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) obstack.c
+choose-temp.o: $(srcdir)/../libiberty/choose-temp.c $(CONFIG_H) system.h
+ rm -f choose-temp.c
+ $(LN_S) $(srcdir)/../libiberty/choose-temp.c choose-temp.c
+ $(CC) -c $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) choose-temp.c
+
+mkstemp.o: $(srcdir)/../libiberty/mkstemp.c $(CONFIG_H) system.h
+ rm -f mkstemp.c
+ $(LN_S) $(srcdir)/../libiberty/mkstemp.c mkstemp.c
+ $(CC) -c $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) mkstemp.c
+
prefix.o: prefix.c $(CONFIG_H) system.h Makefile prefix.h
$(CC) $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) \
-DPREFIX=\"$(prefix)\" \
@@ -1959,7 +1979,7 @@ cccp.o: cccp.c $(CONFIG_H) intl.h pcp.h version.c config.status system.h \
-c `echo $(srcdir)/cccp.c | sed 's,^\./,,'`
LIBCPP_OBJS = cpplib.o cpphash.o cppalloc.o cpperror.o cppexp.o cppfiles.o \
- cppulp.o prefix.o version.o mbchar.o @extra_cpp_objs@ intl.o
+ cppinit.o cppulp.o prefix.o version.o mbchar.o @extra_cpp_objs@
# All the other archives built/used by this makefile are for targets. This
# one is strictly for the host.
@@ -1996,12 +2016,15 @@ cpphash.o: cpphash.c cpplib.h machmode.h cpphash.h $(CONFIG_H) system.h
cppalloc.o: cppalloc.c $(CONFIG_H) cpplib.h machmode.h system.h
+cppinit.o: cppalloc.c $(CONFIG_H) cpplib.h machmode.h system.h
+
# Note for the stamp targets, we run the program `true' instead of
# having an empty command (nothing following the semicolon).
proto: config.status protoize$(exeext) unprotoize$(exeext) SYSCALLS.c.X
-PROTO_OBJS = getpwd.o intl.o version.o
+PROTO_OBJS = choose-temp.o getopt.o getopt1.o getpwd.o \
+ intl.o pexecute.o version.o mkstemp.o
protoize$(exeext): protoize.o $(PROTO_OBJS) $(LIBDEPS)
$(CC) $(ALL_CFLAGS) $(LDFLAGS) -o $@ protoize.o $(PROTO_OBJS) $(LIBS)
@@ -2031,6 +2054,16 @@ unprotoize.o: unprotoize.c protoize.c $(srcdir)/../include/getopt.h \
-DSTD_PROTO_DIR=\"$(libsubdir)\" \
$(srcdir)/unprotoize.c
+getopt.o: $(srcdir)/../libiberty/getopt.c $(srcdir)/../include/getopt.h
+ rm -f getopt.c
+ $(LN_S) $(srcdir)/../libiberty/getopt.c getopt.c
+ $(CC) -c $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) getopt.c
+
+getopt1.o: $(srcdir)/../libiberty/getopt1.c $(srcdir)/../include/getopt.h
+ rm -f getopt1.c
+ $(LN_S) $(srcdir)/../libiberty/getopt1.c getopt1.c
+ $(CC) -c $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) getopt1.c
+
# This info describes the target machine, so compile with GCC just built.
SYSCALLS.c.X: $(srcdir)/sys-types.h $(srcdir)/sys-protos.h $(GCC_PASSES) \
stmp-int-hdrs
diff --git a/gcc/cppfiles.c b/gcc/cppfiles.c
index 20e939cb43e..9ef74f1b8f9 100644
--- a/gcc/cppfiles.c
+++ b/gcc/cppfiles.c
@@ -814,12 +814,11 @@ read_and_prescan (pfile, fp, desc, len)
int desc;
size_t len;
{
-
U_CHAR *buf = (U_CHAR *) xmalloc (len);
U_CHAR *ip, *op, *line_base;
U_CHAR *ibase;
unsigned int line;
- int count, seen_eof;
+ int count;
size_t offset;
/* 4096 bytes of buffer proper, 2 to detect running off the end without
address arithmetic all the time, and 2 for pushback in the case there's
@@ -832,35 +831,35 @@ read_and_prescan (pfile, fp, desc, len)
line_base = buf;
line = 1;
ibase = intermed + 2;
- seen_eof = 0;
for (;;)
{
read_next:
+
count = read (desc, intermed + 2, INTERMED_BUFFER_SIZE);
if (count < 0)
- goto error;
- if (count == 0)
- seen_eof = 1;
- count += 2 - (ibase - intermed);
- if (count == 0)
+ goto error;
+ else if (count == 0)
break;
+ offset += count;
ip = ibase;
- ip[count] = ip[count+1] = '\0';
ibase = intermed + 2;
- offset += count;
-
+ ibase[count] = ibase[count+1] = '\0';
+
if (offset > len)
{
- size_t delta_op = op - buf;
- size_t delta_line_base = line_base - buf;
+ size_t delta_op;
+ size_t delta_line_base;
len *= 2;
if (offset > len)
/* len overflowed.
This could happen if the file is larger than half the
maximum address space of the machine. */
goto too_big;
+
+ delta_op = op - buf;
+ delta_line_base = line_base - buf;
buf = xrealloc (buf, len);
op = buf + delta_op;
line_base = buf + delta_line_base;
@@ -868,7 +867,7 @@ read_and_prescan (pfile, fp, desc, len)
for (;;)
{
- U_CHAR c;
+ unsigned int c;
c = *ip++;
switch (c)
{
@@ -880,16 +879,14 @@ read_and_prescan (pfile, fp, desc, len)
break;
case '\0':
- if (seen_eof)
- goto eof;
- else
- goto read_next;
+ goto read_next;
case '\r':
if (*ip == '\n') ip++;
- else if (*ip == '\0' && !seen_eof)
+ else if (*ip == '\0')
{
- *--ibase = '\r';
- break;
+ --ibase;
+ intermed[1] = '\r';
+ goto read_next;
}
*op++ = '\n';
line++;
@@ -898,10 +895,11 @@ read_and_prescan (pfile, fp, desc, len)
case '\n':
if (*ip == '\r') ip++;
- else if (*ip == '\0' && !seen_eof)
+ else if (*ip == '\0')
{
- *--ibase = '\n';
- break;
+ --ibase;
+ intermed[1] = '\n';
+ goto read_next;
}
*op++ = '\n';
line++;
@@ -912,28 +910,30 @@ read_and_prescan (pfile, fp, desc, len)
if (CPP_OPTIONS (pfile)->trigraphs
|| CPP_OPTIONS (pfile)->warn_trigraphs)
{
+ unsigned int d;
/* If we're at the end of the intermediate buffer,
we have to shift the ?'s down to the start and
come back next pass. */
- c = ip[0];
- if (c == '\0' && !seen_eof)
+ d = ip[0];
+ if (d == '\0')
{
- *--ibase = '?';
- break;
+ --ibase;
+ intermed[1] = '?';
+ goto read_next;
}
- if (c != '?')
+ if (d != '?')
{
*op++ = '?';
break;
}
- c = ip[1];
- if (c == '\0' && !seen_eof)
+ d = ip[1];
+ if (d == '\0')
{
- *--ibase = '?';
- *--ibase = '?';
- break;
+ ibase -= 2;
+ intermed[0] = intermed[1] = '?';
+ goto read_next;
}
- if (!trigraph_table[c])
+ if (!trigraph_table[d])
{
*op++ = '?';
break;
@@ -941,35 +941,49 @@ read_and_prescan (pfile, fp, desc, len)
if (CPP_OPTIONS (pfile)->warn_trigraphs)
cpp_warning_with_line (pfile, line, op-line_base,
- "trigraph ??%c encountered", c);
+ "trigraph ??%c encountered", d);
if (CPP_OPTIONS (pfile)->trigraphs)
- {
- *op++ = trigraph_table[c];
- ip += 2;
- break;
- }
+ *op++ = trigraph_table[d];
else
{
*op++ = '?';
*op++ = '?';
- *op++ = c;
- ip += 2;
+ *op++ = d;
}
+ ip += 2;
}
else
*op++ = c;
}
}
}
- eof:
- if (op == buf)
+ if (offset == 0)
return 0;
+ /* Deal with pushed-back chars at true EOF.
+ If two chars were pushed back, they must both be ?'s.
+ If one was, it might be ?, \r, or \n, and \r needs to
+ become \n.
+ We know we have space already. */
+ if (ibase == intermed)
+ {
+ *op++ = '?';
+ *op++ = '?';
+ }
+ else if (ibase == intermed + 1)
+ {
+ if (*ibase == '?')
+ *op++ = '?';
+ else
+ *op++ = '\n';
+ }
+
if (op[-1] != '\n' || op[-2] == '\\')
{
- cpp_pedwarn_with_line (pfile, line, op - line_base,
- "no newline at end of file");
+ if (CPP_PEDANTIC (pfile))
+ cpp_pedwarn_with_line (pfile, line, op - line_base,
+ "no newline at end of file");
if (offset + 2 > len)
{
len += 2;
@@ -983,8 +997,7 @@ read_and_prescan (pfile, fp, desc, len)
*op++ = '\n';
}
- buf = xrealloc (buf, op - buf);
- fp->buf = buf;
+ fp->buf = (len - offset < 20) ? buf : xrealloc (buf, op - buf);
return op - buf;
too_big:
diff --git a/gcc/cppinit.c b/gcc/cppinit.c
new file mode 100644
index 00000000000..da7030f5b1b
--- /dev/null
+++ b/gcc/cppinit.c
@@ -0,0 +1,129 @@
+/* CPP Library.
+ Copyright (C) 1986, 87, 89, 92-98, 1999 Free Software Foundation, Inc.
+ Contributed by Per Bothner, 1994-95.
+ Based on CCCP program by Paul Rubin, June 1986
+ Adapted to ANSI C, Richard Stallman, Jan 1987
+
+This program is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 2, or (at your option) any
+later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+/* This file will have more stuff in it eventually, but right now
+ we just have one hack: we move all the is_* table initialization
+ in here, and we can declare them const in cpplib.h, which improves
+ code a bit. */
+
+#include "config.h"
+#include "system.h"
+
+typedef unsigned char U_CHAR;
+
+/* table to tell if char can be part of a C identifier. */
+U_CHAR is_idchar[256] = { 0 };
+/* table to tell if char can be first char of a c identifier. */
+U_CHAR is_idstart[256] = { 0 };
+/* table to tell if c is horizontal space. */
+U_CHAR is_hor_space[256] = { 0 };
+/* table to tell if c is horizontal or vertical space. */
+U_CHAR is_space[256] = { 0 };
+/* Table to handle trigraph conversion, which occurs before all other
+ processing, everywhere in the file. (This is necessary since one
+ of the trigraphs encodes backslash.) Note it's off by default.
+
+ from to from to from to
+ ?? = # ?? ) ] ?? ! |
+ ?? ( [ ?? ' ^ ?? > }
+ ?? / \ ?? < { ?? - ~
+
+ There is not a space between the ?? and the third char. I put spaces
+ there to avoid warnings when compiling this file. */
+U_CHAR trigraph_table[256] = { 0 };
+
+/* Initialize syntactic classifications of characters. */
+void
+initialize_char_syntax (int dollar_in_ident)
+{
+ is_idstart['a'] = 1; is_idstart['b'] = 1; is_idstart['c'] = 1;
+ is_idstart['d'] = 1; is_idstart['e'] = 1; is_idstart['f'] = 1;
+ is_idstart['g'] = 1; is_idstart['h'] = 1; is_idstart['i'] = 1;
+ is_idstart['j'] = 1; is_idstart['k'] = 1; is_idstart['l'] = 1;
+ is_idstart['m'] = 1; is_idstart['n'] = 1; is_idstart['o'] = 1;
+ is_idstart['p'] = 1; is_idstart['q'] = 1; is_idstart['r'] = 1;
+ is_idstart['s'] = 1; is_idstart['t'] = 1; is_idstart['u'] = 1;
+ is_idstart['v'] = 1; is_idstart['w'] = 1; is_idstart['x'] = 1;
+ is_idstart['y'] = 1; is_idstart['z'] = 1;
+
+ is_idstart['A'] = 1; is_idstart['B'] = 1; is_idstart['C'] = 1;
+ is_idstart['D'] = 1; is_idstart['E'] = 1; is_idstart['F'] = 1;
+ is_idstart['G'] = 1; is_idstart['H'] = 1; is_idstart['I'] = 1;
+ is_idstart['J'] = 1; is_idstart['K'] = 1; is_idstart['L'] = 1;
+ is_idstart['M'] = 1; is_idstart['N'] = 1; is_idstart['O'] = 1;
+ is_idstart['P'] = 1; is_idstart['Q'] = 1; is_idstart['R'] = 1;
+ is_idstart['S'] = 1; is_idstart['T'] = 1; is_idstart['U'] = 1;
+ is_idstart['V'] = 1; is_idstart['W'] = 1; is_idstart['X'] = 1;
+ is_idstart['Y'] = 1; is_idstart['Z'] = 1;
+
+ is_idstart['_'] = 1;
+
+ is_idchar['a'] = 1; is_idchar['b'] = 1; is_idchar['c'] = 1;
+ is_idchar['d'] = 1; is_idchar['e'] = 1; is_idchar['f'] = 1;
+ is_idchar['g'] = 1; is_idchar['h'] = 1; is_idchar['i'] = 1;
+ is_idchar['j'] = 1; is_idchar['k'] = 1; is_idchar['l'] = 1;
+ is_idchar['m'] = 1; is_idchar['n'] = 1; is_idchar['o'] = 1;
+ is_idchar['p'] = 1; is_idchar['q'] = 1; is_idchar['r'] = 1;
+ is_idchar['s'] = 1; is_idchar['t'] = 1; is_idchar['u'] = 1;
+ is_idchar['v'] = 1; is_idchar['w'] = 1; is_idchar['x'] = 1;
+ is_idchar['y'] = 1; is_idchar['z'] = 1;
+
+ is_idchar['A'] = 1; is_idchar['B'] = 1; is_idchar['C'] = 1;
+ is_idchar['D'] = 1; is_idchar['E'] = 1; is_idchar['F'] = 1;
+ is_idchar['G'] = 1; is_idchar['H'] = 1; is_idchar['I'] = 1;
+ is_idchar['J'] = 1; is_idchar['K'] = 1; is_idchar['L'] = 1;
+ is_idchar['M'] = 1; is_idchar['N'] = 1; is_idchar['O'] = 1;
+ is_idchar['P'] = 1; is_idchar['Q'] = 1; is_idchar['R'] = 1;
+ is_idchar['S'] = 1; is_idchar['T'] = 1; is_idchar['U'] = 1;
+ is_idchar['V'] = 1; is_idchar['W'] = 1; is_idchar['X'] = 1;
+ is_idchar['Y'] = 1; is_idchar['Z'] = 1;
+
+ is_idchar['1'] = 1; is_idchar['2'] = 1; is_idchar['3'] = 1;
+ is_idchar['4'] = 1; is_idchar['5'] = 1; is_idchar['6'] = 1;
+ is_idchar['7'] = 1; is_idchar['8'] = 1; is_idchar['9'] = 1;
+ is_idchar['0'] = 1;
+
+ is_idchar['_'] = 1;
+
+ /* These will be reset later if -$ is in effect. */
+ is_idchar['$'] = dollar_in_ident;
+ is_idstart['$'] = dollar_in_ident;
+
+ /* horizontal space table */
+ is_hor_space[' '] = 1;
+ is_hor_space['\t'] = 1;
+ is_hor_space['\v'] = 1;
+ is_hor_space['\f'] = 1;
+ is_hor_space['\r'] = 1;
+
+ is_space[' '] = 1;
+ is_space['\t'] = 1;
+ is_space['\v'] = 1;
+ is_space['\f'] = 1;
+ is_space['\n'] = 1;
+ is_space['\r'] = 1;
+
+ /* trigraph conversion */
+ trigraph_table['='] = '#'; trigraph_table[')'] = ']';
+ trigraph_table['!'] = '|'; trigraph_table['('] = '[';
+ trigraph_table['\''] = '^'; trigraph_table['>'] = '}';
+ trigraph_table['/'] = '\\'; trigraph_table['<'] = '{';
+ trigraph_table['-'] = '~';
+}
diff --git a/gcc/cpplib.c b/gcc/cpplib.c
index 770956bcb25..abe54d8af83 100644
--- a/gcc/cpplib.c
+++ b/gcc/cpplib.c
@@ -127,10 +127,8 @@ struct cpp_pending {
extern void cpp_hash_cleanup PARAMS ((cpp_reader *));
static char *my_strerror PROTO ((int));
-static void make_assertion PROTO ((cpp_reader *, char *, U_CHAR *));
static void path_include PROTO ((cpp_reader *, char *));
static void initialize_builtins PROTO ((cpp_reader *));
-static void initialize_char_syntax PROTO ((void));
static void validate_else PROTO ((cpp_reader *, char *));
static int comp_def_part PROTO ((int, U_CHAR *, int, U_CHAR *,
int, int));
@@ -279,75 +277,6 @@ static struct directive directive_table[] = {
{ 8, do_unassert, "unassert", T_UNASSERT },
{ -1, 0, "", T_UNUSED }
};
-
-/* table to tell if char can be part of a C identifier. */
-U_CHAR is_idchar[256] = { 0 };
-/* table to tell if char can be first char of a c identifier. */
-U_CHAR is_idstart[256] = { 0 };
-/* table to tell if c is horizontal space. */
-U_CHAR is_hor_space[256] = { 0 };
-/* table to tell if c is horizontal or vertical space. */
-U_CHAR is_space[256] = { 0 };
-/* Table to handle trigraph conversion, which occurs before all other
- processing, everywhere in the file. (This is necessary since one
- of the trigraphs encodes backslash.) Note it's off by default.
-
- from to from to from to
- ?? = # ?? ) ] ?? ! |
- ?? ( [ ?? ' ^ ?? > }
- ?? / \ ?? < { ?? - ~
-
- There is not a space between the ?? and the third char. I put spaces
- there to avoid warnings when compiling this file. */
-U_CHAR trigraph_table[256] = { 0 };
-
-/* Initialize syntactic classifications of characters. */
-static void
-initialize_char_syntax ()
-{
- register int i;
-
- /*
- * Set up is_idchar and is_idstart tables. These should be
- * faster than saying (is_alpha (c) || c == '_'), etc.
- * Set up these things before calling any routines tthat
- * refer to them.
- * XXX We should setlocale(LC_CTYPE, "C") here for safety.
- */
- for (i = 0; i < 256; i++)
- {
- is_idchar[i] = ISALNUM (i);
- is_idstart[i] = ISALPHA (i);
- }
-
- is_idchar['_'] = 1;
- is_idstart['_'] = 1;
-
- /* These will be reset later if -$ is in effect. */
- is_idchar['$'] = 1;
- is_idstart['$'] = 1;
-
- /* horizontal space table */
- is_hor_space[' '] = 1;
- is_hor_space['\t'] = 1;
- is_hor_space['\v'] = 1;
- is_hor_space['\f'] = 1;
- is_hor_space['\r'] = 1;
-
- is_space[' '] = 1;
- is_space['\t'] = 1;
- is_space['\v'] = 1;
- is_space['\f'] = 1;
- is_space['\n'] = 1;
- is_space['\r'] = 1;
-
- /* trigraph conversion */
- trigraph_table['='] = '#'; trigraph_table[')'] = ']';
- trigraph_table['!'] = '|'; trigraph_table['('] = '[';
- trigraph_table['\''] = '^'; trigraph_table['>'] = '}';
- trigraph_table['/'] = '\\'; trigraph_table['<'] = '{';
- trigraph_table['-'] = '~';
-}
/* Place into PFILE a quoted string representing the string SRC.
Caller must reserve enough space in pfile->token_buffer. */
@@ -400,13 +329,10 @@ cpp_grow_buffer (pfile, n)
CPP_SET_WRITTEN (pfile, old_written);
}
-
-/*
- * process a given definition string, for initialization
- * If STR is just an identifier, define it with value 1.
- * If STR has anything after the identifier, then it should
- * be identifier=definition.
- */
+/* Process the string STR as if it appeared as the body of a #define
+ If STR is just an identifier, define it with value 1.
+ If STR has anything after the identifier, then it should
+ be identifier=definition. */
void
cpp_define (pfile, str)
@@ -414,101 +340,37 @@ cpp_define (pfile, str)
U_CHAR *str;
{
U_CHAR *buf, *p;
+ size_t count;
- buf = str;
- p = str;
- if (!is_idstart[*p])
- {
- cpp_error (pfile, "malformed option `-D %s'", str);
- return;
- }
- while (is_idchar[*++p])
- ;
- if (*p == '(') {
- while (is_idchar[*++p] || *p == ',' || is_hor_space[*p])
- ;
- if (*p++ != ')')
- p = (U_CHAR *) str; /* Error */
- }
- if (*p == 0)
- {
- buf = (U_CHAR *) alloca (p - buf + 4);
- strcpy ((char *)buf, str);
- strcat ((char *)buf, " 1");
- }
- else if (*p != '=')
+ /* Copy the entire option so we can modify it. */
+ count = strlen (str) + 3;
+ buf = (U_CHAR *) alloca (count);
+ memcpy (buf, str, count - 2);
+ /* Change the first "=" in the string to a space. If there is none,
+ tack " 1" on the end. */
+ p = strchr (buf, '=');
+ if (p)
{
- cpp_error (pfile, "malformed option `-D %s'", str);
- return;
+ *p = ' ';
+ count -= 2;
}
else
- {
- U_CHAR *q;
- /* Copy the entire option so we can modify it. */
- buf = (U_CHAR *) alloca (2 * strlen (str) + 1);
- strncpy (buf, str, p - str);
- /* Change the = to a space. */
- buf[p - str] = ' ';
- /* Scan for any backslash-newline and remove it. */
- p++;
- q = &buf[p - str];
- while (*p)
- {
- if (*p == '\\' && p[1] == '\n')
- p += 2;
- else
- *q++ = *p++;
- }
- *q = 0;
- }
+ strcpy (&buf[count-3], " 1");
- if (cpp_push_buffer (pfile, buf, strlen (buf)) != NULL)
+ if (cpp_push_buffer (pfile, buf, count - 1) != NULL)
{
do_define (pfile, NULL);
cpp_pop_buffer (pfile);
}
}
-
-/* Process the string STR as if it appeared as the body of a #assert.
- OPTION is the option name for which STR was the argument. */
-static void
-make_assertion (pfile, option, str)
+/* Process the string STR as if it appeared as the body of a #assert. */
+void
+cpp_assert (pfile, str)
cpp_reader *pfile;
- char *option;
U_CHAR *str;
{
- U_CHAR *buf, *p, *q;
-
- /* Copy the entire option so we can modify it. */
- buf = (U_CHAR *) alloca (strlen (str) + 1);
- strcpy ((char *) buf, str);
- /* Scan for any backslash-newline and remove it. */
- p = q = buf;
- while (*p) {
-#if 0
- if (*p == '\\' && p[1] == '\n')
- p += 2;
- else
-#endif
- *q++ = *p++;
- }
- *q = 0;
-
- p = buf;
- if (!is_idstart[*p]) {
- cpp_error (pfile, "malformed option `%s %s'", option, str);
- return;
- }
- while (is_idchar[*++p])
- ;
- while (*p == ' ' || *p == '\t') p++;
- if (! (*p == 0 || *p == '(')) {
- cpp_error (pfile, "malformed option `%s %s'", option, str);
- return;
- }
-
- if (cpp_push_buffer (pfile, buf, strlen (buf)) != NULL)
+ if (cpp_push_buffer (pfile, str, strlen (str)) != NULL)
{
do_assert (pfile, NULL);
cpp_pop_buffer (pfile);
@@ -563,32 +425,10 @@ cpp_options_init (opts)
cpp_options *opts;
{
bzero ((char *) opts, sizeof *opts);
- opts->in_fname = NULL;
- opts->out_fname = NULL;
opts->dollars_in_ident = 1;
- initialize_char_syntax ();
-
- opts->no_line_commands = 0;
- opts->trigraphs = 0;
- opts->put_out_comments = 0;
- opts->print_include_names = 0;
- opts->dump_macros = dump_none;
- opts->no_output = 0;
- opts->remap = 0;
- opts->cplusplus = 0;
opts->cplusplus_comments = 1;
-
- opts->verbose = 0;
- opts->objc = 0;
- opts->lang_asm = 0;
- opts->for_lint = 0;
- opts->chill = 0;
- opts->pedantic_errors = 0;
- opts->inhibit_warnings = 0;
- opts->warn_comments = 0;
opts->warn_import = 1;
- opts->warnings_are_errors = 0;
}
enum cpp_token
@@ -1707,7 +1547,6 @@ cpp_expand_to_buffer (pfile, buf, length)
#if 0
cpp_buffer obuf;
#endif
- U_CHAR *limit = buf + length;
U_CHAR *buf1;
#if 0
int odepth = indepth;
@@ -1719,13 +1558,7 @@ cpp_expand_to_buffer (pfile, buf, length)
/* Set up the input on the input stack. */
buf1 = (U_CHAR *) alloca (length + 1);
- {
- register U_CHAR *p1 = buf;
- register U_CHAR *p2 = buf1;
-
- while (p1 != limit)
- *p2++ = *p1++;
- }
+ memcpy (buf1, buf, length);
buf1[length] = 0;
ip = cpp_push_buffer (pfile, buf1, length);
@@ -1739,11 +1572,6 @@ cpp_expand_to_buffer (pfile, buf, length)
/* Scan the input, create the output. */
cpp_scan_buffer (pfile);
-#if 0
- if (indepth != odepth)
- abort ();
-#endif
-
CPP_NUL_TERMINATE (pfile);
}
@@ -2932,19 +2760,7 @@ do_include (pfile, keyword)
&& !CPP_BUFFER (pfile)->system_header_p && !pfile->import_warning)
{
pfile->import_warning = 1;
- cpp_warning (pfile, "using `#import' is not recommended");
- cpp_notice ("The fact that a certain header file need not be processed more than once\n\
-should be indicated in the header file, not where it is used.\n\
-The best way to do this is with a conditional of this form:\n\
-\n\
- #ifndef _FOO_H_INCLUDED\n\
- #define _FOO_H_INCLUDED\n\
- ... <real contents of file> ...\n\
- #endif /* Not _FOO_H_INCLUDED */\n\
-\n\
-Then users can use `#include' any number of times.\n\
-GNU C automatically avoids processing the file more than once\n\
-when it is equipped with such a conditional.\n");
+ cpp_warning (pfile, "`#import' is obsolete, use an #ifndef wrapper in the header file");
}
pfile->parsing_include_directive++;
@@ -3139,57 +2955,9 @@ when it is equipped with such a conditional.\n");
return 0;
}
-
-/* Convert a character string literal into a nul-terminated string.
- The input string is [IN ... LIMIT).
- The result is placed in RESULT. RESULT can be the same as IN.
- The value returned in the end of the string written to RESULT,
- or NULL on error. */
-
-static U_CHAR *
-convert_string (pfile, result, in, limit, handle_escapes)
- cpp_reader *pfile;
- register U_CHAR *result, *in, *limit;
- int handle_escapes;
-{
- U_CHAR c;
- c = *in++;
- if (c != '\"')
- return NULL;
- while (in < limit)
- {
- U_CHAR c = *in++;
- switch (c)
- {
- case '\0':
- return NULL;
- case '\"':
- limit = in;
- break;
- case '\\':
- if (handle_escapes)
- {
- char *bpc = (char *) in;
- int i = (U_CHAR) cpp_parse_escape (pfile, &bpc, 0x00ff);
- in = (U_CHAR *) bpc;
- if (i >= 0)
- *result++ = (U_CHAR)c;
- break;
- }
- /* else fall through */
- default:
- *result++ = c;
- }
- }
- *result = 0;
- return result;
-}
-
-/*
- * interpret #line command. Remembers previously seen fnames
- * in its very own hash table.
- */
-#define FNAME_HASHSIZE 37
+/* Interpret #line command.
+ Note that the filename string (if any) is treated as if it were an
+ include filename. That means no escape handling. */
static int
do_line (pfile, keyword)
@@ -3201,126 +2969,121 @@ do_line (pfile, keyword)
long old_written = CPP_WRITTEN (pfile);
enum file_change_code file_change = same_file;
enum cpp_token token;
+ char *x;
token = get_directive_token (pfile);
- if (token != CPP_NUMBER
- || !ISDIGIT(pfile->token_buffer[old_written]))
+ if (token != CPP_NUMBER)
{
- cpp_error (pfile, "invalid format `#line' command");
+ cpp_error (pfile, "token after `#line' is not an integer");
goto bad_line_directive;
}
- /* The Newline at the end of this line remains to be processed.
- To put the next line at the specified line number,
- we must store a line number now that is one less. */
- new_lineno = atoi ((char *)(pfile->token_buffer + old_written)) - 1;
+ new_lineno = strtol (pfile->token_buffer + old_written, &x, 10);
+ if (x[0] != '\0')
+ {
+ cpp_error (pfile, "token after `#line' is not an integer");
+ goto bad_line_directive;
+ }
CPP_SET_WRITTEN (pfile, old_written);
- /* NEW_LINENO is one less than the actual line number here. */
- if (CPP_PEDANTIC (pfile) && new_lineno < 0)
+ if (CPP_PEDANTIC (pfile) && new_lineno <= 0)
cpp_pedwarn (pfile, "line number out of range in `#line' command");
-#if 0 /* #line 10"foo.c" is supposed to be allowed. */
- if (PEEKC() && !is_space[PEEKC()]) {
- cpp_error (pfile, "invalid format `#line' command");
- goto bad_line_directive;
- }
-#endif
-
token = get_directive_token (pfile);
- if (token == CPP_STRING) {
- U_CHAR *fname = pfile->token_buffer + old_written;
- U_CHAR *end_name;
- static HASHNODE *fname_table[FNAME_HASHSIZE];
- HASHNODE *hp, **hash_bucket;
- U_CHAR *p;
- long num_start;
- int fname_length;
-
- /* Turn the file name, which is a character string literal,
- into a null-terminated string. Do this in place. */
- end_name = convert_string (pfile, fname, fname, CPP_PWRITTEN (pfile), 1);
- if (end_name == NULL)
+ if (token == CPP_STRING)
{
- cpp_error (pfile, "invalid format `#line' command");
- goto bad_line_directive;
- }
+ U_CHAR *fname = pfile->token_buffer + old_written + 1;
+ U_CHAR *end_name = CPP_PWRITTEN (pfile) - 1;
+ long num_start = CPP_WRITTEN (pfile);
- fname_length = end_name - fname;
+ token = get_directive_token (pfile);
+ if (token != CPP_VSPACE && token != CPP_EOF && token != CPP_POP)
+ {
+ U_CHAR *p = pfile->token_buffer + num_start;
+ if (CPP_PEDANTIC (pfile))
+ cpp_pedwarn (pfile, "garbage at end of `#line' command");
- num_start = CPP_WRITTEN (pfile);
- token = get_directive_token (pfile);
- if (token != CPP_VSPACE && token != CPP_EOF && token != CPP_POP) {
- p = pfile->token_buffer + num_start;
- if (CPP_PEDANTIC (pfile))
- cpp_pedwarn (pfile, "garbage at end of `#line' command");
+ if (token != CPP_NUMBER || *p < '0' || *p > '4' || p[1] != '\0')
+ {
+ cpp_error (pfile, "invalid format `#line' command");
+ goto bad_line_directive;
+ }
+ if (*p == '1')
+ file_change = enter_file;
+ else if (*p == '2')
+ file_change = leave_file;
+ else if (*p == '3')
+ ip->system_header_p = 1;
+ else /* if (*p == '4') */
+ ip->system_header_p = 2;
+
+ CPP_SET_WRITTEN (pfile, num_start);
+ token = get_directive_token (pfile);
+ p = pfile->token_buffer + num_start;
+ if (token == CPP_NUMBER && p[1] == '\0' && (*p == '3' || *p== '4'))
+ {
+ ip->system_header_p = *p == '3' ? 1 : 2;
+ token = get_directive_token (pfile);
+ }
+ if (token != CPP_VSPACE)
+ {
+ cpp_error (pfile, "invalid format `#line' command");
+ goto bad_line_directive;
+ }
+ }
+
+ *end_name = '\0';
+
+ if (strcmp (fname, ip->nominal_fname))
+ {
+ char *newname, *oldname;
+ if (!strcmp (fname, ip->fname))
+ newname = ip->fname;
+ else if (ip->last_nominal_fname
+ && !strcmp (fname, ip->last_nominal_fname))
+ newname = ip->last_nominal_fname;
+ else
+ newname = xstrdup (fname);
- if (token != CPP_NUMBER || *p < '0' || *p > '4' || p[1] != '\0')
- {
- cpp_error (pfile, "invalid format `#line' command");
- goto bad_line_directive;
- }
- if (*p == '1')
- file_change = enter_file;
- else if (*p == '2')
- file_change = leave_file;
- else if (*p == '3')
- ip->system_header_p = 1;
- else /* if (*p == '4') */
- ip->system_header_p = 2;
-
- CPP_SET_WRITTEN (pfile, num_start);
- token = get_directive_token (pfile);
- p = pfile->token_buffer + num_start;
- if (token == CPP_NUMBER && p[1] == '\0' && (*p == '3' || *p== '4')) {
- ip->system_header_p = *p == '3' ? 1 : 2;
- token = get_directive_token (pfile);
- }
- if (token != CPP_VSPACE) {
- cpp_error (pfile, "invalid format `#line' command");
- goto bad_line_directive;
- }
- }
+ oldname = ip->nominal_fname;
+ ip->nominal_fname = newname;
- hash_bucket = &fname_table[hashf (fname, fname_length, FNAME_HASHSIZE)];
- for (hp = *hash_bucket; hp != NULL; hp = hp->next)
- if (hp->length == fname_length
- && strncmp (hp->value.cpval, fname, fname_length) == 0) {
- ip->nominal_fname = hp->value.cpval;
- break;
- }
- if (hp == 0) {
- /* Didn't find it; cons up a new one. */
- hp = (HASHNODE *) xcalloc (1, sizeof (HASHNODE) + fname_length + 1);
- hp->next = *hash_bucket;
- *hash_bucket = hp;
-
- hp->length = fname_length;
- ip->nominal_fname = hp->value.cpval = ((char *) hp) + sizeof (HASHNODE);
- bcopy (fname, hp->value.cpval, fname_length);
+ if (ip->last_nominal_fname
+ && ip->last_nominal_fname != oldname
+ && ip->last_nominal_fname != newname)
+ free (ip->last_nominal_fname);
+
+ if (newname == ip->fname)
+ ip->last_nominal_fname = NULL;
+ else
+ ip->last_nominal_fname = oldname;
+ }
+ }
+ else if (token != CPP_VSPACE && token != CPP_EOF)
+ {
+ cpp_error (pfile, "token after `#line %d' is not a string", new_lineno);
+ goto bad_line_directive;
}
- }
- else if (token != CPP_VSPACE && token != CPP_EOF) {
- cpp_error (pfile, "invalid format `#line' command");
- goto bad_line_directive;
- }
- ip->lineno = new_lineno;
+ /* The Newline at the end of this line remains to be processed.
+ To put the next line at the specified line number,
+ we must store a line number now that is one less. */
+ ip->lineno = new_lineno - 1;
+ CPP_SET_WRITTEN (pfile, old_written);
+ output_line_command (pfile, 0, file_change);
+ return 0;
+
bad_line_directive:
skip_rest_of_line (pfile);
CPP_SET_WRITTEN (pfile, old_written);
- output_line_command (pfile, 0, file_change);
return 0;
}
-/*
- * remove the definition of a symbol from the symbol table.
- * according to un*x /lib/cpp, it is not an error to undef
- * something that has no definitions, so it isn't one here either.
- */
-
+/* Remove the definition of a symbol from the symbol table.
+ According to the C standard, it is not an error to undef
+ something that has no definitions. */
static int
do_undef (pfile, keyword)
cpp_reader *pfile;
@@ -4711,22 +4474,21 @@ cpp_start_read (pfile, fname)
cpp_buffer *fp;
struct include_hash *ih_fake;
- /* The code looks at the defaults through this pointer, rather than through
- the constant structure above. This pointer gets changed if an environment
- variable specifies other defaults. */
+ /* The code looks at the defaults through this pointer, rather than
+ through the constant structure above. This pointer gets changed
+ if an environment variable specifies other defaults. */
struct default_include *include_defaults = include_defaults_array;
- /* Now that we know dollars_in_ident for real,
- reset is_idchar/is_idstart. */
- is_idchar['$'] = opts->dollars_in_ident;
- is_idstart['$'] = opts->dollars_in_ident;
+ /* Now that we know dollars_in_ident, we can initialize the syntax
+ tables. */
+ initialize_char_syntax (opts->dollars_in_ident);
/* Add dirs from CPATH after dirs from -I. */
/* There seems to be confusion about what CPATH should do,
so for the moment it is not documented. */
- /* Some people say that CPATH should replace the standard include dirs,
- but that seems pointless: it comes before them, so it overrides them
- anyway. */
+ /* Some people say that CPATH should replace the standard include
+ dirs, but that seems pointless: it comes before them, so it
+ overrides them anyway. */
GET_ENV_PATH_LIST (p, "CPATH");
if (p != 0 && ! opts->no_standard_includes)
path_include (pfile, p);
@@ -4810,7 +4572,7 @@ cpp_start_read (pfile, fname)
save_char = *termination;
*termination = '\0';
/* Install the assertion. */
- make_assertion (pfile, "-A", assertion);
+ cpp_assert (pfile, assertion);
*termination = (char) save_char;
p = termination;
while (*p == ' ' || *p == '\t')
@@ -4844,7 +4606,7 @@ cpp_start_read (pfile, fname)
cpp_define (pfile, pend->arg);
break;
case 'A':
- make_assertion (pfile, "-A", pend->arg);
+ cpp_assert (pfile, pend->arg);
break;
}
}
@@ -5273,6 +5035,10 @@ print_help ()
printf (" -lang-objc++ Assume that the input sources are in ObjectiveC++\n");
printf (" -lang-asm Assume that the input sources are in assembler\n");
printf (" -lang-chill Assume that the input sources are in Chill\n");
+ printf (" -std=<std name> Specify the conformance standard; one of:\n");
+ printf (" gnu89, gnu9x, c89, c9x, iso9899:1990,\n");
+ printf (" iso9899:199409, iso9899:199x\n");
+
printf (" -+ Allow parsing of C++ style features\n");
printf (" -w Inhibit warning messages\n");
printf (" -Wtrigraphs Warn if trigraphs are encountered\n");
@@ -5520,19 +5286,19 @@ cpp_handle_option (pfile, argc, argv)
case 'l':
if (! strcmp (argv[i], "-lang-c"))
opts->cplusplus = 0, opts->cplusplus_comments = 1, opts->c89 = 0,
- opts->objc = 0;
+ opts->c9x = 1, opts->objc = 0;
if (! strcmp (argv[i], "-lang-c89"))
opts->cplusplus = 0, opts->cplusplus_comments = 0, opts->c89 = 1,
- opts->objc = 0;
+ opts->c9x = 0, opts->objc = 0;
if (! strcmp (argv[i], "-lang-c++"))
opts->cplusplus = 1, opts->cplusplus_comments = 1, opts->c89 = 0,
- opts->objc = 0;
+ opts->c9x = 0, opts->objc = 0;
if (! strcmp (argv[i], "-lang-objc"))
opts->cplusplus = 0, opts->cplusplus_comments = 1, opts->c89 = 0,
- opts->objc = 1;
+ opts->c9x = 0, opts->objc = 1;
if (! strcmp (argv[i], "-lang-objc++"))
opts->cplusplus = 1, opts->cplusplus_comments = 1, opts->c89 = 0,
- opts->objc = 1;
+ opts->c9x = 0, opts->objc = 1;
if (! strcmp (argv[i], "-lang-asm"))
opts->lang_asm = 1;
if (! strcmp (argv[i], "-lint"))
@@ -5545,7 +5311,21 @@ cpp_handle_option (pfile, argc, argv)
case '+':
opts->cplusplus = 1, opts->cplusplus_comments = 1;
break;
-
+
+ case 's':
+ if (!strcmp (argv[i], "-std=iso9899:1990")
+ || !strcmp (argv[i], "-std=iso9899:199409")
+ || !strcmp (argv[i], "-std=c89")
+ || !strcmp (argv[i], "-std=gnu89"))
+ opts->cplusplus = 0, opts->cplusplus_comments = 0,
+ opts->c89 = 1, opts->c9x = 0, opts->objc = 0;
+ else if (!strcmp (argv[i], "-std=iso9899:199x")
+ || !strcmp (argv[i], "-std=c9x")
+ || !strcmp (argv[i], "-std=gnu9x"))
+ opts->cplusplus = 0, opts->cplusplus_comments = 1, opts->c89 = 0,
+ opts->c9x = 1, opts->objc = 0;
+ break;
+
case 'w':
opts->inhibit_warnings = 1;
break;
diff --git a/gcc/cpplib.h b/gcc/cpplib.h
index bd041920c69..bd2caf5c3ca 100644
--- a/gcc/cpplib.h
+++ b/gcc/cpplib.h
@@ -108,6 +108,8 @@ struct cpp_buffer {
char *fname;
/* Filename specified with #line command. */
char *nominal_fname;
+ /* Last filename specified with #line command. */
+ char *last_nominal_fname;
/* Actual directory of this file, used only for "" includes */
struct file_name_list *actual_dir;
@@ -422,6 +424,9 @@ struct cpp_options {
/* Nonzero for the 1989 C Standard, including corrigenda and amendments. */
char c89;
+ /* Nonzero for the 199x C Standard, including corrigenda and amendments. */
+ char c9x;
+
/* Nonzero means give all the error messages the ANSI standard requires. */
char pedantic;
@@ -639,10 +644,11 @@ struct definition {
} args;
};
-extern unsigned char is_idchar[256];
-extern unsigned char is_hor_space[256];
-extern unsigned char is_space[256];
-extern unsigned char trigraph_table[256];
+extern const unsigned char is_idstart[256];
+extern const unsigned char is_idchar[256];
+extern const unsigned char is_hor_space[256];
+extern const unsigned char is_space[256];
+extern const unsigned char trigraph_table[256];
/* Stack of conditionals currently in progress
(including both successful and failing conditionals). */
@@ -669,6 +675,7 @@ typedef struct if_stack IF_STACK_FRAME;
extern void cpp_buf_line_and_col PARAMS((cpp_buffer *, long *, long *));
extern cpp_buffer* cpp_file_buffer PARAMS((cpp_reader *));
extern void cpp_define PARAMS ((cpp_reader*, unsigned char *));
+extern void cpp_assert PARAMS ((cpp_reader *, unsigned char *));
extern void cpp_error PVPROTO ((cpp_reader *, const char *, ...))
ATTRIBUTE_PRINTF_2;
@@ -729,6 +736,9 @@ extern int finclude PROTO ((cpp_reader *, int,
extern void deps_output PROTO ((cpp_reader *, char *, int));
extern struct include_hash *include_hash PROTO ((cpp_reader *, char *, int));
+/* cppinit.c */
+extern void initialize_char_syntax PROTO ((int));
+
#ifndef INCLUDE_LEN_FUDGE
#define INCLUDE_LEN_FUDGE 0
#endif