+2000-12-07 Neil Booth <neilb@earthling.net>
+
+ * cppfiles.c (struct include_file): Move from cpphash.h.
+ (_cpp_never_reread): New function.
+ (open_file, read_include_file): Use it.
+ (stack_include_file): Set the buffer's sysp according to the
+ path in which the file was found.
+ (find_include_file): Don't set sysp.
+ (cpp_make_system_header, actual_directory): Update.
+ (_cpp_execute_include): Do #include_next lookup handling here,
+ not in cpplib.c. Use _cpp_never_reread.
+ * cpphash.h (struct_include_file): Remove.
+ (struct cpp_buffer): New member sysp.
+ (CPP_IN_SYSTEM_HEADER, _cpp_execute_include): Update.
+ (_cpp_never_reread): New.
+ * cpplib.c (read_line_number): Rename read_flag. Rework slightly.
+ (end_directive): Clear line_extension flag.
+ (_cpp_handle_directive): Set line_extension flag for #number.
+ (do_include_next): Handle path lookup in _cpp_execute_include.
+ (do_line): Cleanup to use read_flag. Don't allow flags in #line.
+ (_cpp_do_file_change): Update.
+ (do_pragma_once): Use cpp_never_reread. Clean up.
+ * cpplib.h (struct lexer_state): New member line_extension.
+
2000-12-07 Richard Henderson <rth@redhat.com>
* flow.c (calculate_global_regs_live): Force the stack pointer live
C. It is unlikely that glibc's strcmp macro helps this file at all. */
#undef strcmp
+/* This structure is used for the table of all includes. */
+struct include_file
+{
+ const char *name; /* actual path name of file */
+ const cpp_hashnode *cmacro; /* macro, if any, preventing reinclusion. */
+ const struct file_name_list *foundhere;
+ /* location in search path where file was
+ found, for #include_next and sysp. */
+ const unsigned char *buffer; /* pointer to cached file contents */
+ struct stat st; /* copy of stat(2) data for file */
+ int fd; /* fd open on file (short term storage only) */
+ 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 */
+};
+
static struct file_name_map *read_name_map
PARAMS ((cpp_reader *, const char *));
static char *read_filename_string PARAMS ((int, FILE *));
splay_tree_delete (pfile->all_include_files);
}
+/* Mark a file to not be reread (e.g. #import, read failure). */
+void
+_cpp_never_reread (file)
+ struct include_file *file;
+{
+ file->cmacro = NEVER_REREAD;
+}
+
/* Given a file name, look it up in the cache; if there is no entry,
create one with a non-NULL value (regardless of success in opening
the file). If the file doesn't exist or is inaccessible, this
}
else
{
+ /* In particular, this clears foundhere. */
file = xcnew (struct include_file);
file->name = xstrdup (filename);
splay_tree_insert (pfile->all_include_files,
/* Mark a regular, zero-length file never-reread now. */
if (S_ISREG (file->st.st_mode) && file->st.st_size == 0)
{
- file->cmacro = NEVER_REREAD;
+ _cpp_never_reread (file);
close (file->fd);
file->fd = -1;
}
fp->line_base = fp->buf;
fp->lineno = 0; /* For _cpp_do_file_change. */
fp->inc->refcnt++;
+ if (inc->foundhere)
+ fp->sysp = inc->foundhere->sysp;
/* The ->actual_dir field is only used when ignore_srcdir is not in effect;
see do_include */
/* Do not try to read this file again. */
close (inc->fd);
inc->fd = -1;
- inc->cmacro = NEVER_REREAD;
+ _cpp_never_reread (inc);
return;
}
file = open_file (pfile, name);
if (file)
{
- file->sysp = path->sysp;
file->foundhere = path;
return file;
}
}
/* Not everyone who wants to set system-header-ness on a buffer can
- see the details of struct include_file. This is an exported interface
- because fix-header needs it. */
+ see the details of a buffer. This is an exported interface because
+ fix-header needs it. */
void
cpp_make_system_header (pfile, syshdr, externc)
cpp_reader *pfile;
/* 1 = system header, 2 = system header to be treated as C. */
if (syshdr)
flags = 1 + (externc != 0);
- pfile->buffer->inc->sysp = flags;
+ pfile->buffer->sysp = flags;
}
/* Report on all files that might benefit from a multiple include guard.
#define PRINT_THIS_DEP(p, b) (CPP_PRINT_DEPS(p) > (b||p->system_include_depth))
void
-_cpp_execute_include (pfile, header, no_reinclude, search_start)
+_cpp_execute_include (pfile, header, no_reinclude, include_next)
cpp_reader *pfile;
const cpp_token *header;
int no_reinclude;
- struct file_name_list *search_start;
+ int include_next;
{
+ struct file_name_list *search_start = 0;
unsigned int len = header->val.str.len;
unsigned int angle_brackets = header->type == CPP_HEADER_NAME;
struct include_file *inc;
return;
}
+ /* For #include_next, skip in the search path past the dir in which
+ the current file was found. If this is the last directory in the
+ search path, don't include anything. If the current file was
+ specified with an absolute path, use the normal search logic. If
+ this is the primary source file, use the normal search logic and
+ generate a warning. */
+ if (include_next)
+ {
+ if (! pfile->buffer->prev)
+ cpp_warning (pfile, "#include_next in primary source file");
+ else
+ {
+ if (pfile->buffer->inc->foundhere)
+ {
+ search_start = pfile->buffer->inc->foundhere->next;
+ if (! search_start)
+ return;
+ }
+ }
+ }
+
fname = alloca (len + 1);
memcpy (fname, header->val.str.text, len);
fname[len] = '\0';
if (! DO_NOT_REREAD (inc))
{
if (no_reinclude)
- inc->cmacro = NEVER_REREAD;
+ _cpp_never_reread (inc);
/* Handle -H option. */
if (CPP_OPTION (pfile, print_include_names))
x->nlen = dlen;
x->next = CPP_OPTION (pfile, quote_include);
x->alloc = pfile->actual_dirs;
- x->sysp = CPP_BUFFER (pfile)->inc->sysp;
+ x->sysp = pfile->buffer->sysp;
x->name_map = NULL;
pfile->actual_dirs = x;
};
#define ABSOLUTE_PATH ((struct file_name_list *)-1)
-/* This structure is used for the table of all includes. */
-struct include_file
-{
- const char *name; /* actual path name of file */
- const cpp_hashnode *cmacro; /* macro, if any, preventing reinclusion. */
- const struct file_name_list *foundhere;
- /* location in search path where file was
- found, for #include_next */
- const unsigned char *buffer; /* pointer to cached file contents */
- struct stat st; /* copy of stat(2) data for file */
- int fd; /* fd open on file (short term storage only) */
- unsigned short include_count; /* number of times file has been read */
- unsigned short refcnt; /* number of stacked buffers using this file */
- unsigned char sysp; /* file is a system header */
- 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
/* Temporary storage for pfile->skipping whilst in a directive. */
unsigned char was_skipping;
+
+ /* 1 = system header file, 2 = C system header file used for C++. */
+ unsigned char sysp;
};
/* Character classes.
#define CPP_PREV_BUFFER(BUFFER) ((BUFFER)->prev)
#define CPP_PRINT_DEPS(PFILE) CPP_OPTION (PFILE, print_deps)
#define CPP_IN_SYSTEM_HEADER(PFILE) \
- (CPP_BUFFER (PFILE) && CPP_BUFFER (PFILE)->inc \
- && CPP_BUFFER (PFILE)->inc->sysp)
+ (CPP_BUFFER (PFILE) && CPP_BUFFER (PFILE)->sysp)
#define CPP_PEDANTIC(PF) \
CPP_OPTION (PF, pedantic)
#define CPP_WTRADITIONAL(PF) \
unsigned int));
/* In cppfiles.c */
+extern void _cpp_never_reread PARAMS ((struct include_file *));
extern void _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,
- struct file_name_list *));
+ const cpp_token *, int, int));
extern int _cpp_compare_file_date PARAMS ((cpp_reader *,
const cpp_token *));
extern void _cpp_report_missing_guards PARAMS ((cpp_reader *));
static int parse_include PARAMS ((cpp_reader *, cpp_token *));
static void push_conditional PARAMS ((cpp_reader *, int, int,
const cpp_hashnode *));
-static int read_line_number PARAMS ((cpp_reader *, int *));
+static unsigned int read_flag PARAMS ((cpp_reader *));
static int strtoul_for_line PARAMS ((const U_CHAR *, unsigned int,
unsigned long *));
static void do_diagnostic PARAMS ((cpp_reader *, enum error_type, int));
pfile->state.save_comments = ! CPP_OPTION (pfile, discard_comments);
pfile->state.in_directive = 0;
pfile->state.angled_headers = 0;
+ pfile->state.line_extension = 0;
pfile->directive = 0;
}
if (! buffer->was_skipping && CPP_OPTION (pfile, lang) != CLK_ASM)
{
dir = &dtable[T_LINE];
+ pfile->state.line_extension = 1;
_cpp_push_token (pfile, &dname, &pfile->directive_pos);
if (CPP_PEDANTIC (pfile) && buffer->inc
&& ! CPP_OPTION (pfile, preprocessed))
cpp_reader *pfile;
{
cpp_token header;
- struct file_name_list *search_start = 0;
- if (parse_include (pfile, &header))
- return;
-
- /* For #include_next, skip in the search path past the dir in which
- the current file was found. If this is the last directory in the
- search path, don't include anything. If the current file was
- specified with an absolute path, use the normal search logic. If
- this is the primary source file, use the normal search logic and
- generate a warning. */
- if (CPP_PREV_BUFFER (CPP_BUFFER (pfile)))
- {
- if (CPP_BUFFER (pfile)->inc->foundhere)
- {
- search_start = CPP_BUFFER (pfile)->inc->foundhere->next;
- if (!search_start)
- return;
- }
- }
- else
- cpp_warning (pfile, "#include_next in primary source file");
-
- _cpp_execute_include (pfile, &header, 0, search_start);
+ if (!parse_include (pfile, &header))
+ _cpp_execute_include (pfile, &header, 0, 1);
}
-/* Subroutine of do_line. Read next token from PFILE without adding it to
- the output buffer. If it is a number between 1 and 4, store it in *NUM
- and return 1; otherwise, return 0 and complain if we aren't at the end
- of the directive. */
+/* Subroutine of do_line. Read possible flags after file name. If it
+ is a number between 1 and 4, return it, otherwise return 0. If
+ it's not the end of the directive complain. */
-static int
-read_line_number (pfile, num)
+static unsigned int
+read_flag (pfile)
cpp_reader *pfile;
- int *num;
{
cpp_token token;
- unsigned int val;
_cpp_lex_token (pfile, &token);
if (token.type == CPP_NUMBER && token.val.str.len == 1)
{
- val = token.val.str.text[0] - '1';
- if (val <= 3)
- {
- *num = val + 1;
- return 1;
- }
+ unsigned int flag = token.val.str.text[0] - '1';
+ if (flag <= 3)
+ return flag + 1;
}
if (token.type != CPP_EOF)
- cpp_error (pfile, "invalid format #line");
+ cpp_error (pfile, "invalid flag \"%s\" in line directive",
+ cpp_token_as_text (pfile, &token));
return 0;
}
{
char *fname;
unsigned int len;
- int action_number = 0;
/* FIXME: memory leak. */
len = token.val.str.len;
_cpp_simplify_pathname (fname);
buffer->nominal_fname = fname;
- if (read_line_number (pfile, &action_number) != 0)
+ if (pfile->state.line_extension)
{
- if (! CPP_OPTION (pfile, preprocessed) && CPP_PEDANTIC (pfile))
- cpp_pedwarn (pfile, "extra tokens at end of #line directive");
+ int flag, sysp = 0;
- if (action_number == 1)
+ flag = read_flag (pfile);
+ if (flag == 1)
{
reason = FC_ENTER;
- cpp_make_system_header (pfile, 0, 0);
- read_line_number (pfile, &action_number);
+ flag = read_flag (pfile);
}
- else if (action_number == 2)
+ else if (flag == 2)
{
reason = FC_LEAVE;
- cpp_make_system_header (pfile, 0, 0);
- read_line_number (pfile, &action_number);
+ flag = read_flag (pfile);
}
- if (action_number == 3)
+ if (flag == 3)
{
- cpp_make_system_header (pfile, 1, 0);
- read_line_number (pfile, &action_number);
- }
- if (action_number == 4)
- {
- cpp_make_system_header (pfile, 1, 1);
- read_line_number (pfile, &action_number);
+ flag = read_flag (pfile);
+ sysp = 1;
}
+
+ cpp_make_system_header (pfile, sysp, flag == 4);
}
check_eol (pfile);
fc.from.lineno = from_lineno;
fc.to.filename = buffer->nominal_fname;
fc.to.lineno = buffer->lineno + 1;
- fc.sysp = buffer->inc->sysp;
- fc.externc = CPP_OPTION (pfile, cplusplus) && buffer->inc->sysp == 2;
+ fc.sysp = buffer->sysp;
+ fc.externc = CPP_OPTION (pfile, cplusplus) && buffer->sysp == 2;
pfile->cb.change_file (pfile, &fc);
}
}
do_pragma_once (pfile)
cpp_reader *pfile;
{
- cpp_buffer *ip = CPP_BUFFER (pfile);
-
cpp_warning (pfile, "#pragma once is obsolete");
- if (CPP_PREV_BUFFER (ip) == NULL)
+ if (pfile->buffer->prev == NULL)
cpp_warning (pfile, "#pragma once in main file");
else
- ip->inc->cmacro = NEVER_REREAD;
+ _cpp_never_reread (pfile->buffer->inc);
check_eol (pfile);
}
/* Nonzero when parsing arguments to a function-like macro. */
unsigned char parsing_args;
+
+ /* Nonzero when in a # NUMBER directive. */
+ unsigned char line_extension;
};
/* Special nodes - identifiers with predefined significance. */