OSDN Git Service

1998-11-26 01:17 -0500 Zack Weinberg <zack@rabi.phys.columbia.edu>
authorbrolley <brolley@138bc75d-0d04-0410-961f-82ee72b054a4>
Mon, 7 Dec 1998 13:35:20 +0000 (13:35 +0000)
committerbrolley <brolley@138bc75d-0d04-0410-961f-82ee72b054a4>
Mon, 7 Dec 1998 13:35:20 +0000 (13:35 +0000)
* cpplib.h (struct cpp_buffer): Replace dir and dlen members
with a struct file_name_list pointer.
(struct cpp_reader): Add pointer to chain of `actual
directory' include searchpath entries.
(struct file_name_list): Add *alloc pointer for the sake of
the actual-directory chain.
Move definition of HOST_WIDE_INT here.
(cpp_parse_escape): Change prototype to match changes in
cppexp.c.
* cppfiles.c (actual_directory): New function.
(finclude): Use it to initialize the buffer's actual_dir
entry.
(find_include_file): We don't need to fix up max_include_len
here.
* cpplib.c (do_include): Don't allocate a file_name_list on
the fly for current directory "" includes, use the one that's
been preallocated in pfile->buffer->actual_dir.  Hoist out
duplicate code from the search_start selection logic.
(cpp_reader_init): Initialize pfile->actual_dirs.
Remove definition of HOST_WIDE_INT.  Change calls
to cpp_parse_escape to match changes in cppexp.c (note
hardcoded MASK, which is safe since this is the source
character set).
* cppexp.c: Bring over changes to cpp_parse_escape from cccp.c
to handle wide character constants in #if directives.  The
function now returns a HOST_WIDE_INT, and takes a third
argument which is a binary mask for all legal values (0x00ff
for 8-bit `char', 0xffff for 16-bit `wchar_t', etc.)  Define
MAX_CHAR_TYPE_MASK and MAX_WCHAR_TYPE_MASK.  Change callers of
cpp_parse_escape to match.  [Fixes c-torture/execute/widechar-1.c]

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@24153 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/cppexp.c
gcc/cppfiles.c
gcc/cpplib.c
gcc/cpplib.h

index 84a79ba..f2f0aaf 100644 (file)
@@ -1,3 +1,41 @@
+1998-11-26 01:17 -0500  Zack Weinberg  <zack@rabi.phys.columbia.edu>
+
+       * cpplib.h (struct cpp_buffer): Replace dir and dlen members
+       with a struct file_name_list pointer.
+       (struct cpp_reader): Add pointer to chain of `actual
+       directory' include searchpath entries.
+       (struct file_name_list): Add *alloc pointer for the sake of
+       the actual-directory chain.
+
+       Move definition of HOST_WIDE_INT here.
+       (cpp_parse_escape): Change prototype to match changes in
+       cppexp.c.
+
+       * cppfiles.c (actual_directory): New function.
+       (finclude): Use it to initialize the buffer's actual_dir
+       entry.
+       (find_include_file): We don't need to fix up max_include_len
+       here.
+
+       * cpplib.c (do_include): Don't allocate a file_name_list on
+       the fly for current directory "" includes, use the one that's
+       been preallocated in pfile->buffer->actual_dir.  Hoist out
+       duplicate code from the search_start selection logic.
+       (cpp_reader_init): Initialize pfile->actual_dirs.
+
+       Remove definition of HOST_WIDE_INT.  Change calls
+       to cpp_parse_escape to match changes in cppexp.c (note
+       hardcoded MASK, which is safe since this is the source
+       character set).
+
+       * cppexp.c: Bring over changes to cpp_parse_escape from cccp.c
+       to handle wide character constants in #if directives.  The
+       function now returns a HOST_WIDE_INT, and takes a third
+       argument which is a binary mask for all legal values (0x00ff
+       for 8-bit `char', 0xffff for 16-bit `wchar_t', etc.)  Define
+       MAX_CHAR_TYPE_MASK and MAX_WCHAR_TYPE_MASK.  Change callers of
+       cpp_parse_escape to match.  [Fixes c-torture/execute/widechar-1.c]
+
 Mon Dec  7 15:38:25 1998  Dave Brolley  <brolley@cygnus.com>
 
        * gcc.c (default_compilers): Fix typo in USE_CPPLIB spec for cc1.
index 419e5bd..87b84a6 100644 (file)
@@ -72,6 +72,14 @@ struct arglist {
 #define MAX_WCHAR_TYPE_SIZE WCHAR_TYPE_SIZE
 #endif
 
+#define MAX_CHAR_TYPE_MASK (MAX_CHAR_TYPE_SIZE < HOST_BITS_PER_WIDE_INT \
+                           ? (~ (~ (HOST_WIDE_INT) 0 << MAX_CHAR_TYPE_SIZE)) \
+                           : ~ (HOST_WIDE_INT) 0)
+
+#define MAX_WCHAR_TYPE_MASK (MAX_WCHAR_TYPE_SIZE < HOST_BITS_PER_WIDE_INT \
+                            ? ~ (~ (HOST_WIDE_INT) 0 << MAX_WCHAR_TYPE_SIZE) \
+                            : ~ (HOST_WIDE_INT) 0)
+
 /* Yield nonzero if adding two numbers with A's and B's signs can yield a
    number with SUM's sign, where A, B, and SUM are all C integers.  */
 #define possible_sum_sign(a, b, sum) ((((a) ^ (b)) | ~ ((a) ^ (sum))) < 0)
@@ -101,28 +109,6 @@ static long right_shift PARAMS ((cpp_reader *, long, int, unsigned long));
 #define SKIP_OPERAND 8
 /*#define UNSIGNEDP 16*/
 
-/* Find the largest host integer type and set its size and type.
-   Watch out: on some crazy hosts `long' is shorter than `int'.  */
-
-#ifndef HOST_WIDE_INT
-# if HAVE_INTTYPES_H
-#  include <inttypes.h>
-#  define HOST_WIDE_INT intmax_t
-# else
-#  if (HOST_BITS_PER_LONG <= HOST_BITS_PER_INT \
-       && HOST_BITS_PER_LONGLONG <= HOST_BITS_PER_INT)
-#   define HOST_WIDE_INT int
-#  else
-#  if (HOST_BITS_PER_LONGLONG <= HOST_BITS_PER_LONG \
-       || ! (defined LONG_LONG_MAX || defined LLONG_MAX))
-#   define HOST_WIDE_INT long
-#  else
-#   define HOST_WIDE_INT long long
-#  endif
-#  endif
-# endif
-#endif
-
 #ifndef CHAR_BIT
 #define CHAR_BIT 8
 #endif
