Commit 64aaf407 by Neil Booth Committed by Neil Booth

cppexp.c (parse_charconst): Null does not end character constants.

	* 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.

From-SVN: r33013
parent 62828c00
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.
......
......@@ -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
......
......@@ -274,7 +274,7 @@ parse_charconst (pfile, start, end)
while (ptr < end)
{
c = *ptr++;
if (c == '\'' || c == '\0')
if (c == '\'')
break;
else if (c == '\\')
{
......
......@@ -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
......
......@@ -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,7 +541,11 @@ 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);
......@@ -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':
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)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment