This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
cpplib: small buffer / file handling improvement
- To: gcc-patches at gcc dot gnu dot org
- Subject: cpplib: small buffer / file handling improvement
- From: Neil Booth <neilb at earthling dot net>
- Date: Tue, 5 Dec 2000 21:00:11 +0000
This patch
o Pushes a zero-length buffer on cpplib's buffer stack, instead of pushing
no buffer at all, when we have an error reading / opening the file, or
a zero-length file, or the file has been marked not to be reread for
any other reason.
o Moves the test for #include recursion to the common #include handler,
rather than cpp_push_buffer. This avoids innocent victims of this
check, such as _Pragma.
o Similarly moves another ICE check to the #include handler where it more
properly belongs.
These changes mean that some internal functions that used to return
error codes, such as stack_include_file, can no longer fail, so they
return void instead. A buffer is stacked no matter what.
This state of affairs is still not perfect, but better than the
current situation where the caller can be expecting a buffer to have
been stacked but it hasn't (even in non-error conditions like
zero-length files). I hope this cures the failures on zero-length
files with integrated cpp.
Neil.
* cppfiles.c (stack_include_file): Push zero-length buffers
in case of failure. Return void, as we don't fail any more.
(read_include_file): Check for files we shouldn't re-read.
Don't return an error code; errors are implied by marking the
file NEVER_REREAD.
(_cpp_execute_include): Move the recursion and in-macro checks
here. Update for stack_include_file not failing.
* cpplib.c (cpp_push_buffer): Always succeed, since
_cpp_execute_include performs the recursion check. Tidy up.
* cpplib.h (cpp_push_buffer): Update prototype.
Index: cppfiles.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cppfiles.c,v
retrieving revision 1.87
diff -u -p -r1.87 cppfiles.c
--- cppfiles.c 2000/12/04 07:32:03 1.87
+++ cppfiles.c 2000/12/05 20:46:36
@@ -74,8 +74,8 @@ static struct include_file *find_include
PARAMS ((cpp_reader *, const char *,
struct file_name_list *));
static struct include_file *open_file PARAMS ((cpp_reader *, const char *));
-static int read_include_file PARAMS ((cpp_reader *, struct include_file *));
-static int stack_include_file PARAMS ((cpp_reader *, struct include_file *));
+static void read_include_file PARAMS ((cpp_reader *, struct include_file *));
+static void stack_include_file PARAMS ((cpp_reader *, struct include_file *));
static void purge_cache PARAMS ((struct include_file *));
static void destroy_include_file_node PARAMS ((splay_tree_value));
static int report_missing_guard PARAMS ((splay_tree_node, void *));
@@ -204,10 +204,11 @@ open_file (pfile, filename)
return 0;
}
-/* Place the file referenced by INC into a new buffer on PFILE's stack.
- Return 1 if successful, 0 if not. */
+/* Place the file referenced by INC into a new buffer on PFILE's
+ stack. If there are errors, or the file should not be re-included,
+ a null buffer is pushed. */
-static int
+static void
stack_include_file (pfile, inc)
cpp_reader *pfile;
struct include_file *inc;
@@ -221,46 +222,38 @@ stack_include_file (pfile, inc)
filename = pfile->buffer->nominal_fname;
lineno = pfile->buffer->lineno;
}
-
- if (pfile->context->prev)
- cpp_ice (pfile, "attempt to push file buffer with contexts stacked");
- if (DO_NOT_REREAD (inc))
- return 0;
+ /* Not in cache? */
+ if (! inc->buffer)
+ read_include_file (pfile, inc);
- if (inc->buffer == NULL)
- if (read_include_file (pfile, inc) == 0)
- return 0;
-
+ /* Push a null buffer. */
fp = cpp_push_buffer (pfile, NULL, 0);
- if (fp == 0)
- return 0;
-
- /* Initialise controlling macro state. */
- pfile->mi_state = MI_OUTSIDE;
- pfile->mi_cmacro = 0;
-
fp->inc = inc;
fp->nominal_fname = inc->name;
fp->buf = inc->buffer;
- fp->rlimit = fp->buf + inc->st.st_size;
+ fp->rlimit = fp->buf;
+ if (! DO_NOT_REREAD (inc))
+ fp->rlimit += inc->st.st_size;
fp->cur = fp->buf;
- fp->lineno = 0;
fp->line_base = fp->buf;
+ fp->lineno = 0; /* For _cpp_do_file_change. */
+ fp->inc->refcnt++;
/* The ->actual_dir field is only used when ignore_srcdir is not in effect;
see do_include */
if (!CPP_OPTION (pfile, ignore_srcdir))
fp->actual_dir = actual_directory (pfile, inc->name);
- fp->inc->refcnt++;
+ /* Initialise controlling macro state. */
+ pfile->mi_state = MI_OUTSIDE;
+ pfile->mi_cmacro = 0;
pfile->include_depth++;
pfile->input_stack_listing_current = 0;
_cpp_do_file_change (pfile, FC_ENTER, filename, lineno);
fp->lineno = 1;
- return 1;
}
/* Read the file referenced by INC into the file cache.
@@ -278,7 +271,7 @@ stack_include_file (pfile, inc)
FIXME: Flush file cache and try again if we run out of memory. */
-static int
+static void
read_include_file (pfile, inc)
cpp_reader *pfile;
struct include_file *inc;
@@ -289,6 +282,9 @@ read_include_file (pfile, inc)
static int pagesize = -1;
#endif
+ if (DO_NOT_REREAD (inc))
+ return;
+
if (S_ISREG (inc->st.st_mode))
{
/* off_t might have a wider range than ssize_t - in other words,
@@ -373,7 +369,7 @@ read_include_file (pfile, inc)
close (inc->fd);
inc->buffer = buf;
inc->fd = -1;
- return 1;
+ return;
perror_fail:
cpp_error_from_errno (pfile, inc->name);
@@ -382,7 +378,7 @@ read_include_file (pfile, inc)
close (inc->fd);
inc->fd = -1;
inc->cmacro = NEVER_REREAD;
- return 0;
+ return;
}
static void
@@ -583,6 +579,20 @@ _cpp_execute_include (pfile, header, no_
struct include_file *inc;
char *fname;
+ /* 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;
+ }
+
fname = alloca (len + 1);
memcpy (fname, header->val.str.text, len);
fname[len] = '\0';
@@ -613,23 +623,22 @@ _cpp_execute_include (pfile, header, no_
inc->include_count++;
/* Actually process the file. */
- if (stack_include_file (pfile, inc))
- {
- if (angle_brackets)
- pfile->system_include_depth++;
+ stack_include_file (pfile, inc);
- if (no_reinclude)
- inc->cmacro = NEVER_REREAD;
+ if (angle_brackets)
+ pfile->system_include_depth++;
+ if (no_reinclude)
+ inc->cmacro = NEVER_REREAD;
- /* Handle -H option. */
- if (CPP_OPTION (pfile, print_include_names))
- {
- cpp_buffer *fp = CPP_BUFFER (pfile);
- while ((fp = CPP_PREV_BUFFER (fp)) != NULL)
- putc ('.', stderr);
- fprintf (stderr, " %s\n", inc->name);
- }
+ /* Handle -H option. */
+ if (CPP_OPTION (pfile, print_include_names))
+ {
+ cpp_buffer *fp = CPP_BUFFER (pfile);
+ while ((fp = CPP_PREV_BUFFER (fp)) != NULL)
+ putc ('.', stderr);
+ fprintf (stderr, " %s\n", inc->name);
}
+
return;
}
@@ -730,11 +739,8 @@ _cpp_read_file (pfile, fname)
return 0;
}
- /* Return success for zero-length files. */
- if (DO_NOT_REREAD (f))
- return 1;
-
- return stack_include_file (pfile, f);
+ stack_include_file (pfile, f);
+ return 1;
}
/* Do appropriate cleanup when a file buffer is popped off the input
Index: cpplib.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cpplib.c,v
retrieving revision 1.226
diff -u -p -r1.226 cpplib.c
--- cpplib.c 2000/12/04 07:32:03 1.226
+++ cpplib.c 2000/12/05 20:46:56
@@ -1731,42 +1731,34 @@ handle_assertion (pfile, str, type)
run_directive (pfile, type, str, count, 0);
}
-/* Allocate a new cpp_buffer for PFILE, and push it on the input
- buffer stack. If BUFFER != NULL, then use the LENGTH characters in
- BUFFER as the new input buffer. Return the new buffer, or NULL on
- failure. */
+/* Push a new buffer on the buffer stack. Buffer can be NULL, but
+ then LEN should be 0. Returns the new buffer; it doesn't fail. */
cpp_buffer *
-cpp_push_buffer (pfile, buffer, length)
+cpp_push_buffer (pfile, buffer, len)
cpp_reader *pfile;
const U_CHAR *buffer;
- long length;
+ size_t len;
{
- cpp_buffer *buf = CPP_BUFFER (pfile);
- cpp_buffer *new;
- if (++pfile->buffer_stack_depth == CPP_STACK_MAX)
- {
- cpp_fatal (pfile, "#include nested too deeply");
- return NULL;
- }
+ cpp_buffer *new = xobnew (pfile->buffer_ob, cpp_buffer);
- new = xobnew (pfile->buffer_ob, cpp_buffer);
/* Clears, amongst other things, if_stack and mi_cmacro. */
memset (new, 0, sizeof (cpp_buffer));
-
- pfile->lexer_pos.output_line = 1;
new->line_base = new->buf = new->cur = buffer;
- new->rlimit = buffer + length;
- new->prev = buf;
+ new->rlimit = buffer + len;
+ new->prev = pfile->buffer;
new->pfile = pfile;
/* Preprocessed files don't do trigraph and escaped newline processing. */
new->from_stage3 = CPP_OPTION (pfile, preprocessed);
/* No read ahead or extra char initially. */
new->read_ahead = EOF;
new->extra_char = EOF;
+
pfile->state.next_bol = 1;
+ pfile->buffer_stack_depth++;
+ pfile->lexer_pos.output_line = 1;
- CPP_BUFFER (pfile) = new;
+ pfile->buffer = new;
return new;
}
Index: cpplib.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cpplib.h,v
retrieving revision 1.145
diff -u -p -r1.145 cpplib.h
--- cpplib.h 2000/12/04 07:32:04 1.145
+++ cpplib.h 2000/12/05 20:46:59
@@ -725,7 +725,7 @@ extern void cpp_undef PARAMS ((cpp_read
extern void cpp_unassert PARAMS ((cpp_reader *, const char *));
extern cpp_buffer *cpp_push_buffer PARAMS ((cpp_reader *,
- const unsigned char *, long));
+ const unsigned char *, size_t));
extern cpp_buffer *cpp_pop_buffer PARAMS ((cpp_reader *));
extern int cpp_defined PARAMS ((cpp_reader *, const unsigned char *, int));