]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
Bunch of fixes. See ChangeLog.
authorPer Bothner <bothner@gcc.gnu.org>
Sun, 30 Apr 1995 21:43:12 +0000 (14:43 -0700)
committerPer Bothner <bothner@gcc.gnu.org>
Sun, 30 Apr 1995 21:43:12 +0000 (14:43 -0700)
From-SVN: r9552

gcc/cpplib.c

index 19ec3f7801fcfac4e81414adda995406bde66b29..f25925ed788a62d1cae12993b91beec523ef9966 100644 (file)
@@ -70,7 +70,6 @@ Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
 #include <stdio.h>
 #include <signal.h>
 #ifdef __STDC__
-#include <string.h>
 #include <stdlib.h>
 #endif
 
@@ -903,6 +902,11 @@ file_cleanup (pbuf, pfile)
      cpp_buffer *pbuf;
      cpp_reader *pfile;
 {
+  if (pbuf->buf)
+    {
+      free (pbuf->buf);
+      pbuf->buf = 0;
+    }
   return 0;
 }
 
@@ -1035,6 +1039,9 @@ cpp_skip_hspace (pfile)
       else if (c == '\\' && PEEKN(1) == '\n') {
        FORWARD(2);
       }
+      else if (c == '@' && CPP_BUFFER (pfile)->has_escapes
+              && is_hor_space[PEEKN(1)])
+       FORWARD(2);
       else return;
     }
 }
