OSDN Git Service

update
[pf3gnuchains/gcc-fork.git] / gcc / c-common.c
index d16bbc3..9983cdb 100644 (file)
@@ -26,6 +26,14 @@ Boston, MA 02111-1307, USA.  */
 #include "flags.h"
 #include "obstack.h"
 #include "toplev.h"
+#include "output.h"
+
+#if USE_CPPLIB
+#include "cpplib.h"
+cpp_reader  parse_in;
+cpp_options parse_options;
+static enum cpp_token cpp_token;
+#endif
 
 #ifndef WCHAR_TYPE_SIZE
 #ifdef INT_TYPE_SIZE
@@ -971,10 +979,10 @@ typedef struct {
   int pointer_count;
   /* Type of argument if no length modifier is used.  */
   tree *nolen;
-  /* Type of argument if length modifier for shortening is used.
+  /* Type of argument if length modifier for shortening to byte is used.
      If NULL, then this modifier is not allowed.  */
   tree *hhlen;
-  /* Type of argument if length modifier for shortening to byte if used.
+  /* Type of argument if length modifier for shortening is used.
      If NULL, then this modifier is not allowed.  */
   tree *hlen;
   /* Type of argument if length modifier `l' is used.
@@ -1235,7 +1243,6 @@ check_format_info (info, params)
   int length_char;
   int format_char;
   int format_length;
-  int integral_format;
   tree format_tree;
   tree cur_param;
   tree cur_type;
@@ -1549,6 +1556,13 @@ check_format_info (info, params)
              if (pedantic)
                warning ("ANSI C does not support the `ll' length modifier");
            }
+         else if (length_char == 'h' && *format_chars == 'h')
+           {
+             length_char = 'H', format_chars++;
+             /* FIXME: Is allowed in ISO C 9x.  */
+             if (pedantic)
+               warning ("ANSI C does not support the `hh' length modifier");
+           }
          if (*format_chars == 'a' && info->format_type == scanf_format_type)
            {
              if (format_chars[1] == 's' || format_chars[1] == 'S'
@@ -1681,15 +1695,6 @@ check_format_info (info, params)
        warning ("use of `%c' length character with `%c' type character",
                 length_char, format_char);
 
-      /*
-       ** XXX -- should kvetch about stuff such as
-       **      {
-       **              const int       i;
-       **
-       **              scanf ("%d", &i);
-       **      }
-       */
-
       /* Finally. . .check type of argument against desired type!  */
       if (info->first_arg_num == 0)
        continue;
@@ -1732,8 +1737,10 @@ check_format_info (info, params)
        }
 
       /* See if this is an attempt to write into a const type with
-        scanf.  */
-      if (info->format_type == scanf_format_type
+        scanf or with printf "%n".  */
+      if ((info->format_type == scanf_format_type
+          || (info->format_type == printf_format_type
+              && format_char == 'n'))
          && i == fci->pointer_count + aflag
          && wanted_type != 0
          && TREE_CODE (cur_type) != ERROR_MARK
@@ -2673,6 +2680,105 @@ truthvalue_conversion (expr)
   return build_binary_op (NE_EXPR, expr, integer_zero_node, 1);
 }
 \f
+#if USE_CPPLIB
+/* Read the rest of a #-directive from input stream FINPUT.
+   In normal use, the directive name and the white space after it
+   have already been read, so they won't be included in the result.
+   We allow for the fact that the directive line may contain
+   a newline embedded within a character or string literal which forms
+   a part of the directive.
+
+   The value is a string in a reusable buffer.  It remains valid
+   only until the next time this function is called.  */
+unsigned char *yy_cur, *yy_lim;
+
+#define GETC() (yy_cur < yy_lim ? *yy_cur++ : yy_get_token ())
+#define UNGETC(c) ((c), yy_cur--)
+
+int
+yy_get_token ()
+{
+  for (;;)
+    {
+      parse_in.limit = parse_in.token_buffer;
+      cpp_token = cpp_get_token (&parse_in);
+      if (cpp_token == CPP_EOF)
+       return -1;
+      yy_lim = CPP_PWRITTEN (&parse_in);
+      yy_cur = parse_in.token_buffer;
+      if (yy_cur < yy_lim)
+       return *yy_cur++;
+    }
+}
+
+char *
+get_directive_line ()
+{
+  static char *directive_buffer = NULL;
+  static unsigned buffer_length = 0;
+  register char *p;
+  register char *buffer_limit;
+  register int looking_for = 0;
+  register int char_escaped = 0;
+
+  if (buffer_length == 0)
+    {
+      directive_buffer = (char *)xmalloc (128);
+      buffer_length = 128;
+    }
+
+  buffer_limit = &directive_buffer[buffer_length];
+
+  for (p = directive_buffer; ; )
+    {
+      int c;
+
+      /* Make buffer bigger if it is full.  */
+      if (p >= buffer_limit)
+        {
+         register unsigned bytes_used = (p - directive_buffer);
+
+         buffer_length *= 2;
+         directive_buffer
+           = (char *)xrealloc (directive_buffer, buffer_length);
+         p = &directive_buffer[bytes_used];
+         buffer_limit = &directive_buffer[buffer_length];
+        }
+
+      c = GETC ();
+
+      /* Discard initial whitespace.  */
+      if ((c == ' ' || c == '\t') && p == directive_buffer)
+       continue;
+
+      /* Detect the end of the directive.  */
+      if (c == '\n' && looking_for == 0)
+       {
+          UNGETC (c);
+         c = '\0';
+       }
+
+      *p++ = c;
+
+      if (c == 0)
+       return directive_buffer;
+
+      /* Handle string and character constant syntax.  */
+      if (looking_for)
+       {
+         if (looking_for == c && !char_escaped)
+           looking_for = 0;    /* Found terminator... stop looking.  */
+       }
+      else
+        if (c == '\'' || c == '"')
+         looking_for = c;      /* Don't stop buffering until we see another
+                                  another one of these (or an EOF).  */
+
+      /* Handle backslash.  */
+      char_escaped = (c == '\\' && ! char_escaped);
+    }
+}
+#else
 /* Read the rest of a #-directive from input stream FINPUT.
    In normal use, the directive name and the white space after it
    have already been read, so they won't be included in the result.
@@ -2749,12 +2855,13 @@ get_directive_line (finput)
       else
         if (c == '\'' || c == '"')
          looking_for = c;      /* Don't stop buffering until we see another
-                                  another one of these (or an EOF).  */
+                                  one of these (or an EOF).  */
 
       /* Handle backslash.  */
       char_escaped = (c == '\\' && ! char_escaped);
     }
 }
+#endif /* !USE_CPPLIB */
 \f
 /* Make a variant type in the proper way for C/C++, propagating qualifiers
    down to the element type of an array.  */