From ba133c968c260e4f4c9623630812846202b5e54f Mon Sep 17 00:00:00 2001 From: Neil Booth Date: Thu, 15 Mar 2001 07:57:13 +0000 Subject: [PATCH] cpp.texi: Update documentation for -include and -imacros. * cpp.texi: Update documentation for -include and -imacros. * cppfiles.c (struct include_file): Remove "defined" memeber. (find_or_create_entry): Make a copy of the file name, and simplify it. (open_file): Update to ensure we use the simplified filename. (stack_include_file): Don't set search_from. (cpp_included): Don't simplify the path name here. (find_include_file): New prototype. Call search_from to get the start of the "" include chain. Don't simplify the filenames here. (_cpp_execute_include): New prototype. Move diagnostics to do_include_common. Update. (_cpp_pop_file_buffer): Don't set defined. (search_from): New prototype. Use the preprocessor's cwd for files included from the command line. (read_name_map): Don't simplify the pathname here. * cpphash.h (enum include_type): New. (struct buffer): Delete search from. New search_cached. (_cpp_execute_include): Update prototype. * cppinit.c (do_includes): Use _cpp_execute_include. * cpplib.c (do_include_common): New function. (do_include, do_include_next, do_import): Use it. From-SVN: r40486 --- gcc/ChangeLog | 25 +++++++++ gcc/cpp.texi | 29 +++++++--- gcc/cppfiles.c | 145 ++++++++++++++++++++++++------------------------- gcc/cpphash.h | 17 +++--- gcc/cppinit.c | 11 +++- gcc/cpplib.c | 49 +++++++++++------ 6 files changed, 170 insertions(+), 106 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 12c04efe6a5..3161f0a9224 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,28 @@ +2001-03-15 Neil Booth + + * cpp.texi: Update documentation for -include and -imacros. + * cppfiles.c (struct include_file): Remove "defined" memeber. + (find_or_create_entry): Make a copy of the file name, and + simplify it. + (open_file): Update to ensure we use the simplified filename. + (stack_include_file): Don't set search_from. + (cpp_included): Don't simplify the path name here. + (find_include_file): New prototype. Call search_from to + get the start of the "" include chain. Don't simplify the + filenames here. + (_cpp_execute_include): New prototype. Move diagnostics to + do_include_common. Update. + (_cpp_pop_file_buffer): Don't set defined. + (search_from): New prototype. Use the preprocessor's cwd + for files included from the command line. + (read_name_map): Don't simplify the pathname here. + * cpphash.h (enum include_type): New. + (struct buffer): Delete search from. New search_cached. + (_cpp_execute_include): Update prototype. + * cppinit.c (do_includes): Use _cpp_execute_include. + * cpplib.c (do_include_common): New function. + (do_include, do_include_next, do_import): Use it. + 2001-03-14 Mark Mitchell * varasm.c (assemble_alias): Use DECL_ASSEMBLER_NAME, not the diff --git a/gcc/cpp.texi b/gcc/cpp.texi index 57da93332f7..316ebbff7bd 100644 --- a/gcc/cpp.texi +++ b/gcc/cpp.texi @@ -3596,16 +3596,31 @@ activities. @item -imacros @var{file} @findex -imacros -Process @var{file} as input, discarding the resulting output, before -processing the regular input file. Because the output generated from -@var{file} is discarded, the only effect of @samp{-imacros @var{file}} -is to make the macros defined in @var{file} available for use in the -main input. +Process @var{file} as input and discard the resulting output. + +This has all the effects of @code{#include "file"} appearing on the +first line of the main source file, such as generating dependencies and +being listed with the @samp{-H} option, except that no output is +generated, and that the first directory searched for @var{file} is the +preprocessor's working directory @emph{instead of} the directory +containing the main source file. If not found there, it is searched for +in the remainder of the @code{#include "..."} search chain as normal. + +Because the output is discarded, the main effect of @samp{-imacros +@var{file}} is to make the macros defined in @var{file} available for +use in the main input. @item -include @var{file} @findex -include -Process @var{file} as input, and include all the resulting output, -before processing the regular input file. +Process @var{file} as input, and include all the resulting output. + +This has all the effects of @code{#include "file"} appearing on the +first line of the main source file, such as generating dependencies and +being listed with the @samp{-H} option, except that the first directory +searched for @var{file} is the preprocessor's working directory +@emph{instead of} the directory containing the main source file. If not +found there, it is searched for in the remainder of the @code{#include +"..."} search chain as normal. @item -idirafter @var{dir} @findex -idirafter diff --git a/gcc/cppfiles.c b/gcc/cppfiles.c index 62c3e862912..434d3e44bab 100644 --- a/gcc/cppfiles.c +++ b/gcc/cppfiles.c @@ -70,18 +70,16 @@ struct include_file unsigned short include_count; /* number of times file has been read */ unsigned short refcnt; /* number of stacked buffers using this file */ unsigned char mapped; /* file buffer is mmapped */ - unsigned char defined; /* cmacro prevents inclusion in this state */ }; /* The cmacro works like this: If it's NULL, the file is to be included again. If it's NEVER_REREAD, the file is never to be included again. Otherwise it is a macro hashnode, and the file is - to be included again if the macro is defined or not as specified by - DEFINED. */ + to be included again if the macro is defined. */ #define NEVER_REREAD ((const cpp_hashnode *)-1) #define DO_NOT_REREAD(inc) \ ((inc)->cmacro && ((inc)->cmacro == NEVER_REREAD \ - || ((inc)->cmacro->type == NT_MACRO) == (inc)->defined)) + || (inc)->cmacro->type == NT_MACRO)) #define NO_INCLUDE_PATH ((struct include_file *) -1) static struct file_name_map *read_name_map @@ -90,9 +88,10 @@ static char *read_filename_string PARAMS ((int, FILE *)); static char *remap_filename PARAMS ((cpp_reader *, char *, struct search_path *)); static struct search_path *search_from PARAMS ((cpp_reader *, - struct include_file *)); + enum include_type)); static struct include_file * - find_include_file PARAMS ((cpp_reader *, const cpp_token *, int)); + find_include_file PARAMS ((cpp_reader *, const cpp_token *, + enum include_type)); static struct include_file *open_file PARAMS ((cpp_reader *, const char *)); static void read_include_file PARAMS ((cpp_reader *, struct include_file *)); static void stack_include_file PARAMS ((cpp_reader *, struct include_file *)); @@ -155,7 +154,8 @@ _cpp_never_reread (file) file->cmacro = NEVER_REREAD; } -/* Lookup a simplified filename, and create an entry if none exists. */ +/* Lookup a filename, which is simplified after making a copy, and + create an entry if none exists. */ static splay_tree_node find_or_create_entry (pfile, fname) cpp_reader *pfile; @@ -163,12 +163,16 @@ find_or_create_entry (pfile, fname) { splay_tree_node node; struct include_file *file; + char *name = xstrdup (fname); - node = splay_tree_lookup (pfile->all_include_files, (splay_tree_key) fname); - if (! node) + _cpp_simplify_pathname (name); + node = splay_tree_lookup (pfile->all_include_files, (splay_tree_key) name); + if (node) + free (name); + else { file = xcnew (struct include_file); - file->name = xstrdup (fname); + file->name = name; node = splay_tree_insert (pfile->all_include_files, (splay_tree_key) file->name, (splay_tree_value) file); @@ -177,8 +181,7 @@ find_or_create_entry (pfile, fname) return node; } -/* Enter a simplified file name in the splay tree, for the sake of - cpp_included (). */ +/* Enter a file name in the splay tree, for the sake of cpp_included. */ void _cpp_fake_include (pfile, fname) cpp_reader *pfile; @@ -234,7 +237,7 @@ open_file (pfile, filename) if (filename[0] == '\0') file->fd = 0; else - file->fd = open (filename, O_RDONLY | O_NOCTTY | O_BINARY, 0666); + file->fd = open (file->name, O_RDONLY | O_NOCTTY | O_BINARY, 0666); if (file->fd != -1 && fstat (file->fd, &file->st) == 0) { @@ -251,7 +254,7 @@ open_file (pfile, filename) /* Don't issue an error message if the file doesn't exist. */ if (errno != ENOENT && errno != ENOTDIR) - cpp_error_from_errno (pfile, filename); + cpp_error_from_errno (pfile, file->name); /* Create a negative node for this path, and return null. */ file->fd = -2; @@ -308,7 +311,6 @@ stack_include_file (pfile, inc) fp->inc = inc; fp->inc->refcnt++; fp->sysp = sysp; - fp->search_from = search_from (pfile, inc); /* Initialise controlling macro state. */ pfile->mi_state = MI_OUTSIDE; @@ -487,7 +489,7 @@ cpp_included (pfile, fname) if (CPP_OPTION (pfile, remap)) n = remap_filename (pfile, name, path); else - n = _cpp_simplify_pathname (name); + n = name; nd = splay_tree_lookup (pfile->all_include_files, (splay_tree_key) n); if (nd && nd->value) @@ -503,10 +505,10 @@ cpp_included (pfile, fname) from a #include_next directive, set INCLUDE_NEXT to true. */ static struct include_file * -find_include_file (pfile, header, include_next) +find_include_file (pfile, header, type) cpp_reader *pfile; const cpp_token *header; - int include_next; + enum include_type type; { const char *fname = (const char *) header->val.str.text; struct search_path *path; @@ -519,12 +521,12 @@ find_include_file (pfile, header, include_next) /* For #include_next, skip in the search path past the dir in which the current file was found, but if it was found via an absolute path use the normal search logic. */ - if (include_next && pfile->buffer->inc->foundhere) + if (type == IT_INCLUDE_NEXT && pfile->buffer->inc->foundhere) path = pfile->buffer->inc->foundhere->next; else if (header->type == CPP_HEADER_NAME) path = CPP_OPTION (pfile, bracket_include); else - path = pfile->buffer->search_from; + path = search_from (pfile, type); if (path == NULL) { @@ -542,7 +544,7 @@ find_include_file (pfile, header, include_next) if (CPP_OPTION (pfile, remap)) n = remap_filename (pfile, name, path); else - n = _cpp_simplify_pathname (name); + n = name; file = open_file (pfile, n); if (file) @@ -653,30 +655,14 @@ handle_missing_header (pfile, fname, angle_brackets) cpp_error_from_errno (pfile, fname); } -void -_cpp_execute_include (pfile, header, no_reinclude, include_next) +/* Returns non-zero if a buffer was stacked. */ +int +_cpp_execute_include (pfile, header, type) cpp_reader *pfile; const cpp_token *header; - int no_reinclude; - int include_next; + enum include_type type; { - struct include_file *inc; - - /* Help protect #include or similar from recursion. */ - if (pfile->buffer_stack_depth >= CPP_STACK_MAX) - { - cpp_fatal (pfile, "#include nested too deeply"); - return; - } - - /* Check we've tidied up #include before entering the buffer. */ - if (pfile->context->prev) - { - cpp_ice (pfile, "attempt to push file buffer with contexts stacked"); - return; - } - - inc = find_include_file (pfile, header, include_next); + struct include_file *inc = find_include_file (pfile, header, type); if (inc == 0) handle_missing_header (pfile, (const char *) header->val.str.text, @@ -688,9 +674,13 @@ _cpp_execute_include (pfile, header, no_reinclude, include_next) stack_include_file (pfile, inc); - if (no_reinclude) + if (type == IT_IMPORT) _cpp_never_reread (inc); + + return 1; } + + return 0; } /* Locate HEADER, and determine whether it is newer than the current @@ -749,13 +739,10 @@ _cpp_pop_file_buffer (pfile, buf) if (pfile->include_depth) pfile->include_depth--; - /* Record the inclusion-preventing macro and its definedness. */ + /* Record the inclusion-preventing macro, which could be NULL + meaning no controlling macro, if we haven't got it already. */ if (pfile->mi_state == MI_OUTSIDE && inc->cmacro == NULL) - { - /* This could be NULL meaning no controlling macro. */ - inc->cmacro = pfile->mi_cmacro; - inc->defined = 1; - } + inc->cmacro = pfile->mi_cmacro; /* Invalidate control macros in the #including file. */ pfile->mi_state = MI_FAILED; @@ -767,41 +754,55 @@ _cpp_pop_file_buffer (pfile, buf) /* Returns the first place in the include chain to start searching for "" includes. This involves stripping away the basename of the - current file, unless -I- was specified. */ + current file, unless -I- was specified. + + If we're handling -include or -imacros, use the "" chain, but with + the preprocessor's cwd prepended. */ static struct search_path * -search_from (pfile, inc) +search_from (pfile, type) cpp_reader *pfile; - struct include_file *inc; + enum include_type type; { cpp_buffer *buffer = pfile->buffer; unsigned int dlen; + /* Command line uses the cwd, and does not cache the result. */ + if (type == IT_CMDLINE) + goto use_cwd; + /* Ignore the current file's directory if -I- was given. */ if (CPP_OPTION (pfile, ignore_srcdir)) return CPP_OPTION (pfile, quote_include); - dlen = lbasename (inc->name) - inc->name; - if (dlen) - { - /* We don't guarantee NAME is null-terminated. This saves - allocating and freeing memory, and duplicating it when faking - buffers in cpp_push_buffer. Drop a trailing '/'. */ - buffer->dir.name = inc->name; - if (dlen > 1) - dlen--; - } - else + if (! buffer->search_cached) { - buffer->dir.name = "."; - dlen = 1; - } + buffer->search_cached = 1; - if (dlen > pfile->max_include_len) - pfile->max_include_len = dlen; + dlen = lbasename (buffer->inc->name) - buffer->inc->name; - buffer->dir.len = dlen; - buffer->dir.next = CPP_OPTION (pfile, quote_include); - buffer->dir.sysp = buffer->sysp; + if (dlen) + { + /* We don't guarantee NAME is null-terminated. This saves + allocating and freeing memory, and duplicating it when faking + buffers in cpp_push_buffer. Drop a trailing '/'. */ + buffer->dir.name = buffer->inc->name; + if (dlen > 1) + dlen--; + } + else + { + use_cwd: + buffer->dir.name = "."; + dlen = 1; + } + + if (dlen > pfile->max_include_len) + pfile->max_include_len = dlen; + + buffer->dir.len = dlen; + buffer->dir.next = CPP_OPTION (pfile, quote_include); + buffer->dir.sysp = buffer->sysp; + } return &buffer->dir; } @@ -928,8 +929,6 @@ read_name_map (pfile, dirname) strcpy (ptr->map_to + dirlen + 1, to); free (to); } - /* Simplify the result now. */ - _cpp_simplify_pathname (ptr->map_to); ptr->map_next = map_list_ptr->map_list_map; map_list_ptr->map_list_map = ptr; diff --git a/gcc/cpphash.h b/gcc/cpphash.h index 5d452c38661..9cac65d64c8 100644 --- a/gcc/cpphash.h +++ b/gcc/cpphash.h @@ -96,6 +96,9 @@ struct search_path enum mi_state {MI_FAILED = 0, MI_OUTSIDE}; enum mi_ind {MI_IND_NONE = 0, MI_IND_NOT}; +/* #include types. */ +enum include_type {IT_INCLUDE, IT_INCLUDE_NEXT, IT_IMPORT, IT_CMDLINE}; + typedef struct toklist toklist; struct toklist { @@ -222,17 +225,16 @@ struct cpp_buffer containing files that matches the current status. */ unsigned char include_stack_listed; + /* Nonzero means that the directory to start searching for "" + include files has been calculated and stored in "dir" below. */ + unsigned char search_cached; + /* Buffer type. */ ENUM_BITFIELD (cpp_buffer_type) type : 8; /* The directory of the this buffer's file. Its NAME member is not allocated, so we don't need to worry about freeing it. */ struct search_path dir; - - /* The directory to start searching for "" include files. Is either - "dir" above, or options.quote_include, depending upon whether -I- - was on the command line. */ - struct search_path *search_from; }; /* A cpp_reader encapsulates the "state" of a pre-processor run. @@ -411,8 +413,9 @@ extern void _cpp_fake_include PARAMS ((cpp_reader *, const char *)); extern void _cpp_never_reread PARAMS ((struct include_file *)); extern char *_cpp_simplify_pathname PARAMS ((char *)); extern int _cpp_read_file PARAMS ((cpp_reader *, const char *)); -extern void _cpp_execute_include PARAMS ((cpp_reader *, - const cpp_token *, int, int)); +extern int _cpp_execute_include PARAMS ((cpp_reader *, + const cpp_token *, + enum include_type)); extern int _cpp_compare_file_date PARAMS ((cpp_reader *, const cpp_token *)); extern void _cpp_report_missing_guards PARAMS ((cpp_reader *)); diff --git a/gcc/cppinit.c b/gcc/cppinit.c index 457d2662771..13a0e645b92 100644 --- a/gcc/cppinit.c +++ b/gcc/cppinit.c @@ -885,8 +885,15 @@ do_includes (pfile, p, scan) use the #include "" search path if cpp_read_file fails. */ if (CPP_OPTION (pfile, preprocessed)) cpp_error (pfile, "-include and -imacros cannot be used with -fpreprocessed"); - else if (_cpp_read_file (pfile, p->arg) && scan) - cpp_scan_buffer_nooutput (pfile, 0); + else + { + cpp_token header; + header.type = CPP_STRING; + header.val.str.text = (const unsigned char *) p->arg; + header.val.str.len = strlen (p->arg); + if (_cpp_execute_include (pfile, &header, IT_CMDLINE) && scan) + cpp_scan_buffer_nooutput (pfile, 0); + } q = p->next; free (p); p = q; diff --git a/gcc/cpplib.c b/gcc/cpplib.c index 963ab9b2a99..00fb1483cc0 100644 --- a/gcc/cpplib.c +++ b/gcc/cpplib.c @@ -95,6 +95,7 @@ static int strtoul_for_line PARAMS ((const U_CHAR *, unsigned int, unsigned long *)); static void do_diagnostic PARAMS ((cpp_reader *, enum error_type, int)); static cpp_hashnode *lex_macro_node PARAMS ((cpp_reader *)); +static void do_include_common PARAMS ((cpp_reader *, enum include_type)); static void do_pragma_once PARAMS ((cpp_reader *)); static void do_pragma_poison PARAMS ((cpp_reader *)); static void do_pragma_system_header PARAMS ((cpp_reader *)); @@ -585,22 +586,47 @@ parse_include (pfile, header) return 0; } +/* Handle #include, #include_next and #import. */ static void -do_include (pfile) +do_include_common (pfile, type) cpp_reader *pfile; + enum include_type type; { cpp_token header; if (!parse_include (pfile, &header)) - _cpp_execute_include (pfile, &header, 0, 0); + { + /* Prevent #include recursion. */ + if (pfile->buffer_stack_depth >= CPP_STACK_MAX) + cpp_fatal (pfile, "#include nested too deeply"); + else if (pfile->context->prev) + cpp_ice (pfile, "attempt to push file buffer with contexts stacked"); + else + { + /* For #include_next, if this is the primary source file, + warn and use the normal search logic. */ + if (type == IT_INCLUDE_NEXT && ! pfile->buffer->prev) + { + cpp_warning (pfile, "#include_next in primary source file"); + type = IT_INCLUDE; + } + + _cpp_execute_include (pfile, &header, type); + } + } } static void -do_import (pfile) +do_include (pfile) cpp_reader *pfile; { - cpp_token header; + do_include_common (pfile, IT_INCLUDE); +} +static void +do_import (pfile) + cpp_reader *pfile; +{ if (!pfile->import_warning && CPP_OPTION (pfile, warn_import)) { pfile->import_warning = 1; @@ -608,25 +634,14 @@ do_import (pfile) "#import is obsolete, use an #ifndef wrapper in the header file"); } - if (!parse_include (pfile, &header)) - _cpp_execute_include (pfile, &header, 1, 0); + do_include_common (pfile, IT_IMPORT); } static void do_include_next (pfile) cpp_reader *pfile; { - cpp_token header; - - if (!parse_include (pfile, &header)) - { - /* If this is the primary source file, warn and use the normal - search logic. */ - if (! pfile->buffer->prev) - cpp_warning (pfile, "#include_next in primary source file"); - - _cpp_execute_include (pfile, &header, 0, pfile->buffer->prev != 0); - } + do_include_common (pfile, IT_INCLUDE_NEXT); } /* Subroutine of do_line. Read possible flags after file name. LAST -- 2.30.2