Commit f7531123 by Paul Eggert

(quote_string): New function.

(special_symbol, write_output, output_line_command): Use it to quote
special characters in file names on output.
(do_line): Parse escape sequences in #line directives' file names.

From-SVN: r5529
parent cf1d841d
...@@ -188,6 +188,7 @@ extern char *version_string; ...@@ -188,6 +188,7 @@ extern char *version_string;
extern struct tm *localtime (); extern struct tm *localtime ();
extern int sys_nerr; extern int sys_nerr;
extern char *sys_errlist[]; extern char *sys_errlist[];
extern int parse_escape ();
#ifndef errno #ifndef errno
extern int errno; extern int errno;
...@@ -308,7 +309,7 @@ static char *macarg (); ...@@ -308,7 +309,7 @@ static char *macarg ();
static U_CHAR *skip_to_end_of_comment (); static U_CHAR *skip_to_end_of_comment ();
static U_CHAR *skip_quoted_string (); static U_CHAR *skip_quoted_string ();
static U_CHAR *skip_paren_group (); static U_CHAR *skip_paren_group ();
static void quote_string (); static char *quote_string ();
static char *check_precompiled (); static char *check_precompiled ();
/* static struct macrodef create_definition (); [moved below] */ /* static struct macrodef create_definition (); [moved below] */
...@@ -3664,7 +3665,7 @@ special_symbol (hp, op) ...@@ -3664,7 +3665,7 @@ special_symbol (hp, op)
if (string) if (string)
{ {
buf = (char *) alloca (3 + 2 * strlen (string)); buf = (char *) alloca (3 + 4 * strlen (string));
quote_string (buf, string); quote_string (buf, string);
} }
else else
...@@ -4734,12 +4735,14 @@ write_output () ...@@ -4734,12 +4735,14 @@ write_output ()
if (next_string if (next_string
&& cur_buf_loc - outbuf.buf == next_string->output_mark) { && cur_buf_loc - outbuf.buf == next_string->output_mark) {
if (next_string->writeflag) { if (next_string->writeflag) {
len = strlen (next_string->filename); len = 4 * strlen (next_string->filename) + 32;
if (len > line_command_len) while (len > line_command_len)
line_command = xrealloc (line_command, line_command = xrealloc (line_command,
line_command_len *= 2); line_command_len *= 2);
sprintf (line_command, "\n# %d \"%s\"\n", sprintf (line_command, "\n# %d ", next_string->lineno);
next_string->lineno, next_string->filename); strcpy (quote_string (line_command + strlen (line_command),
next_string->filename),
"\n");
if (write (fileno (stdout), line_command, strlen (line_command)) < 0) if (write (fileno (stdout), line_command, strlen (line_command)) < 0)
pfatal_with_name (out_fname); pfatal_with_name (out_fname);
if (write (fileno (stdout), next_string->contents, next_string->len) < 0) if (write (fileno (stdout), next_string->contents, next_string->len) < 0)
...@@ -5888,21 +5891,39 @@ do_line (buf, limit, op, keyword) ...@@ -5888,21 +5891,39 @@ do_line (buf, limit, op, keyword)
if (*bp == '\"') { if (*bp == '\"') {
static HASHNODE *fname_table[FNAME_HASHSIZE]; static HASHNODE *fname_table[FNAME_HASHSIZE];
HASHNODE *hp, **hash_bucket; HASHNODE *hp, **hash_bucket;
U_CHAR *fname; U_CHAR *fname, *p;
int fname_length; int fname_length;
fname = ++bp; fname = ++bp;
while (*bp && *bp != '\"') /* Turn the file name, which is a character string literal,
bp++; into a null-terminated string. Do this in place. */
if (*bp != '\"') { p = bp;
for (;;)
switch ((*p++ = *bp++)) {
case '\0':
error ("invalid format `#line' command"); error ("invalid format `#line' command");
return 0; return 0;
case '\\':
{
char *bpc = (char *) bp;
int c = parse_escape (&bpc);
bp = (U_CHAR *) bpc;
if (c < 0)
p--;
else
p[-1] = c;
} }
break;
fname_length = bp - fname; case '\"':
p[-1] = 0;
goto fname_done;
}
fname_done:
fname_length = p - fname;
bp++;
SKIP_WHITE_SPACE (bp); SKIP_WHITE_SPACE (bp);
if (*bp) { if (*bp) {
if (pedantic) if (pedantic)
...@@ -6908,28 +6929,38 @@ skip_quoted_string (bp, limit, start_line, count_newlines, backslash_newlines_p, ...@@ -6908,28 +6929,38 @@ skip_quoted_string (bp, limit, start_line, count_newlines, backslash_newlines_p,
return bp; return bp;
} }
/* Place into DST a quoted string representing the string SRC. */ /* Place into DST a quoted string representing the string SRC.
static void Return the address of DST's terminating null. */
static char *
quote_string (dst, src) quote_string (dst, src)
char *dst, *src; char *dst, *src;
{ {
char c; U_CHAR c;
for (*dst++ = '\"'; ; *dst++ = c) *dst++ = '\"';
for (;;)
switch ((c = *src++)) switch ((c = *src++))
{ {
case '\n': default:
c = 'n'; if (isprint (c))
/* fall through */ *dst++ = c;
else
{
sprintf (dst, "\\%03o", c);
dst += 4;
}
break;
case '\"': case '\"':
case '\\': case '\\':
*dst++ = '\\'; *dst++ = '\\';
*dst++ = c;
break; break;
case '\0': case '\0':
*dst++ = '\"'; *dst++ = '\"';
*dst = '\0'; *dst = '\0';
return; return dst;
} }
} }
...@@ -6999,7 +7030,7 @@ output_line_command (ip, op, conditional, file_change) ...@@ -6999,7 +7030,7 @@ output_line_command (ip, op, conditional, file_change)
enum file_change_code file_change; enum file_change_code file_change;
{ {
int len; int len;
char *line_cmd_buf; char *line_cmd_buf, *line_end;
if (no_line_commands if (no_line_commands
|| ip->fname == NULL || ip->fname == NULL
...@@ -7031,19 +7062,25 @@ output_line_command (ip, op, conditional, file_change) ...@@ -7031,19 +7062,25 @@ output_line_command (ip, op, conditional, file_change)
ip->bufp++; ip->bufp++;
} }
line_cmd_buf = (char *) alloca (strlen (ip->nominal_fname) + 100); line_cmd_buf = (char *) alloca (4 * strlen (ip->nominal_fname) + 100);
#ifdef OUTPUT_LINE_COMMANDS #ifdef OUTPUT_LINE_COMMANDS
sprintf (line_cmd_buf, "#line %d \"%s\"", ip->lineno, ip->nominal_fname); sprintf (line_cmd_buf, "#line %d ", ip->lineno);
#else #else
sprintf (line_cmd_buf, "# %d \"%s\"", ip->lineno, ip->nominal_fname); sprintf (line_cmd_buf, "# %d ", ip->lineno);
#endif #endif
if (file_change != same_file) line_end = quote_string (line_cmd_buf + strlen (line_cmd_buf),
strcat (line_cmd_buf, file_change == enter_file ? " 1" : " 2"); ip->nominal_fname);
if (file_change != same_file) {
*line_end++ = ' ';
*line_end++ = file_change == enter_file ? '1' : '2';
}
/* Tell cc1 if following text comes from a system header file. */ /* Tell cc1 if following text comes from a system header file. */
if (ip->system_header_p) if (ip->system_header_p) {
strcat (line_cmd_buf, " 3"); *line_end++ = ' ';
len = strlen (line_cmd_buf); *line_end++ = '3';
line_cmd_buf[len++] = '\n'; }
*line_end++ = '\n';
len = line_end - line_cmd_buf;
check_expand (op, len + 1); check_expand (op, len + 1);
if (op->bufp > op->buf && op->bufp[-1] != '\n') if (op->bufp > op->buf && op->bufp[-1] != '\n')
*op->bufp++ = '\n'; *op->bufp++ = '\n';
......
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