@@ -275,7 +261,7 @@ cpp_lex (pfile, skip_evaluation)
      cpp_reader *pfile;
      int skip_evaluation;
 {
-  register int c;
+  register HOST_WIDE_INT c;
   register struct token *toktab;
   enum cpp_token token;
   struct operation op;
@@ -359,7 +345,9 @@ cpp_lex (pfile, skip_evaluation)
          {
            if (c == '\\')
              {
-               c = cpp_parse_escape (pfile, (char **) &ptr);
+               c = cpp_parse_escape (pfile, (char **) &ptr,
+                                     wide_flag ? MAX_WCHAR_TYPE_MASK
+                                               : MAX_CHAR_TYPE_MASK);
                if (width < HOST_BITS_PER_INT
                  && (unsigned) c >= (unsigned)(1 << width))
                    cpp_pedwarn (pfile,
@@ -480,10 +468,11 @@ cpp_lex (pfile, skip_evaluation)
    If \ is followed by 000, we return 0 and leave the string pointer
    after the zeros.  A value of 0 does not mean end of string.  */
 
-int
-cpp_parse_escape (pfile, string_ptr)
+HOST_WIDE_INT
+cpp_parse_escape (pfile, string_ptr, result_mask)
      cpp_reader *pfile;
      char **string_ptr;
+     HOST_WIDE_INT result_mask;
 {
   register int c = *(*string_ptr)++;
   switch (c)
@@ -494,7 +483,7 @@ cpp_parse_escape (pfile, string_ptr)
       return TARGET_BS;
     case 'e':
     case 'E':
-      if (CPP_PEDANTIC (pfile))
+      if (CPP_OPTIONS (pfile)->pedantic)
        cpp_pedwarn (pfile, "non-ANSI-standard escape sequence, `\\%c'", c);
       return 033;
     case 'f':
@@ -522,7 +511,7 @@ cpp_parse_escape (pfile, string_ptr)
     case '6':
     case '7':
       {
-       register int i = c - '0';
+       register HOST_WIDE_INT i = c - '0';
        register int count = 0;
        while (++count < 3)
          {
@@ -535,17 +524,17 @@ cpp_parse_escape (pfile, string_ptr)
                break;
              }
          }
-       if ((i & ~((1 << MAX_CHAR_TYPE_SIZE) - 1)) != 0)
+       if (i != (i & result_mask))
          {
-           i &= (1 << MAX_CHAR_TYPE_SIZE) - 1;
-           cpp_pedwarn (pfile,
-                         "octal character constant does not fit in a byte");
+           i &= result_mask;
+           cpp_pedwarn (pfile, "octal escape sequence out of range");
          }
        return i;
       }
     case 'x':
       {
-       register unsigned i = 0, overflow = 0, digits_found = 0, digit;
+       register unsigned HOST_WIDE_INT i = 0, overflow = 0;
+       register int digits_found = 0, digit;
        for (;;)
          {
            c = *(*string_ptr)++;
@@ -566,11 +555,10 @@ cpp_parse_escape (pfile, string_ptr)
          }
        if (!digits_found)
          cpp_error (pfile, "\\x used with no following hex digits");
-       if (overflow | (i & ~((1 << BITS_PER_UNIT) - 1)))
+       if (overflow | (i != (i & result_mask)))
          {
-           i &= (1 << BITS_PER_UNIT) - 1;
-           cpp_pedwarn (pfile,
-                        "hex character constant does not fit in a byte");
+           i &= result_mask;
+           cpp_pedwarn (pfile, "hex escape sequence out of range");
          }
        return i;
       }
index 8a4a0ef..8c01cdd 100644 (file)
@@ -42,6 +42,7 @@ static char *remap_filename           PROTO ((cpp_reader *, char *,
                                                struct file_name_list *));
 static long safe_read                  PROTO ((int, char *, int));
 static void simplify_pathname          PROTO ((char *));
+static struct file_name_list *actual_directory PROTO ((cpp_reader *, char *));
 
 #if 0
 static void hack_vms_include_specification PROTO ((char *));
@@ -422,11 +423,6 @@ find_include_file (pfile, fname, search_start, ihash, before)
 
   /* Search directory path, trying to open the file. */
 
-  /* The first entry in the search list may be a buffer-specific entry,
-     and its directory name may be longer than max_include_len.  Adjust
-     as appropriate. */
- if (pfile->max_include_len < search_start->nlen)
-    pfile->max_include_len = search_start->nlen;
   len = strlen (fname);
   name = xmalloc (len + pfile->max_include_len + 2 + INCLUDE_LEN_FUDGE);
 
@@ -690,34 +686,11 @@ finclude (pfile, fd, ihash)
   fp->colno = 1;
   fp->cleanup = file_cleanup;
 
-  /* The ->dir field is only used when ignore_srcdir is not in effect;
+  /* The ->actual_dir field is only used when ignore_srcdir is not in effect;
      see do_include */
   if (!CPP_OPTIONS (pfile)->ignore_srcdir)
-    {
-      char *last_slash;
-      fp->dir = savestring (fp->fname);
-      last_slash = rindex (fp->dir, '/');
-      if (last_slash)
-        {
-         if (last_slash == fp->dir)
-           {
-             fp->dlen = 1;
-             last_slash[1] = '\0';
-           }
-         else
-           {
-             fp->dlen = last_slash - fp->dir;
-             *last_slash = '\0';
-           }
-       }
-      else
-        {
-         fp->dir[0] = '.';
-         fp->dir[1] = '\0';
-         fp->dlen = 1;
-       }
-    }
-
+    fp->actual_dir = actual_directory (pfile, fp->fname);
+       
   if (S_ISREG (st.st_mode))
     {
       st_size = (size_t) st.st_size;
@@ -790,6 +763,60 @@ finclude (pfile, fd, ihash)
   return 0;
 }
 
+static struct file_name_list *
+actual_directory (pfile, fname)
+     cpp_reader *pfile;
+     char *fname;
+{
+  char *last_slash, *dir;
+  size_t dlen;
+  struct file_name_list *x;
+  
+  dir = savestring (fname);
+  last_slash = rindex (dir, '/');
+  if (last_slash)
+    {
+      if (last_slash == dir)
+        {
+         dlen = 1;
+         last_slash[1] = '\0';
+       }
+      else
+       {
+         dlen = last_slash - dir;
+         *last_slash = '\0';
+       }
+    }
+  else
+    {
+      dir[0] = '.';
+      dir[1] = '\0';
+      dlen = 1;
+    }
+
+  if (dlen > pfile->max_include_len)
+    pfile->max_include_len = dlen;
+
+  for (x = pfile->actual_dirs; x; x = x->alloc)
+    if (!strcmp (x->name, dir))
+      {
+       free (dir);
+       return x;
+      }
+
+  /* Not found, make a new one. */
+  x = (struct file_name_list *) xmalloc (sizeof (struct file_name_list));
+  x->name = dir;
+  x->nlen = dlen;
+  x->next = CPP_OPTIONS (pfile)->quote_include;
+  x->alloc = pfile->actual_dirs;
+  x->sysp = 0;
+  x->name_map = NULL;
+
+  pfile->actual_dirs = x;
+  return x;
+}
+
 /* Read LEN bytes at PTR from descriptor DESC, for file FILENAME,
    retrying if necessary.  If MAX_READ_LEN is defined, read at most
    that bytes at a time.  Return a negative value if an error occurs,
index a9bb550..dbdf2f4 100644 (file)
@@ -50,27 +50,6 @@ extern char *update_path PARAMS ((char *, char *));
 #define MIN(X,Y) ((X) < (Y) ? (X) : (Y))
 #define MAX(X,Y) ((X) > (Y) ? (X) : (Y))
 
-/* Find the largest host integer type and set its size and type.
-   Watch out: on some crazy hosts `long' is shorter than `int'.  */
-
-#ifndef HOST_WIDE_INT
-# if HAVE_INTTYPES_H
-#  include <inttypes.h>
-#  define HOST_WIDE_INT intmax_t
-# else
-#  if (HOST_BITS_PER_LONG <= HOST_BITS_PER_INT \
-       && HOST_BITS_PER_LONGLONG <= HOST_BITS_PER_INT)
-#   define HOST_WIDE_INT int
-#  else
-#  if (HOST_BITS_PER_LONGLONG <= HOST_BITS_PER_LONG \
-       || ! (defined LONG_LONG_MAX || defined LLONG_MAX))
-#   define HOST_WIDE_INT long
-#  else
-#   define HOST_WIDE_INT long long
-#  endif
-#  endif
-# endif
-#endif
 
 /* By default, colon separates directories in a path.  */
 #ifndef PATH_SEPARATOR
@@ -2932,7 +2911,7 @@ do_include (pfile, keyword, unused1, unused2)
   int before;  /* included before? */
   long flen;
   char *fbeg, *fend;
-  struct file_name_list *srcdir = 0;  /* for "" includes */
+  cpp_buffer *fp;
 
   enum cpp_token token;
 
@@ -3015,48 +2994,39 @@ do_include (pfile, keyword, unused1, unused2)
       cpp_error (pfile, "empty file name in `#%s'", keyword->name);
       return 0;
     }
+
+  search_start = 0;
+
+  for (fp = CPP_BUFFER (pfile);
+       fp != CPP_NULL_BUFFER (pfile);
+       fp = CPP_PREV_BUFFER (fp))
+    if (fp->fname != NULL)
+      break;
+
+  if (fp == CPP_NULL_BUFFER (pfile))
+    fp = NULL;
   
   /* For #include_next, skip in the search path
      past the dir in which the containing file was found.  */
   if (skip_dirs)
     {
-      cpp_buffer *fp = CPP_BUFFER (pfile);
-      for (; fp != CPP_NULL_BUFFER (pfile); fp = CPP_PREV_BUFFER (fp))
-       if (fp->fname != NULL)
-         {
-           /* Don't skip anything if the containing file was found
-              by an absolute path. */
-           if (fp->ihash->foundhere == ABSOLUTE_PATH)
-             search_start = angle_brackets
-                 ? CPP_OPTIONS (pfile)->bracket_include
-                 : CPP_OPTIONS (pfile)->quote_include;
-           else
-             search_start = fp->ihash->foundhere->next;
-           break;
-         }
+      if (fp)
+       search_start = fp->ihash->foundhere->next;
     }
   else
-    search_start = angle_brackets
-       ? CPP_OPTIONS (pfile)->bracket_include
-       : CPP_OPTIONS (pfile)->quote_include;
-
-  /* For "" includes when ignore_srcdir is off, tack the actual directory
-     of the current file onto the beginning of the search path.
-     The block must be permanently allocated since it may wind up
-     in the include hash. */
-  if (!angle_brackets 
-      && search_start == CPP_OPTIONS (pfile)->quote_include
-      && !CPP_OPTIONS (pfile)->ignore_srcdir)
     {
-      srcdir = (struct file_name_list *)
-         xmalloc (sizeof (struct file_name_list));
-      srcdir->next = CPP_OPTIONS (pfile)->quote_include;
-      srcdir->name = CPP_BUFFER (pfile)->dir;
-      srcdir->nlen = CPP_BUFFER (pfile)->dlen;
-      srcdir->sysp = 0;
-      srcdir->name_map = NULL;
-
-      search_start = srcdir;
+      if (angle_brackets)
+       search_start = CPP_OPTIONS (pfile)->bracket_include;
+      else
+        {
+         if (!CPP_OPTIONS (pfile)->ignore_srcdir)
+           {
+             if (fp)
+               search_start = fp->actual_dir;
+           }
+         else
+           search_start = CPP_OPTIONS (pfile)->quote_include;
+       }
     }
 
   if (!search_start)
@@ -3067,10 +3037,6 @@ do_include (pfile, keyword, unused1, unused2)
 
   fd = find_include_file (pfile, fbeg, search_start, &ihash, &before);
 
-  if (srcdir
-      && (ihash == (struct include_hash *)-1 || srcdir != ihash->foundhere))
-    free (srcdir);
-  
   if (fd == -2)
     return 0;
   
@@ -3128,8 +3094,8 @@ do_include (pfile, keyword, unused1, unused2)
   /* Handle -H option.  */
   if (CPP_OPTIONS(pfile)->print_include_names)
     {
-      cpp_buffer *buf = CPP_BUFFER (pfile);
-      while ((buf = CPP_PREV_BUFFER (buf)) != CPP_NULL_BUFFER (pfile))
+      fp = CPP_BUFFER (pfile);
+      while ((fp = CPP_PREV_BUFFER (fp)) != CPP_NULL_BUFFER (pfile))
        putc ('.', stderr);
       fprintf (stderr, " %s\n", ihash->name);
     }
@@ -3282,7 +3248,7 @@ convert_string (pfile, result, in, limit, handle_escapes)
          if (handle_escapes)
            {
              char *bpc = (char *) in;
-             int i = (U_CHAR) cpp_parse_escape (pfile, &bpc);
+             int i = (U_CHAR) cpp_parse_escape (pfile, &bpc, 0x00ffU);
              in = (U_CHAR *) bpc;
              if (i >= 0)
                *result++ = (U_CHAR)c;
@@ -5380,6 +5346,7 @@ cpp_reader_init (pfile)
   pfile->timebuf = NULL;
   pfile->only_seen_white = 1;
   pfile->buffer = CPP_NULL_BUFFER(pfile);
+  pfile->actual_dirs = NULL;
 }
 
 static struct cpp_pending *
index fe28102..3cb2753 100644 (file)
@@ -110,8 +110,7 @@ struct cpp_buffer {
   /* Filename specified with #line command.  */
   char *nominal_fname;
   /* Actual directory of this file, used only for "" includes */
-  char *dir;
-  size_t dlen;
+  struct file_name_list *actual_dir;
 
   /* Pointer into the include hash table.  Used for include_next and
      to record control macros.
@@ -182,6 +181,10 @@ struct cpp_reader {
 #define ALL_INCLUDE_HASHSIZE 71
   struct include_hash *all_include_files[ALL_INCLUDE_HASHSIZE];
 
+  /* Chain of `actual directory' file_name_list entries,
+     for "" inclusion. */
+  struct file_name_list *actual_dirs;
+
   /* Current maximum length of directory names in the search path
      for include files.  (Altered as we get more of them.)  */
   unsigned int max_include_len;
@@ -485,6 +488,8 @@ struct cpp_options {
 struct file_name_list
 {
   struct file_name_list *next;
+  struct file_name_list *alloc; /* for the cache of
+                                  current directory entries */
   char *name;
   unsigned int nlen;
   /* We use these to tell if the directory mentioned here is a duplicate
@@ -656,6 +661,28 @@ struct if_stack {
 };
 typedef struct if_stack IF_STACK_FRAME;
 
+/* Find the largest host integer type and set its size and type.
+   Watch out: on some crazy hosts `long' is shorter than `int'.  */
+
+#ifndef HOST_WIDE_INT
+# if HAVE_INTTYPES_H
+#  include <inttypes.h>
+#  define HOST_WIDE_INT intmax_t
+# else
+#  if (HOST_BITS_PER_LONG <= HOST_BITS_PER_INT \
+       && HOST_BITS_PER_LONGLONG <= HOST_BITS_PER_INT)
+#   define HOST_WIDE_INT int
+#  else
+#  if (HOST_BITS_PER_LONGLONG <= HOST_BITS_PER_LONG \
+       || ! (defined LONG_LONG_MAX || defined LLONG_MAX))
+#   define HOST_WIDE_INT long
+#  else
+#   define HOST_WIDE_INT long long
+#  endif
+#  endif
+# endif
+#endif
+
 extern void cpp_buf_line_and_col PARAMS((cpp_buffer *, long *, long *));
 extern cpp_buffer* cpp_file_buffer PARAMS((cpp_reader *));
 extern void cpp_define PARAMS ((cpp_reader*, unsigned char *));
@@ -678,7 +705,7 @@ extern void cpp_perror_with_name PROTO ((cpp_reader *, const char *));
 extern void v_cpp_message PROTO ((cpp_reader *, int, const char *, va_list));
 
 extern void cpp_grow_buffer PARAMS ((cpp_reader *, long));
-extern int cpp_parse_escape PARAMS ((cpp_reader *, char **));
+extern HOST_WIDE_INT cpp_parse_escape PARAMS ((cpp_reader *, char **, HOST_WIDE_INT));
 extern cpp_buffer *cpp_push_buffer PARAMS ((cpp_reader *,
                                            unsigned char *, long));
 extern cpp_buffer *cpp_pop_buffer PARAMS ((cpp_reader *));