cppfiles.c: Move all default-#defines to top of file.

* cppfiles.c: Move all default-#defines to top of file.
	(open_include_file): Replace by lookup_include_file.
	(read_with_read, read_file): Merged into read_include_file.
	(stack_include_file, purge_cache): New functions.
	(close_cached_fd): Delete.
	(lookup_include_file, read_include_file, _cpp_pop_file_buffer):
	Cache the in-memory buffer, not the file descriptor.

	* cpphash.h (struct include_file): Add buffer, st, refcnt,
	mapped fields.
	(xcnew): New utility macro.
	(DO_NOT_REREAD, NEVER_REREAD): Move up by struct include_file.
	* cpplib.h (struct cpp_buffer): Remove mapped field.

	* cpplex.c (parse_string): Accept backslash space newline as a
	line continuation.
	(lex_line): Likewise.
	(_cpp_get_token): Remove hard limit on macro nesting.

testsuite:
	* gcc.dg/cpp/backslash.c: New test.

From-SVN: r36347
This commit is contained in:
Zack Weinberg 2000-09-12 03:42:30 +00:00 committed by Zack Weinberg
parent 4ba01ed2ae
commit a58d32c208
7 changed files with 376 additions and 392 deletions

View File

@ -1,3 +1,26 @@
2000-09-11 Zack Weinberg <zack@wolery.cumb.org>
* cppfiles.c: Move all default-#defines to top of file.
(open_include_file): Replace by lookup_include_file.
(read_with_read, read_file): Merged into read_include_file.
(stack_include_file, purge_cache): New functions.
(close_cached_fd): Delete.
(lookup_include_file, read_include_file, _cpp_pop_file_buffer):
Cache the in-memory buffer, not the file descriptor.
* cpphash.h (struct include_file): Add buffer, st, refcnt,
mapped fields.
(xcnew): New utility macro.
(DO_NOT_REREAD, NEVER_REREAD): Move up by struct include_file.
* cpplib.h (struct cpp_buffer): Remove mapped field.
2000-09-11 Zack Weinberg <zack@wolery.cumb.org>
* cpplex.c (parse_string): Accept backslash space newline as a
line continuation.
(lex_line): Likewise.
(_cpp_get_token): Remove hard limit on macro nesting.
2000-09-12 Philipp Thomas <pthomas@suse.de>
* aclocal.m4 (AM_WITH_NLS): Don't force use of included gettext.

View File

