/* CPP Library.
Copyright (C) 1986, 1987, 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
- 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
+ 1999, 2000, 2001, 2002, 2003, 2004 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
static void init_library (void);
static void mark_named_operators (cpp_reader *);
static void read_original_filename (cpp_reader *);
+static void read_original_directory (cpp_reader *);
static void post_options (cpp_reader *);
/* If we have designated initializers (GCC >2.7) these tables can be
/* Initialize a cpp_reader structure. */
cpp_reader *
-cpp_create_reader (enum c_lang lang, hash_table *table)
+cpp_create_reader (enum c_lang lang, hash_table *table,
+ struct line_maps *line_table)
{
cpp_reader *pfile;
pfile = xcalloc (1, sizeof (cpp_reader));
cpp_set_lang (pfile, lang);
- CPP_OPTION (pfile, warn_import) = 1;
CPP_OPTION (pfile, warn_multichar) = 1;
CPP_OPTION (pfile, discard_comments) = 1;
CPP_OPTION (pfile, discard_comments_in_macro_exp) = 1;
CPP_OPTION (pfile, warn_long_long) = !CPP_OPTION (pfile, c99);
CPP_OPTION (pfile, dollars_in_ident) = 1;
CPP_OPTION (pfile, warn_dollars) = 1;
+ CPP_OPTION (pfile, warn_variadic_macros) = 1;
/* Default CPP arithmetic to something sensible for the host for the
benefit of dumb users like fix-header. */
CPP_OPTION (pfile, bytes_big_endian) = 1; /* does not matter */
/* Default to no charset conversion. */
- CPP_OPTION (pfile, narrow_charset) = 0;
+ CPP_OPTION (pfile, narrow_charset) = _cpp_default_encoding ();
CPP_OPTION (pfile, wide_charset) = 0;
+ /* Default the input character set to UTF-8. */
+ CPP_OPTION (pfile, input_charset) = _cpp_default_encoding ();
+
+ /* A fake empty "directory" used as the starting point for files
+ looked up without a search path. Name cannot be '/' because we
+ don't want to prepend anything at all to filenames using it. All
+ other entries are correct zero-initialized. */
+ pfile->no_search_path.name = (char *) "";
+
/* Initialize 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_table = line_table;
+ pfile->line = 1;
/* Initialize lexer state. */
pfile->state.save_comments = ! CPP_OPTION (pfile, discard_comments);
(void *(*) (long)) xmalloc,
(void (*) (void *)) free);
- _cpp_init_includes (pfile);
+ _cpp_init_files (pfile);
_cpp_init_hashtable (pfile, table);
obstack_free (&pfile->buffer_ob, 0);
_cpp_destroy_hashtable (pfile);
- _cpp_cleanup_includes (pfile);
+ _cpp_cleanup_files (pfile);
_cpp_destroy_iconv (pfile);
_cpp_free_buff (pfile->a_buff);
free (context);
}
- free_line_maps (&pfile->line_maps);
free (pfile);
}
type precisions made by cpplib. */
test--;
if (test < 1)
- cpp_error (pfile, DL_ICE, "cppchar_t must be an unsigned type");
+ cpp_error (pfile, CPP_DL_ICE, "cppchar_t must be an unsigned type");
if (CPP_OPTION (pfile, precision) > max_precision)
- cpp_error (pfile, DL_ICE,
+ cpp_error (pfile, CPP_DL_ICE,
"preprocessor arithmetic has maximum precision of %lu bits;"
" target requires %lu bits",
(unsigned long) max_precision,
(unsigned long) CPP_OPTION (pfile, precision));
if (CPP_OPTION (pfile, precision) < CPP_OPTION (pfile, int_precision))
- cpp_error (pfile, DL_ICE,
+ cpp_error (pfile, CPP_DL_ICE,
"CPP arithmetic must be at least as precise as a target int");
if (CPP_OPTION (pfile, char_precision) < 8)
- cpp_error (pfile, DL_ICE, "target char is less than 8 bits wide");
+ cpp_error (pfile, CPP_DL_ICE, "target char is less than 8 bits wide");
if (CPP_OPTION (pfile, wchar_precision) < CPP_OPTION (pfile, char_precision))
- cpp_error (pfile, DL_ICE,
+ cpp_error (pfile, CPP_DL_ICE,
"target wchar_t is narrower than target char");
if (CPP_OPTION (pfile, int_precision) < CPP_OPTION (pfile, char_precision))
- cpp_error (pfile, DL_ICE,
+ cpp_error (pfile, CPP_DL_ICE,
"target int is narrower than target char");
/* This is assumed in eval_token() and could be fixed if necessary. */
if (sizeof (cppchar_t) > sizeof (cpp_num_part))
- cpp_error (pfile, DL_ICE, "CPP half-integer narrower than CPP character");
+ cpp_error (pfile, CPP_DL_ICE,
+ "CPP half-integer narrower than CPP character");
if (CPP_OPTION (pfile, wchar_precision) > BITS_PER_CPPCHAR_T)
- cpp_error (pfile, DL_ICE,
+ cpp_error (pfile, CPP_DL_ICE,
"CPP on this host cannot handle wide character constants over"
" %lu bits, but the target requires %lu bits",
(unsigned long) BITS_PER_CPPCHAR_T,
deps_add_target (pfile->deps, target, quote);
}
-/* This sets up for processing input from the file FNAME.
- It returns false on error. */
-bool
-cpp_read_next_file (cpp_reader *pfile, const char *fname)
-{
- /* Open the main input file. */
- return _cpp_read_file (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 (cpp_reader *pfile, const char *fname)
+ processed. */
+void
+cpp_post_options (cpp_reader *pfile)
{
sanity_checks (pfile);
/* Mark named operators before handling command line macros. */
if (CPP_OPTION (pfile, cplusplus) && CPP_OPTION (pfile, operator_names))
mark_named_operators (pfile);
+}
+/* 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 (cpp_reader *pfile, const char *fname)
+{
if (CPP_OPTION (pfile, deps.style) != DEPS_NONE)
{
if (!pfile->deps)
deps_add_default_target (pfile->deps, fname);
}
- pfile->line = 1;
- if (!cpp_read_next_file (pfile, fname))
- return NULL;
+ pfile->main_file
+ = _cpp_find_file (pfile, fname, &pfile->no_search_path, false);
+ if (_cpp_find_failed (pfile->main_file))
+ return false;
- /* Set this here 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);
+ _cpp_stack_file (pfile, pfile->main_file, false);
/* 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;
+ {
+ read_original_filename (pfile);
+ fname = pfile->line_table->maps[pfile->line_table->used-1].to_file;
+ }
+ return fname;
}
/* For preprocessed files, if the first tokens are of the form # NUM.
if (token1->type == CPP_NUMBER)
{
_cpp_handle_directive (pfile, token->flags & PREV_WHITE);
+ read_original_directory (pfile);
return;
}
}
_cpp_backup_tokens (pfile, 1);
}
+/* For preprocessed files, if the tokens following the first filename
+ line is of the form # <line> "/path/name//", handle the
+ directive so we know the original current directory. */
+static void
+read_original_directory (cpp_reader *pfile)
+{
+ const cpp_token *hash, *token;
+
+ /* Lex ahead; if the first tokens are of the form # NUM, then
+ process the directive, otherwise back up. */
+ hash = _cpp_lex_direct (pfile);
+ if (hash->type != CPP_HASH)
+ {
+ _cpp_backup_tokens (pfile, 1);
+ return;
+ }
+
+ token = _cpp_lex_direct (pfile);
+
+ if (token->type != CPP_NUMBER)
+ {
+ _cpp_backup_tokens (pfile, 2);
+ return;
+ }
+
+ token = _cpp_lex_direct (pfile);
+
+ if (token->type != CPP_STRING
+ || ! (token->val.str.len >= 5
+ && token->val.str.text[token->val.str.len-2] == '/'
+ && token->val.str.text[token->val.str.len-3] == '/'))
+ {
+ _cpp_backup_tokens (pfile, 3);
+ return;
+ }
+
+ if (pfile->cb.dir_change)
+ {
+ char *debugdir = alloca (token->val.str.len - 3);
+
+ memcpy (debugdir, (const char *) token->val.str.text + 1,
+ token->val.str.len - 4);
+ debugdir[token->val.str.len - 4] = '\0';
+
+ pfile->cb.dir_change (pfile, debugdir);
+ }
+}
+
/* This is called at the end of preprocessing. It pops the last
buffer and writes dependency output, and returns the number of
errors.
-
+
Maybe it should also reset state, such that you could call
cpp_start_read with a new filename to restart processing. */
int