aboutsummaryrefslogtreecommitdiff
path: root/gcc/cppfiles.c
diff options
context:
space:
mode:
authorZack Weinberg <zack@wolery.cumb.org>2000-03-13 22:01:08 +0000
committerZack Weinberg <zack@gcc.gnu.org>2000-03-13 22:01:08 +0000
commit45b966db65e4ab054d31f01f65b7a98023dbcb54 (patch)
tree665428b0af6694941ce92f0755dc66596d94fa55 /gcc/cppfiles.c
parent46089b8642e5054073af90a85cfdd07f0f09353b (diff)
downloadgcc-45b966db65e4ab054d31f01f65b7a98023dbcb54.zip
gcc-45b966db65e4ab054d31f01f65b7a98023dbcb54.tar.gz
gcc-45b966db65e4ab054d31f01f65b7a98023dbcb54.tar.bz2
Makefile.in (LIBCPP_OBJS): Add cpplex.o.
* Makefile.in (LIBCPP_OBJS): Add cpplex.o. (cpplex.o): New target. * po/POTFILES.in: Add cpplex.c. * cpplex.c (_cpp_grow_token_buffer, null_cleanup, cpp_push_buffer, cpp_pop_buffer, cpp_scan_buffer, cpp_expand_to_buffer, cpp_buf_line_and_col, cpp_file_buffer, skip_block_comment, skip_line_comment, skip_comment, copy_comment, _cpp_skip_hspace, _cpp_skip_rest_of_line, _cpp_parse_name, skip_string, parse_string, _cpp_parse_assertion, cpp_get_token, cpp_get_non_space_token, _cpp_get_directive_token, find_position, _cpp_read_and_prescan, _cpp_init_input_buffer): Move here. (maybe_macroexpand, _cpp_lex_token): New functions. * cpplib.c (SKIP_WHITE_SPACE, eval_if_expr, parse_set_mark, parse_goto_mark): Delete. (_cpp_handle_eof): New function. (_cpp_handle_directive): Rename from handle_directive. (_cpp_output_line_command): Rename from output_line_command. (do_if, do_elif): Call _cpp_parse_expr directly. * cppfiles.c (_cpp_read_include_file): Don't call init_input_buffer here. * cpphash.c (quote_string): Move here, rename _cpp_quote_string. * cppexp.c (_cpp_parse_expr): Diddle parsing_if_directive here; pop the token_buffer and skip the rest of the line here. * cppinit.c (cpp_start_read): Call _cpp_init_input_buffer here. * cpphash.h (CPP_RESERVE, CPP_IS_MACRO_BUFFER, ACTIVE_MARK_P): Define here. (CPP_SET_BUF_MARK, CPP_GOTO_BUF_MARK, CPP_SET_MARK, CPP_GOTO_MARK): New macros. (_cpp_quote_string, _cpp_parse_name, _cpp_skip_rest_of_line, _cpp_skip_hspace, _cpp_parse_assertion, _cpp_lex_token, _cpp_read_and_prescan, _cpp_init_input_buffer, _cpp_grow_token_buffer, _cpp_get_directive_token, _cpp_handle_directive, _cpp_handle_eof, _cpp_output_line_command): Prototype them here. * cpplib.h (enum cpp_token): Add CPP_MACRO. (CPP_RESERVE, get_directive_token, cpp_grow_buffer, quote_string, output_line_command): Remove. From-SVN: r32513
Diffstat (limited to 'gcc/cppfiles.c')
-rw-r--r--gcc/cppfiles.c405
1 files changed, 1 insertions, 404 deletions
diff --git a/gcc/cppfiles.c b/gcc/cppfiles.c
index 3354663..ec7529f 100644
--- a/gcc/cppfiles.c
+++ b/gcc/cppfiles.c
@@ -38,17 +38,13 @@ static struct file_name_map *read_name_map
static char *read_filename_string PARAMS ((int, FILE *));
static char *remap_filename PARAMS ((cpp_reader *, char *,
struct file_name_list *));
-static long read_and_prescan PARAMS ((cpp_reader *, cpp_buffer *,
- int, size_t));
static struct file_name_list *actual_directory
PARAMS ((cpp_reader *, const char *));
static unsigned int hash_IHASH PARAMS ((const void *));
static int eq_IHASH PARAMS ((const void *, const void *));
-static void init_input_buffer PARAMS ((cpp_reader *, int, struct stat *));
static int file_cleanup PARAMS ((cpp_buffer *, cpp_reader *));
-static U_CHAR *find_position PARAMS ((U_CHAR *, U_CHAR *, unsigned long *));
#if 0
static void hack_vms_include_specification PARAMS ((char *));
@@ -587,14 +583,11 @@ _cpp_read_include_file (pfile, fd, ihash)
goto fail;
}
- if (pfile->input_buffer == NULL)
- init_input_buffer (pfile, fd, &st);
-
/* Read the file, converting end-of-line characters and trigraphs
(if enabled). */
fp->ihash = ihash;
fp->nominal_fname = ihash->name;
- length = read_and_prescan (pfile, fp, fd, st_size);
+ length = _cpp_read_and_prescan (pfile, fp, fd, st_size);
if (length < 0)
goto fail;
if (length == 0)
@@ -687,402 +680,6 @@ actual_directory (pfile, fname)
return x;
}
-/* Determine the current line and column. Used only by read_and_prescan. */
-static U_CHAR *
-find_position (start, limit, linep)
- U_CHAR *start;
- U_CHAR *limit;
- unsigned long *linep;
-{
- unsigned long line = *linep;
- U_CHAR *lbase = start;
- while (start < limit)
- {
- U_CHAR ch = *start++;
- if (ch == '\n' || ch == '\r')
- {
- line++;
- lbase = start;
- }
- }
- *linep = line;
- return lbase;
-}
-
-/* Read the entire contents of file DESC into buffer BUF. LEN is how
- much memory to allocate initially; more will be allocated if
- necessary. Convert end-of-line markers (\n, \r, \r\n, \n\r) to
- canonical form (\n). If enabled, convert and/or warn about
- trigraphs. Convert backslash-newline to a one-character escape
- (\r) and remove it from "embarrassing" places (i.e. the middle of a
- token). If there is no newline at the end of the file, add one and
- warn. Returns -1 on failure, or the actual length of the data to
- be scanned.
-
- This function does a lot of work, and can be a serious performance
- bottleneck. It has been tuned heavily; make sure you understand it
- before hacking. The common case - no trigraphs, Unix style line
- breaks, backslash-newline set off by whitespace, newline at EOF -
- has been optimized at the expense of the others. The performance
- penalty for DOS style line breaks (\r\n) is about 15%.
-
- Warnings lose particularly heavily since we have to determine the
- line number, which involves scanning from the beginning of the file
- or from the last warning. The penalty for the absence of a newline
- at the end of reload1.c is about 60%. (reload1.c is 329k.)
-
- If your file has more than one kind of end-of-line marker, you
- will get messed-up line numbering. */
-
-/* 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
-
-static long
-read_and_prescan (pfile, fp, desc, len)
- cpp_reader *pfile;
- cpp_buffer *fp;
- int desc;
- size_t len;
-{
- U_CHAR *buf = (U_CHAR *) xmalloc (len);
- U_CHAR *ip, *op, *line_base;
- U_CHAR *ibase;
- U_CHAR *speccase = pfile->input_speccase;
- unsigned long line;
- unsigned int deferred_newlines;
- int count;
- size_t offset;
-
- offset = 0;
- op = buf;
- line_base = buf;
- line = 1;
- ibase = pfile->input_buffer + 2;
- deferred_newlines = 0;
-
- for (;;)
- {
- read_next:
-
- count = read (desc, pfile->input_buffer + 2, pfile->input_buffer_len);
- if (count < 0)
- goto error;
- else if (count == 0)
- break;
-
- offset += count;
- ip = ibase;
- ibase = pfile->input_buffer + 2;
- ibase[count] = ibase[count+1] = '\0';
-
- if (offset > len)
- {
- size_t delta_op;
- size_t delta_line_base;
- len *= 2;
- if (offset > len)
- /* len overflowed.
- This could happen if the file is larger than half the
- maximum address space of the machine. */
- goto too_big;
-
- delta_op = op - buf;
- delta_line_base = line_base - buf;
- buf = (U_CHAR *) xrealloc (buf, len);
- op = buf + delta_op;
- line_base = buf + delta_line_base;
- }
-
- for (;;)
- {
- unsigned int span = 0;
-
- /* Deal with \-newline in the middle of a token. */
- if (deferred_newlines)
- {
- while (speccase[ip[span]] == SPECCASE_EMPTY
- && ip[span] != '\n'
- && ip[span] != '\t'
- && ip[span] != ' ')
- span++;
- memcpy (op, ip, span);
- op += span;
- ip += span;
- /* If ip[0] is SPECCASE_EMPTY, we have hit white space.
- Dump out the remaining deferred \-newlines. */
- if (speccase[ip[0]] == SPECCASE_EMPTY)
- while (deferred_newlines)
- deferred_newlines--, *op++ = '\r';
- span = 0;
- }
-
- /* Copy as much as we can without special treatment. */
- while (speccase[ip[span]] == SPECCASE_EMPTY) span++;
- memcpy (op, ip, span);
- op += span;
- ip += span;
-
- switch (speccase[*ip++])
- {
- case SPECCASE_NUL: /* \0 */
- ibase[-1] = op[-1];
- goto read_next;
-
- case SPECCASE_CR: /* \r */
- if (ip[-2] == '\n')
- continue;
- else if (*ip == '\n')
- ip++;
- else if (*ip == '\0')
- {
- *--ibase = '\r';
- goto read_next;
- }
- *op++ = '\n';
- break;
-
- case SPECCASE_BACKSLASH: /* \ */
- backslash:
- {
- /* If we're at the end of the intermediate buffer,
- we have to shift the backslash down to the start
- and come back next pass. */
- if (*ip == '\0')
- {
- *--ibase = '\\';
- goto read_next;
- }
- else if (*ip == '\n')
- {
- ip++;
- if (*ip == '\r') ip++;
- if (*ip == '\n' || *ip == '\t' || *ip == ' ')
- *op++ = '\r';
- else if (op[-1] == '\t' || op[-1] == ' '
- || op[-1] == '\r' || op[-1] == '\n')
- *op++ = '\r';
- else
- deferred_newlines++;
- }
- else if (*ip == '\r')
- {
- ip++;
- if (*ip == '\n') ip++;
- else if (*ip == '\0')
- {
- *--ibase = '\r';
- *--ibase = '\\';
- goto read_next;
- }
- else if (*ip == '\r' || *ip == '\t' || *ip == ' ')
- *op++ = '\r';
- else
- deferred_newlines++;
- }
- else
- *op++ = '\\';
- }
- break;
-
- case SPECCASE_QUESTION: /* ? */
- {
- unsigned int d, t;
- /* If we're at the end of the intermediate buffer,
- we have to shift the ?'s down to the start and
- come back next pass. */
- d = ip[0];
- if (d == '\0')
- {
- *--ibase = '?';
- goto read_next;
- }
- if (d != '?')
- {
- *op++ = '?';
- break;
- }
- d = ip[1];
- if (d == '\0')
- {
- *--ibase = '?';
- *--ibase = '?';
- goto read_next;
- }
-
- /* Trigraph map:
- * from to from to from to
- * ?? = # ?? ) ] ?? ! |
- * ?? ( [ ?? ' ^ ?? > }
- * ?? / \ ?? < { ?? - ~
- */
- if (d == '=') t = '#';
- else if (d == ')') t = ']';
- else if (d == '!') t = '|';
- else if (d == '(') t = '[';
- else if (d == '\'') t = '^';
- else if (d == '>') t = '}';
- else if (d == '/') t = '\\';
- else if (d == '<') t = '{';
- else if (d == '-') t = '~';
- else
- {
- *op++ = '?';
- break;
- }
- ip += 2;
- if (CPP_OPTIONS (pfile)->warn_trigraphs)
- {
- unsigned long col;
- line_base = find_position (line_base, op, &line);
- col = op - line_base + 1;
- if (CPP_OPTIONS (pfile)->trigraphs)
- cpp_warning_with_line (pfile, line, col,
- "trigraph ??%c converted to %c", d, t);
- else
- cpp_warning_with_line (pfile, line, col,
- "trigraph ??%c ignored", d);
- }
- if (CPP_OPTIONS (pfile)->trigraphs)
- {
- if (t == '\\')
- goto backslash;
- else
- *op++ = t;
- }
- else
- {
- *op++ = '?';
- *op++ = '?';
- *op++ = d;
- }
- }
- }
- }
- }
-
- if (offset == 0)
- return 0;
-
- /* Deal with pushed-back chars at true EOF.
- This may be any of: ?? ? \ \r \n \\r \\n.
- \r must become \n, \\r or \\n must become \r.
- We know we have space already. */
- if (ibase == pfile->input_buffer)
- {
- if (*ibase == '?')
- {
- *op++ = '?';
- *op++ = '?';
- }
- else
- *op++ = '\r';
- }
- else if (ibase == pfile->input_buffer + 1)
- {
- if (*ibase == '\r')
- *op++ = '\n';
- else
- *op++ = *ibase;
- }
-
- if (op[-1] != '\n')
- {
- unsigned long col;
- line_base = find_position (line_base, op, &line);
- col = op - line_base + 1;
- cpp_warning_with_line (pfile, line, col, "no newline at end of file\n");
- if (offset + 1 > len)
- {
- len += 1;
- if (offset + 1 > len)
- goto too_big;
- buf = (U_CHAR *) xrealloc (buf, len);
- op = buf + offset;
- }
- *op++ = '\n';
- }
-
- fp->buf = ((len - offset < 20) ? buf : (U_CHAR *)xrealloc (buf, op - buf));
- return op - buf;
-
- too_big:
- cpp_error (pfile, "file is too large (>%lu bytes)\n", (unsigned long)offset);
- free (buf);
- return -1;
-
- error:
- cpp_error_from_errno (pfile, fp->ihash->name);
- free (buf);
- 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
-init_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 = (U_CHAR *) 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 = (U_CHAR *) xmalloc (pipe_buf + 2 + 2);
- pfile->input_buffer = tmp;
- pfile->input_buffer_len = pipe_buf;
-}
-
/* Simplify a path name in place, deleting redundant components. This
reduces OS overhead and guarantees that equivalent paths compare
the same (modulo symlinks).