Commit 0b22d65c by Zack Weinberg Committed by Zack Weinberg

cppinit.c: Instead of one pending list...

1999-03-15 21:39 -0500  Zack Weinberg  <zack@rabi.columbia.edu>
	* cppinit.c: Instead of one pending list, keep separate lists
	for each category of pending option: -D/-U, -A, -include,
	-imacros.  Move the four partial include-path lists into the
	pending block.  Use head and tail pointers so we don't ever
	have to reverse the lists.
	(cpp_start_read): Break out blocks of code to their own
	functions: install_predefs and initialize_dependency_output.
	Use path_include for C_INCLUDE_PATH and friends as well as
	CPATH.  Remove include_defaults gunk.  Warn about the
	combination of -lang-chill and -trigraphs.  Optimize string
	bashing.  Walk each pending list once, deallocating as we go.
	(append_include_chain): Brought over from cppfiles.c.  Mark
	dirs as system include dirs if and only if appending to
	system include path. If opts->verbose, print a notice when a
	dir is dropped from the include path because it doesn't
	exist.  Fix memory leak: this function is not supposed to copy
	its DIR argument.
	(nreverse_pending, push_pending): Removed.
	(APPEND): New macro for adding to pending lists.
	(path_include): Can now add to any partial include path.
	(base_name): Bring over from cccp.c.
	(cpp_options_init): Allocate the pending block.
	(cpp_handle_option): Add --version.  Exit after --help.  Fix
	formatting.  Order -ifoo options by frequency of usage.
	(install_predefs): New function, simplified version of code
	that was in cpp_start_read.
	(initialize_dependency_output): Likewise.  Understand OBJECT_SUFFIX.
	* cppfiles.c (simplify_pathname): Export.
	(merge_include_chains):  Don't nreverse the lists.  If
	opts->verbose, print a notice when a duplicate dir is detected
	and dropped from the include path.
	(finclude): Fix excessive cleverness in setting
	fp->system_header_p.
	(actual_directory): Set x->sysp from
	CPP_BUFFER (pfile)->system_header_p so that one system header
	may include another with "".
	(deps_output): Fix double adjustment of deps_size which would
	cause all dependencies after the first two lines to be lost.
	* cpplib.c (cpp_unassert): New function.
	* cpplib.h: Lay out struct cpp_pending here.  Adjust
	prototypes.  Add include_prefix_len to struct cpp_options.

