/* CPP Library.
Copyright (C) 1986, 1987, 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
- 1999, 2000, 2001 Free Software Foundation, Inc.
+ 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
Contributed by Per Bothner, 1994-95.
Based on CCCP program by Paul Rubin, June 1986
Adapted to ANSI C, Richard Stallman, Jan 1987
#include "system.h"
#include "cpplib.h"
#include "cpphash.h"
-#include "output.h"
#include "prefix.h"
#include "intl.h"
#include "version.h"
#include "mkdeps.h"
#include "cppdefault.h"
+#include "except.h" /* for USING_SJLJ_EXCEPTIONS */
/* Predefined symbols, built-in macros, and the default include path. */
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)))
+# define INO_T_EQ(A, B) (!memcmp (&(A), &(B), sizeof (A)))
+# define INO_T_COPY(DEST, SRC) memcpy(&(DEST), &(SRC), sizeof (SRC))
#else
# if (defined _WIN32 && ! defined (_UWIN)) || defined __MSDOS__
-# define INO_T_EQ(a, b) 0
+# define INO_T_EQ(A, B) 0
# else
-# define INO_T_EQ(a, b) ((a) == (b))
+# define INO_T_EQ(A, B) ((A) == (B))
# endif
+# define INO_T_COPY(DEST, SRC) (DEST) = (SRC)
#endif
/* Internal structures and prototypes. */
/* A `struct pending_option' remembers one -D, -A, -U, -include, or
-imacros switch. */
-
typedef void (* cl_directive_handler) PARAMS ((cpp_reader *, const char *));
struct pending_option
{
};
/* The `pending' structure accumulates all the options that are not
- actually processed until we hit cpp_start_read. It consists of
+ actually processed until we hit cpp_read_main_file. It consists of
several lists, one for each type of option. We keep both head and
tail pointers for quick insertion. */
struct cpp_pending
static void set_lang PARAMS ((cpp_reader *, enum c_lang));
static void init_dependency_output PARAMS ((cpp_reader *));
static void init_standard_includes PARAMS ((cpp_reader *));
+static void read_original_filename PARAMS ((cpp_reader *));
static void new_pending_directive PARAMS ((struct cpp_pending *,
const char *,
cl_directive_handler));
/* Given a colon-separated list of file names PATH,
add all the names to the search path for include files. */
-
static void
path_include (pfile, list, path)
cpp_reader *pfile;
}
/* Append DIR to include path PATH. DIR must be allocated on the
- heap; this routine takes responsibility for freeing it. */
+ heap; this routine takes responsibility for freeing it. CXX_AWARE
+ is non-zero if the header contains extern "C" guards for C++,
+ otherwise it is zero. */
static void
append_include_chain (pfile, dir, path, cxx_aware)
cpp_reader *pfile;
new = (struct search_path *) xmalloc (sizeof (struct search_path));
new->name = dir;
new->len = len;
- new->ino = st.st_ino;
+ INO_T_COPY (new->ino, st.st_ino);
new->dev = st.st_dev;
/* Both systm and after include file lists should be treated as system
include files since these two lists are really just a concatenation
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. */
-
+ bracket_include path. */
static void
merge_include_chains (pfile)
cpp_reader *pfile;
CPP_OPTION (pfile, bracket_include) = brack;
}
-/* Sets internal flags correctly for a given language, and defines
- macros if necessary. */
-
+/* A set of booleans indicating what CPP features each source language
+ requires. */
struct lang_flags
{
char c99;
/* ASM */ { 0, 0, 0, 1, 0, 0, 1, 0 }
};
+/* Sets internal flags correctly for a given language. */
static void
set_lang (pfile, lang)
cpp_reader *pfile;
/* init initializes library global state. It might not need to
do anything depending on the platform and compiler. */
-
static void
init_library ()
{
/* Initialize a cpp_reader structure. */
cpp_reader *
-cpp_create_reader (table, lang)
- hash_table *table;
+cpp_create_reader (lang)
enum c_lang lang;
{
- struct spec_nodes *s;
cpp_reader *pfile;
/* Initialise this instance of the library if it hasn't been already. */
be needed. */
pfile->deps = deps_init ();
- /* Initialise the line map. */
+ /* Initialise the line map. Start at logical line 1, so we can use
+ a line number of zero for special states. */
init_line_maps (&pfile->line_maps);
+ pfile->line = 1;
/* Initialize lexer state. */
pfile->state.save_comments = ! CPP_OPTION (pfile, discard_comments);
- /* Indicate date and time not yet calculated. */
+ /* Set up static tokens. */
pfile->date.type = CPP_EOF;
+ pfile->avoid_paste.type = CPP_PADDING;
+ pfile->avoid_paste.val.source = NULL;
+ pfile->eof.type = CPP_EOF;
+ pfile->eof.flags = 0;
+
+ /* Create a token buffer for the lexer. */
+ _cpp_init_tokenrun (&pfile->base_run, 250);
+ pfile->cur_run = &pfile->base_run;
+ pfile->cur_token = pfile->base_run.base;
/* Initialise the base context. */
pfile->context = &pfile->base_context;
pfile->base_context.macro = 0;
pfile->base_context.prev = pfile->base_context.next = 0;
- /* Identifier pool initially 8K. Unaligned, permanent pool. */
- _cpp_init_pool (&pfile->ident_pool, 8 * 1024, 1, 0);
-
- /* Argument pool initially 8K. Aligned, temporary pool. */
- _cpp_init_pool (&pfile->argument_pool, 8 * 1024, 0, 1);
-
- /* Macro pool initially 8K. Aligned, permanent pool. */
- _cpp_init_pool (&pfile->macro_pool, 8 * 1024, 0, 0);
+ /* Aligned and unaligned storage. */
+ pfile->a_buff = _cpp_get_buff (pfile, 0);
+ pfile->u_buff = _cpp_get_buff (pfile, 0);
/* Initialise the buffer obstack. */
gcc_obstack_init (&pfile->buffer_ob);
- /* Initialise the hashtable. */
- _cpp_init_hashtable (pfile, table);
-
- _cpp_init_directives (pfile);
_cpp_init_includes (pfile);
- _cpp_init_internal_pragmas (pfile);
-
- /* Initialize the special nodes. */
- s = &pfile->spec_nodes;
- s->n_L = cpp_lookup (pfile, DSC("L"));
- s->n_defined = cpp_lookup (pfile, DSC("defined"));
- s->n_true = cpp_lookup (pfile, DSC("true"));
- s->n_false = cpp_lookup (pfile, DSC("false"));
- s->n__Pragma = cpp_lookup (pfile, DSC("_Pragma"));
- s->n__STRICT_ANSI__ = cpp_lookup (pfile, DSC("__STRICT_ANSI__"));
- s->n__CHAR_UNSIGNED__ = cpp_lookup (pfile, DSC("__CHAR_UNSIGNED__"));
- s->n__VA_ARGS__ = cpp_lookup (pfile, DSC("__VA_ARGS__"));
- s->n__VA_ARGS__->flags |= NODE_DIAGNOSTIC;
return pfile;
}
/* Free resources used by PFILE. Accessing PFILE after this function
- returns leads to undefined behaviour. */
+ returns leads to undefined behaviour. Returns the error count. */
int
cpp_destroy (pfile)
cpp_reader *pfile;
int result;
struct search_path *dir, *dirn;
cpp_context *context, *contextn;
+ tokenrun *run, *runn;
while (CPP_BUFFER (pfile) != NULL)
_cpp_pop_buffer (pfile);
_cpp_destroy_hashtable (pfile);
_cpp_cleanup_includes (pfile);
- _cpp_free_lookaheads (pfile);
- _cpp_free_pool (&pfile->ident_pool);
- _cpp_free_pool (&pfile->macro_pool);
- _cpp_free_pool (&pfile->argument_pool);
+ _cpp_free_buff (pfile->a_buff);
+ _cpp_free_buff (pfile->u_buff);
+ _cpp_free_buff (pfile->free_buffs);
+
+ for (run = &pfile->base_run; run; run = runn)
+ {
+ runn = run->next;
+ free (run->base);
+ if (run != &pfile->base_run)
+ free (run);
+ }
for (dir = CPP_OPTION (pfile, quote_include); dir; dir = dirn)
{
ULP value is the global user_label_prefix
Also, macros with CPLUS set in the flags field are entered only for C++. */
-
struct builtin
{
const U_CHAR *name;
B("__BASE_FILE__", BT_BASE_FILE),
B("__LINE__", BT_SPECLINE),
B("__INCLUDE_LEVEL__", BT_INCLUDE_LEVEL),
+ B("_Pragma", BT_PRAGMA),
X("__VERSION__", VERS),
X("__USER_LABEL_PREFIX__", ULP),
C("__REGISTER_PREFIX__", REGISTER_PREFIX),
C("__HAVE_BUILTIN_SETJMP__", "1"),
+#if USING_SJLJ_EXCEPTIONS
+ /* libgcc needs to know this. */
+ C("__USING_SJLJ_EXCEPTIONS__","1"),
+#endif
#ifndef NO_BUILTIN_SIZE_TYPE
C("__SIZE_TYPE__", SIZE_TYPE),
#endif
#define builtin_array_end \
builtin_array + sizeof(builtin_array)/sizeof(struct builtin)
-/* Subroutine of cpp_start_read; reads the builtins table above and
- enters the macros into the hash table. */
+/* Subroutine of cpp_read_main_file; reads the builtins table above and
+ enters them, and language-specific macros, into the hash table. */
static void
init_builtins (pfile)
cpp_reader *pfile;
}
}
-/* Pushes a -imacro and -include file given on the command line onto
+/* Pushes a command line -imacro and -include file indicated by P onto
the buffer stack. Returns non-zero if successful. */
static bool
push_include (pfile, p)
header.val.str.text = (const unsigned char *) p->arg;
header.val.str.len = strlen (p->arg);
/* Make the command line directive take up a line. */
- pfile->lexer_pos.line = pfile->lexer_pos.output_line = ++pfile->line;
+ pfile->line++;
return _cpp_execute_include (pfile, &header, IT_CMDLINE);
}
}
}
-/* This is called after options have been processed. Setup for
- processing input from the file named FNAME, or stdin if it is the
- empty string. Return 1 on success, 0 on failure. */
-int
-cpp_start_read (pfile, fname)
+/* This is called after options have been parsed, and partially
+ processed. Setup for processing input from the file named FNAME,
+ or stdin if it is the empty string. Return the original filename
+ on success (e.g. foo.i->foo.c), or NULL on failure. */
+const char *
+cpp_read_main_file (pfile, fname, table)
cpp_reader *pfile;
const char *fname;
+ hash_table *table;
{
+ /* The front ends don't set up the hash table until they have
+ finished processing the command line options, so initializing the
+ hashtable is deferred until now. */
+ _cpp_init_hashtable (pfile, table);
+
/* Set up the include search path now. */
if (! CPP_OPTION (pfile, no_standard_includes))
init_standard_includes (pfile);
/* Set the default target (if there is none already). */
deps_add_default_target (pfile->deps, fname);
- /* Open the main input file. This must be done early, so we have a
- buffer to stand on. */
+ /* Open the main input file. */
if (!_cpp_read_file (pfile, fname))
- return 0;
+ return NULL;
/* Set this after cpp_post_options so the client can change the
option if it wishes, and after stacking the main file so we don't
trace the main file. */
pfile->line_maps.trace_includes = CPP_OPTION (pfile, print_include_names);
+ /* For foo.i, read the original filename foo.c now, for the benefit
+ of the front ends. */
+ if (CPP_OPTION (pfile, preprocessed))
+ read_original_filename (pfile);
+
+ return pfile->map->to_file;
+}
+
+/* For preprocessed files, if the first tokens are of the form # NUM.
+ handle the directive so we know the original file name. This will
+ generate file_change callbacks, which the front ends must handle
+ appropriately given their state of initialization. */
+static void
+read_original_filename (pfile)
+ cpp_reader *pfile;
+{
+ const cpp_token *token, *token1;
+
+ /* Lex ahead; if the first tokens are of the form # NUM, then
+ process the directive, otherwise back up. */
+ token = _cpp_lex_direct (pfile);
+ if (token->type == CPP_HASH)
+ {
+ token1 = _cpp_lex_direct (pfile);
+ _cpp_backup_tokens (pfile, 1);
+
+ /* If it's a #line directive, handle it. */
+ if (token1->type == CPP_NUMBER)
+ {
+ _cpp_handle_directive (pfile, token->flags & PREV_WHITE);
+ return;
+ }
+ }
+
+ /* Backup as if nothing happened. */
+ _cpp_backup_tokens (pfile, 1);
+}
+
+/* Handle pending command line options: -D, -U, -A, -imacros and
+ -include. This should be called after debugging has been properly
+ set up in the front ends. */
+void
+cpp_finish_options (pfile)
+ cpp_reader *pfile;
+{
/* Install builtins and process command line macros etc. in the order
they appeared, but only if not already preprocessed. */
if (! CPP_OPTION (pfile, preprocessed))
{
struct pending_option *p;
- _cpp_do_file_change (pfile, LC_RENAME, _("<builtin>"), 1, 0);
+ _cpp_do_file_change (pfile, LC_RENAME, _("<built-in>"), 1, 0);
init_builtins (pfile);
_cpp_do_file_change (pfile, LC_RENAME, _("<command line>"), 1, 0);
for (p = CPP_OPTION (pfile, pending)->directive_head; p; p = p->next)
free_chain (CPP_OPTION (pfile, pending)->directive_head);
_cpp_push_next_buffer (pfile);
-
- return 1;
}
/* Called to push the next buffer on the stack given by -include. If
{
/* Stream on which to print the dependency information. */
FILE *deps_stream = 0;
- const char *deps_mode = CPP_OPTION (pfile, print_deps_append) ? "a" : "w";
+ const char *const deps_mode =
+ CPP_OPTION (pfile, print_deps_append) ? "a" : "w";
if (CPP_OPTION (pfile, deps_file) == 0)
deps_stream = stdout;
{
/* cpplex.c leaves the final buffer on the stack. This it so that
it returns an unending stream of CPP_EOFs to the client. If we
- popped the buffer, we'd derefence a NULL buffer pointer and
+ popped the buffer, we'd dereference a NULL buffer pointer and
segfault. It's nice to allow the client to do worry-free excess
cpp_get_token calls. */
while (pfile->buffer)
_cpp_report_missing_guards (pfile);
}
+/* Add a directive to be handled later in the initialization phase. */
static void
new_pending_directive (pend, text, handler)
struct cpp_pending *pend;
/* Irix6 "cc -n32" and OSF4 cc have problems with char foo[] = ("string");
I.e. a const string initializer with parens around it. That is
what N_("string") resolves to, so we make no_* be macros instead. */
-#define no_arg N_("Argument missing after %s")
-#define no_ass N_("Assertion missing after %s")
-#define no_dir N_("Directory name missing after %s")
-#define no_fil N_("File name missing after %s")
-#define no_mac N_("Macro name missing after %s")
-#define no_pth N_("Path name missing after %s")
-#define no_num N_("Number missing after %s")
-#define no_tgt N_("Target missing after %s")
+#define no_arg N_("argument missing after %s")
+#define no_ass N_("assertion missing after %s")
+#define no_dir N_("directory name missing after %s")
+#define no_fil N_("file name missing after %s")
+#define no_mac N_("macro name missing after %s")
+#define no_pth N_("path name missing after %s")
+#define no_num N_("number missing after %s")
+#define no_tgt N_("target missing after %s")
/* This is the list of all command line options, with the leading
"-" removed. It must be sorted in ASCII collating order. */
/* Handle one command-line option in (argc, argv).
Can be called multiple times, to handle multiple sets of options.
Returns number of strings consumed. */
-
int
cpp_handle_option (pfile, argc, argv)
cpp_reader *pfile;
else if (CPP_OPTION (pfile, out_fname) == NULL)
CPP_OPTION (pfile, out_fname) = argv[i];
else
- cpp_fatal (pfile, "Too many filenames. Type %s --help for usage info",
+ cpp_fatal (pfile, "too many filenames. Type %s --help for usage info",
progname);
}
else
CPP_OPTION (pfile, out_fname) = arg;
else
{
- cpp_fatal (pfile, "Output filename specified twice");
+ cpp_fatal (pfile, "output filename specified twice");
return argc;
}
break;
}
}
+/* Handle --help output. */
static void
print_help ()
{