@@ -1276,18 +1283,18 @@ struct arglist {
    MACRONAME is the macro name itself (so we can avoid recursive expansion)
    and NAMELEN is its length in characters.
    
-Note that comments and backslash-newlines have already been deleted
-from the argument.  */
+   Note that comments, backslash-newlines, and leading white space
+   have already been deleted from the argument.  */
 
 static DEFINITION *
-collect_expansion (pfile, buf, end, nargs, arglist)
+collect_expansion (pfile, buf, limit, nargs, arglist)
      cpp_reader *pfile;
-     U_CHAR *buf, *end;
+     U_CHAR *buf, *limit;
      int nargs;
      struct arglist *arglist;
 {
   DEFINITION *defn;
-  register U_CHAR *p, *limit, *lastp, *exp_p;
+  register U_CHAR *p, *lastp, *exp_p;
   struct reflist *endpat = NULL;
   /* Pointer to first nonspace after last ## seen.  */
   U_CHAR *concat = 0;
@@ -1301,24 +1308,24 @@ collect_expansion (pfile, buf, end, nargs, arglist)
      thru the arg list on every potential symbol.  Profiling might say
      that something smarter should happen. */
 
-  if (end < buf)
+  if (limit < buf)
     abort ();
 
   /* Find the beginning of the trailing whitespace.  */
-  /* Find end of leading whitespace.  */
-  limit = end;
   p = buf;
   while (p < limit && is_space[limit[-1]]) limit--;
-  while (p < limit && is_space[*p]) p++;
 
   /* Allocate space for the text in the macro definition.
      Leading and trailing whitespace chars need 2 bytes each.
      Each other input char may or may not need 1 byte,
-     so this is an upper bound.
-     The extra 2 are for invented trailing newline-marker and final null.  */
+     so this is an upper bound.  The extra 5 are for invented
+     leading and trailing newline-marker and final null.  */
   maxsize = (sizeof (DEFINITION)
-            + 2 * (end - limit) + 2 * (p - buf)
-            + (limit - p) + 3);
+            + (limit - p) + 5);
+  /* Occurrences of '@' get doubled, so allocate extra space for them. */
+  while (p < limit)
+    if (*p++ == '@')
+      maxsize++;
   defn = (DEFINITION *) xcalloc (1, maxsize);
 
   defn->nargs = nargs;
@@ -1327,7 +1334,9 @@ collect_expansion (pfile, buf, end, nargs, arglist)
 
   p = buf;
 
-  /* Add one initial space (often removed by macroexpand). */
+  /* Add one initial space escape-marker to prevent accidental
+     token-pasting (often removed by macroexpand). */
+  *exp_p++ = '@';
   *exp_p++ = ' ';
 
   if (limit - p >= 2 && p[0] == '#' && p[1] == '#') {
@@ -1353,16 +1362,8 @@ collect_expansion (pfile, buf, end, nargs, arglist)
           expected_delimiter = c;
        break;
 
-       /* Special hack: if a \# is written in the #define
-          include a # in the definition.  This is useless for C code
-          but useful for preprocessing other things.  */
-
       case '\\':
-       /* \# quotes a # even outside of strings.  */
-       if (p < limit && *p == '#' && !expected_delimiter) {
-         exp_p--;
-         *exp_p++ = *p++;
-       } else if (p < limit && expected_delimiter) {
+       if (p < limit && expected_delimiter) {
          /* In a string, backslash goes through
             and makes next char ordinary.  */
          *exp_p++ = *p++;
@@ -1523,16 +1524,14 @@ collect_expansion (pfile, buf, end, nargs, arglist)
     }
   }
 
-  if (limit < end) {
-    while (limit < end && is_space[*limit]) {
-      *exp_p++ = *limit++;
+  if (!CPP_TRADITIONAL (pfile) && expected_delimiter == 0)
+    {
+      /* If ANSI, put in a "@ " marker to prevent token pasting.
+         But not if "inside a string" (which in ANSI mode
+         happens only for -D option).  */
+      *exp_p++ = '@';
+      *exp_p++ = ' ';
     }
-  } else if (!CPP_TRADITIONAL (pfile) && expected_delimiter == 0) {
-    /* There is no trailing whitespace, so invent some in ANSI mode.
-       But not if "inside a string" (which in ANSI mode
-       happens only for -D option).  */
-    *exp_p++ = ' ';
-  }
 
   *exp_p = '\0';
 
@@ -1671,8 +1670,7 @@ create_definition (buf, limit, pfile, predefinition)
     }
 
     ++bp;                      /* skip paren */
-    /* Skip exactly one space or tab if any.  */
-    if (bp < limit && (*bp == ' ' || *bp == '\t')) ++bp;
+    SKIP_WHITE_SPACE (bp);
     /* now everything from bp before limit is the definition. */
     defn = collect_expansion (pfile, bp, limit, argno, arg_ptrs);
     defn->rest_args = rest_args;
@@ -1944,7 +1942,6 @@ struct argdata {
   int raw_length, expand_length;
   int stringified_length;
   char newlines;
-  char comments;
   char use_count;
 };
 
@@ -2016,20 +2013,15 @@ cpp_scan_buffer (pfile)
 }
 
 /*
- * Rescan a string into pfile's buffer.
+ * Rescan a string (which may have escape marks) into pfile's buffer.
  * Place the result in pfile->token_buffer.
  *
  * The input is copied before it is scanned, so it is safe to pass
  * it something from the token_buffer that will get overwritten
  * (because it follows CPP_WRITTEN).  This is used by do_include.
- *
- * OUTPUT_MARKS nonzero means keep Newline markers found in the input
- * and insert such markers when appropriate.  See `rescan' for details.
- * OUTPUT_MARKS is 1 for macroexpanding a macro argument separately
- * before substitution; it is 0 for other uses.
  */
 
-void
+static void
 cpp_expand_to_buffer (pfile, buf, length)
      cpp_reader *pfile;
      U_CHAR *buf;
@@ -2059,6 +2051,7 @@ cpp_expand_to_buffer (pfile, buf, length)
   buf1[length] = 0;
 
   ip = cpp_push_buffer (pfile, buf1, length);
+  ip->has_escapes = 1;
 #if 0
   ip->lineno = obuf.lineno = 1;
 #endif
@@ -2249,7 +2242,7 @@ output_line_command (pfile, conditional, file_change)
 }
 \f
 /*
- * Parse a macro argument and store the info on it into *ARGPTR.
+ * Parse a macro argument and append the info on PFILE's token_buffer.
  * REST_ARGS means to absorb the rest of the args.
  * Return nonzero to indicate a syntax error.
  */
@@ -2734,6 +2727,8 @@ macroexpand (pfile, hp)
     dump_single_macro (hp, pcp_outfile);
 #endif
 
+  pfile->output_escapes++;
+  
   nargs = defn->nargs;
 
   if (nargs >= 0)
