OSDN Git Service

* cppexp.c (parse_charconst): Null does not end character
authorneil <neil@138bc75d-0d04-0410-961f-82ee72b054a4>
Sat, 8 Apr 2000 04:00:02 +0000 (04:00 +0000)
committerneil <neil@138bc75d-0d04-0410-961f-82ee72b054a4>
Sat, 8 Apr 2000 04:00:02 +0000 (04:00 +0000)
constants.
* cppinit.c (ISTABLE): Null character handled as whitespace.
* cpplex.c (null_warning):  new function.
(skip_string): Emit warning if nulls encountered.
(_cpp_skip_hspace): Emit warning if nulls encountered.
(_cpp_lex_token): Emit warning if nulls encountered.  Drop
them.
* cpp.texi: Update.

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

gcc/ChangeLog
gcc/cpp.texi
gcc/cppexp.c
gcc/cppinit.c
gcc/cpplex.c

index f99fa3c..c3c5b54 100644 (file)
@@ -1,3 +1,15 @@
+2000-04-08  Neil Booth  <NeilB@earthling.net>
+
+       * cppexp.c (parse_charconst): Null does not end character
+       constants.
+       * cppinit.c (ISTABLE): Null character handled as whitespace.
+       * cpplex.c (null_warning):  new function.
+       (skip_string): Emit warning if nulls encountered.
+       (_cpp_skip_hspace): Emit warning if nulls encountered.
+       (_cpp_lex_token): Emit warning if nulls encountered.  Drop
+       them.
+       * cpp.texi: Update.
+
 2000-04-07  Richard Henderson  <rth@cygnus.com>
 
        * flow.c (loop_depth): Remove.
index 0d2b2ee..e0442a1 100644 (file)
@@ -138,6 +138,7 @@ and this may cause problems with other languages.
 
 @node Global Actions, Directives, Top, Top
 @section Transformations Made Globally
