diff options
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/Makefile.in | 51 | ||||
-rw-r--r-- | gcc/cppfiles.c | 111 | ||||
-rw-r--r-- | gcc/cppinit.c | 129 | ||||
-rw-r--r-- | gcc/cpplib.c | 520 | ||||
-rw-r--r-- | gcc/cpplib.h | 18 |
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 |