mirror of
https://gcc.gnu.org/git/gcc.git
synced 2024-11-23 10:54:07 +08:00
Makefile.in (LIBCPP_DEPS): New macro.
* Makefile.in (LIBCPP_DEPS): New macro. (cpplib.o, cpphash.o, cpperror.o, cppexp.o, cppfiles.o): Use it to declare deps. * cpperror.c: Include cpphash.h. * cppexp.c: Include cpphash.h. Remove MULTIBYTE_CHARS dingleberry. (lex): Don't use CPP_WARN_UNDEF. (_cpp_parse_expr): Return an int, the truth value. * cppfiles.c: Include cpphash.h. (_cpp_merge_include_chains): Move to cppinit.c and make static. * cppinit.c (include_defaults_array): Disentangle. (cpp_cleanup): Don't free the if stack here. (cpp_finish): Pop off all buffers, not just one. * cpplib.c (eval_if_expr): Return int. (do_xifdef): Rename do_ifdef. (handle_directive): Don't use CPP_PREPROCESSED. (cpp_get_token): Don't use CPP_C89. * fix-header.c: Don't use CPP_OPTIONS. * cpplib.h: Move U_CHAR, enum node_type, struct file_name_list, struct ihash, is_idchar, is_idstart, is_numchar, is_numstart, is_hspace, is_space, CPP_BUF_PEEK, CPP_BUF_GET, CPP_FORWARD, CPP_PUTS, CPP_PUTS_Q, CPP_PUTC, CPP_PUTC_Q, CPP_NUL_TERMINATE, CPP_NUL_TERMINATE_Q, CPP_BUMP_BUFFER_LINE, CPP_BUMP_LINE, CPP_PREV_BUFFER, CPP_PRINT_DEPS, CPP_TRADITIONAL, CPP_PEDANTIC, and prototypes of _cpp_simplify_pathname, _cpp_find_include_file, _cpp_read_include_file, and _cpp_parse_expr to cpphash.h. Move struct if_stack to cpplib.c. Move struct cpp_pending to cppinit.c. Change all uses of U_CHAR to be unsigned char instead. Delete CPP_WARN_UNDEF, CPP_C89, and CPP_PREPROCESSED. From-SVN: r32435
This commit is contained in:
parent
737faf1404
commit
88ae23e71d
@ -1,3 +1,38 @@
|
||||
2000-03-08 Zack Weinberg <zack@wolery.cumb.org>
|
||||
|
||||
* Makefile.in (LIBCPP_DEPS): New macro.
|
||||
(cpplib.o, cpphash.o, cpperror.o, cppexp.o, cppfiles.o): Use
|
||||
it to declare deps.
|
||||
* cpperror.c: Include cpphash.h.
|
||||
* cppexp.c: Include cpphash.h. Remove MULTIBYTE_CHARS
|
||||
dingleberry.
|
||||
(lex): Don't use CPP_WARN_UNDEF.
|
||||
(_cpp_parse_expr): Return an int, the truth value.
|
||||
* cppfiles.c: Include cpphash.h.
|
||||
(_cpp_merge_include_chains): Move to cppinit.c and make static.
|
||||
* cppinit.c (include_defaults_array): Disentangle.
|
||||
(cpp_cleanup): Don't free the if stack here.
|
||||
(cpp_finish): Pop off all buffers, not just one.
|
||||
* cpplib.c (eval_if_expr): Return int.
|
||||
(do_xifdef): Rename do_ifdef.
|
||||
(handle_directive): Don't use CPP_PREPROCESSED.
|
||||
(cpp_get_token): Don't use CPP_C89.
|
||||
* fix-header.c: Don't use CPP_OPTIONS.
|
||||
|
||||
* cpplib.h: Move U_CHAR, enum node_type, struct
|
||||
file_name_list, struct ihash, is_idchar, is_idstart,
|
||||
is_numchar, is_numstart, is_hspace, is_space, CPP_BUF_PEEK,
|
||||
CPP_BUF_GET, CPP_FORWARD, CPP_PUTS, CPP_PUTS_Q, CPP_PUTC,
|
||||
CPP_PUTC_Q, CPP_NUL_TERMINATE, CPP_NUL_TERMINATE_Q,
|
||||
CPP_BUMP_BUFFER_LINE, CPP_BUMP_LINE, CPP_PREV_BUFFER,
|
||||
CPP_PRINT_DEPS, CPP_TRADITIONAL, CPP_PEDANTIC, and prototypes
|
||||
of _cpp_simplify_pathname, _cpp_find_include_file,
|
||||
_cpp_read_include_file, and _cpp_parse_expr to cpphash.h.
|
||||
Move struct if_stack to cpplib.c. Move struct cpp_pending to
|
||||
cppinit.c.
|
||||
Change all uses of U_CHAR to be unsigned char instead.
|
||||
Delete CPP_WARN_UNDEF, CPP_C89, and CPP_PREPROCESSED.
|
||||
|
||||
2000-03-08 Jason Merrill <jason@casey.cygnus.com>
|
||||
|
||||
* dwarf2out.c (dw_fde_struct): Add 'nothrow'.
|
||||
|
@ -26,6 +26,7 @@ Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
#include "config.h"
|
||||
#include "system.h"
|
||||
#include "cpplib.h"
|
||||
#include "cpphash.h"
|
||||
#include "intl.h"
|
||||
|
||||
static void print_containing_files PARAMS ((cpp_reader *, cpp_buffer *));
|
||||
|
13
gcc/cppexp.c
13
gcc/cppexp.c
@ -27,10 +27,7 @@ Written by Per Bothner 1994. */
|
||||
#include "config.h"
|
||||
#include "system.h"
|
||||
#include "cpplib.h"
|
||||
|
||||
#ifdef MULTIBYTE_CHARS
|
||||
#include <locale.h>
|
||||
#endif
|
||||
#include "cpphash.h"
|
||||
|
||||
#ifndef CHAR_TYPE_SIZE
|
||||
#define CHAR_TYPE_SIZE BITS_PER_UNIT
|
||||
@ -453,7 +450,7 @@ lex (pfile, skip_evaluation)
|
||||
op.unsignedp = 0;
|
||||
op.value = 0;
|
||||
|
||||
if (CPP_WARN_UNDEF (pfile) && !skip_evaluation)
|
||||
if (CPP_OPTIONS (pfile)->warn_undef && !skip_evaluation)
|
||||
cpp_warning (pfile, "`%.*s' is not defined",
|
||||
(int) (tok_end - tok_start), tok_start);
|
||||
return op;
|
||||
@ -669,9 +666,9 @@ right_shift (pfile, a, unsignedp, b)
|
||||
? (unsigned HOST_WIDEST_INT) v1 OP (unsigned HOST_WIDEST_INT) v2 : (v1 OP v2)
|
||||
|
||||
/* Parse and evaluate a C expression, reading from PFILE.
|
||||
Returns the value of the expression. */
|
||||
Returns the truth value of the expression. */
|
||||
|
||||
HOST_WIDEST_INT
|
||||
int
|
||||
_cpp_parse_expr (pfile)
|
||||
cpp_reader *pfile;
|
||||
{
|
||||
@ -1004,7 +1001,7 @@ _cpp_parse_expr (pfile)
|
||||
cpp_ice (pfile, "unbalanced stack in #if expression");
|
||||
if (stack != init_stack)
|
||||
free (stack);
|
||||
return top->value;
|
||||
return (top->value != 0);
|
||||
}
|
||||
top++;
|
||||
|
||||
|
142
gcc/cppfiles.c
142
gcc/cppfiles.c
@ -27,6 +27,7 @@ Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
#include "config.h"
|
||||
#include "system.h"
|
||||
#include "cpplib.h"
|
||||
#include "cpphash.h"
|
||||
#include "intl.h"
|
||||
|
||||
static IHASH *include_hash PARAMS ((cpp_reader *, const char *, int));
|
||||
@ -49,151 +50,10 @@ static U_CHAR *find_position PARAMS ((U_CHAR *, U_CHAR *, unsigned long *));
|
||||
static void hack_vms_include_specification PARAMS ((char *));
|
||||
#endif
|
||||
|
||||
/* Windows does not natively support inodes, and neither does MSDOS.
|
||||
Cygwin's emulation can generate non-unique inodes, so don't use it.
|
||||
VMS has non-numeric inodes. */
|
||||
#ifdef VMS
|
||||
#define INO_T_EQ(a, b) (!bcmp((char *) &(a), (char *) &(b), sizeof (a)))
|
||||
#elif (defined _WIN32 && ! defined (_UWIN)) \
|
||||
|| defined __MSDOS__
|
||||
#define INO_T_EQ(a, b) 0
|
||||
#else
|
||||
#define INO_T_EQ(a, b) ((a) == (b))
|
||||
#endif
|
||||
|
||||
#ifndef INCLUDE_LEN_FUDGE
|
||||
#define INCLUDE_LEN_FUDGE 0
|
||||
#endif
|
||||
|
||||
/* Merge the four include chains together in the order quote, bracket,
|
||||
system, after. Remove duplicate dirs (as determined by
|
||||
INO_T_EQ()). The system_include and after_include chains are never
|
||||
referred to again after this function; all access is through the
|
||||
bracket_include path.
|
||||
|
||||
For the future: Check if the directory is empty (but
|
||||
how?) and possibly preload the include hash. */
|
||||
|
||||
void
|
||||
_cpp_merge_include_chains (opts)
|
||||
struct cpp_options *opts;
|
||||
{
|
||||
struct file_name_list *prev, *cur, *other;
|
||||
struct file_name_list *quote, *brack, *systm, *after;
|
||||
struct file_name_list *qtail, *btail, *stail, *atail;
|
||||
|
||||
qtail = opts->pending->quote_tail;
|
||||
btail = opts->pending->brack_tail;
|
||||
stail = opts->pending->systm_tail;
|
||||
atail = opts->pending->after_tail;
|
||||
|
||||
quote = opts->pending->quote_head;
|
||||
brack = opts->pending->brack_head;
|
||||
systm = opts->pending->systm_head;
|
||||
after = opts->pending->after_head;
|
||||
|
||||
/* Paste together bracket, system, and after include chains. */
|
||||
if (stail)
|
||||
stail->next = after;
|
||||
else
|
||||
systm = after;
|
||||
if (btail)
|
||||
btail->next = systm;
|
||||
else
|
||||
brack = systm;
|
||||
|
||||
/* This is a bit tricky.
|
||||
First we drop dupes from the quote-include list.
|
||||
Then we drop dupes from the bracket-include list.
|
||||
Finally, if qtail and brack are the same directory,
|
||||
we cut out qtail.
|
||||
|
||||
We can't just merge the lists and then uniquify them because
|
||||
then we may lose directories from the <> search path that should
|
||||
be there; consider -Ifoo -Ibar -I- -Ifoo -Iquux. It is however
|
||||
safe to treat -Ibar -Ifoo -I- -Ifoo -Iquux as if written
|
||||
-Ibar -I- -Ifoo -Iquux.
|
||||
|
||||
Note that this algorithm is quadratic in the number of -I switches,
|
||||
which is acceptable since there aren't usually that many of them. */
|
||||
|
||||
for (cur = quote, prev = NULL; cur; cur = cur->next)
|
||||
{
|
||||
for (other = quote; other != cur; other = other->next)
|
||||
if (INO_T_EQ (cur->ino, other->ino)
|
||||
&& cur->dev == other->dev)
|
||||
{
|
||||
if (opts->verbose)
|
||||
fprintf (stderr, _("ignoring duplicate directory `%s'\n"),
|
||||
cur->name);
|
||||
|
||||
prev->next = cur->next;
|
||||
free (cur->name);
|
||||
free (cur);
|
||||
cur = prev;
|
||||
break;
|
||||
}
|
||||
prev = cur;
|
||||
}
|
||||
qtail = prev;
|
||||
|
||||
for (cur = brack; cur; cur = cur->next)
|
||||
{
|
||||
for (other = brack; other != cur; other = other->next)
|
||||
if (INO_T_EQ (cur->ino, other->ino)
|
||||
&& cur->dev == other->dev)
|
||||
{
|
||||
if (opts->verbose)
|
||||
fprintf (stderr, _("ignoring duplicate directory `%s'\n"),
|
||||
cur->name);
|
||||
|
||||
prev->next = cur->next;
|
||||
free (cur->name);
|
||||
free (cur);
|
||||
cur = prev;
|
||||
break;
|
||||
}
|
||||
prev = cur;
|
||||
}
|
||||
|
||||
if (quote)
|
||||
{
|
||||
if (INO_T_EQ (qtail->ino, brack->ino) && qtail->dev == brack->dev)
|
||||
{
|
||||
if (quote == qtail)
|
||||
{
|
||||
if (opts->verbose)
|
||||
fprintf (stderr, _("ignoring duplicate directory `%s'\n"),
|
||||
quote->name);
|
||||
|
||||
free (quote->name);
|
||||
free (quote);
|
||||
quote = brack;
|
||||
}
|
||||
else
|
||||
{
|
||||
cur = quote;
|
||||
while (cur->next != qtail)
|
||||
cur = cur->next;
|
||||
cur->next = brack;
|
||||
if (opts->verbose)
|
||||
fprintf (stderr, _("ignoring duplicate directory `%s'\n"),
|
||||
qtail->name);
|
||||
|
||||
free (qtail->name);
|
||||
free (qtail);
|
||||
}
|
||||
}
|
||||
else
|
||||
qtail->next = brack;
|
||||
}
|
||||
else
|
||||
quote = brack;
|
||||
|
||||
opts->quote_include = quote;
|
||||
opts->bracket_include = brack;
|
||||
}
|
||||
|
||||
/* Look up or add an entry to the table of all includes. This table
|
||||
is indexed by the name as it appears in the #include line. The
|
||||
->next_this_file chain stores all different files with the same
|
||||
|
171
gcc/cpphash.h
171
gcc/cpphash.h
@ -1,5 +1,5 @@
|
||||
/* Part of CPP library. (Macro hash table support.)
|
||||
Copyright (C) 1997, 1998, 1999 Free Software Foundation, Inc.
|
||||
/* Part of CPP library.
|
||||
Copyright (C) 1997, 1998, 1999, 2000 Free Software Foundation, Inc.
|
||||
|
||||
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
|
||||
@ -15,9 +15,15 @@ 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 header defines all the internal data structures and functions
|
||||
that need to be visible across files. It's called cpphash.h for
|
||||
historical reasons. */
|
||||
|
||||
#ifndef __GCC_CPPHASH__
|
||||
#define __GCC_CPPHASH__
|
||||
|
||||
typedef unsigned char U_CHAR;
|
||||
|
||||
/* Structure allocated for every #define. For a simple replacement
|
||||
such as
|
||||
#define foo bar ,
|
||||
@ -70,6 +76,50 @@ struct definition
|
||||
U_CHAR *argnames;
|
||||
};
|
||||
|
||||
/* The structure of a node in the hash table. The hash table
|
||||
has entries for all tokens defined by #define commands (type T_MACRO),
|
||||
plus some special tokens like __LINE__ (these each have their own
|
||||
type, and the appropriate code is run when that type of node is seen.
|
||||
It does not contain control words like "#define", which are recognized
|
||||
by a separate piece of code. */
|
||||
|
||||
/* different flavors of hash nodes --- also used in keyword table */
|
||||
enum node_type
|
||||
{
|
||||
T_DEFINE = 1, /* `#define' */
|
||||
T_INCLUDE, /* `#include' */
|
||||
T_INCLUDE_NEXT, /* `#include_next' */
|
||||
T_IMPORT, /* `#import' */
|
||||
T_IFDEF, /* `#ifdef' */
|
||||
T_IFNDEF, /* `#ifndef' */
|
||||
T_IF, /* `#if' */
|
||||
T_ELSE, /* `#else' */
|
||||
T_PRAGMA, /* `#pragma' */
|
||||
T_ELIF, /* `#elif' */
|
||||
T_UNDEF, /* `#undef' */
|
||||
T_LINE, /* `#line' */
|
||||
T_ERROR, /* `#error' */
|
||||
T_WARNING, /* `#warning' */
|
||||
T_ENDIF, /* `#endif' */
|
||||
T_SCCS, /* `#sccs' */
|
||||
T_IDENT, /* `#ident' */
|
||||
T_ASSERT, /* `#assert' */
|
||||
T_UNASSERT, /* `#unassert', */
|
||||
T_SPECLINE, /* `__LINE__' */
|
||||
T_DATE, /* `__DATE__' */
|
||||
T_FILE, /* `__FILE__' */
|
||||
T_BASE_FILE, /* `__BASE_FILE__' */
|
||||
T_INCLUDE_LEVEL, /* `__INCLUDE_LEVEL__' */
|
||||
T_VERSION, /* `__VERSION__' */
|
||||
T_TIME, /* `__TIME__' */
|
||||
T_STDC, /* `__STDC__' */
|
||||
T_CONST, /* Constant string, used by `__SIZE_TYPE__' etc */
|
||||
T_MACRO, /* macro defined by `#define' */
|
||||
T_DISABLED, /* macro temporarily turned off for rescan */
|
||||
T_POISON, /* macro defined with `#pragma poison' */
|
||||
T_UNUSED /* Used for something not defined. */
|
||||
};
|
||||
|
||||
/* different kinds of things that can appear in the value field
|
||||
of a hash node. */
|
||||
union hashval
|
||||
@ -80,7 +130,8 @@ union hashval
|
||||
};
|
||||
|
||||
typedef struct hashnode HASHNODE;
|
||||
struct hashnode {
|
||||
struct hashnode
|
||||
{
|
||||
struct hashnode *next; /* double links for easy deletion */
|
||||
struct hashnode *prev;
|
||||
struct hashnode **bucket_hdr; /* also, a back pointer to this node's hash
|
||||
@ -92,6 +143,110 @@ struct hashnode {
|
||||
union hashval value; /* pointer to expansion, or whatever */
|
||||
};
|
||||
|
||||
/* List of directories to look for include files in. */
|
||||
struct file_name_list
|
||||
{
|
||||
struct file_name_list *next;
|
||||
struct file_name_list *alloc; /* for the cache of
|
||||
current directory entries */
|
||||
char *name;
|
||||
unsigned int nlen;
|
||||
/* We use these to tell if the directory mentioned here is a duplicate
|
||||
of an earlier directory on the search path. */
|
||||
ino_t ino;
|
||||
dev_t dev;
|
||||
/* If the following is nonzero, it is a C-language system include
|
||||
directory. */
|
||||
int sysp;
|
||||
/* Mapping of file names for this directory.
|
||||
Only used on MS-DOS and related platforms. */
|
||||
struct file_name_map *name_map;
|
||||
};
|
||||
#define ABSOLUTE_PATH ((struct file_name_list *)-1)
|
||||
|
||||
/* This structure is used for the table of all includes. It is
|
||||
indexed by the `short name' (the name as it appeared in the
|
||||
#include statement) which is stored in *nshort. */
|
||||
struct ihash
|
||||
{
|
||||
struct ihash *next;
|
||||
/* Next file with the same short name but a
|
||||
different (partial) pathname). */
|
||||
struct ihash *next_this_file;
|
||||
|
||||
/* Location of the file in the include search path.
|
||||
Used for include_next */
|
||||
struct file_name_list *foundhere;
|
||||
const char *name; /* (partial) pathname of file */
|
||||
const char *nshort; /* name of file as referenced in #include */
|
||||
const U_CHAR *control_macro; /* macro, if any, preventing reinclusion -
|
||||
see redundant_include_p */
|
||||
char *buf, *limit; /* for file content cache,
|
||||
not yet implemented */
|
||||
};
|
||||
typedef struct ihash IHASH;
|
||||
|
||||
/* Character classes.
|
||||
If the definition of `numchar' looks odd to you, please look up the
|
||||
definition of a pp-number in the C standard [section 6.4.8 of C99] */
|
||||
#define ISidnum 0x01 /* a-zA-Z0-9_ */
|
||||
#define ISidstart 0x02 /* _a-zA-Z */
|
||||
#define ISnumstart 0x04 /* 0-9 */
|
||||
#define IShspace 0x08 /* ' ' \t \f \v */
|
||||
#define ISspace 0x10 /* ' ' \t \f \v \n */
|
||||
|
||||
#define _dollar_ok(x) ((x) == '$' && CPP_OPTIONS (pfile)->dollars_in_ident)
|
||||
|
||||
#define is_idchar(x) ((_cpp_IStable[x] & ISidnum) || _dollar_ok(x))
|
||||
#define is_idstart(x) ((_cpp_IStable[x] & ISidstart) || _dollar_ok(x))
|
||||
#define is_numchar(x) (_cpp_IStable[x] & ISidnum)
|
||||
#define is_numstart(x) (_cpp_IStable[x] & ISnumstart)
|
||||
#define is_hspace(x) (_cpp_IStable[x] & IShspace)
|
||||
#define is_space(x) (_cpp_IStable[x] & ISspace)
|
||||
|
||||
/* This table is constant if it can be initialized at compile time,
|
||||
which is the case if cpp was compiled with GCC >=2.7, or another
|
||||
compiler that supports C99. */
|
||||
#if (GCC_VERSION >= 2007) || (__STDC_VERSION__ >= 199901L)
|
||||
extern const unsigned char _cpp_IStable[256];
|
||||
#else
|
||||
extern unsigned char _cpp_IStable[256];
|
||||
#endif
|
||||
|
||||
/* Macros. */
|
||||
|
||||
#define CPP_BUF_PEEK(BUFFER) \
|
||||
((BUFFER)->cur < (BUFFER)->rlimit ? *(BUFFER)->cur : EOF)
|
||||
#define CPP_BUF_GET(BUFFER) \
|
||||
((BUFFER)->cur < (BUFFER)->rlimit ? *(BUFFER)->cur++ : EOF)
|
||||
#define CPP_FORWARD(BUFFER, N) ((BUFFER)->cur += (N))
|
||||
|
||||
/* Append string STR (of length N) to PFILE's output buffer.
|
||||
Assume there is enough space. */
|
||||
#define CPP_PUTS_Q(PFILE, STR, N) \
|
||||
(memcpy ((PFILE)->limit, STR, (N)), (PFILE)->limit += (N))
|
||||
/* Append string STR (of length N) to PFILE's output buffer. Make space. */
|
||||
#define CPP_PUTS(PFILE, STR, N) CPP_RESERVE(PFILE, N), CPP_PUTS_Q(PFILE, STR,N)
|
||||
/* Append character CH to PFILE's output buffer. Assume sufficient space. */
|
||||
#define CPP_PUTC_Q(PFILE, CH) (*(PFILE)->limit++ = (CH))
|
||||
/* Append character CH to PFILE's output buffer. Make space if need be. */
|
||||
#define CPP_PUTC(PFILE, CH) (CPP_RESERVE (PFILE, 1), CPP_PUTC_Q (PFILE, CH))
|
||||
/* Make sure PFILE->limit is followed by '\0'. */
|
||||
#define CPP_NUL_TERMINATE_Q(PFILE) (*(PFILE)->limit = 0)
|
||||
#define CPP_NUL_TERMINATE(PFILE) (CPP_RESERVE(PFILE, 1), *(PFILE)->limit = 0)
|
||||
|
||||
/* Advance the current line by one. */
|
||||
#define CPP_BUMP_BUFFER_LINE(PBUF) ((PBUF)->lineno++,\
|
||||
(PBUF)->line_base = (PBUF)->cur)
|
||||
#define CPP_BUMP_LINE(PFILE) CPP_BUMP_BUFFER_LINE(CPP_BUFFER(PFILE))
|
||||
#define CPP_PREV_BUFFER(BUFFER) ((BUFFER)->prev)
|
||||
|
||||
#define CPP_PRINT_DEPS(PFILE) (CPP_OPTIONS (PFILE)->print_deps)
|
||||
#define CPP_TRADITIONAL(PFILE) (CPP_OPTIONS(PFILE)->traditional)
|
||||
#define CPP_PEDANTIC(PFILE) \
|
||||
(CPP_OPTIONS (PFILE)->pedantic && !CPP_BUFFER (pfile)->system_header_p)
|
||||
|
||||
/* In cpphash.c */
|
||||
extern HASHNODE *_cpp_install PARAMS ((cpp_reader *, const U_CHAR *, int,
|
||||
enum node_type, const char *));
|
||||
extern HASHNODE *_cpp_lookup PARAMS ((cpp_reader *, const U_CHAR *, int));
|
||||
@ -106,4 +261,14 @@ extern void _cpp_macroexpand PARAMS ((cpp_reader *, HASHNODE *));
|
||||
extern void _cpp_dump_definition PARAMS ((cpp_reader *, const U_CHAR *, long,
|
||||
DEFINITION *));
|
||||
|
||||
/* In cppfiles.c */
|
||||
extern void _cpp_simplify_pathname PARAMS ((char *));
|
||||
extern int _cpp_find_include_file PARAMS ((cpp_reader *, const char *,
|
||||
struct file_name_list *,
|
||||
IHASH **, int *));
|
||||
extern int _cpp_read_include_file PARAMS ((cpp_reader *, int, IHASH *));
|
||||
|
||||
/* In cppexp.c */
|
||||
extern int _cpp_parse_expr PARAMS ((cpp_reader *));
|
||||
|
||||
#endif
|
||||
|
224
gcc/cppinit.c
224
gcc/cppinit.c
@ -36,6 +36,17 @@ Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
||||
#define GET_ENV_PATH_LIST(VAR,NAME) do { (VAR) = getenv (NAME); } while (0)
|
||||
#endif
|
||||
|
||||
/* Windows does not natively support inodes, and neither does MSDOS.
|
||||
Cygwin's emulation can generate non-unique inodes, so don't use it.
|
||||
VMS has non-numeric inodes. */
|
||||
#ifdef VMS
|
||||
#define INO_T_EQ(a, b) (!memcmp (&(a), &(b), sizeof (a)))
|
||||
#elif (defined _WIN32 && ! defined (_UWIN)) || defined __MSDOS__
|
||||
#define INO_T_EQ(a, b) 0
|
||||
#else
|
||||
#define INO_T_EQ(a, b) ((a) == (b))
|
||||
#endif
|
||||
|
||||
#ifndef STANDARD_INCLUDE_DIR
|
||||
#define STANDARD_INCLUDE_DIR "/usr/include"
|
||||
#endif
|
||||
@ -97,47 +108,51 @@ struct default_include
|
||||
C++. */
|
||||
};
|
||||
|
||||
#ifndef STANDARD_INCLUDE_COMPONENT
|
||||
#define STANDARD_INCLUDE_COMPONENT 0
|
||||
#endif
|
||||
|
||||
#ifdef CROSS_COMPILE
|
||||
#undef LOCAL_INCLUDE_DIR
|
||||
#undef SYSTEM_INCLUDE_DIR
|
||||
#undef STANDARD_INCLUDE_DIR
|
||||
#else
|
||||
#undef CROSS_INCLUDE_DIR
|
||||
#endif
|
||||
|
||||
static const struct default_include include_defaults_array[]
|
||||
#ifdef INCLUDE_DEFAULTS
|
||||
= INCLUDE_DEFAULTS;
|
||||
#else
|
||||
= {
|
||||
#ifdef GPLUSPLUS_INCLUDE_DIR
|
||||
/* Pick up GNU C++ specific include files. */
|
||||
{ GPLUSPLUS_INCLUDE_DIR, "G++", 1, 1 },
|
||||
#ifdef CROSS_COMPILE
|
||||
/* This is the dir for fixincludes. Put it just before
|
||||
the files that we fix. */
|
||||
{ GCC_INCLUDE_DIR, "GCC", 0, 0 },
|
||||
/* For cross-compilation, this dir name is generated
|
||||
automatically in Makefile.in. */
|
||||
{ CROSS_INCLUDE_DIR, "GCC", 0, 0 },
|
||||
#ifdef TOOL_INCLUDE_DIR
|
||||
/* This is another place that the target system's headers might be. */
|
||||
{ TOOL_INCLUDE_DIR, "BINUTILS", 0, 1 },
|
||||
#endif
|
||||
#else /* not CROSS_COMPILE */
|
||||
#ifdef LOCAL_INCLUDE_DIR
|
||||
/* This should be /usr/local/include and should come before
|
||||
the fixincludes-fixed header files. */
|
||||
/* /usr/local/include comes before the fixincluded header files. */
|
||||
{ LOCAL_INCLUDE_DIR, 0, 0, 1 },
|
||||
#endif
|
||||
#ifdef GCC_INCLUDE_DIR
|
||||
/* This is the dir for fixincludes and for gcc's private headers. */
|
||||
{ GCC_INCLUDE_DIR, "GCC", 0, 0 },
|
||||
#endif
|
||||
#ifdef CROSS_INCLUDE_DIR
|
||||
/* One place the target system's headers might be. */
|
||||
{ CROSS_INCLUDE_DIR, "GCC", 0, 0 },
|
||||
#endif
|
||||
#ifdef TOOL_INCLUDE_DIR
|
||||
/* This is here ahead of GCC_INCLUDE_DIR because assert.h goes here.
|
||||
Likewise, behind LOCAL_INCLUDE_DIR, where glibc puts its assert.h. */
|
||||
/* Another place the target system's headers might be. */
|
||||
{ TOOL_INCLUDE_DIR, "BINUTILS", 0, 1 },
|
||||
#endif
|
||||
/* This is the dir for fixincludes. Put it just before
|
||||
the files that we fix. */
|
||||
{ GCC_INCLUDE_DIR, "GCC", 0, 0 },
|
||||
/* Some systems have an extra dir of include files. */
|
||||
#ifdef SYSTEM_INCLUDE_DIR
|
||||
/* Some systems have an extra dir of include files. */
|
||||
{ SYSTEM_INCLUDE_DIR, 0, 0, 0 },
|
||||
#endif
|
||||
#ifndef STANDARD_INCLUDE_COMPONENT
|
||||
#define STANDARD_INCLUDE_COMPONENT 0
|
||||
#endif
|
||||
#ifdef STANDARD_INCLUDE_DIR
|
||||
/* /usr/include comes dead last. */
|
||||
{ STANDARD_INCLUDE_DIR, STANDARD_INCLUDE_COMPONENT, 0, 0 },
|
||||
#endif /* not CROSS_COMPILE */
|
||||
#endif
|
||||
{ 0, 0, 0, 0 }
|
||||
};
|
||||
#endif /* no INCLUDE_DEFAULTS */
|
||||
@ -156,6 +171,24 @@ struct pending_option
|
||||
int undef;
|
||||
};
|
||||
|
||||
/* The `pending' structure accumulates all the options that are not
|
||||
actually processed until we hit cpp_start_read. It consists of
|
||||
several lists, one for each type of option. We keep both head and
|
||||
tail pointers for quick insertion. */
|
||||
struct cpp_pending
|
||||
{
|
||||
struct pending_option *define_head, *define_tail;
|
||||
struct pending_option *assert_head, *assert_tail;
|
||||
|
||||
struct file_name_list *quote_head, *quote_tail;
|
||||
struct file_name_list *brack_head, *brack_tail;
|
||||
struct file_name_list *systm_head, *systm_tail;
|
||||
struct file_name_list *after_head, *after_tail;
|
||||
|
||||
struct pending_option *imacros_head, *imacros_tail;
|
||||
struct pending_option *include_head, *include_tail;
|
||||
};
|
||||
|
||||
#ifdef __STDC__
|
||||
#define APPEND(pend, list, elt) \
|
||||
do { if (!(pend)->list##_head) (pend)->list##_head = (elt); \
|
||||
@ -178,6 +211,8 @@ static void initialize_builtins PARAMS ((cpp_reader *));
|
||||
static void append_include_chain PARAMS ((cpp_reader *,
|
||||
struct cpp_pending *,
|
||||
char *, int, int));
|
||||
static void merge_include_chains PARAMS ((struct cpp_options *));
|
||||
|
||||
static void dump_special_to_buffer PARAMS ((cpp_reader *, const char *));
|
||||
static void initialize_dependency_output PARAMS ((cpp_reader *));
|
||||
static void initialize_standard_includes PARAMS ((cpp_reader *));
|
||||
@ -341,6 +376,135 @@ append_include_chain (pfile, pend, dir, path, cxx_aware)
|
||||
}
|
||||
}
|
||||
|
||||
/* Merge the four include chains together in the order quote, bracket,
|
||||
system, after. Remove duplicate dirs (as determined by
|
||||
INO_T_EQ()). The system_include and after_include chains are never
|
||||
referred to again after this function; all access is through the
|
||||
bracket_include path.
|
||||
|
||||
For the future: Check if the directory is empty (but
|
||||
how?) and possibly preload the include hash. */
|
||||
|
||||
static void
|
||||
merge_include_chains (opts)
|
||||
struct cpp_options *opts;
|
||||
{
|
||||
struct file_name_list *prev, *cur, *other;
|
||||
struct file_name_list *quote, *brack, *systm, *after;
|
||||
struct file_name_list *qtail, *btail, *stail, *atail;
|
||||
|
||||
qtail = opts->pending->quote_tail;
|
||||
btail = opts->pending->brack_tail;
|
||||
stail = opts->pending->systm_tail;
|
||||
atail = opts->pending->after_tail;
|
||||
|
||||
quote = opts->pending->quote_head;
|
||||
brack = opts->pending->brack_head;
|
||||
systm = opts->pending->systm_head;
|
||||
after = opts->pending->after_head;
|
||||
|
||||
/* Paste together bracket, system, and after include chains. */
|
||||
if (stail)
|
||||
stail->next = after;
|
||||
else
|
||||
systm = after;
|
||||
if (btail)
|
||||
btail->next = systm;
|
||||
else
|
||||
brack = systm;
|
||||
|
||||
/* This is a bit tricky.
|
||||
First we drop dupes from the quote-include list.
|
||||
Then we drop dupes from the bracket-include list.
|
||||
Finally, if qtail and brack are the same directory,
|
||||
we cut out qtail.
|
||||
|
||||
We can't just merge the lists and then uniquify them because
|
||||
then we may lose directories from the <> search path that should
|
||||
be there; consider -Ifoo -Ibar -I- -Ifoo -Iquux. It is however
|
||||
safe to treat -Ibar -Ifoo -I- -Ifoo -Iquux as if written
|
||||
-Ibar -I- -Ifoo -Iquux.
|
||||
|
||||
Note that this algorithm is quadratic in the number of -I switches,
|
||||
which is acceptable since there aren't usually that many of them. */
|
||||
|
||||
for (cur = quote, prev = NULL; cur; cur = cur->next)
|
||||
{
|
||||
for (other = quote; other != cur; other = other->next)
|
||||
if (INO_T_EQ (cur->ino, other->ino)
|
||||
&& cur->dev == other->dev)
|
||||
{
|
||||
if (opts->verbose)
|
||||
fprintf (stderr, _("ignoring duplicate directory `%s'\n"),
|
||||
cur->name);
|
||||
|
||||
prev->next = cur->next;
|
||||
free (cur->name);
|
||||
free (cur);
|
||||
cur = prev;
|
||||
break;
|
||||
}
|
||||
prev = cur;
|
||||
}
|
||||
qtail = prev;
|
||||
|
||||
for (cur = brack; cur; cur = cur->next)
|
||||
{
|
||||
for (other = brack; other != cur; other = other->next)
|
||||
if (INO_T_EQ (cur->ino, other->ino)
|
||||
&& cur->dev == other->dev)
|
||||
{
|
||||
if (opts->verbose)
|
||||
fprintf (stderr, _("ignoring duplicate directory `%s'\n"),
|
||||
cur->name);
|
||||
|
||||
prev->next = cur->next;
|
||||
free (cur->name);
|
||||
free (cur);
|
||||
cur = prev;
|
||||
break;
|
||||
}
|
||||
prev = cur;
|
||||
}
|
||||
|
||||
if (quote)
|
||||
{
|
||||
if (INO_T_EQ (qtail->ino, brack->ino) && qtail->dev == brack->dev)
|
||||
{
|
||||
if (quote == qtail)
|
||||
{
|
||||
if (opts->verbose)
|
||||
fprintf (stderr, _("ignoring duplicate directory `%s'\n"),
|
||||
quote->name);
|
||||
|
||||
free (quote->name);
|
||||
free (quote);
|
||||
quote = brack;
|
||||
}
|
||||
else
|
||||
{
|
||||
cur = quote;
|
||||
while (cur->next != qtail)
|
||||
cur = cur->next;
|
||||
cur->next = brack;
|
||||
if (opts->verbose)
|
||||
fprintf (stderr, _("ignoring duplicate directory `%s'\n"),
|
||||
qtail->name);
|
||||
|
||||
free (qtail->name);
|
||||
free (qtail);
|
||||
}
|
||||
}
|
||||
else
|
||||
qtail->next = brack;
|
||||
}
|
||||
else
|
||||
quote = brack;
|
||||
|
||||
opts->quote_include = quote;
|
||||
opts->bracket_include = brack;
|
||||
}
|
||||
|
||||
|
||||
/* Write out a #define command for the special named MACRO_NAME
|
||||
to PFILE's token_buffer. */
|
||||
@ -418,13 +582,6 @@ cpp_cleanup (pfile)
|
||||
if (pfile->deps)
|
||||
deps_free (pfile->deps);
|
||||
|
||||
while (pfile->if_stack)
|
||||
{
|
||||
IF_STACK *temp = pfile->if_stack;
|
||||
pfile->if_stack = temp->next;
|
||||
free (temp);
|
||||
}
|
||||
|
||||
for (i = ALL_INCLUDE_HASHSIZE; --i >= 0; )
|
||||
{
|
||||
IHASH *imp, *next;
|
||||
@ -723,7 +880,7 @@ cpp_start_read (pfile, fname)
|
||||
if (! opts->no_standard_includes)
|
||||
initialize_standard_includes (pfile);
|
||||
|
||||
_cpp_merge_include_chains (opts);
|
||||
merge_include_chains (opts);
|
||||
|
||||
/* With -v, print the list of dirs to search. */
|
||||
if (opts->verbose)
|
||||
@ -844,9 +1001,10 @@ cpp_finish (pfile)
|
||||
{
|
||||
struct cpp_options *opts = CPP_OPTIONS (pfile);
|
||||
|
||||
if (CPP_PREV_BUFFER (CPP_BUFFER (pfile)) != NULL)
|
||||
if (CPP_PREV_BUFFER (CPP_BUFFER (pfile)))
|
||||
cpp_ice (pfile, "buffers still stacked in cpp_finish");
|
||||
cpp_pop_buffer (pfile);
|
||||
while (CPP_BUFFER (pfile))
|
||||
cpp_pop_buffer (pfile);
|
||||
|
||||
/* Don't write the deps file if preprocessing has failed. */
|
||||
if (opts->print_deps && pfile->errors == 0)
|
||||
|
56
gcc/cpplib.c
56
gcc/cpplib.c
@ -52,6 +52,20 @@ struct directive
|
||||
enum node_type type; /* Code which describes which directive. */
|
||||
};
|
||||
|
||||
/* Stack of conditionals currently in progress
|
||||
(including both successful and failing conditionals). */
|
||||
|
||||
struct if_stack
|
||||
{
|
||||
struct if_stack *next;
|
||||
int lineno; /* line number where condition started */
|
||||
int if_succeeded; /* truth of last condition in this group */
|
||||
const U_CHAR *control_macro; /* macro name for #ifndef around entire file */
|
||||
enum node_type type; /* type of last directive seen in this group */
|
||||
};
|
||||
typedef struct if_stack IF_STACK;
|
||||
|
||||
|
||||
/* These functions are declared to return int instead of void since they
|
||||
are going to be placed in a table and some old compilers have trouble with
|
||||
pointers to functions returning void. */
|
||||
@ -64,7 +78,7 @@ static int do_error PARAMS ((cpp_reader *, const struct directive *));
|
||||
static int do_pragma PARAMS ((cpp_reader *, const struct directive *));
|
||||
static int do_ident PARAMS ((cpp_reader *, const struct directive *));
|
||||
static int do_if PARAMS ((cpp_reader *, const struct directive *));
|
||||
static int do_xifdef PARAMS ((cpp_reader *, const struct directive *));
|
||||
static int do_ifdef PARAMS ((cpp_reader *, const struct directive *));
|
||||
static int do_else PARAMS ((cpp_reader *, const struct directive *));
|
||||
static int do_elif PARAMS ((cpp_reader *, const struct directive *));
|
||||
static int do_endif PARAMS ((cpp_reader *, const struct directive *));
|
||||
@ -78,7 +92,7 @@ static int do_warning PARAMS ((cpp_reader *, const struct directive *));
|
||||
/* Forward declarations. */
|
||||
|
||||
static void validate_else PARAMS ((cpp_reader *, const char *));
|
||||
static HOST_WIDEST_INT eval_if_expr PARAMS ((cpp_reader *));
|
||||
static int eval_if_expr PARAMS ((cpp_reader *));
|
||||
static void conditional_skip PARAMS ((cpp_reader *, int,
|
||||
enum node_type, U_CHAR *));
|
||||
static void skip_if_group PARAMS ((cpp_reader *));
|
||||
@ -118,10 +132,10 @@ static const struct directive directive_table[] = {
|
||||
{ 6, do_define, "define", T_DEFINE }, /* 270554 */
|
||||
{ 7, do_include, "include", T_INCLUDE }, /* 52262 */
|
||||
{ 5, do_endif, "endif", T_ENDIF }, /* 45855 */
|
||||
{ 5, do_xifdef, "ifdef", T_IFDEF }, /* 22000 */
|
||||
{ 5, do_ifdef, "ifdef", T_IFDEF }, /* 22000 */
|
||||
{ 2, do_if, "if", T_IF }, /* 18162 */
|
||||
{ 4, do_else, "else", T_ELSE }, /* 9863 */
|
||||
{ 6, do_xifdef, "ifndef", T_IFNDEF }, /* 9675 */
|
||||
{ 6, do_ifdef, "ifndef", T_IFNDEF }, /* 9675 */
|
||||
{ 5, do_undef, "undef", T_UNDEF }, /* 4837 */
|
||||
{ 4, do_line, "line", T_LINE }, /* 2465 */
|
||||
{ 4, do_elif, "elif", T_ELIF }, /* 610 */
|
||||
@ -529,7 +543,7 @@ handle_directive (pfile)
|
||||
return 0;
|
||||
|
||||
if (CPP_PEDANTIC (pfile)
|
||||
&& ! CPP_PREPROCESSED (pfile)
|
||||
&& ! CPP_OPTIONS (pfile)->preprocessed
|
||||
&& ! CPP_BUFFER (pfile)->manual_pop)
|
||||
cpp_pedwarn (pfile, "`#' followed by integer");
|
||||
do_line (pfile, NULL);
|
||||
@ -538,7 +552,7 @@ handle_directive (pfile)
|
||||
|
||||
/* If we are rescanning preprocessed input, don't obey any directives
|
||||
other than # nnn. */
|
||||
if (CPP_PREPROCESSED (pfile))
|
||||
if (CPP_OPTIONS (pfile)->preprocessed)
|
||||
return 0;
|
||||
|
||||
/* Now find the directive name. */
|
||||
@ -1842,16 +1856,8 @@ detect_if_not_defined (pfile)
|
||||
}
|
||||
|
||||
/*
|
||||
* handle #if command by
|
||||
* 1) inserting special `defined' keyword into the hash table
|
||||
* that gets turned into 0 or 1 by special_symbol (thus,
|
||||
* if the luser has a symbol called `defined' already, it won't
|
||||
* work inside the #if command)
|
||||
* 2) rescan the input into a temporary output buffer
|
||||
* 3) pass the output buffer to the yacc parser and collect a value
|
||||
* 4) clean up the mess left from steps 1 and 2.
|
||||
* 5) call conditional_skip to skip til the next #endif (etc.),
|
||||
* or not, depending on the value from step 3.
|
||||
* #if is straightforward; just call eval_if_expr, then conditional_skip.
|
||||
* Also, check for a reinclude preventer of the form #if !defined (MACRO).
|
||||
*/
|
||||
|
||||
static int
|
||||
@ -1860,7 +1866,7 @@ do_if (pfile, keyword)
|
||||
const struct directive *keyword ATTRIBUTE_UNUSED;
|
||||
{
|
||||
U_CHAR *control_macro = detect_if_not_defined (pfile);
|
||||
HOST_WIDEST_INT value = eval_if_expr (pfile);
|
||||
int value = eval_if_expr (pfile);
|
||||
conditional_skip (pfile, value == 0, T_IF, control_macro);
|
||||
return 0;
|
||||
}
|
||||
@ -1895,7 +1901,7 @@ do_elif (pfile, keyword)
|
||||
skip_if_group (pfile);
|
||||
else
|
||||
{
|
||||
HOST_WIDEST_INT value = eval_if_expr (pfile);
|
||||
int value = eval_if_expr (pfile);
|
||||
if (value == 0)
|
||||
skip_if_group (pfile);
|
||||
else
|
||||
@ -1907,16 +1913,15 @@ do_elif (pfile, keyword)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* evaluate a #if expression in BUF, of length LENGTH,
|
||||
* then parse the result as a C expression and return the value as an int.
|
||||
/* Thin wrapper around _cpp_parse_expr, which doesn't have access to
|
||||
* skip_rest_of_line. Also centralizes toggling parsing_if_directive.
|
||||
*/
|
||||
|
||||
static HOST_WIDEST_INT
|
||||
static int
|
||||
eval_if_expr (pfile)
|
||||
cpp_reader *pfile;
|
||||
{
|
||||
HOST_WIDEST_INT value;
|
||||
int value;
|
||||
long old_written = CPP_WRITTEN (pfile);
|
||||
|
||||
pfile->parsing_if_directive++;
|
||||
@ -1936,7 +1941,7 @@ eval_if_expr (pfile)
|
||||
*/
|
||||
|
||||
static int
|
||||
do_xifdef (pfile, keyword)
|
||||
do_ifdef (pfile, keyword)
|
||||
cpp_reader *pfile;
|
||||
const struct directive *keyword;
|
||||
{
|
||||
@ -2578,7 +2583,8 @@ cpp_get_token (pfile)
|
||||
break;
|
||||
if (!is_numchar(c) && c != '.'
|
||||
&& ((c2 != 'e' && c2 != 'E'
|
||||
&& ((c2 != 'p' && c2 != 'P') || CPP_C89 (pfile)))
|
||||
&& ((c2 != 'p' && c2 != 'P')
|
||||
|| CPP_OPTIONS (pfile)->c89))
|
||||
|| (c != '+' && c != '-')))
|
||||
break;
|
||||
FORWARD(1);
|
||||
|
231
gcc/cpplib.h
231
gcc/cpplib.h
@ -28,8 +28,6 @@ Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef unsigned char U_CHAR;
|
||||
|
||||
typedef struct cpp_reader cpp_reader;
|
||||
typedef struct cpp_buffer cpp_buffer;
|
||||
typedef struct cpp_options cpp_options;
|
||||
@ -63,14 +61,6 @@ enum cpp_token
|
||||
|
||||
typedef int (*parse_cleanup_t) PARAMS((cpp_buffer *, cpp_reader *));
|
||||
|
||||
extern int cpp_handle_options PARAMS ((cpp_reader *, int, char **));
|
||||
extern enum cpp_token cpp_get_token PARAMS ((cpp_reader *));
|
||||
extern enum cpp_token cpp_get_non_space_token PARAMS ((cpp_reader *));
|
||||
extern enum cpp_token get_directive_token PARAMS ((cpp_reader *));
|
||||
|
||||
/* This frees resources used by PFILE. */
|
||||
extern void cpp_cleanup PARAMS ((cpp_reader *PFILE));
|
||||
|
||||
struct cpp_buffer
|
||||
{
|
||||
unsigned char *cur; /* current position */
|
||||
@ -227,8 +217,8 @@ struct cpp_reader
|
||||
/* A buffer and a table, used only by read_and_prescan (in cppfiles.c)
|
||||
which are allocated once per cpp_reader object to keep them off the
|
||||
stack and avoid setup costs. */
|
||||
U_CHAR *input_buffer;
|
||||
U_CHAR *input_speccase;
|
||||
unsigned char *input_buffer;
|
||||
unsigned char *input_speccase;
|
||||
size_t input_buffer_len;
|
||||
};
|
||||
|
||||
@ -236,70 +226,25 @@ struct cpp_reader
|
||||
/* True if we have seen a "fatal" error. */
|
||||
#define CPP_FATAL_ERRORS(READER) ((READER)->errors >= CPP_FATAL_LIMIT)
|
||||
|
||||
#define CPP_BUF_PEEK(BUFFER) \
|
||||
((BUFFER)->cur < (BUFFER)->rlimit ? *(BUFFER)->cur : EOF)
|
||||
#define CPP_BUF_GET(BUFFER) \
|
||||
((BUFFER)->cur < (BUFFER)->rlimit ? *(BUFFER)->cur++ : EOF)
|
||||
#define CPP_FORWARD(BUFFER, N) ((BUFFER)->cur += (N))
|
||||
|
||||
/* Macros for manipulating the token_buffer. */
|
||||
|
||||
#define CPP_OUT_BUFFER(PFILE) ((PFILE)->token_buffer)
|
||||
|
||||
/* Number of characters currently in PFILE's output buffer. */
|
||||
#define CPP_WRITTEN(PFILE) ((size_t)((PFILE)->limit - (PFILE)->token_buffer))
|
||||
#define CPP_PWRITTEN(PFILE) ((PFILE)->limit)
|
||||
#define CPP_ADJUST_WRITTEN(PFILE,DELTA) ((PFILE)->limit += (DELTA))
|
||||
#define CPP_SET_WRITTEN(PFILE,N) ((PFILE)->limit = (PFILE)->token_buffer + (N))
|
||||
|
||||
/* Make sure PFILE->token_buffer has space for at least N more characters. */
|
||||
#define CPP_RESERVE(PFILE, N) \
|
||||
(CPP_WRITTEN (PFILE) + (size_t)(N) > (PFILE)->token_buffer_size \
|
||||
&& (cpp_grow_buffer (PFILE, N), 0))
|
||||
|
||||
/* Append string STR (of length N) to PFILE's output buffer.
|
||||
Assume there is enough space. */
|
||||
#define CPP_PUTS_Q(PFILE, STR, N) \
|
||||
(memcpy ((PFILE)->limit, STR, (N)), (PFILE)->limit += (N))
|
||||
/* Append string STR (of length N) to PFILE's output buffer. Make space. */
|
||||
#define CPP_PUTS(PFILE, STR, N) CPP_RESERVE(PFILE, N), CPP_PUTS_Q(PFILE, STR,N)
|
||||
/* Append character CH to PFILE's output buffer. Assume sufficient space. */
|
||||
#define CPP_PUTC_Q(PFILE, CH) (*(PFILE)->limit++ = (CH))
|
||||
/* Append character CH to PFILE's output buffer. Make space if need be. */
|
||||
#define CPP_PUTC(PFILE, CH) (CPP_RESERVE (PFILE, 1), CPP_PUTC_Q (PFILE, CH))
|
||||
/* Make sure PFILE->limit is followed by '\0'. */
|
||||
#define CPP_NUL_TERMINATE_Q(PFILE) (*(PFILE)->limit = 0)
|
||||
#define CPP_NUL_TERMINATE(PFILE) (CPP_RESERVE(PFILE, 1), *(PFILE)->limit = 0)
|
||||
#define CPP_ADJUST_WRITTEN(PFILE,DELTA) ((PFILE)->limit += (DELTA))
|
||||
#define CPP_SET_WRITTEN(PFILE,N) ((PFILE)->limit = (PFILE)->token_buffer + (N))
|
||||
|
||||
/* Advance the current line by one. */
|
||||
#define CPP_BUMP_BUFFER_LINE(PBUF) ((PBUF)->lineno++,\
|
||||
(PBUF)->line_base = (PBUF)->cur)
|
||||
#define CPP_BUMP_LINE(PFILE) CPP_BUMP_BUFFER_LINE(CPP_BUFFER(PFILE))
|
||||
|
||||
#define CPP_OPTIONS(PFILE) ((PFILE)->opts)
|
||||
#define CPP_BUFFER(PFILE) ((PFILE)->buffer)
|
||||
#define CPP_PREV_BUFFER(BUFFER) ((BUFFER)->prev)
|
||||
|
||||
/* The `pending' structure accumulates all the options that are not
|
||||
actually processed until we hit cpp_start_read. It consists of
|
||||
several lists, one for each type of option. We keep both head and
|
||||
tail pointers for quick insertion. */
|
||||
struct cpp_pending
|
||||
{
|
||||
struct pending_option *define_head, *define_tail;
|
||||
struct pending_option *assert_head, *assert_tail;
|
||||
|
||||
struct file_name_list *quote_head, *quote_tail;
|
||||
struct file_name_list *brack_head, *brack_tail;
|
||||
struct file_name_list *systm_head, *systm_tail;
|
||||
struct file_name_list *after_head, *after_tail;
|
||||
|
||||
struct pending_option *imacros_head, *imacros_tail;
|
||||
struct pending_option *include_head, *include_tail;
|
||||
};
|
||||
|
||||
/* Pointed to by cpp_reader.opts. */
|
||||
struct cpp_options {
|
||||
struct cpp_options
|
||||
{
|
||||
char *in_fname;
|
||||
|
||||
/* Name of output file, for error messages. */
|
||||
@ -488,144 +433,19 @@ struct cpp_options {
|
||||
char *deps_target;
|
||||
};
|
||||
|
||||
#define CPP_TRADITIONAL(PFILE) (CPP_OPTIONS(PFILE)-> traditional)
|
||||
#define CPP_WARN_UNDEF(PFILE) (CPP_OPTIONS(PFILE)->warn_undef)
|
||||
#define CPP_C89(PFILE) (CPP_OPTIONS(PFILE)->c89)
|
||||
#define CPP_PREPROCESSED(PFILE) (CPP_OPTIONS (PFILE)->preprocessed)
|
||||
#define CPP_PRINT_DEPS(PFILE) (CPP_OPTIONS (PFILE)->print_deps)
|
||||
|
||||
#define CPP_PEDANTIC(PFILE) \
|
||||
(CPP_OPTIONS (PFILE)->pedantic && !CPP_BUFFER (pfile)->system_header_p)
|
||||
|
||||
/* List of directories to look for include files in. */
|
||||
struct file_name_list
|
||||
{
|
||||
struct file_name_list *next;
|
||||
struct file_name_list *alloc; /* for the cache of
|
||||
current directory entries */
|
||||
char *name;
|
||||
unsigned int nlen;
|
||||
/* We use these to tell if the directory mentioned here is a duplicate
|
||||
of an earlier directory on the search path. */
|
||||
ino_t ino;
|
||||
dev_t dev;
|
||||
/* If the following is nonzero, it is a C-language system include
|
||||
directory. */
|
||||
int sysp;
|
||||
/* Mapping of file names for this directory.
|
||||
Only used on MS-DOS and related platforms. */
|
||||
struct file_name_map *name_map;
|
||||
};
|
||||
#define ABSOLUTE_PATH ((struct file_name_list *)-1)
|
||||
|
||||
/* This structure is used for the table of all includes. It is
|
||||
indexed by the `short name' (the name as it appeared in the
|
||||
#include statement) which is stored in *nshort. */
|
||||
struct ihash
|
||||
{
|
||||
struct ihash *next;
|
||||
/* Next file with the same short name but a
|
||||
different (partial) pathname). */
|
||||
struct ihash *next_this_file;
|
||||
|
||||
/* Location of the file in the include search path.
|
||||
Used for include_next */
|
||||
struct file_name_list *foundhere;
|
||||
const char *name; /* (partial) pathname of file */
|
||||
const char *nshort; /* name of file as referenced in #include */
|
||||
const U_CHAR *control_macro; /* macro, if any, preventing reinclusion -
|
||||
see redundant_include_p */
|
||||
char *buf, *limit; /* for file content cache,
|
||||
not yet implemented */
|
||||
};
|
||||
typedef struct ihash IHASH;
|
||||
|
||||
/* Name under which this program was invoked. */
|
||||
|
||||
extern const char *progname;
|
||||
|
||||
/* The structure of a node in the hash table. The hash table
|
||||
has entries for all tokens defined by #define commands (type T_MACRO),
|
||||
plus some special tokens like __LINE__ (these each have their own
|
||||
type, and the appropriate code is run when that type of node is seen.
|
||||
It does not contain control words like "#define", which are recognized
|
||||
by a separate piece of code. */
|
||||
extern int cpp_handle_options PARAMS ((cpp_reader *, int, char **));
|
||||
extern enum cpp_token cpp_get_token PARAMS ((cpp_reader *));
|
||||
extern enum cpp_token cpp_get_non_space_token PARAMS ((cpp_reader *));
|
||||
extern enum cpp_token get_directive_token PARAMS ((cpp_reader *));
|
||||
|
||||
/* different flavors of hash nodes --- also used in keyword table */
|
||||
enum node_type {
|
||||
T_DEFINE = 1, /* the `#define' keyword */
|
||||
T_INCLUDE, /* the `#include' keyword */
|
||||
T_INCLUDE_NEXT, /* the `#include_next' keyword */
|
||||
T_IMPORT, /* the `#import' keyword */
|
||||
T_IFDEF, /* the `#ifdef' keyword */
|
||||
T_IFNDEF, /* the `#ifndef' keyword */
|
||||
T_IF, /* the `#if' keyword */
|
||||
T_ELSE, /* `#else' */
|
||||
T_PRAGMA, /* `#pragma' */
|
||||
T_ELIF, /* `#elif' */
|
||||
T_UNDEF, /* `#undef' */
|
||||
T_LINE, /* `#line' */
|
||||
T_ERROR, /* `#error' */
|
||||
T_WARNING, /* `#warning' */
|
||||
T_ENDIF, /* `#endif' */
|
||||
T_SCCS, /* `#sccs', used on system V. */
|
||||
T_IDENT, /* `#ident', used on system V. */
|
||||
T_ASSERT, /* `#assert', taken from system V. */
|
||||
T_UNASSERT, /* `#unassert', taken from system V. */
|
||||
T_SPECLINE, /* special symbol `__LINE__' */
|
||||
T_DATE, /* `__DATE__' */
|
||||
T_FILE, /* `__FILE__' */
|
||||
T_BASE_FILE, /* `__BASE_FILE__' */
|
||||
T_INCLUDE_LEVEL, /* `__INCLUDE_LEVEL__' */
|
||||
T_VERSION, /* `__VERSION__' */
|
||||
T_TIME, /* `__TIME__' */
|
||||
T_STDC, /* `__STDC__' */
|
||||
T_CONST, /* Constant string, used by `__SIZE_TYPE__' etc */
|
||||
T_MACRO, /* macro defined by `#define' */
|
||||
T_DISABLED, /* macro temporarily turned off for rescan */
|
||||
T_POISON, /* defined with `#pragma poison' */
|
||||
T_UNUSED /* Used for something not defined. */
|
||||
};
|
||||
|
||||
/* Character classes.
|
||||
If the definition of `numchar' looks odd to you, please look up the
|
||||
definition of a pp-number in the C standard [section 6.4.8 of C99] */
|
||||
#define ISidnum 0x01 /* a-zA-Z0-9_ */
|
||||
#define ISidstart 0x02 /* _a-zA-Z */
|
||||
#define ISnumstart 0x04 /* 0-9 */
|
||||
#define IShspace 0x08 /* ' ' \t \f \v */
|
||||
#define ISspace 0x10 /* ' ' \t \f \v \n */
|
||||
|
||||
#define _dollar_ok(x) ((x) == '$' && CPP_OPTIONS (pfile)->dollars_in_ident)
|
||||
|
||||
#define is_idchar(x) ((_cpp_IStable[x] & ISidnum) || _dollar_ok(x))
|
||||
#define is_idstart(x) ((_cpp_IStable[x] & ISidstart) || _dollar_ok(x))
|
||||
#define is_numchar(x) (_cpp_IStable[x] & ISidnum)
|
||||
#define is_numstart(x) (_cpp_IStable[x] & ISnumstart)
|
||||
#define is_hspace(x) (_cpp_IStable[x] & IShspace)
|
||||
#define is_space(x) (_cpp_IStable[x] & ISspace)
|
||||
|
||||
/* This table is constant if it can be initialized at compile time,
|
||||
which is the case if cpp was compiled with GCC >=2.7, or another
|
||||
compiler that supports C99. */
|
||||
#if (GCC_VERSION >= 2007) || (__STDC_VERSION__ >= 199901L)
|
||||
extern const unsigned char _cpp_IStable[256];
|
||||
#else
|
||||
extern unsigned char _cpp_IStable[256];
|
||||
#endif
|
||||
|
||||
/* Stack of conditionals currently in progress
|
||||
(including both successful and failing conditionals). */
|
||||
|
||||
struct if_stack
|
||||
{
|
||||
struct if_stack *next;
|
||||
int lineno; /* line number where condition started */
|
||||
int if_succeeded; /* truth of last condition in this group */
|
||||
const U_CHAR *control_macro; /* macro name for #ifndef around entire file */
|
||||
enum node_type type; /* type of last directive seen in this group */
|
||||
};
|
||||
typedef struct if_stack IF_STACK;
|
||||
extern void cpp_reader_init PARAMS ((cpp_reader *));
|
||||
extern void cpp_options_init PARAMS ((cpp_options *));
|
||||
extern int cpp_start_read PARAMS ((cpp_reader *, char *));
|
||||
extern void cpp_finish PARAMS ((cpp_reader *));
|
||||
extern void cpp_cleanup PARAMS ((cpp_reader *PFILE));
|
||||
|
||||
extern void cpp_buf_line_and_col PARAMS((cpp_buffer *, long *, long *));
|
||||
extern cpp_buffer *cpp_file_buffer PARAMS((cpp_reader *));
|
||||
@ -667,16 +487,11 @@ extern void cpp_grow_buffer PARAMS ((cpp_reader *, long));
|
||||
extern cpp_buffer *cpp_push_buffer PARAMS ((cpp_reader *,
|
||||
unsigned char *, long));
|
||||
extern cpp_buffer *cpp_pop_buffer PARAMS ((cpp_reader *));
|
||||
extern int cpp_defined PARAMS ((cpp_reader *, const U_CHAR *, int));
|
||||
|
||||
extern void cpp_reader_init PARAMS ((cpp_reader *));
|
||||
extern void cpp_options_init PARAMS ((cpp_options *));
|
||||
extern int cpp_start_read PARAMS ((cpp_reader *, char *));
|
||||
extern void cpp_finish PARAMS ((cpp_reader *));
|
||||
extern int cpp_defined PARAMS ((cpp_reader *, const unsigned char *, int));
|
||||
|
||||
extern void quote_string PARAMS ((cpp_reader *, const char *));
|
||||
extern void cpp_expand_to_buffer PARAMS ((cpp_reader *, const U_CHAR *,
|
||||
int));
|
||||
extern void cpp_expand_to_buffer PARAMS ((cpp_reader *,
|
||||
const unsigned char *, int));
|
||||
extern void cpp_scan_buffer PARAMS ((cpp_reader *));
|
||||
|
||||
/* Last arg to output_line_command. */
|
||||
@ -688,16 +503,6 @@ extern void output_line_command PARAMS ((cpp_reader *,
|
||||
extern int cpp_included PARAMS ((cpp_reader *, const char *));
|
||||
extern int cpp_read_file PARAMS ((cpp_reader *, const char *));
|
||||
|
||||
extern void _cpp_simplify_pathname PARAMS ((char *));
|
||||
extern void _cpp_merge_include_chains PARAMS ((struct cpp_options *));
|
||||
extern int _cpp_find_include_file PARAMS ((cpp_reader *, const char *,
|
||||
struct file_name_list *,
|
||||
IHASH **, int *));
|
||||
extern int _cpp_read_include_file PARAMS ((cpp_reader *, int, IHASH *));
|
||||
|
||||
/* In cppexp.c */
|
||||
extern HOST_WIDEST_INT _cpp_parse_expr PARAMS ((cpp_reader *));
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
@ -631,6 +631,7 @@ read_scan_file (in_fname, argc, argv)
|
||||
so ignore warnings and errors. */
|
||||
scan_options.inhibit_warnings = 1;
|
||||
scan_options.inhibit_errors = 1;
|
||||
scan_options.no_line_commands = 1;
|
||||
i = cpp_handle_options (&scan_in, argc, argv);
|
||||
if (i < argc && ! CPP_FATAL_ERRORS (&scan_in))
|
||||
cpp_fatal (&scan_in, "Invalid option `%s'", argv[i]);
|
||||
@ -639,7 +640,6 @@ read_scan_file (in_fname, argc, argv)
|
||||
|
||||
if (! cpp_start_read (&scan_in, in_fname))
|
||||
exit (FATAL_EXIT_CODE);
|
||||
CPP_OPTIONS (&scan_in)->no_line_commands = 1;
|
||||
|
||||
scan_decls (&scan_in, argc, argv);
|
||||
for (cur_symbols = &symbol_table[0]; cur_symbols->names; cur_symbols++)
|
||||
|
Loading…
Reference in New Issue
Block a user