]> 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 6fd240787fdecbfa4c44faf6037225692b23df01..dfeddcc8ca278d8e06b3892648dd33d87fd364ce 100644 (file)
@@ -43,7 +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 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 *));
@@ -196,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++;
@@ -303,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;
@@ -430,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)
            {
@@ -496,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);
 
@@ -648,10 +655,12 @@ finclude (pfile, fd, ihash)
        }
     }
   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. */
@@ -663,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;
@@ -707,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;
@@ -758,16 +770,15 @@ actual_directory (pfile, fname)
   return x;
 }
 
-/* Almost but not quite the same as adjust_position in cpplib.c.
-   Used only by read_and_prescan. */
+/* 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;
-     long *linep;
-     long *colp;
+     unsigned long *linep;
+     unsigned long *colp;
 {
-  long line = *linep, col = 0;
+  unsigned long line = *linep, col = 0;
   while (start < limit)
     {
       U_CHAR ch = *start++;
@@ -804,9 +815,14 @@ find_position (start, limit, linep, colp)
    If your file has more than one kind of end-of-line marker, you
    will get messed-up line numbering.  */
 
-#ifndef PIPE_BUF
-#define PIPE_BUF 4096
-#endif
+/* 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)
@@ -818,44 +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, deferred_newlines;
+  U_CHAR *speccase = pfile->input_speccase;
+  unsigned long line;
+  unsigned int deferred_newlines;
   int count;
   size_t offset;
-  /* 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. */
-  U_CHAR intermed[PIPE_BUF + 2 + 2];
-
-  /* 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
-  U_CHAR speccase[256];
 
   offset = 0;
   op = buf;
   line_base = buf;
   line = 1;
-  ibase = intermed + 2;
+  ibase = pfile->input_buffer + 2;
   deferred_newlines = 0;
 
-  memset (speccase, SPECCASE_EMPTY, sizeof (speccase));
-  speccase['\0'] = SPECCASE_NUL;
-  speccase['\r'] = SPECCASE_CR;
-  speccase['\\'] = SPECCASE_BACKSLASH;
-  if (CPP_OPTIONS (pfile)->trigraphs || CPP_OPTIONS (pfile)->warn_trigraphs)
-    speccase['?'] = SPECCASE_QUESTION;
-
   for (;;)
     {
     read_next:
 
-      count = read (desc, intermed + 2, PIPE_BUF);
+      count = read (desc, pfile->input_buffer + 2, pfile->input_buffer_len);
       if (count < 0)
        goto error;
       else if (count == 0)
@@ -863,7 +859,7 @@ 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)
@@ -923,8 +919,7 @@ read_and_prescan (pfile, fp, desc, len)
                ip++;
              else if (*ip == '\0')
                {
-                 --ibase;
-                 intermed[1] = '\r';
+                 *--ibase = '\r';
                  goto read_next;
                }
              else if (ip[-2] == '\n')
@@ -940,8 +935,7 @@ read_and_prescan (pfile, fp, desc, len)
                 and come back next pass. */
              if (*ip == '\0')
                {
-                 --ibase;
-                 intermed[1] = '\\';
+                 *--ibase = '\\';
                  goto read_next;
                }
              else if (*ip == '\n')
@@ -964,9 +958,8 @@ read_and_prescan (pfile, fp, desc, len)
                  if (*ip == '\n') ip++;
                  else if (*ip == '\0')
                    {
-                     ibase -= 2;
-                     intermed[0] = '\\';
-                     intermed[1] = '\r';
+                     *--ibase = '\r';
+                     *--ibase = '\\';
                      goto read_next;
                    }
                  else if (*ip == '\r' || *ip == '\t' || *ip == ' ')
@@ -983,15 +976,14 @@ read_and_prescan (pfile, fp, desc, len)
 
            case SPECCASE_QUESTION: /* ? */
              {
-               unsigned int d;
+               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;
-                   intermed[1] = '?';
+                   *--ibase = '?';
                    goto read_next;
                  }
                if (d != '?')
@@ -1002,19 +994,34 @@ read_and_prescan (pfile, fp, desc, len)
                d = ip[1];
                if (d == '\0')
                  {
-                   ibase -= 2;
-                   intermed[0] = intermed[1] = '?';
+                   *--ibase = '?';
+                   *--ibase = '?';
                    goto read_next;
                  }
-               if (!trigraph_table[d])
+
+               /* 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)
                  {
-                   long col;
+                   unsigned long col;
                    find_position (line_base, op, &line, &col);
                    line_base = op - col;
                    cpp_warning_with_line (pfile, line, col,
@@ -1022,10 +1029,10 @@ read_and_prescan (pfile, fp, desc, len)
                  }
                if (CPP_OPTIONS (pfile)->trigraphs)
                  {
-                   if (trigraph_table[d] == '\\')
+                   if (t == '\\')
                      goto backslash;
                    else
-                     *op++ = trigraph_table[d];
+                     *op++ = t;
                  }
                else
                  {
@@ -1046,7 +1053,7 @@ read_and_prescan (pfile, fp, desc, len)
      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)
+  if (ibase == pfile->input_buffer)
     {
       if (*ibase == '?')
        {
@@ -1056,7 +1063,7 @@ read_and_prescan (pfile, fp, desc, len)
       else
        *op++ = '\r';
     }
-  else if (ibase == intermed + 1)
+  else if (ibase == pfile->input_buffer + 1)
     {
       if (*ibase == '\r')
        *op++ = '\n';
@@ -1066,7 +1073,7 @@ read_and_prescan (pfile, fp, desc, len)
 
   if (op[-1] != '\n')
     {
-      long col;
+      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)
@@ -1094,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
@@ -1102,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;
This page took 0.041488 seconds and 5 git commands to generate.