From-SVN: r25793
parent 56dc4d15
1999-03-15 21:39 -0500 Zack Weinberg <zack@rabi.columbia.edu>
* cppinit.c: Instead of one pending list, keep separate lists
for each category of pending option: -D/-U, -A, -include,
-imacros. Move the four partial include-path lists into the
pending block. Use head and tail pointers so we don't ever
have to reverse the lists.
(cpp_start_read): Break out blocks of code to their own
functions: install_predefs and initialize_dependency_output.
Use path_include for C_INCLUDE_PATH and friends as well as
CPATH. Remove include_defaults gunk. Warn about the
combination of -lang-chill and -trigraphs. Optimize string
bashing. Walk each pending list once, deallocating as we go.
(append_include_chain): Brought over from cppfiles.c. Mark
dirs as system include dirs if and only if appending to
system include path. If opts->verbose, print a notice when a
dir is dropped from the include path because it doesn't
exist. Fix memory leak: this function is not supposed to copy
its DIR argument.
(nreverse_pending, push_pending): Removed.
(APPEND): New macro for adding to pending lists.
(path_include): Can now add to any partial include path.
(base_name): Bring over from cccp.c.
(cpp_options_init): Allocate the pending block.
(cpp_handle_option): Add --version. Exit after --help. Fix
formatting. Order -ifoo options by frequency of usage.
(install_predefs): New function, simplified version of code
that was in cpp_start_read.
(initialize_dependency_output): Likewise. Understand OBJECT_SUFFIX.
* cppfiles.c (simplify_pathname): Export.
(merge_include_chains): Don't nreverse the lists. If
opts->verbose, print a notice when a duplicate dir is detected
and dropped from the include path.
(finclude): Fix excessive cleverness in setting
fp->system_header_p.
(actual_directory): Set x->sysp from
CPP_BUFFER (pfile)->system_header_p so that one system header
may include another with "".
(deps_output): Fix double adjustment of deps_size which would
cause all dependencies after the first two lines to be lost.
* cpplib.c (cpp_unassert): New function.
* cpplib.h: Lay out struct cpp_pending here. Adjust
prototypes. Add include_prefix_len to struct cpp_options.
Mon Mar 15 16:01:52 1999 Jim Wilson <wilson@cygnus.com> Mon Mar 15 16:01:52 1999 Jim Wilson <wilson@cygnus.com>
* config/misp/mips.h (REGISTER_MOVE_COST): Make the cost of moving * config/misp/mips.h (REGISTER_MOVE_COST): Make the cost of moving
......
...@@ -43,7 +43,6 @@ static char *remap_filename PROTO ((cpp_reader *, char *, ...@@ -43,7 +43,6 @@ static char *remap_filename PROTO ((cpp_reader *, char *,
struct file_name_list *)); struct file_name_list *));
static long read_and_prescan PROTO ((cpp_reader *, cpp_buffer *, static long read_and_prescan PROTO ((cpp_reader *, cpp_buffer *,
int, size_t)); int, size_t));
static void simplify_pathname PROTO ((char *));
static struct file_name_list *actual_directory PROTO ((cpp_reader *, char *)); static struct file_name_list *actual_directory PROTO ((cpp_reader *, char *));
#if 0 #if 0
...@@ -61,54 +60,6 @@ static void hack_vms_include_specification PROTO ((char *)); ...@@ -61,54 +60,6 @@ static void hack_vms_include_specification PROTO ((char *));
#define INO_T_EQ(a, b) ((a) == (b)) #define INO_T_EQ(a, b) ((a) == (b))
#endif #endif
/* Append an entry for dir DIR to list LIST, simplifying it if
possible. SYS says whether this is a system include directory.
*** DIR is modified in place. It must be writable and permanently
allocated. LIST is a pointer to the head pointer, because we actually
*prepend* the dir, and reverse the list later (in merge_include_chains). */
void
append_include_chain (pfile, list, dir, sysp)
cpp_reader *pfile;
struct file_name_list **list;
const char *dir;
int sysp;
{
struct file_name_list *new;
struct stat st;
unsigned int len;
char * newdir = xstrdup (dir);
simplify_pathname (newdir);
if (stat (newdir, &st))
{
/* Dirs that don't exist are silently ignored. */
if (errno != ENOENT)
cpp_perror_with_name (pfile, newdir);
return;
}
if (!S_ISDIR (st.st_mode))
{
cpp_message (pfile, 1, "%s: %s: Not a directory", progname, newdir);
return;
}
len = strlen(newdir);
if (len > pfile->max_include_len)
pfile->max_include_len = len;
new = (struct file_name_list *)xmalloc (sizeof (struct file_name_list));
new->name = newdir;
new->nlen = len;
new->next = *list;
new->ino = st.st_ino;
new->dev = st.st_dev;
new->sysp = sysp;
new->name_map = NULL;
*list = new;
}
/* Merge the four include chains together in the order quote, bracket, /* Merge the four include chains together in the order quote, bracket,
system, after. Remove duplicate dirs (as determined by system, after. Remove duplicate dirs (as determined by
INO_T_EQ()). The system_include and after_include chains are never INO_T_EQ()). The system_include and after_include chains are never
...@@ -122,51 +73,19 @@ void ...@@ -122,51 +73,19 @@ void
merge_include_chains (opts) merge_include_chains (opts)
struct cpp_options *opts; struct cpp_options *opts;
{ {
struct file_name_list *prev, *next, *cur, *other; struct file_name_list *prev, *cur, *other;
struct file_name_list *quote, *brack, *systm, *after; struct file_name_list *quote, *brack, *systm, *after;
struct file_name_list *qtail, *btail, *stail, *atail; struct file_name_list *qtail, *btail, *stail, *atail;
qtail = opts->quote_include; qtail = opts->pending->quote_tail;
btail = opts->bracket_include; btail = opts->pending->brack_tail;
stail = opts->system_include; stail = opts->pending->systm_tail;
atail = opts->after_include; atail = opts->pending->after_tail;
/* Nreverse the four lists. */
prev = 0;
for (cur = qtail; cur; cur = next)
{
next = cur->next;
cur->next = prev;
prev = cur;
}
quote = prev;
prev = 0;
for (cur = btail; cur; cur = next)
{
next = cur->next;
cur->next = prev;
prev = cur;
}
brack = prev;
prev = 0; quote = opts->pending->quote_head;
for (cur = stail; cur; cur = next) brack = opts->pending->brack_head;
{ systm = opts->pending->systm_head;
next = cur->next; after = opts->pending->after_head;
cur->next = prev;
prev = cur;
}
systm = prev;
prev = 0;
for (cur = atail; cur; cur = next)
{
next = cur->next;
cur->next = prev;
prev = cur;
}
after = prev;
/* Paste together bracket, system, and after include chains. */ /* Paste together bracket, system, and after include chains. */
if (stail) if (stail)
...@@ -188,7 +107,10 @@ merge_include_chains (opts) ...@@ -188,7 +107,10 @@ merge_include_chains (opts)
then we may lose directories from the <> search path that should then we may lose directories from the <> search path that should
be there; consider -Ifoo -Ibar -I- -Ifoo -Iquux. It is however be there; consider -Ifoo -Ibar -I- -Ifoo -Iquux. It is however
safe to treat -Ibar -Ifoo -I- -Ifoo -Iquux as if written safe to treat -Ibar -Ifoo -I- -Ifoo -Iquux as if written
-Ibar -I- -Ifoo -Iquux. */ -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; cur; cur = cur->next) for (cur = quote; cur; cur = cur->next)
{ {
...@@ -196,6 +118,9 @@ merge_include_chains (opts) ...@@ -196,6 +118,9 @@ merge_include_chains (opts)
if (INO_T_EQ (cur->ino, other->ino) if (INO_T_EQ (cur->ino, other->ino)
&& cur->dev == other->dev) && cur->dev == other->dev)
{ {
if (opts->verbose)
cpp_notice ("ignoring duplicate directory `%s'\n", cur->name);
prev->next = cur->next; prev->next = cur->next;
free (cur->name); free (cur->name);
free (cur); free (cur);
...@@ -212,6 +137,9 @@ merge_include_chains (opts) ...@@ -212,6 +137,9 @@ merge_include_chains (opts)
if (INO_T_EQ (cur->ino, other->ino) if (INO_T_EQ (cur->ino, other->ino)
&& cur->dev == other->dev) && cur->dev == other->dev)
{ {
if (opts->verbose)
cpp_notice ("ignoring duplicate directory `%s'\n", cur->name);
prev->next = cur->next; prev->next = cur->next;
free (cur->name); free (cur->name);
free (cur); free (cur);
...@@ -227,6 +155,10 @@ merge_include_chains (opts) ...@@ -227,6 +155,10 @@ merge_include_chains (opts)
{ {
if (quote == qtail) if (quote == qtail)
{ {
if (opts->verbose)
cpp_notice ("ignoring duplicate directory `%s'\n",
quote->name);
free (quote->name); free (quote->name);
free (quote); free (quote);
quote = brack; quote = brack;
...@@ -237,6 +169,10 @@ merge_include_chains (opts) ...@@ -237,6 +169,10 @@ merge_include_chains (opts)
while (cur->next != qtail) while (cur->next != qtail)
cur = cur->next; cur = cur->next;
cur->next = brack; cur->next = brack;
if (opts->verbose)
cpp_notice ("ignoring duplicate directory `%s'\n",
qtail->name);
free (qtail->name); free (qtail->name);
free (qtail); free (qtail);
} }
...@@ -249,8 +185,6 @@ merge_include_chains (opts) ...@@ -249,8 +185,6 @@ merge_include_chains (opts)
opts->quote_include = quote; opts->quote_include = quote;
opts->bracket_include = brack; opts->bracket_include = brack;
opts->system_include = NULL;
opts->after_include = NULL;
} }
/* Look up or add an entry to the table of all includes. This table /* Look up or add an entry to the table of all includes. This table
...@@ -742,8 +676,8 @@ finclude (pfile, fd, ihash) ...@@ -742,8 +676,8 @@ finclude (pfile, fd, ihash)
close (fd); close (fd);
fp->rlimit = fp->alimit = fp->buf + length; fp->rlimit = fp->alimit = fp->buf + length;
fp->cur = fp->buf; fp->cur = fp->buf;
fp->system_header_p = (ihash->foundhere != ABSOLUTE_PATH if (ihash->foundhere != ABSOLUTE_PATH)
&& ihash->foundhere->sysp); fp->system_header_p = ihash->foundhere->sysp;
fp->lineno = 1; fp->lineno = 1;
fp->colno = 1; fp->colno = 1;
fp->cleanup = file_cleanup; fp->cleanup = file_cleanup;
...@@ -816,7 +750,7 @@ actual_directory (pfile, fname) ...@@ -816,7 +750,7 @@ actual_directory (pfile, fname)
x->nlen = dlen; x->nlen = dlen;
x->next = CPP_OPTIONS (pfile)->quote_include; x->next = CPP_OPTIONS (pfile)->quote_include;
x->alloc = pfile->actual_dirs; x->alloc = pfile->actual_dirs;
x->sysp = 0; x->sysp = CPP_BUFFER (pfile)->system_header_p;
x->name_map = NULL; x->name_map = NULL;
pfile->actual_dirs = x; pfile->actual_dirs = x;
...@@ -1063,12 +997,11 @@ deps_output (pfile, string, spacer) ...@@ -1063,12 +997,11 @@ deps_output (pfile, string, spacer)
if (pfile->deps_column > 0 if (pfile->deps_column > 0
&& (pfile->deps_column + size) > MAX_OUTPUT_COLUMNS) && (pfile->deps_column + size) > MAX_OUTPUT_COLUMNS)
{ {
size += 5; cr = 5;
cr = 1;
pfile->deps_column = 0; pfile->deps_column = 0;
} }
if (pfile->deps_size + size + 8 > pfile->deps_allocated_size) if (pfile->deps_size + size + cr + 8 > pfile->deps_allocated_size)
{ {
pfile->deps_allocated_size = (pfile->deps_size + size + 50) * 2; pfile->deps_allocated_size = (pfile->deps_size + size + 50) * 2;
pfile->deps_buffer = (char *) xrealloc (pfile->deps_buffer, pfile->deps_buffer = (char *) xrealloc (pfile->deps_buffer,
...@@ -1105,7 +1038,7 @@ deps_output (pfile, string, spacer) ...@@ -1105,7 +1038,7 @@ deps_output (pfile, string, spacer)
Guarantees no trailing slashes. All transforms reduce the length Guarantees no trailing slashes. All transforms reduce the length
of the string. of the string.
*/ */
static void void
simplify_pathname (path) simplify_pathname (path)
char *path; char *path;
{ {
......
...@@ -46,14 +46,6 @@ extern char *version_string; ...@@ -46,14 +46,6 @@ extern char *version_string;
#define STANDARD_INCLUDE_DIR "/usr/include" #define STANDARD_INCLUDE_DIR "/usr/include"
#endif #endif
/* Symbols to predefine. */
#ifdef CPP_PREDEFINES
static char *predefs = CPP_PREDEFINES;
#else
static char *predefs = "";
#endif
/* We let tm.h override the types used here, to handle trivial differences /* We let tm.h override the types used here, to handle trivial differences
such as the choice of unsigned int or long unsigned int for size_t. such as the choice of unsigned int or long unsigned int for size_t.
When machines start needing nontrivial differences in the size type, When machines start needing nontrivial differences in the size type,
...@@ -92,22 +84,48 @@ static char *predefs = ""; ...@@ -92,22 +84,48 @@ static char *predefs = "";
#define REGISTER_PREFIX "" #define REGISTER_PREFIX ""
#endif #endif
/* #include "file" looks in source file dir, then stack. */ /* Suffix for object files, and known input-file extensions. */
/* #include <file> just looks in the stack. */ static char *known_suffixes[] =
/* -I directories are added to the end, then the defaults are added. */ {
/* The */ ".c", ".C", ".s", ".S", ".m",
static struct default_include { ".cc", ".cxx", ".cpp", ".cp", ".c++",
NULL
};
#ifndef OBJECT_SUFFIX
# ifdef VMS
# define OBJECT_SUFFIX ".obj"
# else
# define OBJECT_SUFFIX ".o"
# endif
#endif
/* This is the default list of directories to search for include files.
It may be overridden by the various -I and -ixxx options.
#include "file" looks in the same directory as the current file,
then this list.
#include <file> just looks in this list.
All these directories are treated as `system' include directories
(they are not subject to pedantic warnings in some cases). */
static struct default_include
{
char *fname; /* The name of the directory. */ char *fname; /* The name of the directory. */
char *component; /* The component containing the directory */ char *component; /* The component containing the directory
(see update_path in prefix.c) */
int cplusplus; /* Only look here if we're compiling C++. */ int cplusplus; /* Only look here if we're compiling C++. */
int cxx_aware; /* Includes in this directory don't need to int cxx_aware; /* Includes in this directory don't need to
be wrapped in extern "C" when compiling be wrapped in extern "C" when compiling
C++. */ C++. This is not used anymore. */
} include_defaults_array[] }
include_defaults_array[]
#ifdef INCLUDE_DEFAULTS #ifdef INCLUDE_DEFAULTS
= INCLUDE_DEFAULTS; = INCLUDE_DEFAULTS;
#else #else
= { = {
/* Pick up GNU C++ specific include files. */ /* Pick up GNU C++ specific include files. */
{ GPLUSPLUS_INCLUDE_DIR, "G++", 1, 1 }, { GPLUSPLUS_INCLUDE_DIR, "G++", 1, 1 },
#ifdef CROSS_COMPILE #ifdef CROSS_COMPILE
...@@ -116,7 +134,7 @@ static struct default_include { ...@@ -116,7 +134,7 @@ static struct default_include {
{ GCC_INCLUDE_DIR, "GCC", 0, 0 }, { GCC_INCLUDE_DIR, "GCC", 0, 0 },
/* For cross-compilation, this dir name is generated /* For cross-compilation, this dir name is generated
automatically in Makefile.in. */ automatically in Makefile.in. */
{ CROSS_INCLUDE_DIR, "GCC",0, 0 }, { CROSS_INCLUDE_DIR, "GCC", 0, 0 },
#ifdef TOOL_INCLUDE_DIR #ifdef TOOL_INCLUDE_DIR
/* This is another place that the target system's headers might be. */ /* This is another place that the target system's headers might be. */
{ TOOL_INCLUDE_DIR, "BINUTILS", 0, 1 }, { TOOL_INCLUDE_DIR, "BINUTILS", 0, 1 },
...@@ -145,24 +163,53 @@ static struct default_include { ...@@ -145,24 +163,53 @@ static struct default_include {
{ STANDARD_INCLUDE_DIR, STANDARD_INCLUDE_COMPONENT, 0, 0 }, { STANDARD_INCLUDE_DIR, STANDARD_INCLUDE_COMPONENT, 0, 0 },
#endif /* not CROSS_COMPILE */ #endif /* not CROSS_COMPILE */
{ 0, 0, 0, 0 } { 0, 0, 0, 0 }
}; };
#endif /* no INCLUDE_DEFAULTS */ #endif /* no INCLUDE_DEFAULTS */
/* Internal structures and prototypes. */ /* Internal structures and prototypes. */
struct cpp_pending /* A `struct pending_option' remembers one -D, -A, -U, -include, or -imacros
switch. There are four lists: one for -D and -U, one for -A, one
for -include, one for -imacros. `undef' is set for -U, clear for
-D, ignored for the others.
(Future: add an equivalent of -U for -A) */
struct pending_option
{ {
struct cpp_pending *next; struct pending_option *next;
char *cmd;
char *arg; char *arg;
int undef;
}; };
static struct cpp_pending *nreverse_pending PARAMS ((struct cpp_pending *));
#ifdef __STDC__
#define APPEND(pend, list, elt) \
do { if (!(pend)->list##_head) (pend)->list##_head = (elt); \
else (pend)->list##_tail->next = (elt); \
(pend)->list##_tail = (elt); \
} while (0)
#else
#define APPEND(pend, list, elt) \
do { if (!(pend)->list/**/_head) (pend)->list/**/_head = (elt); \
else (pend)->list/**/_tail->next = (elt); \
(pend)->list/**/_tail = (elt); \
} while (0)
#endif
static void initialize_char_syntax PARAMS ((int)); static void initialize_char_syntax PARAMS ((int));
static void print_help PARAMS ((void)); static void print_help PARAMS ((void));
static void path_include PARAMS ((cpp_reader *, char *)); static void path_include PARAMS ((cpp_reader *,
struct cpp_pending *,
char *, int));
static void initialize_builtins PARAMS ((cpp_reader *)); static void initialize_builtins PARAMS ((cpp_reader *));
static void append_include_chain PARAMS ((cpp_reader *,
struct cpp_pending *,
char *, int));
#ifdef CPP_PREDEFINES
static void install_predefs PARAMS ((cpp_reader *));
#endif
/* Last argument to append_include_chain: chain to use */
enum { QUOTE = 0, BRACKET, SYSTEM, AFTER };
/* If gcc is in use (stage2/stage3) we can make these tables initialized /* If gcc is in use (stage2/stage3) we can make these tables initialized
data. */ data. */
...@@ -338,45 +385,121 @@ initialize_char_syntax (dollar_in_ident) ...@@ -338,45 +385,121 @@ initialize_char_syntax (dollar_in_ident)
add all the names to the search path for include files. */ add all the names to the search path for include files. */
static void static void
path_include (pfile, path) path_include (pfile, pend, list, path)
cpp_reader *pfile; cpp_reader *pfile;
char *path; struct cpp_pending *pend;
char *list;
int path;
{ {
char *p; char *p, *q, *name;
p = path;
if (*p) p = list;
while (1) {
char *q = p;
char *name;
do
{
/* Find the end of this name. */ /* Find the end of this name. */
q = p;
while (*q != 0 && *q != PATH_SEPARATOR) q++; while (*q != 0 && *q != PATH_SEPARATOR) q++;
if (p == q) { if (q == p)
/* An empty name in the path stands for the current directory. */ {
name = (char *) xmalloc (2); /* An empty name in the path stands for the current directory. */
name[0] = '.'; name = (char *) xmalloc (2);
name[1] = 0; name[0] = '.';
} else { name[1] = 0;
/* Otherwise use the directory that is named. */ }
name = (char *) xmalloc (q - p + 1); else
bcopy (p, name, q - p); {
name[q - p] = 0; /* Otherwise use the directory that is named. */
} name = (char *) xmalloc (q - p + 1);
memcpy (name, p, q - p);
name[q - p] = 0;
}
append_include_chain (pfile, append_include_chain (pfile, pend, name, path);
&(CPP_OPTIONS (pfile)->bracket_include), name, 0);
/* Advance past this name. */ /* Advance past this name. */
p = q; if (*q == 0)
if (*p == 0)
break; break;
/* Skip the colon. */ p = q + 1;
p++; }
while (1);
}
/* Find the base name of a (partial) pathname FNAME.
Returns a pointer into the string passed in.
Accepts Unix (/-separated) paths on all systems,
DOS and VMS paths on those systems. */
static char *
base_name (fname)
const char *fname;
{
char *s = (char *)fname;
char *p;
#if defined (__MSDOS__) || defined (_WIN32)
if (ISALPHA (s[0]) && s[1] == ':') s += 2;
if ((p = rindex (s, '\\'))) s = p + 1;
#elif defined VMS
if ((p = rindex (s, ':'))) s = p + 1; /* Skip device. */
if ((p = rindex (s, ']'))) s = p + 1; /* Skip directory. */
if ((p = rindex (s, '>'))) s = p + 1; /* Skip alternate (int'n'l) dir. */
#endif
if ((p = rindex (s, '/'))) s = p + 1;
return s;
}
/* Append DIR to include path PATH. DIR must be permanently allocated
and writable. */
static void
append_include_chain (pfile, pend, dir, path)
cpp_reader *pfile;
struct cpp_pending *pend;
char *dir;
int path;
{
struct file_name_list *new;
struct stat st;
unsigned int len;
simplify_pathname (dir);
if (stat (dir, &st))
{
/* Dirs that don't exist are silently ignored. */
if (errno != ENOENT)
cpp_perror_with_name (pfile, dir);
else if (CPP_OPTIONS (pfile)->verbose)
cpp_notice ("ignoring nonexistent directory `%s'\n", dir);
return;
}
if (!S_ISDIR (st.st_mode))
{
cpp_message (pfile, 1, "%s: %s: Not a directory", progname, dir);
return;
}
len = strlen (dir);
if (len > pfile->max_include_len)
pfile->max_include_len = len;
new = (struct file_name_list *)xmalloc (sizeof (struct file_name_list));
new->name = dir;
new->nlen = len;
new->ino = st.st_ino;
new->dev = st.st_dev;
new->sysp = (path == SYSTEM);
new->name_map = NULL;
switch (path)
{
case QUOTE: APPEND (pend, quote, new); break;
case BRACKET: APPEND (pend, brack, new); break;
case SYSTEM: APPEND (pend, systm, new); break;
case AFTER: APPEND (pend, after, new); break;
} }
} }
/* Write out a #define command for the special named MACRO_NAME /* Write out a #define command for the special named MACRO_NAME
to PFILE's token_buffer. */ to PFILE's token_buffer. */
...@@ -396,47 +519,19 @@ dump_special_to_buffer (pfile, macro_name) ...@@ -396,47 +519,19 @@ dump_special_to_buffer (pfile, macro_name)
CPP_PUTC (pfile, '\n'); CPP_PUTC (pfile, '\n');
} }
/* Pending-list utility routines. Will go away soon. */
static struct cpp_pending *
nreverse_pending (list)
struct cpp_pending *list;
{
register struct cpp_pending *prev = 0, *next, *pend;
for (pend = list; pend; pend = next)
{
next = pend->next;
pend->next = prev;
prev = pend;
}
return prev;
}
static void
push_pending (pfile, cmd, arg)
cpp_reader *pfile;
char *cmd;
char *arg;
{
struct cpp_pending *pend
= (struct cpp_pending *) xmalloc (sizeof (struct cpp_pending));
pend->cmd = cmd;
pend->arg = arg;
pend->next = CPP_OPTIONS (pfile)->pending;
CPP_OPTIONS (pfile)->pending = pend;
}
/* Initialize a cpp_options structure. */ /* Initialize a cpp_options structure. */
void void
cpp_options_init (opts) cpp_options_init (opts)
cpp_options *opts; cpp_options *opts;
{ {
bzero ((char *) opts, sizeof *opts); bzero ((char *) opts, sizeof (struct cpp_options));
opts->dollars_in_ident = 1; opts->dollars_in_ident = 1;
opts->cplusplus_comments = 1; opts->cplusplus_comments = 1;
opts->warn_import = 1; opts->warn_import = 1;
opts->pending = (struct cpp_pending *) xmalloc (sizeof (struct cpp_pending));
bzero ((char *) opts->pending, sizeof (struct cpp_pending));
} }
/* Initialize a cpp_reader structure. */ /* Initialize a cpp_reader structure. */
...@@ -563,6 +658,139 @@ initialize_builtins (pfile) ...@@ -563,6 +658,139 @@ initialize_builtins (pfile)
} }
} }
/* Subroutine of cpp_start_read. Installs the predefined macros
and assertions found in CPP_PREDEFINES.
CPP_PREDEFINES is a string of -D and -A options separated by
whitespace, like this:
"-D__unix__ -D__sparc__ -Asystem(unix) -Amachine(sparc)" */
#ifdef CPP_PREDEFINES
static void
install_predefs (pfile)
cpp_reader *pfile;
{
char *p = (char *) alloca (strlen (CPP_PREDEFINES) + 1);
char *q;
strcpy (p, CPP_PREDEFINES);
while (*p)
{
while (*p == ' ' || *p == '\t') p++;
if (*p != '-')
abort();
p = q = p + 2;
while (*p && *p != ' ' && *p != '\t') p++;
if (*p != 0)
*p++= 0;
if (CPP_OPTIONS (pfile)->debug_output)
output_line_command (pfile, 0, same_file);
if (q[-1] == 'D')
cpp_define (pfile, q);
else if (q[-1] == 'A')
cpp_assert (pfile, q);
else
abort ();
}
}
#endif
/* Another subroutine of cpp_start_read. This one sets up to do
dependency-file output. */
static void
initialize_dependency_output (pfile)
cpp_reader *pfile;
{
cpp_options *opts = CPP_OPTIONS (pfile);
char *spec, *s, *output_file;
/* Either of two environment variables can specify output of deps.
Its value is either "OUTPUT_FILE" or "OUTPUT_FILE DEPS_TARGET",
where OUTPUT_FILE is the file to write deps info to
and DEPS_TARGET is the target to mention in the deps. */
if (opts->print_deps == 0)
{
spec = getenv ("DEPENDENCIES_OUTPUT");
if (spec)
opts->print_deps = 1;
else
{
spec = getenv ("SUNPRO_DEPENDENCIES");
if (spec)
opts->print_deps = 2;
else
return;
}
/* Find the space before the DEPS_TARGET, if there is one. */
s = strchr (spec, ' ');
if (s)
{
opts->deps_target = s + 1;
output_file = (char *) xmalloc (s - spec + 1);
memcpy (output_file, spec, s - spec);
output_file[s - spec] = 0;
}
else
{
opts->deps_target = 0;
output_file = spec;
}
opts->deps_file = output_file;
opts->print_deps_append = 1;
}
/* Print the expected object file name as the target of this Make-rule. */
pfile->deps_allocated_size = 200;
pfile->deps_buffer = (char *) xmalloc (pfile->deps_allocated_size);
pfile->deps_buffer[0] = 0;
pfile->deps_size = 0;
pfile->deps_column = 0;
if (opts->deps_target)
deps_output (pfile, opts->deps_target, ':');
else if (*opts->in_fname == 0)
deps_output (pfile, "-", ':');
else
{
char *p, *q, *r;
int len, x;
/* Discard all directory prefixes from filename. */
q = base_name (opts->in_fname);
/* Copy remainder to mungable area. */
len = strlen (q);
p = (char *) alloca (len + 8);
strcpy (p, q);
/* Output P, but remove known suffixes. */
q = p + len;
/* Point to the filename suffix. */
r = rindex (p, '.');
/* Compare against the known suffixes. */
for (x = 0; known_suffixes[x]; x++)
{
if (strncmp (known_suffixes[x], r, q - r) == 0)
{
/* Make q point to the bit we're going to overwrite
with an object suffix. */
q = r;
break;
}
}
/* Supply our own suffix. */
strcpy (q, OBJECT_SUFFIX);
deps_output (pfile, p, ':');
deps_output (pfile, opts->in_fname, ' ');
}
}
/* This is called after options have been processed. /* This is called after options have been processed.
* Check options for consistency, and setup for processing input * Check options for consistency, and setup for processing input
* from the file named FNAME. (Use standard input if FNAME==NULL.) * from the file named FNAME. (Use standard input if FNAME==NULL.)
...@@ -575,30 +803,35 @@ cpp_start_read (pfile, fname) ...@@ -575,30 +803,35 @@ cpp_start_read (pfile, fname)
char *fname; char *fname;
{ {
struct cpp_options *opts = CPP_OPTIONS (pfile); struct cpp_options *opts = CPP_OPTIONS (pfile);
struct cpp_pending *pend; struct pending_option *p, *q;
char *p;
int f; int f;
cpp_buffer *fp; cpp_buffer *fp;
struct include_hash *ih_fake; struct include_hash *ih_fake;
/* The code looks at the defaults through this pointer, rather than /* -MG doesn't select the form of output and must be specified with one of
through the constant structure above. This pointer gets changed -M or -MM. -MG doesn't make sense with -MD or -MMD since they don't
if an environment variable specifies other defaults. */ inhibit compilation. */
struct default_include *include_defaults = include_defaults_array; if (opts->print_deps_missing_files
&& (opts->print_deps == 0 || !opts->no_output))
{
cpp_fatal (pfile, "-MG must be specified with one of -M or -MM");
return 0;
}
/* Chill should not be used with -trigraphs. */
if (opts->chill && opts->trigraphs)
{
cpp_warning (pfile, "-lang-chill and -trigraphs are mutually exclusive");
opts->trigraphs = 0;
}
/* Set this if it hasn't been set already. */
if (user_label_prefix == NULL)
user_label_prefix = USER_LABEL_PREFIX;
/* Now that we know dollars_in_ident, we can initialize the syntax /* Now that we know dollars_in_ident, we can initialize the syntax
tables. */ tables. */
initialize_char_syntax (opts->dollars_in_ident); 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. */
GET_ENV_PATH_LIST (p, "CPATH");
if (p != 0 && ! opts->no_standard_includes)
path_include (pfile, p);
/* Do partial setup of input buffer for the sake of generating /* Do partial setup of input buffer for the sake of generating
early #line directives (when -g is in effect). */ early #line directives (when -g is in effect). */
...@@ -618,357 +851,170 @@ cpp_start_read (pfile, fname) ...@@ -618,357 +851,170 @@ cpp_start_read (pfile, fname)
and option processing. */ and option processing. */
initialize_builtins (pfile); initialize_builtins (pfile);
#ifdef CPP_PREDEFINES
/* Do standard #defines and assertions /* Do standard #defines and assertions
that identify system and machine type. */ that identify system and machine type. */
if (!opts->inhibit_predefs)
if (!opts->inhibit_predefs) { install_predefs (pfile);
char *p = (char *) alloca (strlen (predefs) + 1); #endif
strcpy (p, predefs);
while (*p) {
char *q;
while (*p == ' ' || *p == '\t')
p++;
/* Handle -D options. */
if (p[0] == '-' && p[1] == 'D') {
q = &p[2];
while (*p && *p != ' ' && *p != '\t')
p++;
if (*p != 0)
*p++= 0;
if (opts->debug_output)
output_line_command (pfile, 0, same_file);
cpp_define (pfile, q);
while (*p == ' ' || *p == '\t')
p++;
} else if (p[0] == '-' && p[1] == 'A') {
/* Handle -A options (assertions). */
char *assertion;
char *past_name;
char *value;
char *past_value;
char *termination;
int save_char;
assertion = &p[2];
past_name = assertion;
/* Locate end of name. */
while (*past_name && *past_name != ' '
&& *past_name != '\t' && *past_name != '(')
past_name++;
/* Locate `(' at start of value. */
value = past_name;
while (*value && (*value == ' ' || *value == '\t'))
value++;
if (*value++ != '(')
abort ();
while (*value && (*value == ' ' || *value == '\t'))
value++;
past_value = value;
/* Locate end of value. */
while (*past_value && *past_value != ' '
&& *past_value != '\t' && *past_value != ')')
past_value++;
termination = past_value;
while (*termination && (*termination == ' ' || *termination == '\t'))
termination++;
if (*termination++ != ')')
abort ();
if (*termination && *termination != ' ' && *termination != '\t')
abort ();
/* Temporarily null-terminate the value. */
save_char = *termination;
*termination = '\0';
/* Install the assertion. */
cpp_assert (pfile, assertion);
*termination = (char) save_char;
p = termination;
while (*p == ' ' || *p == '\t')
p++;
} else {
abort ();
}
}
}
/* Now handle the command line options. */
/* Do -U's, -D's and -A's in the order they were seen. */ /* Do -U's, -D's and -A's in the order they were seen. */
/* First reverse the list. */ p = opts->pending->define_head;
opts->pending = nreverse_pending (opts->pending); while (p)
for (pend = opts->pending; pend; pend = pend->next)
{ {
if (pend->cmd != NULL && pend->cmd[0] == '-') if (opts->debug_output)
{ output_line_command (pfile, 0, same_file);
switch (pend->cmd[1]) if (p->undef)
{ cpp_undef (pfile, p->arg);
case 'U': else
if (opts->debug_output) cpp_define (pfile, p->arg);
output_line_command (pfile, 0, same_file);
cpp_undef (pfile, pend->arg);
break;
case 'D':
if (opts->debug_output)
output_line_command (pfile, 0, same_file);
cpp_define (pfile, pend->arg);
break;
case 'A':
cpp_assert (pfile, pend->arg);
break;
}
}
}
opts->done_initializing = 1;
{ /* Read the appropriate environment variable and if it exists
replace include_defaults with the listed path. */
char *epath = 0;
switch ((opts->objc << 1) + opts->cplusplus)
{
case 0:
GET_ENV_PATH_LIST (epath, "C_INCLUDE_PATH");
break;
case 1:
GET_ENV_PATH_LIST (epath, "CPLUS_INCLUDE_PATH");
break;
case 2:
GET_ENV_PATH_LIST (epath, "OBJC_INCLUDE_PATH");
break;
case 3:
GET_ENV_PATH_LIST (epath, "OBJCPLUS_INCLUDE_PATH");
break;
}
/* If the environment var for this language is set,
add to the default list of include directories. */
if (epath) {
char *nstore = (char *) alloca (strlen (epath) + 2);
int num_dirs;
char *startp, *endp;
for (num_dirs = 1, startp = epath; *startp; startp++)
if (*startp == PATH_SEPARATOR)
num_dirs++;
include_defaults
= (struct default_include *) xmalloc ((num_dirs
* sizeof (struct default_include))
+ sizeof (include_defaults_array));
startp = endp = epath;
num_dirs = 0;
while (1) {
/* Handle cases like c:/usr/lib:d:/gcc/lib */
if ((*endp == PATH_SEPARATOR)
|| *endp == 0) {
strncpy (nstore, startp, endp-startp);
if (endp == startp)
strcpy (nstore, ".");
else
nstore[endp-startp] = '\0';
include_defaults[num_dirs].fname = xstrdup (nstore);
include_defaults[num_dirs].component = 0;
include_defaults[num_dirs].cplusplus = opts->cplusplus;
include_defaults[num_dirs].cxx_aware = 1;
num_dirs++;
if (*endp == '\0')
break;
endp = startp = endp + 1;
} else
endp++;
}
/* Put the usual defaults back in at the end. */
bcopy ((char *) include_defaults_array,
(char *) &include_defaults[num_dirs],
sizeof (include_defaults_array));
}
}
/* Unless -fnostdinc,
tack on the standard include file dirs to the specified list */
if (!opts->no_standard_includes) {
struct default_include *p = include_defaults;
char *specd_prefix = opts->include_prefix;
char *default_prefix = xstrdup (GCC_INCLUDE_DIR);
int default_len = 0;
/* Remove the `include' from /usr/local/lib/gcc.../include. */
if (!strcmp (default_prefix + strlen (default_prefix) - 8, "/include")) {
default_len = strlen (default_prefix) - 7;
default_prefix[default_len] = 0;
}
/* Search "translated" versions of GNU directories.
These have /usr/local/lib/gcc... replaced by specd_prefix. */
if (specd_prefix != 0 && default_len != 0)
for (p = include_defaults; p->fname; p++) {
/* Some standard dirs are only for C++. */
if (!p->cplusplus
|| (opts->cplusplus && !opts->no_standard_cplusplus_includes)) {
/* Does this dir start with the prefix? */
if (!strncmp (p->fname, default_prefix, default_len)) {
/* Yes; change prefix and add to search list. */
int this_len = strlen (specd_prefix)
+ strlen (p->fname) - default_len;
char *str = (char *) xmalloc (this_len + 1);
strcpy (str, specd_prefix);
strcat (str, p->fname + default_len);
append_include_chain (pfile, &opts->system_include,
str, !p->cxx_aware);
}
}
}
/* Search ordinary names for GNU include directories. */
for (p = include_defaults; p->fname; p++) {
/* Some standard dirs are only for C++. */
if (!p->cplusplus
|| (opts->cplusplus && !opts->no_standard_cplusplus_includes)) {
const char *str = update_path (p->fname, p->component);
append_include_chain (pfile, &opts->system_include,
str, !p->cxx_aware);
}
}
}
merge_include_chains (opts);
/* With -v, print the list of dirs to search. */ q = p->next;
if (opts->verbose) { free (p);
struct file_name_list *p; p = q;
cpp_notice ("#include \"...\" search starts here:\n");
for (p = opts->quote_include; p; p = p->next) {
if (p == opts->bracket_include)
cpp_notice ("#include <...> search starts here:\n");
fprintf (stderr, " %s\n", p->name);
} }
cpp_notice ("End of search list.\n");
}
/* Copy the entire contents of the main input file into
the stacked input buffer previously allocated for it. */
if (fname == NULL || *fname == 0) {
fname = "";
f = 0;
} else if ((f = open (fname, O_RDONLY|O_NONBLOCK|O_NOCTTY, 0666)) < 0)
cpp_pfatal_with_name (pfile, fname);
/* -MG doesn't select the form of output and must be specified with one of p = opts->pending->assert_head;
-M or -MM. -MG doesn't make sense with -MD or -MMD since they don't while (p)
inhibit compilation. */
if (opts->print_deps_missing_files
&& (opts->print_deps == 0 || !opts->no_output))
{ {
cpp_fatal (pfile, "-MG must be specified with one of -M or -MM"); if (opts->debug_output)
return 0; output_line_command (pfile, 0, same_file);
} if (p->undef)
cpp_unassert (pfile, p->arg);
else
cpp_assert (pfile, p->arg);
/* Either of two environment variables can specify output of deps. q = p->next;
Its value is either "OUTPUT_FILE" or "OUTPUT_FILE DEPS_TARGET", free (p);
where OUTPUT_FILE is the file to write deps info to p = q;
and DEPS_TARGET is the target to mention in the deps. */ }
opts->done_initializing = 1;
if (opts->print_deps == 0 /* Several environment variables may add to the include search path.
&& (getenv ("SUNPRO_DEPENDENCIES") != 0 CPATH specifies an additional list of directories to be searched
|| getenv ("DEPENDENCIES_OUTPUT") != 0)) { as if specified with -I, while C_INCLUDE_PATH, CPLUS_INCLUDE_PATH,
char *spec = getenv ("DEPENDENCIES_OUTPUT"); etc. specify an additional list of directories to be searched as
char *s; if specified with -isystem, for the language indicated.
char *output_file;
if (spec == 0) These variables are ignored if -nostdinc is on. */
{ if (! opts->no_standard_includes)
spec = getenv ("SUNPRO_DEPENDENCIES"); {
opts->print_deps = 2; char *path;
} GET_ENV_PATH_LIST (path, "CPATH");
else if (path != 0 && *path != 0)
opts->print_deps = 1; path_include (pfile, opts->pending, path, BRACKET);
s = spec;
/* Find the space before the DEPS_TARGET, if there is one. */
/* This should use index. (mrs) */
while (*s != 0 && *s != ' ') s++;
if (*s != 0)
{
opts->deps_target = s + 1;
output_file = (char *) xmalloc (s - spec + 1);
bcopy (spec, output_file, s - spec);
output_file[s - spec] = 0;
}
else
{
opts->deps_target = 0;
output_file = spec;
}
opts->deps_file = output_file; switch ((opts->objc << 1) + opts->cplusplus)
opts->print_deps_append = 1; {
} case 0:
GET_ENV_PATH_LIST (path, "C_INCLUDE_PATH");
break;
case 1:
GET_ENV_PATH_LIST (path, "CPLUS_INCLUDE_PATH");
break;
case 2:
GET_ENV_PATH_LIST (path, "OBJC_INCLUDE_PATH");
break;
case 3:
GET_ENV_PATH_LIST (path, "OBJCPLUS_INCLUDE_PATH");
break;
}
if (path != 0 && *path != 0)
path_include (pfile, opts->pending, path, SYSTEM);
}
/* For -M, print the expected object file name /* Unless -nostdinc, add the compiled-in include path to the list,
as the target of this Make-rule. */ translating prefixes. */
if (opts->print_deps) if (!opts->no_standard_includes)
{ {
pfile->deps_allocated_size = 200; struct default_include *p = include_defaults_array;
pfile->deps_buffer = (char *) xmalloc (pfile->deps_allocated_size); char *specd_prefix = opts->include_prefix;
pfile->deps_buffer[0] = 0; char *default_prefix = alloca (sizeof GCC_INCLUDE_DIR - 7);
pfile->deps_size = 0; int default_len;
pfile->deps_column = 0; int specd_len;
if (opts->deps_target) /* Search "translated" versions of GNU directories.
deps_output (pfile, opts->deps_target, ':'); These have /usr/local/lib/gcc... replaced by specd_prefix. */
else if (*opts->in_fname == 0) if (specd_prefix != 0)
deps_output (pfile, "-", ':');
else
{ {
char *p, *q, *r; /* Remove the `include' from /usr/local/lib/gcc.../include.
int len, x; GCC_INCLUDE_DIR will always end in /include. */
static char *known_suffixes[] = { ".c", ".C", ".s", ".S", ".m", default_len = sizeof GCC_INCLUDE_DIR - 8;
".cc", ".cxx", ".cpp", ".cp", memcpy (default_prefix, GCC_INCLUDE_DIR, default_len);
".c++", 0 default_prefix[default_len] = '\0';
};
/* Discard all directory prefixes from filename. */ specd_len = strlen (specd_prefix);
if ((q = rindex (opts->in_fname, '/')) != NULL for (p = include_defaults_array; p->fname; p++)
#ifdef DIR_SEPARATOR
&& (q = rindex (opts->in_fname, DIR_SEPARATOR)) != NULL
#endif
)
++q;
else
q = opts->in_fname;
/* Copy remainder to mungable area. */
p = (char *) alloca (strlen(q) + 8);
strcpy (p, q);
/* Output P, but remove known suffixes. */
len = strlen (p);
q = p + len;
/* Point to the filename suffix. */
r = rindex (p, '.');
/* Compare against the known suffixes. */
x = 0;
while (known_suffixes[x] != 0)
{ {
if (strncmp (known_suffixes[x], r, q - r) == 0) /* Some standard dirs are only for C++. */
if (!p->cplusplus
|| (opts->cplusplus
&& !opts->no_standard_cplusplus_includes))
{ {
/* Make q point to the bit we're going to overwrite /* Does this dir start with the prefix? */
with an object suffix. */ if (!strncmp (p->fname, default_prefix, default_len))
q = r; {
break; /* Yes; change prefix and add to search list. */
int flen = strlen (p->fname);
int this_len = specd_len - default_len + flen;
char *str = (char *) xmalloc (this_len + 1);
memcpy (str, specd_prefix, specd_len);
memcpy (str+specd_len, p->fname, flen + 1);
append_include_chain (pfile, opts->pending,
str, SYSTEM);
}
} }
x++;
} }
}
/* Supply our own suffix. */ /* Search ordinary names for GNU include directories. */
#ifndef VMS for (p = include_defaults_array; p->fname; p++)
strcpy (q, ".o"); {
#else /* Some standard dirs are only for C++. */
strcpy (q, ".obj"); if (!p->cplusplus
#endif || (opts->cplusplus
&& !opts->no_standard_cplusplus_includes))
{
char *str = (char *) update_path (p->fname, p->component);
str = xstrdup (str); /* XXX Potential memory leak! */
append_include_chain (pfile, opts->pending, str, SYSTEM);
}
}
}
deps_output (pfile, p, ':'); merge_include_chains (opts);
deps_output (pfile, opts->in_fname, ' ');
/* With -v, print the list of dirs to search. */
if (opts->verbose)
{
struct file_name_list *p;
cpp_message (pfile, -1, "#include \"...\" search starts here:\n");
for (p = opts->quote_include; p; p = p->next)
{
if (p == opts->bracket_include)
cpp_message (pfile, -1, "#include <...> search starts here:\n");
fprintf (stderr, " %s\n", p->name);
} }
cpp_message (pfile, -1, "End of search list.\n");
} }
/* Open the main input file.
We do this in nonblocking mode so we don't get stuck here if
someone clever has asked cpp to process /dev/rmt0;
finclude() will check that we have a real file to work with. */
if (fname == NULL || *fname == 0)
{
fname = "";
f = 0;
}
else if ((f = open (fname, O_RDONLY|O_NONBLOCK|O_NOCTTY, 0666)) < 0)
cpp_pfatal_with_name (pfile, fname);
initialize_dependency_output (pfile);
/* Must call finclude() on the main input before processing /* Must call finclude() on the main input before processing
-include switches; otherwise the -included text winds up -include switches; otherwise the -included text winds up
after the main input. */ after the main input. */
...@@ -987,83 +1033,73 @@ cpp_start_read (pfile, fname) ...@@ -987,83 +1033,73 @@ cpp_start_read (pfile, fname)
/* The -imacros files can be scanned now, but the -include files /* The -imacros files can be scanned now, but the -include files
have to be pushed onto the include stack and processed later, have to be pushed onto the include stack and processed later,
in the main loop calling cpp_get_token. That means the -include in the main loop calling cpp_get_token. */
files have to be processed in reverse order of the pending list,
which means the pending list has to be reversed again, which
means the -imacros files have to be done separately and first. */
pfile->no_record_file++; pfile->no_record_file++;
opts->no_output++; opts->no_output++;
for (pend = opts->pending; pend; pend = pend->next) p = opts->pending->imacros_head;
while (p)
{ {
if (pend->cmd != NULL) int fd = open (p->arg, O_RDONLY|O_NONBLOCK|O_NOCTTY, 0666);
{ if (fd < 0)
if (strcmp (pend->cmd, "-imacros") == 0) {
{ cpp_perror_with_name (pfile, p->arg);
int fd = open (pend->arg, O_RDONLY|O_NONBLOCK|O_NOCTTY, 0666); return 0;
if (fd < 0)
{
cpp_perror_with_name (pfile, pend->arg);
return 0;
}
if (!cpp_push_buffer (pfile, NULL, 0))
return 0;
ih_fake = (struct include_hash *)
xmalloc (sizeof (struct include_hash));
ih_fake->next = 0;
ih_fake->next_this_file = 0;
ih_fake->foundhere = ABSOLUTE_PATH; /* well sort of ... */
ih_fake->name = pend->arg;
ih_fake->control_macro = 0;
ih_fake->buf = (char *)-1;
ih_fake->limit = 0;
if (!finclude (pfile, fd, ih_fake))
cpp_scan_buffer (pfile);
free (ih_fake);
}
} }
if (!cpp_push_buffer (pfile, NULL, 0))
return 0;
ih_fake = (struct include_hash *)
xmalloc (sizeof (struct include_hash));
ih_fake->next = 0;
ih_fake->next_this_file = 0;
ih_fake->foundhere = ABSOLUTE_PATH; /* well sort of ... */
ih_fake->name = p->arg;
ih_fake->control_macro = 0;
ih_fake->buf = (char *)-1;
ih_fake->limit = 0;
if (!finclude (pfile, fd, ih_fake))
cpp_scan_buffer (pfile);
free (ih_fake);
q = p->next;
free (p);
p = q;
} }
opts->no_output--; opts->no_output--;
opts->pending = nreverse_pending (opts->pending);
for (pend = opts->pending; pend; pend = pend->next) p = opts->pending->include_head;
while (p)
{ {
if (pend->cmd != NULL) int fd = open (p->arg, O_RDONLY|O_NONBLOCK|O_NOCTTY, 0666);
{ if (fd < 0)
if (strcmp (pend->cmd, "-include") == 0) {
{ cpp_perror_with_name (pfile, p->arg);
int fd = open (pend->arg, O_RDONLY|O_NONBLOCK|O_NOCTTY, 0666); return 0;
if (fd < 0)
{
cpp_perror_with_name (pfile, pend->arg);
return 0;
}
if (!cpp_push_buffer (pfile, NULL, 0))
return 0;
ih_fake = (struct include_hash *)
xmalloc (sizeof (struct include_hash));
ih_fake->next = 0;
ih_fake->next_this_file = 0;
ih_fake->foundhere = ABSOLUTE_PATH; /* well sort of ... */
ih_fake->name = pend->arg;
ih_fake->control_macro = 0;
ih_fake->buf = (char *)-1;
ih_fake->limit = 0;
if (finclude (pfile, fd, ih_fake))
output_line_command (pfile, 0, enter_file);
}
} }
if (!cpp_push_buffer (pfile, NULL, 0))
return 0;
ih_fake = (struct include_hash *)
xmalloc (sizeof (struct include_hash));
ih_fake->next = 0;
ih_fake->next_this_file = 0;
ih_fake->foundhere = ABSOLUTE_PATH; /* well sort of ... */
ih_fake->name = p->arg;
ih_fake->control_macro = 0;
ih_fake->buf = (char *)-1;
ih_fake->limit = 0;
if (finclude (pfile, fd, ih_fake))
output_line_command (pfile, 0, enter_file);
q = p->next;
free (p);
p = q;
} }
pfile->no_record_file--; pfile->no_record_file--;
/* Free the pending list. */ free (opts->pending);
for (pend = opts->pending; pend; )
{
struct cpp_pending *next = pend->next;
free (pend);
pend = next;
}
opts->pending = NULL; opts->pending = NULL;
return 1; return 1;
...@@ -1120,487 +1156,559 @@ cpp_handle_option (pfile, argc, argv) ...@@ -1120,487 +1156,559 @@ cpp_handle_option (pfile, argc, argv)
struct cpp_options *opts = CPP_OPTIONS (pfile); struct cpp_options *opts = CPP_OPTIONS (pfile);
int i = 0; int i = 0;
if (user_label_prefix == NULL) if (argv[i][0] != '-')
user_label_prefix = USER_LABEL_PREFIX; {
if (opts->out_fname != NULL)
if (argv[i][0] != '-') {
if (opts->out_fname != NULL)
{
print_help ();
cpp_fatal (pfile, "Too many arguments");
}
else if (opts->in_fname != NULL)
opts->out_fname = argv[i];
else
opts->in_fname = argv[i];
} else {
switch (argv[i][1]) {
missing_filename:
cpp_fatal (pfile, "Filename missing after `%s' option", argv[i]);
return argc;
missing_dirname:
cpp_fatal (pfile, "Directory name missing after `%s' option", argv[i]);
return argc;
case 'f':
if (!strcmp (argv[i], "-fleading-underscore"))
user_label_prefix = "_";
else if (!strcmp (argv[i], "-fno-leading-underscore"))
user_label_prefix = "";
break;
case 'I': /* Add directory to path for includes. */
if (!strcmp (argv[i] + 2, "-"))
{
if (! opts->ignore_srcdir)
{
opts->ignore_srcdir = 1;
/* Don't use any preceding -I directories for #include <...>. */
opts->quote_include = opts->bracket_include;
opts->bracket_include = 0;
}
}
else
{ {
char *fname; print_help ();
if (argv[i][2] != 0) cpp_fatal (pfile, "Too many arguments");
fname = argv[i] + 2;
else if (i + 1 == argc)
goto missing_dirname;
else
fname = argv[++i];
append_include_chain (pfile, &opts->bracket_include, fname, 0);
}
break;
case 'i':
/* Add directory to beginning of system include path, as a system
include directory. */
if (!strcmp (argv[i], "-isystem"))
{
if (i + 1 == argc)
goto missing_filename;
append_include_chain (pfile, &opts->system_include, argv[++i], 1);
} }
/* Add directory to end of path for includes, else if (opts->in_fname != NULL)
with the default prefix at the front of its name. */ opts->out_fname = argv[i];
else if (!strcmp (argv[i], "-iwithprefix")) else
{ opts->in_fname = argv[i];
char *fname; }
if (i + 1 == argc) else
goto missing_dirname; switch (argv[i][1])
++i; {
case 'f':
if (opts->include_prefix != 0) if (!strcmp (argv[i], "-fleading-underscore"))
{ user_label_prefix = "_";
fname = xmalloc (strlen (opts->include_prefix) else if (!strcmp (argv[i], "-fno-leading-underscore"))
+ strlen (argv[i]) + 1); user_label_prefix = "";
strcpy (fname, opts->include_prefix); break;
strcat (fname, argv[i]);
} case 'I': /* Add directory to path for includes. */
else if (!strcmp (argv[i] + 2, "-"))
{ {
fname = xmalloc (strlen (GCC_INCLUDE_DIR) /* -I- means:
+ strlen (argv[i]) + 1); Use the preceding -I directories for #include "..."
strcpy (fname, GCC_INCLUDE_DIR); but not #include <...>.
/* Remove the `include' from /usr/local/lib/gcc.../include. */ Don't search the directory of the present file
if (!strcmp (fname + strlen (fname) - 8, "/include")) for #include "...". (Note that -I. -I- is not the same as
fname[strlen (fname) - 7] = 0; the default setup; -I. uses the compiler's working dir.) */
strcat (fname, argv[i]); if (! opts->ignore_srcdir)
} {
opts->ignore_srcdir = 1;
opts->pending->quote_head = opts->pending->brack_head;
opts->pending->quote_tail = opts->pending->brack_tail;
opts->pending->brack_head = 0;
opts->pending->brack_tail = 0;
}
else
{
cpp_fatal (pfile, "-I- specified twice");
return argc;
}
}
else
{
char *fname;
if (argv[i][2] != 0)
fname = argv[i] + 2;
else if (i + 1 == argc)
goto missing_dirname;
else
fname = argv[++i];
append_include_chain (pfile, opts->pending,
xstrdup (fname), BRACKET);
}
break;
case 'i':
/* Add directory to beginning of system include path, as a system
include directory. */
if (!strcmp (argv[i], "-isystem"))
{
if (i + 1 == argc)
goto missing_filename;
append_include_chain (pfile, opts->pending,
xstrdup (argv[++i]), SYSTEM);
}
else if (!strcmp (argv[i], "-include"))
{
if (i + 1 == argc)
goto missing_filename;
else
{
struct pending_option *o = (struct pending_option *)
xmalloc (sizeof (struct pending_option));
o->arg = argv[++i];
/* This list has to be built in reverse order so that
when cpp_start_read pushes all the -include files onto
the buffer stack, they will be scanned in forward order. */
o->next = opts->pending->include_head;
opts->pending->include_head = o;
}
}
else if (!strcmp (argv[i], "-imacros"))
{
if (i + 1 == argc)
goto missing_filename;
else
{
struct pending_option *o = (struct pending_option *)
xmalloc (sizeof (struct pending_option));
o->arg = argv[++i];
o->next = NULL;
APPEND (opts->pending, imacros, o);
}
}
/* Add directory to end of path for includes,
with the default prefix at the front of its name. */
else if (!strcmp (argv[i], "-iwithprefix"))
{
char *fname;
int len;
if (i + 1 == argc)
goto missing_dirname;
++i;
len = strlen (argv[i]);
if (opts->include_prefix != 0)
{
fname = xmalloc (opts->include_prefix_len + len + 1);
memcpy (fname, opts->include_prefix, opts->include_prefix_len);
memcpy (fname + opts->include_prefix_len, argv[i], len + 1);
}
else
{
fname = xmalloc (sizeof GCC_INCLUDE_DIR - 8 + len);
memcpy (fname, GCC_INCLUDE_DIR, sizeof GCC_INCLUDE_DIR - 9);
memcpy (fname + sizeof GCC_INCLUDE_DIR - 9, argv[i], len + 1);
}
append_include_chain (pfile, &opts->system_include, fname, 0); append_include_chain (pfile, opts->pending, fname, SYSTEM);
} }
/* Add directory to main path for includes, /* Add directory to main path for includes,
with the default prefix at the front of its name. */ with the default prefix at the front of its name. */
else if (!strcmp (argv[i], "-iwithprefix")) else if (!strcmp (argv[i], "-iwithprefixbefore"))
{ {
char *fname; char *fname;
if (i + 1 == argc) int len;
goto missing_dirname; if (i + 1 == argc)
++i; goto missing_dirname;
++i;
if (opts->include_prefix != 0) len = strlen (argv[i]);
{
fname = xmalloc (strlen (opts->include_prefix) if (opts->include_prefix != 0)
+ strlen (argv[i]) + 1); {
strcpy (fname, opts->include_prefix); fname = xmalloc (opts->include_prefix_len + len + 1);
strcat (fname, argv[i]); memcpy (fname, opts->include_prefix, opts->include_prefix_len);
} memcpy (fname + opts->include_prefix_len, argv[i], len + 1);
else }
{ else
fname = xmalloc (strlen (GCC_INCLUDE_DIR) {
+ strlen (argv[i]) + 1); fname = xmalloc (sizeof GCC_INCLUDE_DIR - 8 + len);
strcpy (fname, GCC_INCLUDE_DIR); memcpy (fname, GCC_INCLUDE_DIR, sizeof GCC_INCLUDE_DIR - 9);
/* Remove the `include' from /usr/local/lib/gcc.../include. */ memcpy (fname + sizeof GCC_INCLUDE_DIR - 9, argv[i], len + 1);
if (!strcmp (fname + strlen (fname) - 8, "/include")) }
fname[strlen (fname) - 7] = 0;
strcat (fname, argv[i]);
}
append_include_chain (pfile, &opts->bracket_include, fname, 0); append_include_chain (pfile, opts->pending, fname, BRACKET);
} }
/* Add directory to end of path for includes. */ /* Add directory to end of path for includes. */
else if (!strcmp (argv[i], "-idirafter")) else if (!strcmp (argv[i], "-idirafter"))
{ {
if (i + 1 == argc) if (i + 1 == argc)
goto missing_dirname; goto missing_dirname;
append_include_chain (pfile, &opts->after_include, argv[++i], 0); append_include_chain (pfile, opts->pending,
} xstrdup (argv[++i]), AFTER);
else if (!strcmp (argv[i], "-include") || !strcmp (argv[i], "-imacros")) }
{ else if (!strcmp (argv[i], "-iprefix"))
if (i + 1 == argc) {
goto missing_filename; if (i + 1 == argc)
else goto missing_filename;
push_pending (pfile, argv[i], argv[i+1]), i++; else
} {
else if (!strcmp (argv[i], "-iprefix")) opts->include_prefix = argv[++i];
{ opts->include_prefix_len = strlen (argv[i]);
if (i + 1 == argc) }
goto missing_filename; }
else else if (!strcmp (argv[i], "-ifoutput"))
opts->include_prefix = argv[++i]; opts->output_conditionals = 1;
}
else if (!strcmp (argv[i], "-ifoutput"))
opts->output_conditionals = 1;
break; break;
case 'o': case 'o':
if (opts->out_fname != NULL) if (opts->out_fname != NULL)
{ {
cpp_fatal (pfile, "Output filename specified twice"); cpp_fatal (pfile, "Output filename specified twice");
return argc; return argc;
} }
if (i + 1 == argc) if (i + 1 == argc)
goto missing_filename; goto missing_filename;
opts->out_fname = argv[++i]; opts->out_fname = argv[++i];
if (!strcmp (opts->out_fname, "-")) if (!strcmp (opts->out_fname, "-"))
opts->out_fname = ""; opts->out_fname = "";
break; break;
case 'p': case 'p':
if (!strcmp (argv[i], "-pedantic")) if (!strcmp (argv[i], "-pedantic"))
CPP_PEDANTIC (pfile) = 1; CPP_PEDANTIC (pfile) = 1;
else if (!strcmp (argv[i], "-pedantic-errors")) { else if (!strcmp (argv[i], "-pedantic-errors"))
CPP_PEDANTIC (pfile) = 1; {
opts->pedantic_errors = 1; CPP_PEDANTIC (pfile) = 1;
} opts->pedantic_errors = 1;
}
#if 0 #if 0
else if (!strcmp (argv[i], "-pcp")) { else if (!strcmp (argv[i], "-pcp")) {
char *pcp_fname = argv[++i]; char *pcp_fname = argv[++i];
pcp_outfile = ((pcp_fname[0] != '-' || pcp_fname[1] != '\0') pcp_outfile = ((pcp_fname[0] != '-' || pcp_fname[1] != '\0')
? fopen (pcp_fname, "w") ? fopen (pcp_fname, "w")
: fdopen (dup (fileno (stdout)), "w")); : fdopen (dup (fileno (stdout)), "w"));
if (pcp_outfile == 0) if (pcp_outfile == 0)
cpp_pfatal_with_name (pfile, pcp_fname); cpp_pfatal_with_name (pfile, pcp_fname);
no_precomp = 1; no_precomp = 1;
} }
#endif #endif
break; break;
case 't': case 't':
if (!strcmp (argv[i], "-traditional")) { if (!strcmp (argv[i], "-traditional"))
opts->traditional = 1; {
opts->cplusplus_comments = 0; opts->traditional = 1;
} else if (!strcmp (argv[i], "-trigraphs")) { opts->cplusplus_comments = 0;
if (!opts->chill) }
else if (!strcmp (argv[i], "-trigraphs"))
opts->trigraphs = 1; opts->trigraphs = 1;
} break;
break;
case 'l': case 'l':
if (! strcmp (argv[i], "-lang-c")) if (! strcmp (argv[i], "-lang-c"))
opts->cplusplus = 0, opts->cplusplus_comments = 1, opts->c89 = 0, opts->cplusplus = 0, opts->cplusplus_comments = 1, opts->c89 = 0,
opts->c9x = 1, opts->objc = 0; opts->c9x = 1, opts->objc = 0;
if (! strcmp (argv[i], "-lang-c89")) if (! strcmp (argv[i], "-lang-c89"))
opts->cplusplus = 0, opts->cplusplus_comments = 0, opts->c89 = 1, opts->cplusplus = 0, opts->cplusplus_comments = 0, opts->c89 = 1,
opts->c9x = 0, opts->objc = 0; opts->c9x = 0, opts->objc = 0;
if (! strcmp (argv[i], "-lang-c++")) if (! strcmp (argv[i], "-lang-c++"))
opts->cplusplus = 1, opts->cplusplus_comments = 1, opts->c89 = 0, opts->cplusplus = 1, opts->cplusplus_comments = 1, opts->c89 = 0,
opts->c9x = 0, opts->objc = 0; opts->c9x = 0, opts->objc = 0;
if (! strcmp (argv[i], "-lang-objc")) if (! strcmp (argv[i], "-lang-objc"))
opts->cplusplus = 0, opts->cplusplus_comments = 1, opts->c89 = 0, opts->cplusplus = 0, opts->cplusplus_comments = 1, opts->c89 = 0,
opts->c9x = 0, opts->objc = 1; opts->c9x = 0, opts->objc = 1;
if (! strcmp (argv[i], "-lang-objc++")) if (! strcmp (argv[i], "-lang-objc++"))
opts->cplusplus = 1, opts->cplusplus_comments = 1, opts->c89 = 0, opts->cplusplus = 1, opts->cplusplus_comments = 1, opts->c89 = 0,
opts->c9x = 0, opts->objc = 1; opts->c9x = 0, opts->objc = 1;
if (! strcmp (argv[i], "-lang-asm")) if (! strcmp (argv[i], "-lang-asm"))
opts->lang_asm = 1; opts->lang_asm = 1;
if (! strcmp (argv[i], "-lint")) if (! strcmp (argv[i], "-lint"))
opts->for_lint = 1; opts->for_lint = 1;
if (! strcmp (argv[i], "-lang-chill")) if (! strcmp (argv[i], "-lang-chill"))
opts->objc = 0, opts->cplusplus = 0, opts->chill = 1, opts->objc = 0, opts->cplusplus = 0, opts->chill = 1,
opts->traditional = 1, opts->trigraphs = 0; opts->traditional = 1;
break; break;
case '+': case '+':
opts->cplusplus = 1, opts->cplusplus_comments = 1; opts->cplusplus = 1, opts->cplusplus_comments = 1;
break; break;
case 's': case 's':
if (!strcmp (argv[i], "-std=iso9899:1990") if (!strcmp (argv[i], "-std=iso9899:1990")
|| !strcmp (argv[i], "-std=iso9899:199409") || !strcmp (argv[i], "-std=iso9899:199409")
|| !strcmp (argv[i], "-std=c89") || !strcmp (argv[i], "-std=c89")
|| !strcmp (argv[i], "-std=gnu89")) || !strcmp (argv[i], "-std=gnu89"))
opts->cplusplus = 0, opts->cplusplus_comments = 0, opts->cplusplus = 0, opts->cplusplus_comments = 0,
opts->c89 = 1, opts->c9x = 0, opts->objc = 0; opts->c89 = 1, opts->c9x = 0, opts->objc = 0;
else if (!strcmp (argv[i], "-std=iso9899:199x") else if (!strcmp (argv[i], "-std=iso9899:199x")
|| !strcmp (argv[i], "-std=c9x") || !strcmp (argv[i], "-std=c9x")
|| !strcmp (argv[i], "-std=gnu9x")) || !strcmp (argv[i], "-std=gnu9x"))
opts->cplusplus = 0, opts->cplusplus_comments = 1, opts->c89 = 0, opts->cplusplus = 0, opts->cplusplus_comments = 1, opts->c89 = 0,
opts->c9x = 1, opts->objc = 0; opts->c9x = 1, opts->objc = 0;
break; break;
case 'w': case 'w':
opts->inhibit_warnings = 1; opts->inhibit_warnings = 1;
break; break;
case 'W': case 'W':
if (!strcmp (argv[i], "-Wtrigraphs")) if (!strcmp (argv[i], "-Wtrigraphs"))
opts->warn_trigraphs = 1;
else if (!strcmp (argv[i], "-Wno-trigraphs"))
opts->warn_trigraphs = 0;
else if (!strcmp (argv[i], "-Wcomment"))
opts->warn_comments = 1;
else if (!strcmp (argv[i], "-Wno-comment"))
opts->warn_comments = 0;
else if (!strcmp (argv[i], "-Wcomments"))
opts->warn_comments = 1;
else if (!strcmp (argv[i], "-Wno-comments"))
opts->warn_comments = 0;
else if (!strcmp (argv[i], "-Wtraditional"))
opts->warn_stringify = 1;
else if (!strcmp (argv[i], "-Wno-traditional"))
opts->warn_stringify = 0;
else if (!strcmp (argv[i], "-Wundef"))
opts->warn_undef = 1;
else if (!strcmp (argv[i], "-Wno-undef"))
opts->warn_undef = 0;
else if (!strcmp (argv[i], "-Wimport"))
opts->warn_import = 1;
else if (!strcmp (argv[i], "-Wno-import"))
opts->warn_import = 0;
else if (!strcmp (argv[i], "-Werror"))
opts->warnings_are_errors = 1;
else if (!strcmp (argv[i], "-Wno-error"))
opts->warnings_are_errors = 0;
else if (!strcmp (argv[i], "-Wall"))
{
opts->warn_trigraphs = 1; opts->warn_trigraphs = 1;
else if (!strcmp (argv[i], "-Wno-trigraphs"))
opts->warn_trigraphs = 0;
else if (!strcmp (argv[i], "-Wcomment"))
opts->warn_comments = 1; opts->warn_comments = 1;
} else if (!strcmp (argv[i], "-Wno-comment"))
break; opts->warn_comments = 0;
else if (!strcmp (argv[i], "-Wcomments"))
case 'M': opts->warn_comments = 1;
/* The style of the choices here is a bit mixed. else if (!strcmp (argv[i], "-Wno-comments"))
The chosen scheme is a hybrid of keeping all options in one string opts->warn_comments = 0;
and specifying each option in a separate argument: else if (!strcmp (argv[i], "-Wtraditional"))
-M|-MM|-MD file|-MMD file [-MG]. An alternative is: opts->warn_stringify = 1;
-M|-MM|-MD file|-MMD file|-MG|-MMG; or more concisely: else if (!strcmp (argv[i], "-Wno-traditional"))
-M[M][G][D file]. This is awkward to handle in specs, and is not opts->warn_stringify = 0;
as extensible. */ else if (!strcmp (argv[i], "-Wundef"))
/* ??? -MG must be specified in addition to one of -M or -MM. opts->warn_undef = 1;
This can be relaxed in the future without breaking anything. else if (!strcmp (argv[i], "-Wno-undef"))
The converse isn't true. */ opts->warn_undef = 0;
else if (!strcmp (argv[i], "-Wimport"))
opts->warn_import = 1;
else if (!strcmp (argv[i], "-Wno-import"))
opts->warn_import = 0;
else if (!strcmp (argv[i], "-Werror"))
opts->warnings_are_errors = 1;
else if (!strcmp (argv[i], "-Wno-error"))
opts->warnings_are_errors = 0;
else if (!strcmp (argv[i], "-Wall"))
{
opts->warn_trigraphs = 1;
opts->warn_comments = 1;
}
break;
/* -MG isn't valid with -MD or -MMD. This is checked for later. */ case 'M':
if (!strcmp (argv[i], "-MG")) /* The style of the choices here is a bit mixed.
{ The chosen scheme is a hybrid of keeping all options in one string
opts->print_deps_missing_files = 1; and specifying each option in a separate argument:
break; -M|-MM|-MD file|-MMD file [-MG]. An alternative is:
} -M|-MM|-MD file|-MMD file|-MG|-MMG; or more concisely:
if (!strcmp (argv[i], "-M")) -M[M][G][D file]. This is awkward to handle in specs, and is not
opts->print_deps = 2; as extensible. */
else if (!strcmp (argv[i], "-MM")) /* ??? -MG must be specified in addition to one of -M or -MM.
opts->print_deps = 1; This can be relaxed in the future without breaking anything.
else if (!strcmp (argv[i], "-MD")) The converse isn't true. */
opts->print_deps = 2;
else if (!strcmp (argv[i], "-MMD"))
opts->print_deps = 1;
/* For -MD and -MMD options, write deps on file named by next arg. */
if (!strcmp (argv[i], "-MD") || !strcmp (argv[i], "-MMD"))
{
if (i+1 == argc)
goto missing_filename;
opts->deps_file = argv[++i];
}
else
{
/* For -M and -MM, write deps on standard output
and suppress the usual output. */
opts->no_output = 1;
}
break;
case 'd': /* -MG isn't valid with -MD or -MMD. This is checked for later. */
{ if (!strcmp (argv[i], "-MG"))
char *p = argv[i] + 2; {
char c; opts->print_deps_missing_files = 1;
while ((c = *p++) != 0) {
/* Arg to -d specifies what parts of macros to dump */
switch (c) {
case 'M':
opts->dump_macros = dump_only;
opts->no_output = 1;
break;
case 'N':
opts->dump_macros = dump_names;
break;
case 'D':
opts->dump_macros = dump_definitions;
break;
case 'I':
opts->dump_includes = 1;
break; break;
} }
if (!strcmp (argv[i], "-M"))
opts->print_deps = 2;
else if (!strcmp (argv[i], "-MM"))
opts->print_deps = 1;
else if (!strcmp (argv[i], "-MD"))
opts->print_deps = 2;
else if (!strcmp (argv[i], "-MMD"))
opts->print_deps = 1;
/* For -MD and -MMD options, write deps on file named by next arg. */
if (!strcmp (argv[i], "-MD") || !strcmp (argv[i], "-MMD"))
{
if (i+1 == argc)
goto missing_filename;
opts->deps_file = argv[++i];
}
else
{
/* For -M and -MM, write deps on standard output
and suppress the usual output. */
opts->no_output = 1;
}
break;
case 'd':
{
char *p = argv[i] + 2;
char c;
while ((c = *p++) != 0)
{
/* Arg to -d specifies what parts of macros to dump */
switch (c)
{
case 'M':
opts->dump_macros = dump_only;
opts->no_output = 1;
break;
case 'N':
opts->dump_macros = dump_names;
break;
case 'D':
opts->dump_macros = dump_definitions;
break;
case 'I':
opts->dump_includes = 1;
break;
}
}
} }
} break;
break;
case 'g': case 'g':
if (argv[i][2] == '3') if (argv[i][2] == '3')
opts->debug_output = 1; opts->debug_output = 1;
break; break;
case '-': case '-':
if (strcmp (argv[i], "--help") != 0) if (!strcmp (argv[i], "--help"))
return i; print_help ();
print_help (); else if (!strcmp (argv[i], "--version"))
break; cpp_notice ("GNU CPP version %s\n", version_string);
exit (0); /* XXX */
break;
case 'v': case 'v':
cpp_notice ("GNU CPP version %s", version_string); cpp_notice ("GNU CPP version %s", version_string);
#ifdef TARGET_VERSION #ifdef TARGET_VERSION
TARGET_VERSION; TARGET_VERSION;
#endif #endif
fprintf (stderr, "\n"); fputc ('\n', stderr);
opts->verbose = 1; opts->verbose = 1;
break; break;
case 'H': case 'H':
opts->print_include_names = 1; opts->print_include_names = 1;
break; break;
case 'D': case 'D':
if (argv[i][2] != 0)
push_pending (pfile, "-D", argv[i] + 2);
else if (i + 1 == argc)
{ {
cpp_fatal (pfile, "Macro name missing after -D option"); struct pending_option *o = (struct pending_option *)
return argc; xmalloc (sizeof (struct pending_option));
if (argv[i][2] != 0)
o->arg = argv[i] + 2;
else if (i + 1 == argc)
{
cpp_fatal (pfile, "Macro name missing after -D option");
return argc;
}
else
o->arg = argv[++i];
o->next = NULL;
o->undef = 0;
APPEND (opts->pending, define, o);
} }
else break;
i++, push_pending (pfile, "-D", argv[i]);
break;
case 'A': case 'A':
{ {
char *p; char *p;
if (argv[i][2] != 0) if (argv[i][2] != 0)
p = argv[i] + 2; p = argv[i] + 2;
else if (i + 1 == argc) else if (i + 1 == argc)
{ {
cpp_fatal (pfile, "Assertion missing after -A option"); cpp_fatal (pfile, "Assertion missing after -A option");
return argc; return argc;
} }
else else
p = argv[++i]; p = argv[++i];
if (!strcmp (p, "-")) { if (strcmp (p, "-"))
struct cpp_pending **ptr;
/* -A- eliminates all predefined macros and assertions.
Let's include also any that were specified earlier
on the command line. That way we can get rid of any
that were passed automatically in from GCC. */
opts->inhibit_predefs = 1;
for (ptr = &opts->pending; *ptr != NULL; )
{ {
struct cpp_pending *pend = *ptr; struct pending_option *o = (struct pending_option *)
if (pend->cmd && pend->cmd[0] == '-' xmalloc (sizeof (struct pending_option));
&& (pend->cmd[1] == 'D' || pend->cmd[1] == 'A'))
o->arg = p;
o->next = NULL;
o->undef = 0;
APPEND (opts->pending, assert, o);
}
else
{
/* -A- eliminates all predefined macros and assertions.
Let's include also any that were specified earlier
on the command line. That way we can get rid of any
that were passed automatically in from GCC. */
struct pending_option *o1, *o2;
o1 = opts->pending->define_head;
while (o1)
{
o2 = o1->next;
free (o1);
o1 = o2;
}
o1 = opts->pending->assert_head;
while (o1)
{ {
*ptr = pend->next; o2 = o1->next;
free (pend); free (o1);
o1 = o2;
} }
else opts->pending->assert_head = NULL;
ptr = &pend->next; opts->pending->assert_tail = NULL;
opts->pending->define_head = NULL;
opts->pending->define_tail = NULL;
opts->inhibit_predefs = 1;
} }
} else {
push_pending (pfile, "-A", p);
} }
} break;
break;
case 'U': /* JF #undef something */ case 'U':
if (argv[i][2] != 0)
push_pending (pfile, "-U", argv[i] + 2);
else if (i + 1 == argc)
{ {
cpp_fatal (pfile, "Macro name missing after -U option"); struct pending_option *o = (struct pending_option *)
return argc; xmalloc (sizeof (struct pending_option));
if (argv[i][2] != 0)
o->arg = argv[i] + 2;
else if (i + 1 == argc)
{
cpp_fatal (pfile, "Macro name missing after -U option");
return argc;
}
else
o->arg = argv[++i];
o->next = NULL;
o->undef = 1;
APPEND (opts->pending, define, o);
} }
else break;
push_pending (pfile, "-U", argv[i+1]), i++;
break;
case 'C': case 'C':
opts->put_out_comments = 1; opts->put_out_comments = 1;
break; break;
case 'E': /* -E comes from cc -E; ignore it. */ case 'E': /* -E comes from cc -E; ignore it. */
break; break;
case 'P': case 'P':
opts->no_line_commands = 1; opts->no_line_commands = 1;
break; break;
case '$': /* Don't include $ in identifiers. */ case '$': /* Don't include $ in identifiers. */
opts->dollars_in_ident = 0; opts->dollars_in_ident = 0;
break; break;
case 'n': case 'n':
if (!strcmp (argv[i], "-nostdinc")) if (!strcmp (argv[i], "-nostdinc"))
/* -nostdinc causes no default include directories. /* -nostdinc causes no default include directories.
You must specify all include-file directories with -I. */ You must specify all include-file directories with -I. */
opts->no_standard_includes = 1; opts->no_standard_includes = 1;
else if (!strcmp (argv[i], "-nostdinc++")) else if (!strcmp (argv[i], "-nostdinc++"))
/* -nostdinc++ causes no default C++-specific include directories. */ /* -nostdinc++ causes no default C++-specific include directories. */
opts->no_standard_cplusplus_includes = 1; opts->no_standard_cplusplus_includes = 1;
#if 0 #if 0
else if (!strcmp (argv[i], "-noprecomp")) else if (!strcmp (argv[i], "-noprecomp"))
no_precomp = 1; no_precomp = 1;
#endif #endif
break; break;
case 'r':
if (!strcmp (argv[i], "-remap"))
opts->remap = 1;
break;
case 'u': case 'r':
/* Sun compiler passes undocumented switch "-undef". if (!strcmp (argv[i], "-remap"))
Let's assume it means to inhibit the predefined symbols. */ opts->remap = 1;
opts->inhibit_predefs = 1; break;
break;
case '\0': /* JF handle '-' as file name meaning stdin or stdout */ case 'u':
if (opts->in_fname == NULL) { if (!strcmp (argv[i], "-undef"))
opts->in_fname = ""; opts->inhibit_predefs = 1;
break; break;
} else if (opts->out_fname == NULL) {
opts->out_fname = ""; case '\0': /* JF handle '-' as file name meaning stdin or stdout */
if (opts->in_fname == NULL)
opts->in_fname = "";
else if (opts->out_fname == NULL)
opts->out_fname = "";
else
return i; /* error */
break; break;
} /* else fall through into error */
default: default:
return i; return i;
} }
}
return i + 1; return i + 1;
missing_filename:
cpp_fatal (pfile, "Filename missing after `%s' option", argv[i]);
return argc;
missing_dirname:
cpp_fatal (pfile, "Directory name missing after `%s' option", argv[i]);
return argc;
} }
/* Handle command-line options in (argc, argv). /* Handle command-line options in (argc, argv).
......
...@@ -2936,6 +2936,19 @@ do_unassert (pfile, keyword) ...@@ -2936,6 +2936,19 @@ do_unassert (pfile, keyword)
return 1; return 1;
} }
/* Process STR as if it appeared as the body of an #unassert. */
void
cpp_unassert (pfile, str)
cpp_reader *pfile;
unsigned char *str;
{
if (cpp_push_buffer (pfile, str, strlen (str)) != NULL)
{
do_assert (pfile, NULL);
cpp_pop_buffer (pfile);
}
}
int int
cpp_read_check_assertion (pfile) cpp_read_check_assertion (pfile)
cpp_reader *pfile; cpp_reader *pfile;
......
...@@ -145,7 +145,6 @@ struct cpp_buffer ...@@ -145,7 +145,6 @@ struct cpp_buffer
char has_escapes; char has_escapes;
}; };
struct cpp_pending; /* Forward declaration - for C++. */
struct file_name_map_list; struct file_name_map_list;
/* Maximum nesting of cpp_buffers. We use a static limit, partly for /* Maximum nesting of cpp_buffers. We use a static limit, partly for
...@@ -297,6 +296,24 @@ struct cpp_reader ...@@ -297,6 +296,24 @@ struct cpp_reader
/* The bottom of the buffer stack. */ /* The bottom of the buffer stack. */
#define CPP_NULL_BUFFER(PFILE) NULL #define CPP_NULL_BUFFER(PFILE) NULL
/* 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. */ /* Pointed to by cpp_reader.opts. */
struct cpp_options { struct cpp_options {
char *in_fname; char *in_fname;
...@@ -435,16 +452,14 @@ struct cpp_options { ...@@ -435,16 +452,14 @@ struct cpp_options {
char done_initializing; char done_initializing;
/* Search paths for include files. system_include, after_include are /* Search paths for include files. */
only used during option parsing. */
struct file_name_list *quote_include; /* First dir to search for "file" */ struct file_name_list *quote_include; /* First dir to search for "file" */
struct file_name_list *bracket_include;/* First dir to search for <file> */ struct file_name_list *bracket_include;/* First dir to search for <file> */
struct file_name_list *system_include; /* First dir with system headers */
struct file_name_list *after_include; /* Headers to search after system */
/* Directory prefix that should replace `/usr' in the standard /* Directory prefix that should replace `/usr/lib/gcc-lib/TARGET/VERSION'
include file directories. */ in the standard include file directories. */
char *include_prefix; char *include_prefix;
int include_prefix_len;
char inhibit_predefs; char inhibit_predefs;
char no_standard_includes; char no_standard_includes;
...@@ -472,7 +487,7 @@ struct cpp_options { ...@@ -472,7 +487,7 @@ struct cpp_options {
even if they are ifdefed out. */ even if they are ifdefed out. */
int dump_includes; int dump_includes;
/* Pending -D, -U and -A options, in reverse order. */ /* Pending options - -D, -U, -A, -I, -ixxx. */
struct cpp_pending *pending; struct cpp_pending *pending;
/* File name which deps are being written to. /* File name which deps are being written to.
...@@ -671,6 +686,7 @@ extern cpp_buffer* cpp_file_buffer PARAMS((cpp_reader *)); ...@@ -671,6 +686,7 @@ extern cpp_buffer* cpp_file_buffer PARAMS((cpp_reader *));
extern void cpp_define PARAMS ((cpp_reader *, unsigned char *)); extern void cpp_define PARAMS ((cpp_reader *, unsigned char *));
extern void cpp_assert PARAMS ((cpp_reader *, unsigned char *)); extern void cpp_assert PARAMS ((cpp_reader *, unsigned char *));
extern void cpp_undef PARAMS ((cpp_reader *, unsigned char *)); extern void cpp_undef PARAMS ((cpp_reader *, unsigned char *));
extern void cpp_unassert PARAMS ((cpp_reader *, unsigned char *));
extern void cpp_error PVPROTO ((cpp_reader *, const char *, ...)) extern void cpp_error PVPROTO ((cpp_reader *, const char *, ...))
ATTRIBUTE_PRINTF_2; ATTRIBUTE_PRINTF_2;
...@@ -728,9 +744,7 @@ extern void cpp_print_containing_files PROTO ((cpp_reader *)); ...@@ -728,9 +744,7 @@ extern void cpp_print_containing_files PROTO ((cpp_reader *));
extern void cpp_notice PVPROTO ((const char *msgid, ...)) ATTRIBUTE_PRINTF_1; extern void cpp_notice PVPROTO ((const char *msgid, ...)) ATTRIBUTE_PRINTF_1;
/* In cppfiles.c */ /* In cppfiles.c */
extern void append_include_chain PROTO ((cpp_reader *, extern void simplify_pathname PROTO ((char *));
struct file_name_list **,
const char *, int));
extern void merge_include_chains PROTO ((struct cpp_options *)); extern void merge_include_chains PROTO ((struct cpp_options *));
extern int find_include_file PROTO ((cpp_reader *, char *, extern int find_include_file PROTO ((cpp_reader *, char *,
struct file_name_list *, struct file_name_list *,
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment