]> gcc.gnu.org Git - gcc.git/blobdiff - gcc/cppfiles.c
Prototypes for functions defined in target C source files.
[gcc.git] / gcc / cppfiles.c
index b43d280abd4bdbdb3fece4d6def070944b2cc506..dfeddcc8ca278d8e06b3892648dd33d87fd364ce 100644 (file)
@@ -43,8 +43,14 @@ static char *remap_filename          PROTO ((cpp_reader *, char *,
                                                struct file_name_list *));
 static long read_and_prescan           PROTO ((cpp_reader *, cpp_buffer *,
                                                int, size_t));
-static void simplify_pathname          PROTO ((char *));
-static struct file_name_list *actual_directory PROTO ((cpp_reader *, char *));
+static struct file_name_list *actual_directory PROTO ((cpp_reader *,
+                                                      const char *));
+static void initialize_input_buffer    PROTO ((cpp_reader *, int,
+                                               struct stat *));
+static int file_cleanup                        PROTO ((cpp_buffer *, cpp_reader *));
+static void find_position              PROTO ((U_CHAR *, U_CHAR *,
+                                               unsigned long *,
+                                               unsigned long *));
 
 #if 0
 static void hack_vms_include_specification PROTO ((char *));
@@ -54,60 +60,13 @@ static void hack_vms_include_specification PROTO ((char *));
    VMS has non-numeric inodes. */
 #ifdef VMS
 #define INO_T_EQ(a, b) (!bcmp((char *) &(a), (char *) &(b), sizeof (a)))
-#elif (defined _WIN32 && !defined CYGWIN) || defined __MSDOS__
+#elif (defined _WIN32 && !defined CYGWIN && ! defined (_UWIN)) \
+       || defined __MSDOS__
 #define INO_T_EQ(a, b) 0
 #else
 #define INO_T_EQ(a, b) ((a) == (b))
 #endif
 
-/* Append an entry for dir DIR to list LIST, simplifying it if
-   possible.  SYS says whether this is a system include directory.
-   *** DIR is modified in place.  It must be writable and permanently
-   allocated. LIST is a pointer to the head pointer, because we actually
-   *prepend* the dir, and reverse the list later (in merge_include_chains). */
-void
-append_include_chain (pfile, list, dir, sysp)
-     cpp_reader *pfile;
-     struct file_name_list **list;
-     const char *dir;
-     int sysp;
-{
-  struct file_name_list *new;
-  struct stat st;
-  unsigned int len;
-  char * newdir = xstrdup (dir);
-
-  simplify_pathname (newdir);
-  if (stat (newdir, &st))
-    {
-      /* Dirs that don't exist are silently ignored. */
-      if (errno != ENOENT)
-       cpp_perror_with_name (pfile, newdir);
-      return;
-    }
-
-  if (!S_ISDIR (st.st_mode))
-    {
-      cpp_message (pfile, 1, "%s: %s: Not a directory", progname, newdir);
-      return;
-    }
-
-  len = strlen(newdir);
-  if (len > pfile->max_include_len)
-    pfile->max_include_len = len;
-  
-  new = (struct file_name_list *)xmalloc (sizeof (struct file_name_list));
-  new->name = newdir;
-  new->nlen = len;
-  new->next = *list;
-  new->ino  = st.st_ino;
-  new->dev  = st.st_dev;
-  new->sysp = sysp;
-  new->name_map = NULL;
-
-  *list = new;
-}
-
 /* Merge the four include chains together in the order quote, bracket,
    system, after.  Remove duplicate dirs (as determined by
    INO_T_EQ()).  The system_include and after_include chains are never
@@ -121,51 +80,19 @@ void
 merge_include_chains (opts)
      struct cpp_options *opts;
 {
-  struct file_name_list *prev, *next, *cur, *other;
+  struct file_name_list *prev, *cur, *other;
   struct file_name_list *quote, *brack, *systm, *after;
   struct file_name_list *qtail, *btail, *stail, *atail;
 
-  qtail = opts->quote_include;
-  btail = opts->bracket_include;
-  stail = opts->system_include;
-  atail = opts->after_include;
-
-  /* Nreverse the four lists. */
-  prev = 0;
-  for (cur = qtail; cur; cur = next)
-    {
-      next = cur->next;
-      cur->next = prev;
-      prev = cur;
-    }
-  quote = prev;
-
-  prev = 0;
-  for (cur = btail; cur; cur = next)
-    {
-      next = cur->next;
-      cur->next = prev;
-      prev = cur;
-    }
-  brack = prev;
-
-  prev = 0;
-  for (cur = stail; cur; cur = next)
-    {
-      next = cur->next;
-      cur->next = prev;
-      prev = cur;
-    }
-  systm = prev;
+  qtail = opts->pending->quote_tail;
+  btail = opts->pending->brack_tail;
+  stail = opts->pending->systm_tail;
+  atail = opts->pending->after_tail;
 
