diff options
Diffstat (limited to 'gcc/cpplex.c')
-rw-r--r-- | gcc/cpplex.c | 215 |
1 files changed, 194 insertions, 21 deletions
diff --git a/gcc/cpplex.c b/gcc/cpplex.c index 9d0a792..deae87e 100644 --- a/gcc/cpplex.c +++ b/gcc/cpplex.c @@ -50,7 +50,13 @@ static void null_warning PARAMS ((cpp_reader *, unsigned int)); static void safe_fwrite PARAMS ((cpp_reader *, const U_CHAR *, size_t, FILE *)); -static void output_line_command PARAMS ((cpp_reader *, cpp_printer *)); +static void output_line_command PARAMS ((cpp_reader *, cpp_printer *, + unsigned int)); +static void bump_column PARAMS ((cpp_printer *, unsigned int, + unsigned int)); +static void expand_name_space PARAMS ((cpp_toklist *)); +static void expand_token_space PARAMS ((cpp_toklist *)); +static void init_token_list PARAMS ((cpp_reader *, cpp_toklist *, int)); /* Re-allocates PFILE->token_buffer so it will hold at least N more chars. */ @@ -149,23 +155,18 @@ safe_fwrite (pfile, buf, len, fp) or the current file name has changed. */ static void -output_line_command (pfile, print) +output_line_command (pfile, print, line) cpp_reader *pfile; cpp_printer *print; + unsigned int line; { - unsigned int line; - cpp_buffer *ip; + cpp_buffer *ip = cpp_file_buffer (pfile); enum { same = 0, enter, leave, rname } change; static const char * const codes[] = { "", " 1", " 2", "" }; if (CPP_OPTION (pfile, no_line_commands)) return; - ip = cpp_file_buffer (pfile); - if (ip == NULL) - return; - line = CPP_BUF_LINE (ip); - /* Determine whether the current filename has changed, and if so, how. 'nominal_fname' values are unique, so they can be compared by comparing pointers. */ @@ -224,6 +225,8 @@ cpp_output_tokens (pfile, print) cpp_reader *pfile; cpp_printer *print; { + cpp_buffer *ip; + if (CPP_WRITTEN (pfile) - print->written) { if (CPP_PWRITTEN (pfile)[-1] == '\n' && print->lineno) @@ -231,10 +234,79 @@ cpp_output_tokens (pfile, print) safe_fwrite (pfile, pfile->token_buffer, CPP_WRITTEN (pfile) - print->written, print->outf); } - output_line_command (pfile, print); + + ip = cpp_file_buffer (pfile); + if (ip) + output_line_command (pfile, print, CPP_BUF_LINE (ip)); + CPP_SET_WRITTEN (pfile, print->written); } +/* Helper for cpp_output_list - increases the column number to match + what we expect it to be. */ + +static void +bump_column (print, from, to) + cpp_printer *print; + unsigned int from, to; +{ + unsigned int tabs, spcs; + unsigned int delta = to - from; + + /* Only if FROM is 0, advance by tabs. */ + if (from == 0) + tabs = delta / 8, spcs = delta % 8; + else + tabs = 0, spcs = delta; + + while (tabs--) putc ('\t', print->outf); + while (spcs--) putc (' ', print->outf); +} + +/* Write out the list L onto pfile->token_buffer. This function is + incomplete: + + 1) pfile->token_buffer is not going to continue to exist. + 2) At the moment, tokens don't carry the information described + in cpplib.h; they are all strings. + 3) The list has to be a complete line, and has to be written starting + at the beginning of a line. */ + +void +cpp_output_list (pfile, print, list) + cpp_reader *pfile; + cpp_printer *print; + const cpp_toklist *list; +{ + unsigned int i; + unsigned int curcol = 1; + + /* XXX Probably does not do what is intended. */ + if (print->lineno != list->line) + output_line_command (pfile, print, list->line); + + for (i = 0; i < list->tokens_used; i++) + { + if (list->tokens[i].type == CPP_VSPACE) + { + output_line_command (pfile, print, list->tokens[i].aux); + continue; + } + + if (curcol < list->tokens[i].col) + { + /* Insert space to bring the column to what it should be. */ + bump_column (print, curcol - 1, list->tokens[i].col); + curcol = list->tokens[i].col; + } + /* XXX We may have to insert space to prevent an accidental + token paste. */ + safe_fwrite (pfile, list->namebuf + list->tokens[i].val.name.offset, + list->tokens[i].val.name.len, print->outf); + curcol += list->tokens[i].val.name.len; + } +} + /* Scan a string (which may have escape marks), perform macro expansion, and write the result to the token_buffer. */ @@ -353,6 +425,107 @@ cpp_file_buffer (pfile) return NULL; } +/* Token-buffer helper functions. */ + +/* Expand a token list's string space. */ +static void +expand_name_space (list) + cpp_toklist *list; +{ + list->name_cap *= 2; + list->namebuf = (unsigned char *) xrealloc (list->namebuf, + list->name_cap); +} + +/* Expand the number of tokens in a list. */ +static void +expand_token_space (list) + cpp_toklist *list; +{ + list->tokens_cap *= 2; + list->tokens = (cpp_token *) + xrealloc (list->tokens, list->tokens_cap * sizeof (cpp_token)); +} + +/* Initialise a token list. */ +static void +init_token_list (pfile, list, recycle) + cpp_reader *pfile; + cpp_toklist *list; + int recycle; +{ + /* Recycling a used list saves 2 free-malloc pairs. */ + if (recycle) + { + list->tokens_used = 0; + list->name_used = 0; + } + else + { + /* Initialise token space. */ + list->tokens_cap = 256; /* 4K on Intel. */ + list->tokens_used = 0; + list->tokens = (cpp_token *) + xmalloc (list->tokens_cap * sizeof (cpp_token)); + + /* Initialise name space. */ + list->name_cap = 1024; + list->name_used = 0; + list->namebuf = (unsigned char *) xmalloc (list->name_cap); + } + + list->line = pfile->buffer->lineno; + list->dir_handler = 0; + list->dir_flags = 0; +} + +/* Scan an entire line and create a token list for it. Does not + macro-expand or execute directives. */ + +void +_cpp_scan_line (pfile, list) + cpp_reader *pfile; + cpp_toklist *list; +{ + int i, col; + long written, len; + enum cpp_ttype type; + + init_token_list (pfile, list, 1); + + written = CPP_WRITTEN (pfile); + i = 0; + for (;;) + { + col = CPP_BUFFER (pfile)->cur - CPP_BUFFER (pfile)->line_base; + type = _cpp_lex_token (pfile); + len = CPP_WRITTEN (pfile) - written; + CPP_SET_WRITTEN (pfile, written); + if (type == CPP_HSPACE) + continue; + + if (list->tokens_used >= list->tokens_cap) + expand_token_space (list); + if (list->name_used + len >= list->name_cap) + expand_name_space (list); + + list->tokens_used++; + list->tokens[i].type = type; + list->tokens[i].col = col; + + if (type == CPP_VSPACE) + break; + + list->tokens[i].val.name.len = len; + list->tokens[i].val.name.offset = list->name_used; + memcpy (list->namebuf + list->name_used, CPP_PWRITTEN (pfile), len); + list->name_used += len; + i++; + } + list->tokens[i].aux = CPP_BUFFER (pfile)->lineno + 1; +} + + /* Skip a C-style block comment. We know it's a comment, and point is at the second character of the starter. */ static void @@ -904,9 +1077,9 @@ _cpp_lex_token (pfile) CPP_PUTC_Q (pfile, GETC ()); } else - return CPP_STRINGIZE; + return CPP_HASH; - return CPP_TOKPASTE; + return CPP_PASTE; } if (!pfile->only_seen_white) @@ -959,7 +1132,7 @@ _cpp_lex_token (pfile) CPP_RESERVE (pfile, 2); CPP_PUTC_Q (pfile, c); CPP_PUTC_Q (pfile, c2); - return CPP_RBRACE; + return CPP_OPEN_BRACE; } /* else fall through */ @@ -1042,7 +1215,7 @@ _cpp_lex_token (pfile) CPP_RESERVE (pfile, 2); CPP_PUTC_Q (pfile, c); CPP_PUTC_Q (pfile, c2); - return CPP_LBRACE; + return CPP_CLOSE_BRACE; } else if (c2 == ':') goto op2; @@ -1082,7 +1255,7 @@ _cpp_lex_token (pfile) CPP_PUTC_Q (pfile, '.'); CPP_PUTC_Q (pfile, '.'); FORWARD (2); - return CPP_3DOTS; + return CPP_ELLIPSIS; } goto randomchar; @@ -1228,12 +1401,12 @@ _cpp_lex_token (pfile) CPP_PUTC (pfile, c); return CPP_VSPACE; - case '(': token = CPP_LPAREN; goto char1; - case ')': token = CPP_RPAREN; goto char1; - case '{': token = CPP_LBRACE; goto char1; - case '}': token = CPP_RBRACE; goto char1; - case ',': token = CPP_COMMA; goto char1; - case ';': token = CPP_SEMICOLON; goto char1; + case '(': token = CPP_OPEN_PAREN; goto char1; + case ')': token = CPP_CLOSE_PAREN; goto char1; + case '{': token = CPP_OPEN_BRACE; goto char1; + case '}': token = CPP_CLOSE_BRACE; goto char1; + case ',': token = CPP_COMMA; goto char1; + case ';': token = CPP_SEMICOLON; goto char1; randomchar: default: |