]> gcc.gnu.org Git - gcc.git/commitdiff
cppfiles.c: Move all default-#defines to top of file.
authorZack Weinberg <zack@wolery.cumb.org>
Tue, 12 Sep 2000 03:42:30 +0000 (03:42 +0000)
committerZack Weinberg <zack@gcc.gnu.org>
Tue, 12 Sep 2000 03:42:30 +0000 (03:42 +0000)
* 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

gcc/ChangeLog
gcc/cppfiles.c
gcc/cpphash.h
gcc/cpplex.c
gcc/cpplib.h
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/cpp/backslash.c [new file with mode: 0644]

index 041537fd11a23eea23bd634a578d1375bff135cb..debb2191b28b85d16c7e4eab0d4b93000ea1eff7 100644 (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.
index 6bd4af4380ac087375ee519f3b0aca0bb6f7eab4..7f5c731c40375f916c307d013d7ca19a6a60662c 100644 (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)
+    goto fail;
+
+  if (fstat (fd, &st) < 0)
+    goto fail;
+  
+  file = xcnew (struct include_file);
+  file->name = xstrdup (filename);
+  file->st = st;
+  file->fd = fd;
+
+  /* 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))
     {
-#ifdef EACCES
-      if (errno == EACCES)
+      /* 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, "included file \"%s\" exists but is not readable",
-                    filename);
+         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
-      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;
+         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;
 
-      /* Nonexistent or inaccessible file.  Create a negative node for it.  */
-      if (nd)
+      if (offset == 0)
        {
-         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);
+         free (buf);
+         return 0;
        }
-      splay_tree_insert (pfile->all_include_files,
-                        (splay_tree_key) xstrdup (filename), 0);
-      return 0;
+
+      if (offset < size)
+       buf = xrealloc (buf, offset);
+      inc->st.st_size = offset;
     }
 
-  /* If we haven't seen this file before, create a positive node for it.  */
-  if (!nd)
+  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)
     {
-      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);
+      if (inc->mapped)
+       munmap ((caddr_t) inc->buffer, inc->st.st_size);
+      else
+       free ((PTR) inc->buffer);
+      inc->buffer = NULL;
     }
-
-  file->fd = fd;
-  file->date = (time_t) -1;
-  return file;
 }
 
 /* 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
index 45abb6919751f1faa73e80bd05a1d71d7c07ba69..41d5b9e5a7f13dd08607f2a21c3c2302c1718679 100644 (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))
index ab5a987d9722d7fe70110850269c7dc4a52ac366..5cb6b7f7611f3c25b0513f3e43732b1b8ad62571 100644 (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 */
index 9122acdec891c51b3e7d8158eedde9fe8b6098ba..9793bc0e92228494ecc6a22bc4de8f82cbabd7bb 100644 (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;
index f9a0543cc4a0e596e1482bfc120fa88342a89b0d..d654affba1c845c6d5bc63417e47d8d41b3125e1 100644 (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.
diff --git a/gcc/testsuite/gcc.dg/cpp/backslash.c b/gcc/testsuite/gcc.dg/cpp/backslash.c
new file mode 100644 (file)
index 0000000..f1b094a
--- /dev/null
@@ -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)
+};
This page took 0.090902 seconds and 5 git commands to generate.