@@ -2886,6 +2881,13 @@ macroexpand (pfile, hp)
                             one space except within an string or char token.*/
                          if (is_space[c])
                            {
+                             if (CPP_WRITTEN (pfile) > arg->stringified
+                                 && (CPP_PWRITTEN (pfile))[-1] == '@')
+                               {
+                                 /* "@ " escape markers are removed */
+                                 CPP_ADJUST_WRITTEN (pfile, -1);
+                                 continue;
+                               }
                              if (need_space == 0)
                                need_space = 1;
                              continue;
@@ -2941,12 +2943,10 @@ macroexpand (pfile, hp)
              if (args[ap->argno].expand_length < 0)
                {
                  args[ap->argno].expanded = CPP_WRITTEN (pfile);
-                 pfile->output_escapes++;
                  cpp_expand_to_buffer (pfile,
                                        ARG_BASE + args[ap->argno].raw,
                                        args[ap->argno].raw_length);
 
-                 pfile->output_escapes--;
                  args[ap->argno].expand_length
                    = CPP_WRITTEN (pfile) - args[ap->argno].expanded;
                }
@@ -3040,7 +3040,10 @@ macroexpand (pfile, hp)
              if (!ap->raw_before && totlen > 0 && arg->expand_length
                  && !CPP_TRADITIONAL(pfile)
                  && unsafe_chars (xbuf[totlen-1], expanded[0]))
-               xbuf[totlen++] = ' ';
+               {
+                 xbuf[totlen++] = '@';
+                 xbuf[totlen++] = ' ';
+               }
 
              bcopy (expanded, xbuf + totlen, arg->expand_length);
              totlen += arg->expand_length;
@@ -3048,7 +3051,10 @@ macroexpand (pfile, hp)
              if (!ap->raw_after && totlen > 0 && offset < defn->length
                  && !CPP_TRADITIONAL(pfile)
                  && unsafe_chars (xbuf[totlen-1], exp[offset]))
-               xbuf[totlen++] = ' ';
+               {
+                 xbuf[totlen++] = '@';
+                 xbuf[totlen++] = ' ';
+               }
 
              /* If a macro argument with newlines is used multiple times,
                 then only expand the newlines once.  This avoids creating
@@ -3086,6 +3092,8 @@ macroexpand (pfile, hp)
 
     }
 
+  pfile->output_escapes--;
+
   /* Now put the expansion on the input stack
      so our caller will commence reading from it.  */
   push_macro_expansion (pfile, xbuf, xbuf_len, hp);
@@ -3113,7 +3121,7 @@ push_macro_expansion (pfile, xbuf, xbuf_len, hp)
   mbuf->cleanup = macro_cleanup;
   mbuf->data = hp;
 
-  /* The first char of the expansion should be a ' ' added by
+  /* The first chars of the expansion should be a "@ " added by
      collect_expansion.  This is to prevent accidental token-pasting
      between the text preceding the macro invocation, and the macro
      expansion text.
@@ -3131,10 +3139,10 @@ push_macro_expansion (pfile, xbuf, xbuf_len, hp)
      Also, we don't need the extra space if the first char is '(',
      or some other (less common) characters.  */
 
-  if (xbuf[0] == ' '
-      && (is_idchar[xbuf[1]] || xbuf[1] == '(' || xbuf[1] == '\''
-         || xbuf[1] == '\"'))
-    mbuf->cur++;
+  if (xbuf[0] == '@' && xbuf[1] == ' '
+      && (is_idchar[xbuf[2]] || xbuf[2] == '(' || xbuf[2] == '\''
+         || xbuf[2] == '\"'))
+    mbuf->cur += 2;
 }
 \f
 /* Like cpp_get_token, except that it does not read past end-of-line.
@@ -3368,7 +3376,7 @@ do_include (pfile, keyword, unused1, unused2)
     if (importing)
       f = lookup_import (pfile, fname, NULL_PTR);
     else
-      f = open_include_file (fname, NULL_PTR);
+      f = open_include_file (pfile, fname, NULL_PTR);
     if (f == -2)
       return 0;                /* Already included this file */
   } else {
@@ -3413,7 +3421,7 @@ do_include (pfile, keyword, unused1, unused2)
       if (importing)
        f = lookup_import (pfile, fname, searchptr);
       else
-       f = open_include_file (fname, searchptr);
+       f = open_include_file (pfile, fname, searchptr);
       if (f == -2)
        return 0;                       /* Already included this file */
 #ifdef EACCES
@@ -3453,7 +3461,7 @@ do_include (pfile, keyword, unused1, unused2)
 
                      if (searchptr->fname[0] == 0)
                        continue;
-                     p = xmalloc (strlen (searchptr->fname)
+                     p = alloca (strlen (searchptr->fname)
                                   + strlen (fname) + 2);
                      strcpy (p, searchptr->fname);
                      strcat (p, "/");
@@ -3717,12 +3725,20 @@ static void
 delete_assertion (hp)
      ASSERTION_HASHNODE *hp;
 {
-
+  struct tokenlist_list *tail;
   if (hp->prev != NULL)
     hp->prev->next = hp->next;
   if (hp->next != NULL)
     hp->next->prev = hp->prev;
 
+  for (tail = hp->value; tail; )
+    {
+      struct tokenlist_list *next = tail->next;
+      free_token_list (tail->tokens);
+      free (tail);
+      tail = next;
+    }
+
   /* make sure that the bucket chain header that
      the deleted guy was on points to the right thing afterwards. */
   if (hp == *hp->bucket_hdr)
@@ -4748,8 +4764,8 @@ cpp_get_token (pfile)
              CPP_PUTC_Q (pfile, ' ');
              return CPP_HSPACE;
            }
-         if (opts->for_lint) {
 #if 0
+         if (opts->for_lint) {
            U_CHAR *argbp;
            int cmdlen, arglen;
            char *lintcmd = get_lintcmd (ibp, limit, &argbp, &arglen, &cmdlen);
@@ -4775,8 +4791,8 @@ cpp_get_token (pfile)
              *(obp++) = ' ';   /* just in case, if comments are copied thru */
              *(obp++) = '/';
            }
-#endif
          }
+#endif
 
        case '#':
 #if 0
@@ -5004,6 +5020,14 @@ cpp_get_token (pfile)
                  parse_name (pfile, GETC ());
                  return CPP_NAME;
                }
+             else if (is_space [c])
+               {
+                 CPP_RESERVE (pfile, 2);
+                 if (pfile->output_escapes)
+                   CPP_PUTC_Q (pfile, '@');
+                 CPP_PUTC_Q (pfile, c);
+                 return CPP_HSPACE;
+               }
            }
          if (pfile->output_escapes)
            {
@@ -5214,22 +5238,21 @@ cpp_get_token (pfile)
                CPP_SET_WRITTEN (pfile, before_name_written);
              }
 
