diff options
author | Zack Weinberg <zack@wolery.cumb.org> | 2000-03-13 22:01:08 +0000 |
---|---|---|
committer | Zack Weinberg <zack@gcc.gnu.org> | 2000-03-13 22:01:08 +0000 |
commit | 45b966db65e4ab054d31f01f65b7a98023dbcb54 (patch) | |
tree | 665428b0af6694941ce92f0755dc66596d94fa55 /gcc/cppfiles.c | |
parent | 46089b8642e5054073af90a85cfdd07f0f09353b (diff) | |
download | gcc-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.c | 405 |
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). |