+@cindex ASCII NUL handling
 
 Most C preprocessor features are inactive unless you give specific directives
 to request their use.  (Preprocessing directives are lines starting with
@@ -214,6 +215,43 @@ This exception is relevant only if you use the @samp{-trigraphs}
 option to enable trigraph processing.  @xref{Invocation}.
 @end itemize
 
+The preprocessor handles null characters embedded in the input file
+depending upon the context in which the null appears.  Note that here we
+are referring not to the two-character escape sequence "\0", but to the
+single character ASCII NUL.
+
+There are three different contexts in which a null character may
+appear:-
+
+@itemize @bullet
+@item
+Within comments.  Here, null characters are silently ignored.
+
+@item
+Within a string or character constant.  Here the preprocessor emits a
+warning, but preserves the null character and passes it through to the
+output file.
+
+@item
+In any other context, the preprocessor issues a warning, and discards
+the null character.  In all other respects the preprocessor treats it
+like whitespace, combining it with any surrounding whitespace to become
+a single whitespace token.  Representing the null character by "^@@",
+this means that code like
+
+@example
+#define X^@@1
+@end example
+
+is equivalent to
+
+@example
+#define X 1
+@end example
+
+and X is defined with replacement text "1".
+@end itemize
+
 @node Directives, Header Files, Global Actions, Top
 @section Preprocessing Directives
 
index 50a1351..3179099 100644 (file)
@@ -274,7 +274,7 @@ parse_charconst (pfile, start, end)
   while (ptr < end)
     {
       c = *ptr++;
-      if (c == '\'' || c == '\0')
+      if (c == '\'')
        break;
       else if (c == '\\')
        {
index 62da1f3..f4391ff 100644 (file)
@@ -265,7 +265,7 @@ ISTABLE
 
   N('1') N('2') N('3') N('4') N('5') N('6') N('7') N('8') N('9') N('0')
 
-  H(' ') H('\t') H('\v') H('\f')
+  H('\0') H(' ') H('\t') H('\v') H('\f')
 
   S('\n')
 END
index 2e79120..b8a1b07 100644 (file)
@@ -45,6 +45,7 @@ static void skip_string               PARAMS ((cpp_reader *, int));
 static void parse_string       PARAMS ((cpp_reader *, int));
 static U_CHAR *find_position   PARAMS ((U_CHAR *, U_CHAR *, unsigned long *));
 static int null_cleanup                PARAMS ((cpp_buffer *, cpp_reader *));
+static void null_warning        PARAMS ((cpp_reader *, unsigned int));
 
 /* Re-allocates PFILE->token_buffer so it will hold at least N more chars.  */
 
@@ -381,23 +382,38 @@ copy_comment (pfile, m)
   return ' ';
 }
 
+static void
+null_warning (pfile, count)
+     cpp_reader *pfile;
+     unsigned int count;
+{
+  if (count == 1)
+    cpp_warning (pfile, "embedded null character ignored");
+  else
+    cpp_warning (pfile, "embedded null characters ignored");
+}
+
 /* Skip whitespace \-newline and comments.  Does not macro-expand.  */
 
 void
 _cpp_skip_hspace (pfile)
      cpp_reader *pfile;
 {
+  unsigned int null_count = 0;
   int c;
+
   while (1)
     {
       c = GETC();
       if (c == EOF)
-       return;
+       goto out;
       else if (is_hspace(c))
        {
          if ((c == '\f' || c == '\v') && CPP_PEDANTIC (pfile))
            cpp_pedwarn (pfile, "%s in preprocessing directive",
                         c == '\f' ? "formfeed" : "vertical tab");
+         else if (c == '\0')
+           null_count++;
        }
       else if (c == '\r')
        {
@@ -423,6 +439,9 @@ _cpp_skip_hspace (pfile)
        break;
     }
   FORWARD(-1);
+ out:
+  if (null_count)
+    null_warning (pfile, null_count);
 }
 
 /* Read and discard the rest of the current line.  */
@@ -505,8 +524,9 @@ skip_string (pfile, c)
      int c;
 {
   long start_line, start_column;
-  cpp_buf_line_and_col (cpp_file_buffer (pfile), &start_line, &start_column);
+  unsigned int null_count = 0;
 
+  cpp_buf_line_and_col (cpp_file_buffer (pfile), &start_line, &start_column);
   while (1)
     {
       int cc = GETC();
@@ -521,8 +541,12 @@ skip_string (pfile, c)
                                 pfile->multiline_string_line, -1,
                         "possible real start of unterminated constant");
          pfile->multiline_string_line = 0;
-         return;
+         goto out;
 
+       case '\0':
+         null_count++;
+         break;
+         
        case '\n':
          CPP_BUMP_LINE (pfile);
          /* In Fortran and assembly language, silently terminate
@@ -533,7 +557,7 @@ skip_string (pfile, c)
              || CPP_OPTION (pfile, lang_asm))
            {
              FORWARD(-1);
-             return;
+             goto out;
            }
          /* Character constants may not extend over multiple lines.
             In Standard C, neither may strings.  We accept multiline
@@ -543,7 +567,7 @@ skip_string (pfile, c)
              cpp_error_with_line (pfile, start_line, start_column,
                                   "unterminated character constant");
              FORWARD(-1);
-             return;
+             goto out;
            }
          if (CPP_PEDANTIC (pfile) && pfile->multiline_string_line == 0)
            cpp_pedwarn_with_line (pfile, start_line, start_column,
@@ -570,10 +594,16 @@ skip_string (pfile, c)
        case '\"':
        case '\'':
          if (cc == c)
-           return;
+           goto out;
          break;
        }
     }
+
+ out:
+  if (null_count == 1)
+    cpp_warning (pfile, "null character in string or character constant");
+  else if (null_count > 1)
+    cpp_warning (pfile, "null characters in string or character constant");
 }
 
 /* Parse a string and copy it to the output.  */
@@ -976,16 +1006,25 @@ _cpp_lex_token (pfile)
     _cpp_parse_name (pfile, c);
     return CPP_MACRO;
 
-    case ' ': case '\t': case '\v': case '\f':
-      for (;;)
-       {
-         CPP_PUTC (pfile, c);
-         c = PEEKC ();
-         if (c == EOF || !is_hspace(c))
-           break;
-         FORWARD(1);
-       }
-      return CPP_HSPACE;
+    case ' ':  case '\t':  case '\v': case '\f': case '\0':
+      {
+       int null_count = 0;
+
+       for (;;)
+         {
+           if (c == '\0')
+             null_count++;
+           else
+             CPP_PUTC (pfile, c);
+           c = PEEKC ();
+           if (c == EOF || !is_hspace(c))
+             break;
+           FORWARD(1);
+         }
+       if (null_count)
+         null_warning (pfile, null_count);
+       return CPP_HSPACE;
+      }
 
     case '\r':
       if (CPP_BUFFER (pfile)->has_escapes)