-           /* An extra space is added to the end of a macro expansion
+           /* An extra "@ " is added to the end of a macro expansion
               to prevent accidental token pasting.  We prefer to avoid
               unneeded extra spaces (for the sake of cpp-using tools like
               imake).  Here we remove the space if it is safe to do so. */
-           if (pfile->buffer->rlimit - pfile->buffer->cur >= 2
+           if (pfile->buffer->rlimit - pfile->buffer->cur >= 3
+               && pfile->buffer->rlimit[-2] == '@'
                && pfile->buffer->rlimit[-1] == ' ')
              {
-               int c1 = pfile->buffer->rlimit[-2];
+               int c1 = pfile->buffer->rlimit[-3];
                int c2 = CPP_BUF_PEEK (CPP_PREV_BUFFER (CPP_BUFFER (pfile)));
                if (c2 == EOF || ! unsafe_chars (c1, c2))
-                 pfile->buffer->rlimit--;
+                 pfile->buffer->rlimit -= 2;
              }
-
-           goto get_next;
          }
-         return CPP_NAME;
+         goto get_next;
 
        case ' ':  case '\t':  case '\v':  case '\r':
          for (;;)
@@ -5342,7 +5365,7 @@ import_hash (f)
 
 static int
 lookup_import (pfile, filename, searchptr)
-cpp_reader *pfile;
+     cpp_reader *pfile;
      char *filename;
      struct file_name_list *searchptr;
 {
@@ -5363,7 +5386,7 @@ cpp_reader *pfile;
     i = i->next;
   }
   /* Open it and try a match on inode/dev */
-  fd = open_include_file (filename, searchptr);
+  fd = open_include_file (pfile, filename, searchptr);
   if (fd < 0)
     return fd;
   fstat (fd, &sb);
@@ -5455,26 +5478,26 @@ read_filename_string (ch, f)
   return alloc;
 }
 
+/* This structure holds a linked list of file name maps, one per directory. */
+struct file_name_map_list
+{
+  struct file_name_map_list *map_list_next;
+  char *map_list_name;
+  struct file_name_map *map_list_map;
+};
+
 /* Read the file name map file for DIRNAME.  */
 
 static struct file_name_map *
-read_name_map (dirname)
+read_name_map (pfile, dirname)
+     cpp_reader *pfile;
      char *dirname;
 {
-  /* This structure holds a linked list of file name maps, one per
-     directory.  */
-  struct file_name_map_list
-    {
-      struct file_name_map_list *map_list_next;
-      char *map_list_name;
-      struct file_name_map *map_list_map;
-    };
-  static struct file_name_map_list *map_list;
   register struct file_name_map_list *map_list_ptr;
   char *name;
   FILE *f;
 
-  for (map_list_ptr = map_list; map_list_ptr;
+  for (map_list_ptr = CPP_OPTIONS (pfile)->map_list; map_list_ptr;
        map_list_ptr = map_list_ptr->map_list_next)
     if (! strcmp (map_list_ptr->map_list_name, dirname))
       return map_list_ptr->map_list_map;
@@ -5535,8 +5558,8 @@ read_name_map (dirname)
       fclose (f);
     }
   
-  map_list_ptr->map_list_next = map_list;
-  map_list = map_list_ptr;
+  map_list_ptr->map_list_next = CPP_OPTIONS (pfile)->map_list;
+  CPP_OPTIONS (pfile)->map_list = map_list_ptr;
 
   return map_list_ptr->map_list_map;
 }  
