cppfiles.c (initialize_input_buffer): New function.
1999-05-10 18:21 -0400 Zack Weinberg <zack@rabi.columbia.edu> * cppfiles.c (initialize_input_buffer): New function. (finclude): Call it, if pfile->input_buffer is NULL. Accept any character device as an input file. (read_and_prescan): Use pfile->input_buffer and pfile->input_speccase. * cppinit.c (cpp_cleanup): Free pfile->input_buffer and pfile->input_speccase. * cpplib.h (cpp_reader): Add input_buffer, input_speccase, and input_buffer_len members. Use memcpy in CPP_PUTS_Q. * cppmain.c: Buffer output in the token_buffer; throttle number of calls to fwrite; check for errors from fwrite. From-SVN: r26869
This commit is contained in:
parent
4338f578a7
commit
2c826217f4
138
gcc/cppfiles.c
138
gcc/cppfiles.c
@ -45,6 +45,9 @@ static long read_and_prescan PROTO ((cpp_reader *, cpp_buffer *,
|
|||||||
int, size_t));
|
int, size_t));
|
||||||
static struct file_name_list *actual_directory PROTO ((cpp_reader *, char *));
|
static struct file_name_list *actual_directory PROTO ((cpp_reader *, char *));
|
||||||
|
|
||||||
|
static void initialize_input_buffer PROTO ((cpp_reader *, int,
|
||||||
|
struct stat *));
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
static void hack_vms_include_specification PROTO ((char *));
|
static void hack_vms_include_specification PROTO ((char *));
|
||||||
#endif
|
#endif
|
||||||
@ -648,10 +651,12 @@ finclude (pfile, fd, ihash)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (S_ISFIFO (st.st_mode) || S_ISSOCK (st.st_mode)
|
else if (S_ISFIFO (st.st_mode) || S_ISSOCK (st.st_mode)
|
||||||
|
/* Permit any kind of character device: the sensible ones are
|
||||||
|
ttys and /dev/null, but weeding out the others is too hard. */
|
||||||
|
|| S_ISCHR (st.st_mode)
|
||||||
/* Some 4.x (x<4) derivatives have a bug that makes fstat() of a
|
/* Some 4.x (x<4) derivatives have a bug that makes fstat() of a
|
||||||
socket or pipe return a stat struct with most fields zeroed. */
|
socket or pipe return a stat struct with most fields zeroed. */
|
||||||
|| (st.st_mode == 0 && st.st_nlink == 0 && st.st_size == 0)
|
|| (st.st_mode == 0 && st.st_nlink == 0 && st.st_size == 0))
|
||||||
|| (S_ISCHR (st.st_mode) && isatty (fd)))
|
|
||||||
{
|
{
|
||||||
/* Cannot get its file size before reading. 4k is a decent
|
/* Cannot get its file size before reading. 4k is a decent
|
||||||
first guess. */
|
first guess. */
|
||||||
@ -663,6 +668,9 @@ finclude (pfile, fd, ihash)
|
|||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (pfile->input_buffer == NULL)
|
||||||
|
initialize_input_buffer (pfile, fd, &st);
|
||||||
|
|
||||||
/* Read the file, converting end-of-line characters and trigraphs
|
/* Read the file, converting end-of-line characters and trigraphs
|
||||||
(if enabled). */
|
(if enabled). */
|
||||||
fp->ihash = ihash;
|
fp->ihash = ihash;
|
||||||
@ -758,8 +766,7 @@ actual_directory (pfile, fname)
|
|||||||
return x;
|
return x;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Almost but not quite the same as adjust_position in cpplib.c.
|
/* Determine the current line and column. Used only by read_and_prescan. */
|
||||||
Used only by read_and_prescan. */
|
|
||||||
static void
|
static void
|
||||||
find_position (start, limit, linep, colp)
|
find_position (start, limit, linep, colp)
|
||||||
U_CHAR *start;
|
U_CHAR *start;
|
||||||
@ -804,9 +811,14 @@ find_position (start, limit, linep, colp)
|
|||||||
If your file has more than one kind of end-of-line marker, you
|
If your file has more than one kind of end-of-line marker, you
|
||||||
will get messed-up line numbering. */
|
will get messed-up line numbering. */
|
||||||
|
|
||||||
#ifndef PIPE_BUF
|
/* Table of characters that can't be handled in the inner loop.
|
||||||
#define PIPE_BUF 4096
|
Keep these contiguous to optimize the performance of the code generated
|
||||||
#endif
|
for the switch that uses them. */
|
||||||
|
#define SPECCASE_EMPTY 0
|
||||||
|
#define SPECCASE_NUL 1
|
||||||
|
#define SPECCASE_CR 2
|
||||||
|
#define SPECCASE_BACKSLASH 3
|
||||||
|
#define SPECCASE_QUESTION 4
|
||||||
|
|
||||||
static long
|
static long
|
||||||
read_and_prescan (pfile, fp, desc, len)
|
read_and_prescan (pfile, fp, desc, len)
|
||||||
@ -818,45 +830,24 @@ read_and_prescan (pfile, fp, desc, len)
|
|||||||
U_CHAR *buf = (U_CHAR *) xmalloc (len);
|
U_CHAR *buf = (U_CHAR *) xmalloc (len);
|
||||||
U_CHAR *ip, *op, *line_base;
|
U_CHAR *ip, *op, *line_base;
|
||||||
U_CHAR *ibase;
|
U_CHAR *ibase;
|
||||||
|
U_CHAR *speccase = pfile->input_speccase;
|
||||||
unsigned long line;
|
unsigned long line;
|
||||||
unsigned int deferred_newlines;
|
unsigned int deferred_newlines;
|
||||||
int count;
|
int count;
|
||||||
size_t offset;
|
size_t offset;
|
||||||
/* PIPE_BUF bytes of buffer proper, 2 to detect running off the end
|
|
||||||
without address arithmetic all the time, and 2 for pushback in
|
|
||||||
the case there's a potential trigraph or end-of-line digraph at
|
|
||||||
the end of a block. */
|
|
||||||
U_CHAR intermed[PIPE_BUF + 2 + 2];
|
|
||||||
|
|
||||||
/* Table of characters that can't be handled in the inner loop.
|
|
||||||
Keep these contiguous to optimize the performance of the code generated
|
|
||||||
for the switch that uses them. */
|
|
||||||
#define SPECCASE_EMPTY 0
|
|
||||||
#define SPECCASE_NUL 1
|
|
||||||
#define SPECCASE_CR 2
|
|
||||||
#define SPECCASE_BACKSLASH 3
|
|
||||||
#define SPECCASE_QUESTION 4
|
|
||||||
U_CHAR speccase[256];
|
|
||||||
|
|
||||||
offset = 0;
|
offset = 0;
|
||||||
op = buf;
|
op = buf;
|
||||||
line_base = buf;
|
line_base = buf;
|
||||||
line = 1;
|
line = 1;
|
||||||
ibase = intermed + 2;
|
ibase = pfile->input_buffer + 2;
|
||||||
deferred_newlines = 0;
|
deferred_newlines = 0;
|
||||||
|
|
||||||
memset (speccase, SPECCASE_EMPTY, sizeof (speccase));
|
|
||||||
speccase['\0'] = SPECCASE_NUL;
|
|
||||||
speccase['\r'] = SPECCASE_CR;
|
|
||||||
speccase['\\'] = SPECCASE_BACKSLASH;
|
|
||||||
if (CPP_OPTIONS (pfile)->trigraphs || CPP_OPTIONS (pfile)->warn_trigraphs)
|
|
||||||
speccase['?'] = SPECCASE_QUESTION;
|
|
||||||
|
|
||||||
for (;;)
|
for (;;)
|
||||||
{
|
{
|
||||||
read_next:
|
read_next:
|
||||||
|
|
||||||
count = read (desc, intermed + 2, PIPE_BUF);
|
count = read (desc, pfile->input_buffer + 2, pfile->input_buffer_len);
|
||||||
if (count < 0)
|
if (count < 0)
|
||||||
goto error;
|
goto error;
|
||||||
else if (count == 0)
|
else if (count == 0)
|
||||||
@ -864,7 +855,7 @@ read_and_prescan (pfile, fp, desc, len)
|
|||||||
|
|
||||||
offset += count;
|
offset += count;
|
||||||
ip = ibase;
|
ip = ibase;
|
||||||
ibase = intermed + 2;
|
ibase = pfile->input_buffer + 2;
|
||||||
ibase[count] = ibase[count+1] = '\0';
|
ibase[count] = ibase[count+1] = '\0';
|
||||||
|
|
||||||
if (offset > len)
|
if (offset > len)
|
||||||
@ -924,8 +915,7 @@ read_and_prescan (pfile, fp, desc, len)
|
|||||||
ip++;
|
ip++;
|
||||||
else if (*ip == '\0')
|
else if (*ip == '\0')
|
||||||
{
|
{
|
||||||
--ibase;
|
*--ibase = '\r';
|
||||||
intermed[1] = '\r';
|
|
||||||
goto read_next;
|
goto read_next;
|
||||||
}
|
}
|
||||||
else if (ip[-2] == '\n')
|
else if (ip[-2] == '\n')
|
||||||
@ -941,8 +931,7 @@ read_and_prescan (pfile, fp, desc, len)
|
|||||||
and come back next pass. */
|
and come back next pass. */
|
||||||
if (*ip == '\0')
|
if (*ip == '\0')
|
||||||
{
|
{
|
||||||
--ibase;
|
*--ibase = '\\';
|
||||||
intermed[1] = '\\';
|
|
||||||
goto read_next;
|
goto read_next;
|
||||||
}
|
}
|
||||||
else if (*ip == '\n')
|
else if (*ip == '\n')
|
||||||
@ -965,9 +954,8 @@ read_and_prescan (pfile, fp, desc, len)
|
|||||||
if (*ip == '\n') ip++;
|
if (*ip == '\n') ip++;
|
||||||
else if (*ip == '\0')
|
else if (*ip == '\0')
|
||||||
{
|
{
|
||||||
ibase -= 2;
|
*--ibase = '\r';
|
||||||
intermed[0] = '\\';
|
*--ibase = '\\';
|
||||||
intermed[1] = '\r';
|
|
||||||
goto read_next;
|
goto read_next;
|
||||||
}
|
}
|
||||||
else if (*ip == '\r' || *ip == '\t' || *ip == ' ')
|
else if (*ip == '\r' || *ip == '\t' || *ip == ' ')
|
||||||
@ -991,8 +979,7 @@ read_and_prescan (pfile, fp, desc, len)
|
|||||||
d = ip[0];
|
d = ip[0];
|
||||||
if (d == '\0')
|
if (d == '\0')
|
||||||
{
|
{
|
||||||
--ibase;
|
*--ibase = '?';
|
||||||
intermed[1] = '?';
|
|
||||||
goto read_next;
|
goto read_next;
|
||||||
}
|
}
|
||||||
if (d != '?')
|
if (d != '?')
|
||||||
@ -1003,8 +990,8 @@ read_and_prescan (pfile, fp, desc, len)
|
|||||||
d = ip[1];
|
d = ip[1];
|
||||||
if (d == '\0')
|
if (d == '\0')
|
||||||
{
|
{
|
||||||
ibase -= 2;
|
*--ibase = '?';
|
||||||
intermed[0] = intermed[1] = '?';
|
*--ibase = '?';
|
||||||
goto read_next;
|
goto read_next;
|
||||||
}
|
}
|
||||||
if (!trigraph_table[d])
|
if (!trigraph_table[d])
|
||||||
@ -1047,7 +1034,7 @@ read_and_prescan (pfile, fp, desc, len)
|
|||||||
This may be any of: ?? ? \ \r \n \\r \\n.
|
This may be any of: ?? ? \ \r \n \\r \\n.
|
||||||
\r must become \n, \\r or \\n must become \r.
|
\r must become \n, \\r or \\n must become \r.
|
||||||
We know we have space already. */
|
We know we have space already. */
|
||||||
if (ibase == intermed)
|
if (ibase == pfile->input_buffer)
|
||||||
{
|
{
|
||||||
if (*ibase == '?')
|
if (*ibase == '?')
|
||||||
{
|
{
|
||||||
@ -1057,7 +1044,7 @@ read_and_prescan (pfile, fp, desc, len)
|
|||||||
else
|
else
|
||||||
*op++ = '\r';
|
*op++ = '\r';
|
||||||
}
|
}
|
||||||
else if (ibase == intermed + 1)
|
else if (ibase == pfile->input_buffer + 1)
|
||||||
{
|
{
|
||||||
if (*ibase == '\r')
|
if (*ibase == '\r')
|
||||||
*op++ = '\n';
|
*op++ = '\n';
|
||||||
@ -1095,6 +1082,67 @@ read_and_prescan (pfile, fp, desc, len)
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Initialize the `input_buffer' and `input_speccase' tables.
|
||||||
|
These are only used by read_and_prescan, but they're large and
|
||||||
|
somewhat expensive to set up, so we want them allocated once for
|
||||||
|
the duration of the cpp run. */
|
||||||
|
|
||||||
|
static void
|
||||||
|
initialize_input_buffer (pfile, fd, st)
|
||||||
|
cpp_reader *pfile;
|
||||||
|
int fd;
|
||||||
|
struct stat *st;
|
||||||
|
{
|
||||||
|
long pipe_buf;
|
||||||
|
U_CHAR *tmp;
|
||||||
|
|
||||||
|
/* Table of characters that cannot be handled by the
|
||||||
|
read_and_prescan inner loop. The number of non-EMPTY entries
|
||||||
|
should be as small as humanly possible. */
|
||||||
|
|
||||||
|
tmp = xmalloc (1 << CHAR_BIT);
|
||||||
|
memset (tmp, SPECCASE_EMPTY, 1 << CHAR_BIT);
|
||||||
|
tmp['\0'] = SPECCASE_NUL;
|
||||||
|
tmp['\r'] = SPECCASE_CR;
|
||||||
|
tmp['\\'] = SPECCASE_BACKSLASH;
|
||||||
|
if (CPP_OPTIONS (pfile)->trigraphs || CPP_OPTIONS (pfile)->warn_trigraphs)
|
||||||
|
tmp['?'] = SPECCASE_QUESTION;
|
||||||
|
|
||||||
|
pfile->input_speccase = tmp;
|
||||||
|
|
||||||
|
/* Determine the appropriate size for the input buffer. Normal C
|
||||||
|
source files are smaller than eight K. If we are reading a pipe,
|
||||||
|
we want to make sure the input buffer is bigger than the kernel's
|
||||||
|
pipe buffer. */
|
||||||
|
pipe_buf = -1;
|
||||||
|
|
||||||
|
if (! S_ISREG (st->st_mode))
|
||||||
|
{
|
||||||
|
#ifdef _PC_PIPE_BUF
|
||||||
|
pipe_buf = fpathconf (fd, _PC_PIPE_BUF);
|
||||||
|
#endif
|
||||||
|
if (pipe_buf == -1)
|
||||||
|
{
|
||||||
|
#ifdef PIPE_BUF
|
||||||
|
pipe_buf = PIPE_BUF;
|
||||||
|
#else
|
||||||
|
pipe_buf = 8192;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pipe_buf < 8192)
|
||||||
|
pipe_buf = 8192;
|
||||||
|
/* PIPE_BUF bytes of buffer proper, 2 to detect running off the end
|
||||||
|
without address arithmetic all the time, and 2 for pushback in
|
||||||
|
the case there's a potential trigraph or end-of-line digraph at
|
||||||
|
the end of a block. */
|
||||||
|
|
||||||
|
tmp = xmalloc (pipe_buf + 2 + 2);
|
||||||
|
pfile->input_buffer = tmp;
|
||||||
|
pfile->input_buffer_len = pipe_buf;
|
||||||
|
}
|
||||||
|
|
||||||
/* Add output to `deps_buffer' for the -M switch.
|
/* Add output to `deps_buffer' for the -M switch.
|
||||||
STRING points to the text to be output.
|
STRING points to the text to be output.
|
||||||
SPACER is ':' for targets, ' ' for dependencies, zero for text
|
SPACER is ':' for targets, ' ' for dependencies, zero for text
|
||||||
|
@ -569,6 +569,14 @@ cpp_cleanup (pfile)
|
|||||||
pfile->deps_allocated_size = 0;
|
pfile->deps_allocated_size = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (pfile->input_buffer)
|
||||||
|
{
|
||||||
|
free (pfile->input_buffer);
|
||||||
|
free (pfile->input_speccase);
|
||||||
|
pfile->input_buffer = pfile->input_speccase = NULL;
|
||||||
|
pfile->input_buffer_len = 0;
|
||||||
|
}
|
||||||
|
|
||||||
while (pfile->if_stack)
|
while (pfile->if_stack)
|
||||||
{
|
{
|
||||||
IF_STACK_FRAME *temp = pfile->if_stack;
|
IF_STACK_FRAME *temp = pfile->if_stack;
|
||||||
|
@ -241,6 +241,13 @@ struct cpp_reader
|
|||||||
|
|
||||||
/* Number of bytes since the last newline. */
|
/* Number of bytes since the last newline. */
|
||||||
int deps_column;
|
int deps_column;
|
||||||
|
|
||||||
|
/* A buffer and a table, used only by read_and_prescan (in cppfiles.c)
|
||||||
|
which are allocated once per cpp_reader object to keep them off the
|
||||||
|
stack and avoid setup costs. */
|
||||||
|
U_CHAR *input_buffer;
|
||||||
|
U_CHAR *input_speccase;
|
||||||
|
size_t input_buffer_len;
|
||||||
};
|
};
|
||||||
|
|
||||||
#define CPP_FATAL_LIMIT 1000
|
#define CPP_FATAL_LIMIT 1000
|
||||||
@ -269,7 +276,7 @@ struct cpp_reader
|
|||||||
/* Append string STR (of length N) to PFILE's output buffer.
|
/* Append string STR (of length N) to PFILE's output buffer.
|
||||||
Assume there is enough space. */
|
Assume there is enough space. */
|
||||||
#define CPP_PUTS_Q(PFILE, STR, N) \
|
#define CPP_PUTS_Q(PFILE, STR, N) \
|
||||||
(bcopy (STR, (PFILE)->limit, (N)), (PFILE)->limit += (N))
|
(memcpy ((PFILE)->limit, STR, (N)), (PFILE)->limit += (N))
|
||||||
/* Append string STR (of length N) to PFILE's output buffer. Make space. */
|
/* Append string STR (of length N) to PFILE's output buffer. Make space. */
|
||||||
#define CPP_PUTS(PFILE, STR, N) CPP_RESERVE(PFILE, N), CPP_PUTS_Q(PFILE, STR,N)
|
#define CPP_PUTS(PFILE, STR, N) CPP_RESERVE(PFILE, N), CPP_PUTS_Q(PFILE, STR,N)
|
||||||
/* Append character CH to PFILE's output buffer. Assume sufficient space. */
|
/* Append character CH to PFILE's output buffer. Assume sufficient space. */
|
||||||
|
@ -46,6 +46,7 @@ main (argc, argv)
|
|||||||
char *p;
|
char *p;
|
||||||
int argi = 1; /* Next argument to handle. */
|
int argi = 1; /* Next argument to handle. */
|
||||||
struct cpp_options *opts = &options;
|
struct cpp_options *opts = &options;
|
||||||
|
enum cpp_token kind;
|
||||||
|
|
||||||
p = argv[0] + strlen (argv[0]);
|
p = argv[0] + strlen (argv[0]);
|
||||||
while (p != argv[0] && p[-1] != '/') --p;
|
while (p != argv[0] && p[-1] != '/') --p;
|
||||||
@ -80,21 +81,30 @@ main (argc, argv)
|
|||||||
else if (! freopen (opts->out_fname, "w", stdout))
|
else if (! freopen (opts->out_fname, "w", stdout))
|
||||||
cpp_pfatal_with_name (&parse_in, opts->out_fname);
|
cpp_pfatal_with_name (&parse_in, opts->out_fname);
|
||||||
|
|
||||||
for (;;)
|
do
|
||||||
{
|
{
|
||||||
enum cpp_token kind;
|
|
||||||
if (! opts->no_output)
|
|
||||||
{
|
|
||||||
fwrite (parse_in.token_buffer, 1, CPP_WRITTEN (&parse_in), stdout);
|
|
||||||
}
|
|
||||||
CPP_SET_WRITTEN (&parse_in, 0);
|
|
||||||
kind = cpp_get_token (&parse_in);
|
kind = cpp_get_token (&parse_in);
|
||||||
if (kind == CPP_EOF)
|
if (CPP_WRITTEN (&parse_in) >= BUFSIZ || kind == CPP_EOF)
|
||||||
break;
|
{
|
||||||
|
if (! opts->no_output)
|
||||||
|
{
|
||||||
|
size_t rem, count = CPP_WRITTEN (&parse_in);
|
||||||
|
|
||||||
|
rem = fwrite (parse_in.token_buffer, 1, count, stdout);
|
||||||
|
if (rem < count)
|
||||||
|
/* Write error. */
|
||||||
|
cpp_pfatal_with_name (&parse_in, opts->out_fname);
|
||||||
|
}
|
||||||
|
|
||||||
|
CPP_SET_WRITTEN (&parse_in, 0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
while (kind != CPP_EOF);
|
||||||
|
|
||||||
cpp_finish (&parse_in);
|
cpp_finish (&parse_in);
|
||||||
fwrite (parse_in.token_buffer, 1, CPP_WRITTEN (&parse_in), stdout);
|
if (fwrite (parse_in.token_buffer, 1, CPP_WRITTEN (&parse_in), stdout)
|
||||||
|
< CPP_WRITTEN (&parse_in))
|
||||||
|
cpp_pfatal_with_name (&parse_in, opts->out_fname);
|
||||||
|
|
||||||
if (parse_in.errors)
|
if (parse_in.errors)
|
||||||
exit (FATAL_EXIT_CODE);
|
exit (FATAL_EXIT_CODE);
|
||||||
|
Loading…
Reference in New Issue
Block a user