cpplib.c (initialize_char_syntax): Move to cppinit.c.

1999-02-04 14:33 -0500  Zack Weinberg  <zack@rabi.phys.columbia.edu>
	* cpplib.c (initialize_char_syntax): Move to cppinit.c.
	(cpp_define): Remove redundant syntax checks.
	(make_assertion): Rename cpp_assert, remove redundant syntax
	checks, export.
	(cpp_options_init): Don't init things to zero twice.
	(cpp_expand_to_buffer): Use memcpy, not a char-by-char loop.
	(do_include): Kill excessively verbose import warning that
	snuck back in in the gcc2 merge.
	(convert_string): Removed.
	(do_line): Rewrite with simple last-name-used cache instead of
	private hashtable.
	(cpp_start_read): Call initialize_char_syntax here, not...
	(cpp_reader_init): ...here.
	(cpp_handle_options): Support the -std switch.
	* cpplib.h (cpp_buffer): Add last_nominal_fname member.
	(cpp_options): Add c9x flag.
	Declare all the is_* tables and trigraph table here, as const.
	Prototype cpp_assert and initialize_char_syntax.
	* cppinit.c: New file.
	* cppfiles.c (read_and_prescan): Optimize.
	* Makefile.in (LIBCPP_OBJS): Add cppinit.o.

From-SVN: r25024
This commit is contained in:
Zack Weinberg 1999-02-04 06:36:54 -05:00 committed by Dave Brolley
parent c20df9e705
commit 5538ada62f
5 changed files with 409 additions and 444 deletions

View File

@ -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

View File

@ -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;
ip = ibase;
ip[count] = ip[count+1] = '\0';
ibase = intermed + 2;
offset += count;
ip = ibase;
ibase = intermed + 2;
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:

129
gcc/cppinit.c Normal file
View File

@ -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['-'] = '~';
}

View File

@ -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])
/* 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;
}
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 != '=')
{
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;
}
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);
if (CPP_PEDANTIC (pfile) && new_lineno <= 0)
cpp_pedwarn (pfile, "line number out of range in `#line' command");
token = get_directive_token (pfile);
if (token == CPP_STRING)
{
U_CHAR *fname = pfile->token_buffer + old_written + 1;
U_CHAR *end_name = CPP_PWRITTEN (pfile) - 1;
long num_start = CPP_WRITTEN (pfile);
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");
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);
oldname = ip->nominal_fname;
ip->nominal_fname = newname;
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;
}
/* 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;
CPP_SET_WRITTEN (pfile, old_written);
/* NEW_LINENO is one less than the actual line number here. */
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)
{
cpp_error (pfile, "invalid format `#line' command");
goto bad_line_directive;
}
fname_length = end_name - fname;
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;
}
}
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);
}
}
else if (token != CPP_VSPACE && token != CPP_EOF) {
cpp_error (pfile, "invalid format `#line' command");
goto bad_line_directive;
}
ip->lineno = new_lineno;
bad_line_directive:
skip_rest_of_line (pfile);
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);
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;

View File

@ -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