@@ -5547,7 +5570,8 @@ read_name_map (dirname)
    read_name_map.  */
 
 static int
-open_include_file (filename, searchptr)
+open_include_file (pfile, filename, searchptr)
+     cpp_reader *pfile;
      char *filename;
      struct file_name_list *searchptr;
 {
@@ -5557,7 +5581,8 @@ open_include_file (filename, searchptr)
 
   if (searchptr && ! searchptr->got_name_map)
     {
-      searchptr->name_map = read_name_map (searchptr->fname
+      searchptr->name_map = read_name_map (pfile,
+                                          searchptr->fname
                                           ? searchptr->fname : ".");
       searchptr->got_name_map = 1;
     }
@@ -5606,7 +5631,7 @@ open_include_file (filename, searchptr)
       dir[p - filename] = '\0';
       from = p + 1;
     }
-  for (map = read_name_map (dir); map; map = map->map_next)
+  for (map = read_name_map (pfile, dir); map; map = map->map_next)
     if (! strcmp (map->map_from, from))
       return open (map->map_to, O_RDONLY, 0666);
 
@@ -6783,6 +6808,74 @@ cpp_finish (pfile)
        }
     }
 }
+
+/* Free resources used by PFILE. */
+
+void
+cpp_cleanup (pfile)
+     cpp_reader *pfile;
+{
+  int i;
+  while ( CPP_BUFFER (pfile) != CPP_NULL_BUFFER (pfile))
+    cpp_pop_buffer (pfile);
+
+  if (pfile->token_buffer)
+    {
+      free (pfile->token_buffer);
+      pfile->token_buffer = NULL;
+    }
+
+  if (pfile->deps_buffer)
+    {
+      free (pfile->deps_buffer);
+      pfile->deps_buffer = NULL;
+      pfile->deps_allocated_size = 0;
+    }
+
+  while (pfile->if_stack)
+    {
+      IF_STACK_FRAME *temp = pfile->if_stack;
+      pfile->if_stack = temp->next;
+      free (temp);
+    }
+
+  while (pfile->dont_repeat_files)
+    {
+      struct file_name_list *temp = pfile->dont_repeat_files;
+      pfile->dont_repeat_files = temp->next;
+      free (temp->fname);
+      free (temp);
+    }
+
+  while (pfile->all_include_files)
+    {
+      struct file_name_list *temp = pfile->all_include_files;
+      pfile->all_include_files = temp->next;
+      free (temp->fname);
+      free (temp);
+    }
+
+  for (i = IMPORT_HASH_SIZE; --i >= 0; )
+    {
+      register struct import_file *imp = pfile->import_hash_table[i];
+      while (imp)
+       {
+         struct import_file *next = imp->next;
+         free (imp->name);
+         free (imp);
+         imp = next;
+       }
+      pfile->import_hash_table[i] = 0;
+    }
+
+  for (i = ASSERTION_HASHSIZE; --i >= 0; )
+    {
+      while (pfile->assertion_hashtab[i])
+       delete_assertion (pfile->assertion_hashtab[i]);
+    }
+
+  cpp_hash_cleanup (pfile);
+}
 \f
 static int
 do_assert (pfile, keyword, buf, limit)
@@ -6914,15 +7007,9 @@ do_unassert (pfile, keyword, buf, limit)
 
     /* If no token list was specified, then eliminate this assertion
        entirely.  */
-    if (! tokens_specified) {
-      struct tokenlist_list *next;
-      for (tail = hp->value; tail; tail = next) {
-       next = tail->next;
-       free_token_list (tail->tokens);
-       free (tail);
-      }
+    if (! tokens_specified)
       delete_assertion (hp);
-    else {
+    else {
       /* If a list of tokens was given, then delete any matching list.  */
 
       tail = hp->value;
@@ -7528,4 +7615,6 @@ cpp_perror_with_name (pfile, name)
  * Support for trigraphs.
  *
  * Support -dM flag (dump_all_macros).
+ *
+ * Support for_lint flag.
  */