-  prev = 0;
-  for (cur = atail; cur; cur = next)
-    {
-      next = cur->next;
-      cur->next = prev;
-      prev = cur;
-    }
-  after = prev;
+  quote = opts->pending->quote_head;
+  brack = opts->pending->brack_head;
+  systm = opts->pending->systm_head;
+  after = opts->pending->after_head;
 
   /* Paste together bracket, system, and after include chains. */
   if (stail)
@@ -187,14 +114,20 @@ merge_include_chains (opts)
      then we may lose directories from the <> search path that should
      be there; consider -Ifoo -Ibar -I- -Ifoo -Iquux. It is however
      safe to treat -Ibar -Ifoo -I- -Ifoo -Iquux as if written
-     -Ibar -I- -Ifoo -Iquux. */
+     -Ibar -I- -Ifoo -Iquux.
 
-  for (cur = quote; cur; cur = cur->next)
+     Note that this algorithm is quadratic in the number of -I switches,
+     which is acceptable since there aren't usually that many of them.  */
+
+  for (cur = quote, prev = NULL; cur; cur = cur->next)
     {
       for (other = quote; other != cur; other = other->next)
         if (INO_T_EQ (cur->ino, other->ino)
            && cur->dev == other->dev)
           {
+           if (opts->verbose)
+             cpp_notice ("ignoring duplicate directory `%s'\n", cur->name);
+
            prev->next = cur->next;
            free (cur->name);
            free (cur);
@@ -211,6 +144,9 @@ merge_include_chains (opts)
         if (INO_T_EQ (cur->ino, other->ino)
            && cur->dev == other->dev)
           {
+           if (opts->verbose)
+             cpp_notice ("ignoring duplicate directory `%s'\n", cur->name);
+
            prev->next = cur->next;
            free (cur->name);
            free (cur);
@@ -226,6 +162,10 @@ merge_include_chains (opts)
         {
          if (quote == qtail)
            {
+             if (opts->verbose)
+               cpp_notice ("ignoring duplicate directory `%s'\n",
+                           quote->name);
+
              free (quote->name);
              free (quote);
              quote = brack;
@@ -236,6 +176,10 @@ merge_include_chains (opts)
              while (cur->next != qtail)
                  cur = cur->next;
              cur->next = brack;
+             if (opts->verbose)
+               cpp_notice ("ignoring duplicate directory `%s'\n",
+                           qtail->name);
+
              free (qtail->name);
              free (qtail);
            }
@@ -248,8 +192,6 @@ merge_include_chains (opts)
 
   opts->quote_include = quote;
   opts->bracket_include = brack;
-  opts->system_include = NULL;
-  opts->after_include = NULL;
 }
 
 /* Look up or add an entry to the table of all includes.  This table
@@ -261,12 +203,12 @@ merge_include_chains (opts)
 struct include_hash *
 include_hash (pfile, fname, add)
      cpp_reader *pfile;
-     char *fname;
+     const char *fname;
      int add;
 {
   unsigned int hash = 0;
   struct include_hash *l, *m;
-  char *f = fname;
+  const char *f = fname;
 
   while (*f)
     hash += *f++;
@@ -368,7 +310,7 @@ file_cleanup (pbuf, pfile)
 int
 find_include_file (pfile, fname, search_start, ihash, before)
      cpp_reader *pfile;
-     char *fname;
+     const char *fname;
      struct file_name_list *search_start;
      struct include_hash **ihash;
      int *before;
@@ -495,10 +437,10 @@ read_filename_string (ch, f)
 
   len = 20;
   set = alloc = xmalloc (len + 1);
-  if (! is_space[ch])
+  if (! is_space(ch))
     {
       *set++ = ch;
-      while ((ch = getc (f)) != EOF && ! is_space[ch])
+      while ((ch = getc (f)) != EOF && ! is_space(ch))
        {
          if (set - alloc == len)
            {
@@ -561,10 +503,10 @@ read_name_map (pfile, dirname)
          char *from, *to;
          struct file_name_map *ptr;
 
-         if (is_space[ch])
+         if (is_space(ch))
            continue;
          from = read_filename_string (ch, f);
-         while ((ch = getc (f)) != EOF && is_hor_space[ch])
+         while ((ch = getc (f)) != EOF && is_hspace(ch))
            ;
          to = read_filename_string (ch, f);
 
@@ -705,18 +647,20 @@ finclude (pfile, fd, ihash)
          a single source file bigger than 4GB needs to rethink
         their coding style.)  */
       st_size = (size_t) st.st_size;
-      if ((unsigned HOST_WIDE_INT) st_size
-         != (unsigned HOST_WIDE_INT) st.st_size)
+      if ((unsigned HOST_WIDEST_INT) st_size
+         != (unsigned HOST_WIDEST_INT) st.st_size)
        {
          cpp_error (pfile, "file `%s' is too large", ihash->name);
          goto fail;
        }
     }
   else if (S_ISFIFO (st.st_mode) || S_ISSOCK (st.st_mode)
+          /* Permit any kind of character device: the sensible ones are
+             ttys and /dev/null, but weeding out the others is too hard.  */
+          || S_ISCHR (st.st_mode)
           /* Some 4.x (x<4) derivatives have a bug that makes fstat() of a
              socket or pipe return a stat struct with most fields zeroed.  */
-          || (st.st_mode == 0 && st.st_nlink == 0 && st.st_size == 0)
-          || (S_ISCHR (st.st_mode) && isatty (fd)))
+          || (st.st_mode == 0 && st.st_nlink == 0 && st.st_size == 0))
     {
       /* Cannot get its file size before reading.  4k is a decent
          first guess. */
@@ -728,6 +672,9 @@ finclude (pfile, fd, ihash)
       goto fail;
     }
 
+  if (pfile->input_buffer == NULL)
+    initialize_input_buffer (pfile, fd, &st);
+
   /* Read the file, converting end-of-line characters and trigraphs
      (if enabled). */
   fp->ihash = ihash;
@@ -741,10 +688,11 @@ finclude (pfile, fd, ihash)
   close (fd);
   fp->rlimit = fp->alimit = fp->buf + length;
   fp->cur = fp->buf;
-  fp->system_header_p = (ihash->foundhere != ABSOLUTE_PATH
-                        && ihash->foundhere->sysp);
+  if (ihash->foundhere != ABSOLUTE_PATH)
+      fp->system_header_p = ihash->foundhere->sysp;
   fp->lineno = 1;
   fp->colno = 1;
+  fp->line_base = fp->buf;
   fp->cleanup = file_cleanup;
 
   /* The ->actual_dir field is only used when ignore_srcdir is not in effect;
@@ -771,7 +719,7 @@ finclude (pfile, fd, ihash)
 static struct file_name_list *
 actual_directory (pfile, fname)
      cpp_reader *pfile;
-     char *fname;
+     const char *fname;
 {
   char *last_slash, *dir;
   size_t dlen;
@@ -815,22 +763,66 @@ actual_directory (pfile, fname)
   x->nlen = dlen;
   x->next = CPP_OPTIONS (pfile)->quote_include;
   x->alloc = pfile->actual_dirs;
-  x->sysp = 0;
+  x->sysp = CPP_BUFFER (pfile)->system_header_p;
   x->name_map = NULL;
 
   pfile->actual_dirs = x;
   return x;
 }
 
-/* Read the entire contents of file DESC into buffer BUF, convert end-of-line
-   markers to canonical form, and convert trigraphs if enabled.  Also, make
-   sure there is a newline at the end of the file.  LEN is how much room we
-   have to start with (this can be expanded if necessary).
-   Returns -1 on failure, or the actual length of the data to be scanned.
+/* Determine the current line and column.  Used only by read_and_prescan. */
+static void
+find_position (start, limit, linep, colp)
+     U_CHAR *start;
+     U_CHAR *limit;
+     unsigned long *linep;
+     unsigned long *colp;
+{
+  unsigned long line = *linep, col = 0;
+  while (start < limit)
+    {
+      U_CHAR ch = *start++;
+      if (ch == '\n' || ch == '\r')
+       line++, col = 1;
+      else
+       col++;
+    }
+  *linep = line, *colp = col;
+}
 
-   N.B. This function has been rearranged to out-of-line the uncommon cases
-   as much as possible; this is important to prevent it from being a
-   performance bottleneck.  */
+/* Read the entire contents of file DESC into buffer BUF.  LEN is how
+   much memory to allocate initially; more will be allocated if
+   necessary.  Convert end-of-line markers (\n, \r, \r\n, \n\r) to
+   canonical form (\n).  If enabled, convert and/or warn about
+   trigraphs.  Convert backslash-newline to a one-character escape
+   (\r) and remove it from "embarrassing" places (i.e. the middle of a
+   token).  If there is no newline at the end of the file, add one and
+   warn.  Returns -1 on failure, or the actual length of the data to
+   be scanned.
+
+   This function does a lot of work, and can be a serious performance
+   bottleneck.  It has been tuned heavily; make sure you understand it
+   before hacking.  The common case - no trigraphs, Unix style line
+   breaks, backslash-newline set off by whitespace, newline at EOF -
+   has been optimized at the expense of the others.  The performance
+   penalty for DOS style line breaks (\r\n) is about 15%.
+   
+   Warnings lose particularly heavily since we have to determine the
+   line number, which involves scanning from the beginning of the file
+   or from the last warning.  The penalty for the absence of a newline
+   at the end of reload1.c is about 60%.  (reload1.c is 329k.)
+
+   If your file has more than one kind of end-of-line marker, you
+   will get messed-up line numbering.  */
+
+/* Table of characters that can't be handled in the inner loop.
+   Keep these contiguous to optimize the performance of the code generated
+   for the switch that uses them.  */
+#define SPECCASE_EMPTY     0
+#define SPECCASE_NUL       1
+#define SPECCASE_CR        2
+#define SPECCASE_BACKSLASH 3
+#define SPECCASE_QUESTION  4
 
 static long
 read_and_prescan (pfile, fp, desc, len)
@@ -842,26 +834,24 @@ read_and_prescan (pfile, fp, desc, len)
   U_CHAR *buf = (U_CHAR *) xmalloc (len);
   U_CHAR *ip, *op, *line_base;
   U_CHAR *ibase;
-  unsigned int line;
+  U_CHAR *speccase = pfile->input_speccase;
+  unsigned long line;
+  unsigned int deferred_newlines;
   int count;
   size_t offset;
-  /* 4096 bytes of buffer proper, 2 to detect running off the end without
-     address arithmetic all the time, and 2 for pushback in the case there's
-     a potential trigraph or end-of-line digraph at the end of a block. */
-#define INTERMED_BUFFER_SIZE 4096
-  U_CHAR intermed[INTERMED_BUFFER_SIZE + 2 + 2];
 
   offset = 0;
   op = buf;
   line_base = buf;
   line = 1;
-  ibase = intermed + 2;
+  ibase = pfile->input_buffer + 2;
+  deferred_newlines = 0;
 
   for (;;)
     {
     read_next:
 
-      count = read (desc, intermed + 2, INTERMED_BUFFER_SIZE);
+      count = read (desc, pfile->input_buffer + 2, pfile->input_buffer_len);
       if (count < 0)
        goto error;
       else if (count == 0)
@@ -869,18 +859,18 @@ read_and_prescan (pfile, fp, desc, len)
 
       offset += count;
       ip = ibase;
-      ibase = intermed + 2;
+      ibase = pfile->input_buffer + 2;
       ibase[count] = ibase[count+1] = '\0';
-      
+
       if (offset > len)
        {
          size_t delta_op;
          size_t delta_line_base;
          len *= 2;
          if (offset > len)
-             /* len overflowed.
-                This could happen if the file is larger than half the
-                maximum address space of the machine. */
+           /* len overflowed.
+              This could happen if the file is larger than half the
+              maximum address space of the machine. */
            goto too_big;
 
          delta_op = op - buf;
@@ -892,93 +882,166 @@ read_and_prescan (pfile, fp, desc, len)
 
       for (;;)
        {
-         unsigned int c;
-         c = *ip++;
-         switch (c)
+         unsigned int span = 0;
+
+         /* Deal with \-newline in the middle of a token. */
+         if (deferred_newlines)
            {
-             /* The default case is at the top so gcc will realize
-                it's the common case, and leave c in a register.
-                Also, cache utilization is a little better this way. */
-           default:
-             *op++ = c;
-             break;
-             
-           case '\0':
+             while (speccase[ip[span]] == SPECCASE_EMPTY
+                    && ip[span] != '\n'
+                    && ip[span] != '\t'
+                    && ip[span] != ' ')
+               span++;
+             memcpy (op, ip, span);
+             op += span;
+             ip += span;
+             if (*ip == '\n' || *ip == '\t'
+                 || *ip == ' ' || *ip == ' ')
+               while (deferred_newlines)
+                 deferred_newlines--, *op++ = '\r';
+             span = 0;
+           }
+
+         /* Copy as much as we can without special treatment. */
+         while (speccase[ip[span]] == SPECCASE_EMPTY) span++;
+         memcpy (op, ip, span);
+         op += span;
+         ip += span;
+
+         switch (speccase[*ip++])
+           {
+           case SPECCASE_NUL:  /* \0 */
+             ibase[-1] = op[-1];
              goto read_next;
-           case '\r':
-             if (*ip == '\n') ip++;
+
+           case SPECCASE_CR:  /* \r */
+             if (*ip == '\n')
+               ip++;
              else if (*ip == '\0')
                {
-                 --ibase;
-                 intermed[1] = '\r';
+                 *--ibase = '\r';
                  goto read_next;
                }
+             else if (ip[-2] == '\n')
+               continue;
              *op++ = '\n';
-             line++;
-             line_base = op;
              break;
 
-           case '\n':
-             if (*ip == '\r') ip++;
-             else if (*ip == '\0')
+           case SPECCASE_BACKSLASH:  /* \ */
+           backslash:
+           {
+             /* If we're at the end of the intermediate buffer,
+                we have to shift the backslash down to the start
+                and come back next pass. */
+             if (*ip == '\0')
                {
-                 --ibase;
-                 intermed[1] = '\n';
+                 *--ibase = '\\';
                  goto read_next;
                }
-             *op++ = '\n';
-             line++;
-             line_base = op;
-             break;
-
-           case '?':
-             if (CPP_OPTIONS (pfile)->trigraphs
-                 || CPP_OPTIONS (pfile)->warn_trigraphs)
+             else if (*ip == '\n')
                {
-                 unsigned int d;
-                 /* If we're at the end of the intermediate buffer,
-                    we have to shift the ?'s down to the start and
-                    come back next pass. */
-                 d = ip[0];
-                 if (d == '\0')
-                   {
-                     --ibase;
-                     intermed[1] = '?';
-                     goto read_next;
-                   }
-                 if (d != '?')
-                   {
-                     *op++ = '?';
-                     break;
-                   }
-                 d = ip[1];
-                 if (d == '\0')
+                 ip++;
+                 if (*ip == '\r') ip++;
+                 if (*ip == '\n' || *ip == '\t' || *ip == ' ')
+                   *op++ = '\r';
+                 else if (op[-1] == '\t' || op[-1] == ' '
+                          || op[-1] == '\r' || op[-1] == '\n')
+                   *op++ = '\r';
+                 else
+                   deferred_newlines++;
+                 line++;
+                 line_base = op;
+               }
+             else if (*ip == '\r')
+               {
+                 ip++;
+                 if (*ip == '\n') ip++;
+                 else if (*ip == '\0')
                    {
-                     ibase -= 2;
-                     intermed[0] = intermed[1] = '?';
+                     *--ibase = '\r';
+                     *--ibase = '\\';
                      goto read_next;
                    }
-                 if (!trigraph_table[d])
-                   {
-                     *op++ = '?';
-                     break;
-                   }
-
-                 if (CPP_OPTIONS (pfile)->warn_trigraphs)
-                   cpp_warning_with_line (pfile, line, op-line_base,
-                                          "trigraph ??%c encountered", d);
-                 if (CPP_OPTIONS (pfile)->trigraphs)
-                   *op++ = trigraph_table[d];
+                 else if (*ip == '\r' || *ip == '\t' || *ip == ' ')
+                   *op++ = '\r';
                  else
-                   {
-                     *op++ = '?';
-                     *op++ = '?';
-                     *op++ = d;
-                   }
-                 ip += 2;
+                   deferred_newlines++;
+                 line++;
+                 line_base = op;
                }
              else
-               *op++ = c;
+               *op++ = '\\';
+           }
+           break;
+
+           case SPECCASE_QUESTION: /* ? */
+             {
+               unsigned int d, t;
+               /* If we're at the end of the intermediate buffer,
+                  we have to shift the ?'s down to the start and
+                  come back next pass. */
+               d = ip[0];
+               if (d == '\0')
+                 {
+                   *--ibase = '?';
+                   goto read_next;
+                 }
+               if (d != '?')
+                 {
+                   *op++ = '?';
+                   break;
+                 }
+               d = ip[1];
+               if (d == '\0')
+                 {
+                   *--ibase = '?';
+                   *--ibase = '?';
+                   goto read_next;
+                 }
+
+               /* Trigraph map:
+                *      from    to      from    to      from    to
+                *      ?? =    #       ?? )    ]       ?? !    |
+                *      ?? (    [       ?? '    ^       ?? >    }
+                *      ?? /    \       ?? <    {       ?? -    ~
+                */
+               if (d == '=') t = '#';
+               else if (d == ')') t = ']';
+               else if (d == '!') t = '|';
+               else if (d == '(') t = '[';
+               else if (d == '\'') t = '^';
+               else if (d == '>') t = '}';
+               else if (d == '/') t = '\\';
+               else if (d == '<') t = '{';
+               else if (d == '-') t = '~';
+               else
+                 {
+                   *op++ = '?';
+                   break;
+                 }
+               if (CPP_OPTIONS (pfile)->warn_trigraphs)
+                 {
+                   unsigned long col;
+                   find_position (line_base, op, &line, &col);
+                   line_base = op - col;
+                   cpp_warning_with_line (pfile, line, col,
+                                          "trigraph ??%c encountered", d);
+                 }
+               if (CPP_OPTIONS (pfile)->trigraphs)
+                 {
+                   if (t == '\\')
+                     goto backslash;
+                   else
+                     *op++ = t;
+                 }
+               else
+                 {
+                   *op++ = '?';
+                   *op++ = '?';
+                   *op++ = d;
+                 }
+               ip += 2;
+             }
            }
        }
     }
@@ -987,47 +1050,48 @@ read_and_prescan (pfile, fp, desc, len)
     return 0;
 
   /* Deal with pushed-back chars at true EOF.
-     If two chars were pushed back, they must both be ?'s.
-     If one was, it might be ?, \r, or \n, and \r needs to
-     become \n.
+     This may be any of:  ?? ? \ \r \n \\r \\n.
+     \r must become \n, \\r or \\n must become \r.
      We know we have space already. */
-  if (ibase == intermed)
-    {
-      *op++ = '?';
-      *op++ = '?';
-    }
-  else if (ibase == intermed + 1)
+  if (ibase == pfile->input_buffer)
     {
       if (*ibase == '?')
-       *op++ = '?';
+       {
+         *op++ = '?';
+         *op++ = '?';
+       }
       else
+       *op++ = '\r';
+    }
+  else if (ibase == pfile->input_buffer + 1)
+    {
+      if (*ibase == '\r')
        *op++ = '\n';
+      else
+       *op++ = *ibase;
     }
 
-  if (op[-1] != '\n' || op[-2] == '\\')
+  if (op[-1] != '\n')
     {
-      if (CPP_PEDANTIC (pfile))
-       cpp_pedwarn_with_line (pfile, line, op - line_base,
-                              "no newline at end of file");
-      if (offset + 2 > len)
+      unsigned long col;
+      find_position (line_base, op, &line, &col);
+      cpp_warning_with_line (pfile, line, col, "no newline at end of file\n");
+      if (offset + 1 > len)
        {
-         len += 2;
-         if (offset + 2 > len)
+         len += 1;
+         if (offset + 1 > len)
            goto too_big;
          buf = (U_CHAR *) xrealloc (buf, len);
          op = buf + offset;
        }
-      if (op[-1] == '\\')
-       *op++ = '\n';
       *op++ = '\n';
     }
 
-  fp->buf =
-    (U_CHAR *) ((len - offset < 20) ? (PTR) buf : xrealloc (buf, op - buf));
+  fp->buf = ((len - offset < 20) ? buf : (U_CHAR *)xrealloc (buf, op - buf));
   return op - buf;
 
  too_big:
-  cpp_error (pfile, "file is too large");
+  cpp_error (pfile, "file is too large (>%lu bytes)\n", (unsigned long)offset);
   free (buf);
   return -1;
 
@@ -1037,6 +1101,67 @@ read_and_prescan (pfile, fp, desc, len)
   return -1;
 }
 
+/* Initialize the `input_buffer' and `input_speccase' tables.
+   These are only used by read_and_prescan, but they're large and
+   somewhat expensive to set up, so we want them allocated once for
+   the duration of the cpp run.  */
+
+static void
+initialize_input_buffer (pfile, fd, st)
+     cpp_reader *pfile;
+     int fd;
+     struct stat *st;
+{
+  long pipe_buf;
+  U_CHAR *tmp;
+
+  /* Table of characters that cannot be handled by the
+     read_and_prescan inner loop.  The number of non-EMPTY entries
+     should be as small as humanly possible.  */
+
+  tmp = (U_CHAR *) xmalloc (1 << CHAR_BIT);
+  memset (tmp, SPECCASE_EMPTY, 1 << CHAR_BIT);
+  tmp['\0'] = SPECCASE_NUL;
+  tmp['\r'] = SPECCASE_CR;
+  tmp['\\'] = SPECCASE_BACKSLASH;
+  if (CPP_OPTIONS (pfile)->trigraphs || CPP_OPTIONS (pfile)->warn_trigraphs)
+    tmp['?'] = SPECCASE_QUESTION;
+
+  pfile->input_speccase = tmp;
+
+  /* Determine the appropriate size for the input buffer.  Normal C
+     source files are smaller than eight K.  If we are reading a pipe,
+     we want to make sure the input buffer is bigger than the kernel's
+     pipe buffer.  */
+  pipe_buf = -1;
+
+  if (! S_ISREG (st->st_mode))
+    {
+#ifdef _PC_PIPE_BUF
+      pipe_buf = fpathconf (fd, _PC_PIPE_BUF);
+#endif
+      if (pipe_buf == -1)
+       {
+#ifdef PIPE_BUF
+         pipe_buf = PIPE_BUF;
+#else
+         pipe_buf = 8192;
+#endif
+       }
+    }
+
+  if (pipe_buf < 8192)
+    pipe_buf = 8192;
+  /* PIPE_BUF bytes of buffer proper, 2 to detect running off the end
+     without address arithmetic all the time, and 2 for pushback in
+     the case there's a potential trigraph or end-of-line digraph at
+     the end of a block. */
+
+  tmp = (U_CHAR *) xmalloc (pipe_buf + 2 + 2);
+  pfile->input_buffer = tmp;
+  pfile->input_buffer_len = pipe_buf;
+}
+
 /* Add output to `deps_buffer' for the -M switch.
    STRING points to the text to be output.
    SPACER is ':' for targets, ' ' for dependencies, zero for text
@@ -1045,7 +1170,7 @@ read_and_prescan (pfile, fp, desc, len)
 void
 deps_output (pfile, string, spacer)
      cpp_reader *pfile;
-     char *string;
+     const char *string;
      int spacer;
 {
   int size;
@@ -1062,12 +1187,11 @@ deps_output (pfile, string, spacer)
   if (pfile->deps_column > 0
       && (pfile->deps_column + size) > MAX_OUTPUT_COLUMNS)
     {
-      size += 5;
-      cr = 1;
+      cr = 5;
       pfile->deps_column = 0;
     }
 
-  if (pfile->deps_size + size + 8 > pfile->deps_allocated_size)
+  if (pfile->deps_size + size + cr + 8 > pfile->deps_allocated_size)
     {
       pfile->deps_allocated_size = (pfile->deps_size + size + 50) * 2;
       pfile->deps_buffer = (char *) xrealloc (pfile->deps_buffer,
@@ -1104,7 +1228,7 @@ deps_output (pfile, string, spacer)
    Guarantees no trailing slashes. All transforms reduce the length
    of the string.
  */
-static void
+void
 simplify_pathname (path)
     char *path;
 {
@@ -1112,7 +1236,7 @@ simplify_pathname (path)
     char *base;
     int absolute = 0;
 
-#if defined _WIN32 || defined __MSDOS__
+#if defined (HAVE_DOS_BASED_FILE_SYSTEM)
     /* Convert all backslashes to slashes. */
     for (from = path; *from; from++)
        if (*from == '\\') *from = '/';
This page took 0.084244 seconds and 5 git commands to generate.