@ -43,6 +43,22 @@ Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
# define O_BINARY 0
#endif
#ifndef INCLUDE_LEN_FUDGE
# define INCLUDE_LEN_FUDGE 0
#endif
/* If errno is inspected immediately after a system call fails, it will be
nonzero, and no error number will ever be zero. */
#ifndef ENOENT
# define ENOENT 0
#endif
#ifndef ENOTDIR
# define ENOTDIR 0
#endif
#ifndef ENOMEM
# define ENOMEM 0
#endif
/* Suppress warning about function macros used w/o arguments in traditional
C. It is unlikely that glibc's strcmp macro helps this file at all. */
#undef strcmp
@ -57,24 +73,18 @@ static struct file_name_list *actual_directory
static struct include_file *find_include_file
PARAMS ((cpp_reader *, const char *,
struct file_name_list *));
static struct include_file *open_include_file
static struct include_file *lookup_include_file
PARAMS ((cpp_reader *, const char *));
static int read_include_file PARAMS ((cpp_reader *, struct include_file *));
static ssize_t read_with_read PARAMS ((cpp_buffer *, int, ssize_t));
static ssize_t read_file PARAMS ((cpp_buffer *, int, ssize_t));
static int 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 close_cached_fd PARAMS ((splay_tree_node, void *));
static int report_missing_guard PARAMS ((splay_tree_node, void *));
#if 0
static void hack_vms_include_specification PARAMS ((char *));
#endif
#ifndef INCLUDE_LEN_FUDGE
#define INCLUDE_LEN_FUDGE 0
#endif
/* We use a splay tree to store information about all the include
files seen in this compilation. The key of each tree node is the
physical path to the file. The value is 0 if the file does not
@ -87,26 +97,11 @@ destroy_include_file_node (v)
struct include_file *f = (struct include_file *)v;
if (f)
{
if (f->fd != -1)
close (f->fd);
purge_cache (f);
free (f);
}
}
static int
close_cached_fd (n, dummy)
splay_tree_node n;
void *dummy ATTRIBUTE_UNUSED;
{
struct include_file *f = (struct include_file *)n->value;
if (f && f->fd != -1)
{
close (f->fd);
f->fd = -1;
}
return 0;
}
void
_cpp_init_includes (pfile)
cpp_reader *pfile;
@ -124,48 +119,24 @@ _cpp_cleanup_includes (pfile)
splay_tree_delete (pfile->all_include_files);
}
/* Given a filename, look it up and possibly open it. If the file
does not exist, return NULL. If the file does exist but doesn't
need to be reread, return an include_file entry with fd == -1.
If it needs to be (re)read, return an include_file entry with
fd a file descriptor open on the file. */
/* Given a file name, look it up in the cache; if there is no entry,
create one. Returns 0 if the file doesn't exist or is
inaccessible, otherwise the cache entry. */
static struct include_file *
open_include_file (pfile, filename)
lookup_include_file (pfile, filename)
cpp_reader *pfile;
const char *filename;
{
{
splay_tree_node nd;
struct include_file *file = 0;
int fd;
struct stat st;
nd = splay_tree_lookup (pfile->all_include_files,
(splay_tree_key) filename);
nd = splay_tree_lookup (pfile->all_include_files, (splay_tree_key) filename);
if (nd)
{
if (nd->value == 0)
return 0;
file = (struct include_file *)nd->value;
if (DO_NOT_REREAD (file))
{
if (file->fd != -1)
{
close (file->fd);
file->fd = -1;
}
return file;
}
/* File descriptors are cached for files that might be reread. */
if (file->fd != -1)
{
lseek (file->fd, 0, SEEK_SET);
return file;
}
}
return (struct include_file *)nd->value;
/* We used to open files in nonblocking mode, but that caused more
problems than it solved. Do take care not to acquire a
@ -180,67 +151,224 @@ open_include_file (pfile, filename)
ourselves.
Special case: the empty string is translated to stdin. */
retry:
if (filename[0] == '\0')
fd = 0;
else
fd = open (filename, O_RDONLY|O_NOCTTY|O_BINARY, 0666);
if (fd == -1)
{
#ifdef EACCES
if (errno == EACCES)
{
cpp_error (pfile, "included file \"%s\" exists but is not readable",
filename);
}
#endif
if (0
#ifdef EMFILE
|| errno == EMFILE
#endif
#ifdef ENFILE
|| errno == ENFILE
#endif
)
{
/* Too many files open. Close all cached file descriptors and
try again. */
splay_tree_foreach (pfile->all_include_files, close_cached_fd, 0);
goto retry;
}
/* Nonexistent or inaccessible file. Create a negative node for it. */
if (nd)
{
cpp_ice (pfile,
"node for '%s' exists, open failed, error '%s', value %lx\n",
filename, strerror (errno), nd->value);
destroy_include_file_node (nd->value);
}
splay_tree_insert (pfile->all_include_files,
(splay_tree_key) xstrdup (filename), 0);
return 0;
}
/* If we haven't seen this file before, create a positive node for it. */
if (!nd)
{
file = xnew (struct include_file);
file->cmacro = 0;
file->include_count = 0;
file->sysp = 0;
file->foundhere = 0;
file->name = xstrdup (filename);
splay_tree_insert (pfile->all_include_files,
(splay_tree_key) file->name,
(splay_tree_value) file);
}
goto fail;
if (fstat (fd, &st) < 0)
goto fail;
file = xcnew (struct include_file);
file->name = xstrdup (filename);
file->st = st;
file->fd = fd;
file->date = (time_t) -1;
/* If the file is plain and zero length, mark it never-reread now. */
if (S_ISREG (st.st_mode) && st.st_size == 0)
file->cmacro = NEVER_REREAD;
splay_tree_insert (pfile->all_include_files,
(splay_tree_key) file->name, (splay_tree_value) file);
return file;
fail:
/* Don't issue an error message if the file doesn't exist. */
if (errno != ENOENT && errno != ENOTDIR)
cpp_error_from_errno (pfile, filename);
/* Create a negative node for this path. */
splay_tree_insert (pfile->all_include_files,
(splay_tree_key) xstrdup (filename), 0);
return 0;
}
/* Place the file referenced by INC into a new buffer on PFILE's stack.
Return 1 if successful, 0 if not. */
static int
stack_include_file (pfile, inc)
cpp_reader *pfile;
struct include_file *inc;
{
cpp_buffer *fp;
if (DO_NOT_REREAD (inc))
return 0;
if (inc->buffer == NULL)
if (read_include_file (pfile, inc) == 0)
return 0;
fp = cpp_push_buffer (pfile, NULL, 0);
if (fp == 0)
return 0;
fp->inc = inc;
fp->nominal_fname = inc->name;
fp->buf = inc->buffer;
fp->rlimit = fp->buf + inc->st.st_size;
fp->cur = fp->buf;
fp->lineno = 1;
fp->line_base = fp->buf;
/* 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++;
pfile->include_depth++;
pfile->input_stack_listing_current = 0;
if (pfile->cb.enter_file)
(*pfile->cb.enter_file) (pfile);
return 1;
}
/* Read the file referenced by INC into the file cache.
If fd points to a plain file, we might be able to mmap it; we can
definitely allocate the buffer all at once. If fd is a pipe or
terminal, we can't do either. If fd is something weird, like a
block device or a directory, we don't want to read it at all.
Unfortunately, different systems use different st.st_mode values
for pipes: some have S_ISFIFO, some S_ISSOCK, some are buggy and
zero the entire struct stat except a couple fields. Hence we don't
even try to figure out what something is, except for plain files,
directories, and block devices.
FIXME: Flush file cache and try again if we run out of memory. */
static int
read_include_file (pfile, inc)
cpp_reader *pfile;
struct include_file *inc;
{
ssize_t size, offset, count;
U_CHAR *buf;
#if MMAP_THRESHOLD
static int pagesize = -1;
#endif
if (S_ISREG (inc->st.st_mode))
{
/* off_t might have a wider range than ssize_t - in other words,
the max size of a file might be bigger than the address
space. We can't handle a file that large. (Anyone with
a single source file bigger than 2GB needs to rethink
their coding style.) Some systems (e.g. AIX 4.1) define
SSIZE_MAX to be much smaller than the actual range of the
type. Use INTTYPE_MAXIMUM unconditionally to ensure this
does not bite us. */
if (inc->st.st_size > INTTYPE_MAXIMUM (ssize_t))
{
cpp_error (pfile, "%s is too large", inc->name);
goto fail;
}
size = inc->st.st_size;
#if MMAP_THRESHOLD
if (pagesize == -1)
pagesize = getpagesize ();
if (size / pagesize >= MMAP_THRESHOLD)
{
buf = (U_CHAR *) mmap (0, size, PROT_READ, MAP_PRIVATE, inc->fd, 0);
if (buf == (U_CHAR *)-1)
goto perror_fail;
inc->mapped = 1;
}
else
#endif
{
buf = (U_CHAR *) xmalloc (size);
offset = 0;
while (offset < size)
{
count = read (inc->fd, buf + offset, size - offset);
if (count < 0)
goto perror_fail;
if (count == 0)
{
cpp_warning (pfile, "%s is shorter than expected", inc->name);
break;
}
offset += count;
}
inc->mapped = 0;
}
}
else if (S_ISBLK (inc->st.st_mode))
{
cpp_error (pfile, "%s is a block device", inc->name);
goto fail;
}
else if (S_ISDIR (inc->st.st_mode))
{
cpp_error (pfile, "%s is a directory", inc->name);
goto fail;
}
else
{
/* 8 kilobytes is a sensible starting size. It ought to be
bigger than the kernel pipe buffer, and it's definitely
bigger than the majority of C source files. */
size = 8 * 1024;
buf = (U_CHAR *) xmalloc (size);
offset = 0;
while ((count = read (inc->fd, buf + offset, size - offset)) > 0)
{
offset += count;
if (offset == size)
buf = xrealloc (buf, (size *= 2));
}
if (count < 0)
goto perror_fail;
if (offset == 0)
{
free (buf);
return 0;
}
if (offset < size)
buf = xrealloc (buf, offset);
inc->st.st_size = offset;
}
close (inc->fd);
inc->buffer = buf;
inc->fd = -1;
return 1;
perror_fail:
cpp_error_from_errno (pfile, inc->name);
fail:
/* Do not try to read this file again. */
close (inc->fd);
inc->fd = -1;
inc->cmacro = NEVER_REREAD;
return 0;
}
static void
purge_cache (inc)
struct include_file *inc;
{
if (inc->buffer)
{
if (inc->mapped)
munmap ((caddr_t) inc->buffer, inc->st.st_size);
else
free ((PTR) inc->buffer);
inc->buffer = NULL;
}
}
/* Return 1 if the file named by FNAME has been included before in
@ -282,8 +410,7 @@ cpp_included (pfile, fname)
/* Search for include file FNAME in the include chain starting at
SEARCH_START. Return 0 if there is no such file (or it's un-openable),
otherwise an include_file structure, possibly with a file descriptor
open on the file. */
otherwise an include_file structure. */
static struct include_file *
find_include_file (pfile, fname, search_start)
@ -296,7 +423,7 @@ find_include_file (pfile, fname, search_start)
struct include_file *file;
if (fname[0] == '/')
return open_include_file (pfile, fname);
return lookup_include_file (pfile, fname);
/* Search directory path for the file. */
name = (char *) alloca (strlen (fname) + pfile->max_include_len
@ -310,7 +437,7 @@ find_include_file (pfile, fname, search_start)
if (CPP_OPTION (pfile, remap))
name = remap_filename (pfile, name, path);
file = open_include_file (pfile, name);
file = lookup_include_file (pfile, name);
if (file)
{
file->sysp = path->sysp;
@ -321,9 +448,9 @@ find_include_file (pfile, fname, search_start)
return 0;
}
/* #line uses this to save artificial file names. We have to try
opening the file because an all_include_files entry is always
either + or -, there's no 'I don't know' value. */
/* #line uses this to save artificial file names. We have to stat the
file because an all_include_files entry is always either + or -,
there's no 'I don't know' value. */
const char *
_cpp_fake_include (pfile, fname)
cpp_reader *pfile;
@ -335,7 +462,14 @@ _cpp_fake_include (pfile, fname)
file = find_include_file (pfile, fname, CPP_OPTION (pfile, quote_include));
if (file)
return file->name;
{
if (file->fd > 0)
{
close (file->fd);
file->fd = -1;
}
return file->name;
}
name = xstrdup (fname);
_cpp_simplify_pathname (name);
@ -453,31 +587,28 @@ _cpp_execute_include (pfile, f, len, no_reinclude, search_start, angle_brackets)
if (inc)
{
if (inc->fd == -1)
return;
/* For -M, add the file to the dependencies on its first inclusion. */
if (!inc->include_count && PRINT_THIS_DEP (pfile, angle_brackets))
deps_add_dep (pfile->deps, inc->name);
inc->include_count++;
/* 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);
}
/* Actually process the file. */
if (no_reinclude)
inc->cmacro = NEVER_REREAD;
if (read_include_file (pfile, inc))
if (stack_include_file (pfile, inc))
{
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);
}
}
return;
}
@ -552,23 +683,13 @@ _cpp_compare_file_date (pfile, f, len, angle_brackets)
if (!inc)
return -1;
if (inc->fd >= 0)
if (inc->fd > 0)
{
struct stat source;
if (fstat (inc->fd, &source) < 0)
{
close (inc->fd);
inc->fd = -1;
return -1;
}
inc->date = source.st_mtime;
close (inc->fd);
inc->fd = -1;
}
if (inc->date == (time_t)-1 || current_include->date == (time_t)-1)
return -1;
return inc->date > current_include->date;
return inc->st.st_mtime > current_include->st.st_mtime;
}
@ -584,7 +705,7 @@ cpp_read_file (pfile, fname)
if (fname == NULL)
fname = "";
f = open_include_file (pfile, fname);
f = lookup_include_file (pfile, fname);
if (f == NULL)
{
@ -592,188 +713,7 @@ cpp_read_file (pfile, fname)
return 0;
}
return read_include_file (pfile, f);
}
/* Read the file referenced by INC into a new buffer on PFILE's stack.
Return 1 if successful, 0 if not. */
static int
read_include_file (pfile, inc)
cpp_reader *pfile;
struct include_file *inc;
{
struct stat st;
ssize_t length;
cpp_buffer *fp;
int fd = inc->fd;
fp = cpp_push_buffer (pfile, NULL, 0);
if (fp == 0)
goto push_fail;
if (fd < 0 || fstat (fd, &st) < 0)
goto perror_fail;
/* These must be set right away. */
inc->date = st.st_mtime;
fp->inc = inc;
fp->nominal_fname = inc->name;
/* If fd points to a plain file, we might be able to mmap it; we can
definitely allocate the buffer all at once. If fd is a pipe or
terminal, we can't do either. If fd is something weird, like a
block device or a directory, we don't want to read it at all.
Unfortunately, different systems use different st.st_mode values
for pipes: some have S_ISFIFO, some S_ISSOCK, some are buggy and
zero the entire struct stat except a couple fields. Hence we don't
even try to figure out what something is, except for plain files,
directories, and block devices. */
if (S_ISREG (st.st_mode))
{
ssize_t st_size;
/* off_t might have a wider range than ssize_t - in other words,
the max size of a file might be bigger than the address
space. We can't handle a file that large. (Anyone with
a single source file bigger than 2GB needs to rethink
their coding style.) Some systems (e.g. AIX 4.1) define
SSIZE_MAX to be much smaller than the actual range of the
type. Use INTTYPE_MAXIMUM unconditionally to ensure this
does not bite us. */
if (st.st_size > INTTYPE_MAXIMUM (ssize_t))
{
cpp_error (pfile, "%s is too large", inc->name);
goto fail;
}
st_size = st.st_size;
length = read_file (fp, fd, st_size);
if (length == -1)
goto perror_fail;
if (length < st_size)
cpp_warning (pfile, "%s is shorter than expected\n", inc->name);
}
else if (S_ISBLK (st.st_mode))
{
cpp_error (pfile, "%s is a block device", inc->name);
goto fail;
}
else if (S_ISDIR (st.st_mode))
{
cpp_error (pfile, "%s is a directory", inc->name);
goto fail;
}
else
{
/* 8 kilobytes is a sensible starting size. It ought to be
bigger than the kernel pipe buffer, and it's definitely
bigger than the majority of C source files. */
length = read_with_read (fp, fd, 8 * 1024);
if (length == -1)
goto perror_fail;
}
if (length == 0)
inc->cmacro = NEVER_REREAD;
fp->rlimit = fp->buf + length;
fp->cur = fp->buf;
fp->lineno = 1;
fp->line_base = fp->buf;
/* 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);
pfile->include_depth++;
pfile->input_stack_listing_current = 0;
if (pfile->cb.enter_file)
(*pfile->cb.enter_file) (pfile);
return 1;
perror_fail:
cpp_error_from_errno (pfile, inc->name);
/* Do not try to read this file again. */
if (fd != -1)
close (fd);
inc->fd = -1;
inc->cmacro = NEVER_REREAD;
fail:
cpp_pop_buffer (pfile);
push_fail:
return 0;
}
static ssize_t
read_file (fp, fd, size)
cpp_buffer *fp;
int fd;
ssize_t size;
{
static int pagesize = -1;
if (size == 0)
return 0;
if (pagesize == -1)
pagesize = getpagesize ();
#if MMAP_THRESHOLD
if (size / pagesize >= MMAP_THRESHOLD)
{
const U_CHAR *result
= (const U_CHAR *) mmap (0, size, PROT_READ, MAP_PRIVATE, fd, 0);
if (result != (const U_CHAR *)-1)
{
fp->buf = result;
fp->mapped = 1;
return size;
}
}
/* If mmap fails, try read. If there's really a problem, read will
fail too. */
#endif
return read_with_read (fp, fd, size);
}
static ssize_t
read_with_read (fp, fd, size)
cpp_buffer *fp;
int fd;
ssize_t size;
{
ssize_t offset, count;
U_CHAR *buf;
buf = (U_CHAR *) xmalloc (size);
offset = 0;
while ((count = read (fd, buf + offset, size - offset)) > 0)
{
offset += count;
if (offset == size)
buf = xrealloc (buf, (size *= 2));
}
if (count < 0)
{
free (buf);
return -1;
}
if (offset == 0)
{
free (buf);
return 0;
}
if (offset < size)
buf = xrealloc (buf, offset);
fp->buf = buf;
fp->mapped = 0;
return offset;
return stack_include_file (pfile, f);
}
/* Do appropriate cleanup when a file buffer is popped off the input
@ -797,21 +737,9 @@ _cpp_pop_file_buffer (pfile, buf)
}
pfile->input_stack_listing_current = 0;
/* Discard file buffer. XXX Would be better to cache these instead
of the file descriptors. */
#ifdef HAVE_MMAP_FILE
if (buf->mapped)
munmap ((caddr_t) buf->buf, buf->rlimit - buf->buf);
else
#endif
free ((PTR) buf->buf);
/* If the file will not be included again, close it. */
if (DO_NOT_REREAD (inc))
{
close (inc->fd);
inc->fd = -1;
}
inc->refcnt--;
if (inc->refcnt == 0 && DO_NOT_REREAD (inc))
purge_cache (inc);
}
/* The file_name_map structure holds a mapping of file names for a

View File

@ -115,12 +115,24 @@ struct include_file
const struct file_name_list *foundhere;
/* location in search path where file was
found, for #include_next */
int fd; /* file descriptor possibly open on file */
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 sysp; /* file is a system header */
time_t date; /* modification date of file, if known */
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 */
};
/* 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 not defined. */
#define NEVER_REREAD ((const cpp_hashnode *)-1)
#define DO_NOT_REREAD(inc) \
((inc)->cmacro && \
((inc)->cmacro == NEVER_REREAD || (inc)->cmacro->type != T_VOID))
/* Special nodes - identifiers with predefined significance.
Note that the array length of dirs[] must be kept in sync with
cpplib.c's dtable[]. */
@ -133,16 +145,6 @@ struct spec_nodes
cpp_hashnode *dirs[19]; /* 19 directives counting #sccs */
};
/* 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 not defined. */
#define NEVER_REREAD ((const cpp_hashnode *)-1)
#define DO_NOT_REREAD(inc) \
((inc)->cmacro && \
((inc)->cmacro == NEVER_REREAD || (inc)->cmacro->type != T_VOID))
/* Character classes.
If the definition of `numchar' looks odd to you, please look up the
definition of a pp-number in the C standard [section 6.4.8 of C99].
@ -293,6 +295,7 @@ extern void _cpp_init_internal_pragmas PARAMS ((cpp_reader *));
/* Utility routines and macros. */
#define xnew(T) (T *) xmalloc (sizeof(T))
#define xcnew(T) (T *) xcalloc (1, sizeof(T))
#define xnewvec(T, N) (T *) xmalloc (sizeof(T) * (N))
#define xcnewvec(T, N) (T *) xcalloc (N, sizeof(T))
#define xobnew(O, T) (T *) obstack_alloc (O, sizeof(T))

View File

@ -1106,12 +1106,23 @@ parse_string (pfile, list, token, terminator)
if (is_vspace (c))
{
/* Drop a backslash newline, and continue. */
U_CHAR *old = namebuf;
while (namebuf > list->namebuf && is_hspace (namebuf[-1]))
namebuf--;
if (namebuf > list->namebuf && namebuf[-1] == '\\')
{
handle_newline (cur, buffer->rlimit, c);
namebuf--;
if (old[-1] != '\\')
{
buffer->cur = cur;
cpp_warning (pfile,
"backslash and newline separated by space");
}
continue;
}
else
namebuf = old;
cur--;
@ -1516,37 +1527,40 @@ lex_line (pfile, list)
handle_newline (cur, buffer->rlimit, c);
if (PREV_TOKEN_TYPE == CPP_BACKSLASH)
{
if (IMMED_TOKEN ())
{
/* Remove the escaped newline. Then continue to process
any interrupted name or number. */
cur_token--;
/* Backslash-newline may not be immediately followed by
EOF (C99 5.1.1.2). */
if (cur >= buffer->rlimit)
{
cpp_pedwarn (pfile, "backslash-newline at end of file");
break;
}
if (IMMED_TOKEN ())
{
cur_token--;
if (cur_token->type == CPP_NAME)
goto continue_name;
else if (cur_token->type == CPP_NUMBER)
goto continue_number;
cur_token++;
}
/* Remember whitespace setting. */
flags = cur_token->flags;
break;
}
else
/* backslash space newline is still treated as backslash-newline;
we think this is standard conforming, with some reservations
about actually _using_ the weasel words in C99 5.1.1.2
(translation phase 1 is allowed to do whatever it wants to
your input as long as it's documented). */
if (! IMMED_TOKEN ())
{
buffer->cur = cur;
cpp_warning (pfile,
"backslash and newline separated by space");
}
/* Remove the escaped newline. Then continue to process
any interrupted name or number. */
cur_token--;
/* Backslash-newline may not be immediately followed by
EOF (C99 5.1.1.2). */
if (cur >= buffer->rlimit)
{
cpp_pedwarn (pfile, "backslash-newline at end of file");
break;
}
if (IMMED_TOKEN ())
{
cur_token--;
if (cur_token->type == CPP_NAME)
goto continue_name;
else if (cur_token->type == CPP_NUMBER)
goto continue_number;
cur_token++;
}
/* Remember whitespace setting. */
flags = cur_token->flags;
break;
}
else if (MIGHT_BE_DIRECTIVE ())
{
@ -3187,12 +3201,6 @@ _cpp_get_token (pfile)
if (is_macro_disabled (pfile, node->value.expansion, token))
return token;
if (pfile->cur_context > CPP_STACK_MAX)
{
cpp_error (pfile, "macros nested too deep invoking '%s'", node->name);
return token;
}
if (push_macro_context (pfile, token))
return token;
/* else loop */

View File

@ -246,9 +246,6 @@ struct cpp_buffer
or for -Wtraditional, and only once per file (otherwise it would
be far too noisy). */
char warned_cplusplus_comments;
/* True if this buffer's data is mmapped. */
char mapped;
};
struct file_name_map_list;

View File

@ -1,3 +1,7 @@
2000-09-11 Zack Weinberg <zack@wolery.cumb.org>
* gcc.dg/cpp/backslash.c: New test.
2000-09-11 Alexandre Oliva <aoliva@redhat.com>
* gcc.c-torture/execute/20000910-1.c: New test.

View File

@ -0,0 +1,21 @@
/* Test backslash newline with and without trailing spaces. */
#define alpha(a, b, c) \
a, \
b, \
c
/* Note the trailing whitespace on the next three lines. */
#define beta(a, b, c) \
a, \
b, \
c
/* { dg-warning "separated by space" "space" { target *-*-* } 9 } */
/* { dg-warning "separated by space" "tab" { target *-*-* } 10 } */
/* { dg-warning "separated by space" "space and tab" { target *-*-* } 11 } */
int x[] = {
alpha(1, 2, 3),
beta(4, 5, 6)
};