OSDN Git Service

* lib/prune.exp (prune_gcc_output): Also handle "In member
[pf3gnuchains/gcc-fork.git] / gcc / cppfiles.c
index ebefd95..33801d6 100644 (file)
@@ -73,6 +73,15 @@ struct include_file
   unsigned char mapped;                /* file buffer is mmapped */
 };
 
+/* Variable length record files on VMS will have a stat size that includes
+   record control characters that won't be included in the read size. */
+#ifdef VMS
+# define FAB_C_VAR 2 /* variable length records (see Starlet fabdef.h) */
+# define STAT_SIZE_TOO_BIG(ST) ((ST).st_fab_rfm == FAB_C_VAR)
+#else
+# define STAT_SIZE_TOO_BIG(ST) 0
+#endif
+
 /* 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
@@ -250,10 +259,13 @@ open_file (pfile, filename)
     {
       if (!S_ISDIR (file->st.st_mode))
        return file;
+
       /* If it's a directory, we return null and continue the search
         as the file we're looking for may appear elsewhere in the
         search path.  */
       errno = ENOENT;
+      close (file->fd);
+      file->fd = -1;
     }
 
   file->err_no = errno;
@@ -287,17 +299,17 @@ stack_include_file (pfile, inc)
   /* Not in cache?  */
   if (! inc->buffer)
     {
-      /* Mark a regular, zero-length file never-reread.  Zero-length
-        files are stacked the first time, so preprocessing a main
-        file of zero length does not raise an error.  */
-      if (S_ISREG (inc->st.st_mode) && inc->st.st_size == 0)
-       _cpp_never_reread (inc);
-      else if (read_include_file (pfile, inc))
+      if (read_include_file (pfile, inc))
        {
          /* If an error occurs, do not try to read this file again.  */
          _cpp_never_reread (inc);
          return false;
        }
+      /* Mark a regular, zero-length file never-reread.  We read it,
+        NUL-terminate it, and stack it once, so preprocessing a main
+        file of zero length does not raise an error.  */
+      if (S_ISREG (inc->st.st_mode) && inc->st.st_size == 0)
+       _cpp_never_reread (inc);
       close (inc->fd);
       inc->fd = -1;
     }
@@ -373,7 +385,13 @@ read_include_file (pfile, inc)
       if (pagesize == -1)
        pagesize = getpagesize ();
 
-      if (size / pagesize >= MMAP_THRESHOLD)
+      /* Use mmap if the file is big enough to be worth it (controlled
+        by MMAP_THRESHOLD) and if we can safely count on there being
+        at least one readable NUL byte after the end of the file's
+        contents.  This is true for all tested operating systems when
+        the file size is not an exact multiple of the page size.  */
+      if (size / pagesize >= MMAP_THRESHOLD
+         && (size % pagesize) != 0)
        {
          buf = (U_CHAR *) mmap (0, size, PROT_READ, MAP_PRIVATE, inc->fd, 0);
          if (buf == (U_CHAR *)-1)
@@ -383,7 +401,7 @@ read_include_file (pfile, inc)
       else
 #endif
        {
-         buf = (U_CHAR *) xmalloc (size);
+         buf = (U_CHAR *) xmalloc (size + 1);
          offset = 0;
          while (offset < size)
            {
@@ -392,11 +410,17 @@ read_include_file (pfile, inc)
                goto perror_fail;
              if (count == 0)
                {
-                 cpp_warning (pfile, "%s is shorter than expected", inc->name);
+                 if (!STAT_SIZE_TOO_BIG (inc->st))
+                   cpp_warning
+                     (pfile, "%s is shorter than expected", inc->name);
+                 buf = xrealloc (buf, offset);
+                 inc->st.st_size = offset;
                  break;
                }
              offset += count;
            }
+         /* The lexer requires that the buffer be NUL-terminated.  */
+         buf[size] = '\0';
        }
     }
   else if (S_ISBLK (inc->st.st_mode))
@@ -411,19 +435,25 @@ read_include_file (pfile, inc)
         bigger than the majority of C source files.  */
       size = 8 * 1024;
 
-      buf = (U_CHAR *) xmalloc (size);
+      buf = (U_CHAR *) xmalloc (size + 1);
       offset = 0;
       while ((count = read (inc->fd, buf + offset, size - offset)) > 0)
        {
          offset += count;
          if (offset == size)
-           buf = xrealloc (buf, (size *= 2));
+           {
+             size *= 2;
+             buf = xrealloc (buf, size + 1);
+           }
        }
       if (count < 0)
        goto perror_fail;
 
-      if (offset < size)
-       buf = xrealloc (buf, offset);
+      if (offset + 1 < size)
+       buf = xrealloc (buf, offset + 1);
+
+      /* The lexer requires that the buffer be NUL-terminated.  */
+      buf[offset] = '\0';
       inc->st.st_size = offset;
     }
 
@@ -521,7 +551,7 @@ find_include_file (pfile, header, type)
 
   if (path == NULL)
     {
-      cpp_error (pfile, "No include path in which to find %s", fname);
+      cpp_error (pfile, "no include path in which to find %s", fname);
       return NO_INCLUDE_PATH;
     }
 
@@ -529,9 +559,14 @@ find_include_file (pfile, header, type)
   name = (char *) alloca (strlen (fname) + pfile->max_include_len + 2);
   for (; path; path = path->next)
     {
-      memcpy (name, path->name, path->len);
-      name[path->len] = '/';
-      strcpy (&name[path->len + 1], fname);
+      int len = path->len;
+      memcpy (name, path->name, len);
+      /* Don't turn / into // or // into ///; // may be a namespace
+        escape.  */
+      if (name[len-1] == '/')
+       len--;
+      name[len] = '/';
+      strcpy (&name[len + 1], fname);
       if (CPP_OPTION (pfile, remap))
        n = remap_filename (pfile, name, path);
       else
@@ -597,7 +632,7 @@ report_missing_guard (n, b)
   return 0;
 }
 
-/* Create a dependency, or issue an error message as appropriate.   */
+/* Create a dependency, or issue an error message as appropriate.  */
 static void
 handle_missing_header (pfile, fname, angle_brackets)
      cpp_reader *pfile;
@@ -635,7 +670,7 @@ handle_missing_header (pfile, fname, angle_brackets)
      we can still produce correct output.  Otherwise, we can't produce
      correct output, because there may be dependencies we need inside
      the missing file, and we don't know what directory this missing
-     file exists in.  FIXME: Use a future cpp_diagnotic_with_errno ()
+     file exists in.  FIXME: Use a future cpp_diagnostic_with_errno ()
      for both of these cases.  */
   else if (CPP_PRINT_DEPS (pfile) && ! print_dep)
     cpp_warning (pfile, "%s: %s", fname, xstrerror (errno));
@@ -859,7 +894,7 @@ read_name_map (pfile, dirname)
      cpp_reader *pfile;
      const char *dirname;
 {
-  register struct file_name_map_list *map_list_ptr;
+  struct file_name_map_list *map_list_ptr;
   char *name;
   FILE *f;