X-Git-Url: http://nsz.repo.hu/git/?a=blobdiff_plain;f=preprocessor.c;h=5d4213b73016e769912254d5f682197f863a7736;hb=94b2f5705c62f16e0bbbd755e93049c831891a4c;hp=4f3078cdd44abe684a8cb8157a76f3bfd2ea9979;hpb=4e4ce90259eabe103654930753cd92e9efab650f;p=cparser diff --git a/preprocessor.c b/preprocessor.c index 4f3078c..5d4213b 100644 --- a/preprocessor.c +++ b/preprocessor.c @@ -1,3 +1,7 @@ +/* + * This file is part of cparser. + * Copyright (C) 2012 Matthias Braun + */ #include #include @@ -38,7 +42,7 @@ typedef struct whitespace_info_t { struct pp_definition_t { symbol_t *symbol; - source_position_t source_position; + position_t pos; pp_definition_t *parent_expansion; size_t expand_pos; whitespace_info_t expand_info; @@ -57,7 +61,7 @@ struct pp_definition_t { typedef struct pp_conditional_t pp_conditional_t; struct pp_conditional_t { - source_position_t source_position; + position_t pos; bool condition; bool in_else; /** conditional in skip mode (then+else gets skipped) */ @@ -73,7 +77,7 @@ struct pp_input_t { utf32 buf[1024+MAX_PUTBACK]; const utf32 *bufend; const utf32 *bufpos; - source_position_t position; + position_t pos; pp_input_t *parent; unsigned output_line; searchpath_entry_t *path; @@ -102,7 +106,7 @@ static FILE *out; static struct obstack pp_obstack; static struct obstack config_obstack; static const char *printed_input_name = NULL; -static source_position_t expansion_pos; +static position_t expansion_pos; static pp_definition_t *current_expansion = NULL; static pp_definition_t *current_call = NULL; static pp_definition_t *current_argument = NULL; @@ -127,7 +131,7 @@ static whitespace_info_t info; static inline void next_char(void); static void next_input_token(void); -static void print_line_directive(const source_position_t *pos, const char *add); +static void print_line_directive(const position_t *pos, const char *add); static symbol_t *symbol_colongreater; static symbol_t *symbol_lesscolon; @@ -136,6 +140,11 @@ static symbol_t *symbol_percentcolon; static symbol_t *symbol_percentcolonpercentcolon; static symbol_t *symbol_percentgreater; +static symbol_t *symbol_L; +static symbol_t *symbol_U; +static symbol_t *symbol_u; +static symbol_t *symbol_u8; + static void init_symbols(void) { symbol_colongreater = symbol_table_insert(":>"); @@ -144,26 +153,31 @@ static void init_symbols(void) symbol_percentcolon = symbol_table_insert("%:"); symbol_percentcolonpercentcolon = symbol_table_insert("%:%:"); symbol_percentgreater = symbol_table_insert("%>"); + + symbol_L = symbol_table_insert("L"); + symbol_U = symbol_table_insert("U"); + symbol_u = symbol_table_insert("u"); + symbol_u8 = symbol_table_insert("u8"); } void switch_pp_input(FILE *const file, char const *const filename, searchpath_entry_t *const path, bool const is_system_header) { - input.file = file; - input.input = input_from_stream(file, NULL); - input.bufend = NULL; - input.bufpos = NULL; - input.output_line = 0; - input.position.input_name = filename; - input.position.lineno = 1; - input.position.is_system_header = is_system_header; - input.path = path; + input.file = file; + input.input = input_from_stream(file, NULL); + input.bufend = NULL; + input.bufpos = NULL; + input.output_line = 0; + input.pos.input_name = filename; + input.pos.lineno = 1; + input.pos.is_system_header = is_system_header; + input.path = path; /* indicate that we're at a new input */ - print_line_directive(&input.position, input_stack != NULL ? "1" : NULL); + print_line_directive(&input.pos, input_stack != NULL ? "1" : NULL); /* place a virtual '\n' so we realize we're at line begin */ - input.position.lineno = 0; - input.c = '\n'; + input.pos.lineno = 0; + input.c = '\n'; } FILE *close_pp_input(void) @@ -225,7 +239,7 @@ static void pop_restore_input(void) */ static void parse_error(const char *msg) { - errorf(&pp_token.base.source_position, "%s", msg); + errorf(&pp_token.base.pos, "%s", msg); } static inline void next_real_char(void) @@ -241,7 +255,7 @@ static inline void next_real_char(void) input.bufend = input.bufpos + n; } input.c = *input.bufpos++; - ++input.position.colno; + ++input.pos.colno; } /** @@ -253,7 +267,7 @@ static inline void put_back(utf32 const pc) { assert(input.bufpos > input.buf); *(--input.bufpos - input.buf + input.buf) = (char) pc; - --input.position.colno; + --input.pos.colno; } #define NEWLINE \ @@ -263,8 +277,8 @@ static inline void put_back(utf32 const pc) case '\n': \ next_char(); \ } \ - ++input.position.lineno; \ - input.position.colno = 1; \ + ++input.pos.lineno; \ + input.pos.colno = 1; \ goto newline; \ newline // Let it look like an ordinary case label. @@ -445,21 +459,96 @@ static utf32 parse_universal_char(unsigned const n_digits) obstack_1grow(&symbol_obstack, input.c); next_char(); } else { - errorf(&input.position, + errorf(&input.pos, "short universal character name, expected %u more digits", k); break; } } if (!is_universal_char_valid(v)) { - errorf(&input.position, + errorf(&input.pos, "\\%c%0*X is not a valid universal character name", n_digits == 4 ? 'u' : 'U', (int)n_digits, v); } return v; } -static bool is_universal_char_valid_identifier(utf32 const v) +static bool is_universal_char_valid_identifier_c99(utf32 const v) +{ + static const utf32 single_chars[] = { + 0x00AA, 0x00BA, 0x0386, 0x038C, 0x03DA, 0x03DC, 0x03DE, 0x03E0, + 0x1F59, 0x1F5B, 0x1F5D, 0x05BF, 0x09B2, 0x0A02, 0x0A5E, 0x0A74, + 0x0A8D, 0x0AD0, 0x0AE0, 0x0B9C, 0x0CDE, 0x0E84, 0x0E8A, 0x0E8D, + 0x0EA5, 0x0EA7, 0x0EC6, 0x0F00, 0x0F35, 0x0F37, 0x0F39, 0x0F97, + 0x0FB9, 0x00B5, 0x00B7, 0x02BB, 0x037A, 0x0559, 0x093D, 0x0B3D, + 0x1FBE, 0x2102, 0x2107, 0x2115, 0x2124, 0x2126, 0x2128 + }; + + static const utf32 ranges[][2] = { + {0x00C0, 0x00D6}, {0x00D8, 0x00F6}, {0x00F8, 0x01F5}, {0x01FA, 0x0217}, + {0x0250, 0x02A8}, {0x1E00, 0x1E9B}, {0x1EA0, 0x1EF9}, {0x0388, 0x038A}, + {0x038E, 0x03A1}, {0x03A3, 0x03CE}, {0x03D0, 0x03D6}, {0x03E2, 0x03F3}, + {0x1F00, 0x1F15}, {0x1F18, 0x1F1D}, {0x1F20, 0x1F45}, {0x1F48, 0x1F4D}, + {0x1F50, 0x1F57}, {0x1F5F, 0x1F7D}, {0x1F80, 0x1FB4}, {0x1FB6, 0x1FBC}, + {0x1FC2, 0x1FC4}, {0x1FC6, 0x1FCC}, {0x1FD0, 0x1FD3}, {0x1FD6, 0x1FDB}, + {0x1FE0, 0x1FEC}, {0x1FF2, 0x1FF4}, {0x1FF6, 0x1FFC}, {0x0401, 0x040C}, + {0x040E, 0x044F}, {0x0451, 0x045C}, {0x045E, 0x0481}, {0x0490, 0x04C4}, + {0x04C7, 0x04C8}, {0x04CB, 0x04CC}, {0x04D0, 0x04EB}, {0x04EE, 0x04F5}, + {0x04F8, 0x04F9}, {0x0531, 0x0556}, {0x0561, 0x0587}, {0x05B0, 0x05B9}, + {0x05BB, 0x05BD}, {0x05C1, 0x05C2}, {0x05D0, 0x05EA}, {0x05F0, 0x05F2}, + {0x0621, 0x063A}, {0x0640, 0x0652}, {0x0670, 0x06B7}, {0x06BA, 0x06BE}, + {0x06C0, 0x06CE}, {0x06D0, 0x06DC}, {0x06E5, 0x06E8}, {0x06EA, 0x06ED}, + {0x0901, 0x0903}, {0x0905, 0x0939}, {0x093E, 0x094D}, {0x0950, 0x0952}, + {0x0958, 0x0963}, {0x0981, 0x0983}, {0x0985, 0x098C}, {0x098F, 0x0990}, + {0x0993, 0x09A8}, {0x09AA, 0x09B0}, {0x09B6, 0x09B9}, {0x09BE, 0x09C4}, + {0x09C7, 0x09C8}, {0x09CB, 0x09CD}, {0x09DC, 0x09DD}, {0x09DF, 0x09E3}, + {0x09F0, 0x09F1}, {0x0A05, 0x0A0A}, {0x0A0F, 0x0A10}, {0x0A13, 0x0A28}, + {0x0A2A, 0x0A30}, {0x0A32, 0x0A33}, {0x0A35, 0x0A36}, {0x0A38, 0x0A39}, + {0x0A3E, 0x0A42}, {0x0A47, 0x0A48}, {0x0A4B, 0x0A4D}, {0x0A59, 0x0A5C}, + {0x0A81, 0x0A83}, {0x0A85, 0x0A8B}, {0x0A8F, 0x0A91}, {0x0A93, 0x0AA8}, + {0x0AAA, 0x0AB0}, {0x0AB2, 0x0AB3}, {0x0AB5, 0x0AB9}, {0x0ABD, 0x0AC5}, + {0x0AC7, 0x0AC9}, {0x0ACB, 0x0ACD}, {0x0B01, 0x0B03}, {0x0B05, 0x0B0C}, + {0x0B0F, 0x0B10}, {0x0B13, 0x0B28}, {0x0B2A, 0x0B30}, {0x0B32, 0x0B33}, + {0x0B36, 0x0B39}, {0x0B3E, 0x0B43}, {0x0B47, 0x0B48}, {0x0B4B, 0x0B4D}, + {0x0B5C, 0x0B5D}, {0x0B5F, 0x0B61}, {0x0B82, 0x0B83}, {0x0B85, 0x0B8A}, + {0x0B8E, 0x0B90}, {0x0B92, 0x0B95}, {0x0B99, 0x0B9A}, {0x0B9E, 0x0B9F}, + {0x0BA3, 0x0BA4}, {0x0BA8, 0x0BAA}, {0x0BAE, 0x0BB5}, {0x0BB7, 0x0BB9}, + {0x0BBE, 0x0BC2}, {0x0BC6, 0x0BC8}, {0x0BCA, 0x0BCD}, {0x0C01, 0x0C03}, + {0x0C05, 0x0C0C}, {0x0C0E, 0x0C10}, {0x0C12, 0x0C28}, {0x0C2A, 0x0C33}, + {0x0C35, 0x0C39}, {0x0C3E, 0x0C44}, {0x0C46, 0x0C48}, {0x0C4A, 0x0C4D}, + {0x0C60, 0x0C61}, {0x0C82, 0x0C83}, {0x0C85, 0x0C8C}, {0x0C8E, 0x0C90}, + {0x0C92, 0x0CA8}, {0x0CAA, 0x0CB3}, {0x0CB5, 0x0CB9}, {0x0CBE, 0x0CC4}, + {0x0CC6, 0x0CC8}, {0x0CCA, 0x0CCD}, {0x0CE0, 0x0CE1}, {0x0D02, 0x0D03}, + {0x0D05, 0x0D0C}, {0x0D0E, 0x0D10}, {0x0D12, 0x0D28}, {0x0D2A, 0x0D39}, + {0x0D3E, 0x0D43}, {0x0D46, 0x0D48}, {0x0D4A, 0x0D4D}, {0x0D60, 0x0D61}, + {0x0E01, 0x0E3A}, {0x0E40, 0x0E5B}, {0x0E81, 0x0E82}, {0x0E87, 0x0E88}, + {0x0E94, 0x0E97}, {0x0E99, 0x0E9F}, {0x0EA1, 0x0EA3}, {0x0EAA, 0x0EAB}, + {0x0EAD, 0x0EAE}, {0x0EB0, 0x0EB9}, {0x0EBB, 0x0EBD}, {0x0EC0, 0x0EC4}, + {0x0EC8, 0x0ECD}, {0x0EDC, 0x0EDD}, {0x0F18, 0x0F19}, {0x0F3E, 0x0F47}, + {0x0F49, 0x0F69}, {0x0F71, 0x0F84}, {0x0F86, 0x0F8B}, {0x0F90, 0x0F95}, + {0x0F99, 0x0FAD}, {0x0FB1, 0x0FB7}, {0x10A0, 0x10C5}, {0x10D0, 0x10F6}, + {0x3041, 0x3093}, {0x309B, 0x309C}, {0x30A1, 0x30F6}, {0x30FB, 0x30FC}, + {0x3105, 0x312C}, {0x4E00, 0x9FA5}, {0xAC00, 0xD7A3}, {0x0660, 0x0669}, + {0x06F0, 0x06F9}, {0x0966, 0x096F}, {0x09E6, 0x09EF}, {0x0A66, 0x0A6F}, + {0x0AE6, 0x0AEF}, {0x0B66, 0x0B6F}, {0x0BE7, 0x0BEF}, {0x0C66, 0x0C6F}, + {0x0CE6, 0x0CEF}, {0x0D66, 0x0D6F}, {0x0E50, 0x0E59}, {0x0ED0, 0x0ED9}, + {0x0F20, 0x0F33}, {0x02B0, 0x02B8}, {0x02BD, 0x02C1}, {0x02D0, 0x02D1}, + {0x02E0, 0x02E4}, {0x203F, 0x2040}, {0x210A, 0x2113}, {0x2118, 0x211D}, + {0x212A, 0x2131}, {0x2133, 0x2138}, {0x2160, 0x2182}, {0x3005, 0x3007}, + {0x3021, 0x3029}, + }; + for (size_t i = 0; i < sizeof(ranges)/sizeof(ranges[0]); ++i) { + if (ranges[i][0] <= v && v <= ranges[i][1]) + return true; + } + for (size_t i = 0; i < sizeof(single_chars)/sizeof(single_chars[0]); ++i) { + if (v == single_chars[i]) + return true; + } + return false; +} + +static bool is_universal_char_valid_identifier_c11(utf32 const v) { /* C11 Annex D.1 */ if ( v == 0x000A8) return true; @@ -510,14 +599,24 @@ static bool is_universal_char_valid_identifier(utf32 const v) return false; } -static bool is_universal_char_valid_identifier_start(utf32 const v) +static bool is_universal_char_valid_identifier(utf32 const v) +{ + if (c_mode & _C11) + return is_universal_char_valid_identifier_c11(v); + return is_universal_char_valid_identifier_c99(v); +} + +static bool is_universal_char_invalid_identifier_start(utf32 const v) { + if (! (c_mode & _C11)) + return false; + /* C11 Annex D.2 */ - if (0x0300 <= v && v <= 0x036F) return false; - if (0x1DC0 <= v && v <= 0x1DFF) return false; - if (0x20D0 <= v && v <= 0x20FF) return false; - if (0xFE20 <= v && v <= 0xFE2F) return false; - return true; + if (0x0300 <= v && v <= 0x036F) return true; + if (0x1DC0 <= v && v <= 0x1DFF) return true; + if (0x20D0 <= v && v <= 0x20FF) return true; + if (0xFE20 <= v && v <= 0xFE2F) return true; + return false; } /** @@ -599,23 +698,35 @@ string_t make_string(char const *const string) return sym_make_string(STRING_ENCODING_CHAR); } +static utf32 get_string_encoding_limit(string_encoding_t const enc) +{ + switch (enc) { + case STRING_ENCODING_CHAR: return 0xFF; + case STRING_ENCODING_CHAR16: return 0xFFFF; + case STRING_ENCODING_CHAR32: return 0xFFFFFFFF; + case STRING_ENCODING_UTF8: return 0xFFFFFFFF; + case STRING_ENCODING_WIDE: return 0xFFFFFFFF; // FIXME depends on settings + } + panic("invalid string encoding"); +} + static void parse_string(utf32 const delimiter, token_kind_t const kind, string_encoding_t const enc, char const *const context) { - const unsigned start_linenr = input.position.lineno; - eat(delimiter); + utf32 const limit = get_string_encoding_limit(enc); while (true) { switch (input.c) { case '\\': { if (resolve_escape_sequences) { utf32 const tc = parse_escape_sequence(); + if (tc > limit) { + warningf(WARN_OTHER, &pp_token.base.pos, + "escape sequence out of range"); + } if (enc == STRING_ENCODING_CHAR) { - if (tc >= 0x100) { - warningf(WARN_OTHER, &pp_token.base.source_position, "escape sequence out of range"); - } obstack_1grow(&symbol_obstack, tc); } else { obstack_grow_utf8(&symbol_obstack, tc); @@ -630,16 +741,12 @@ static void parse_string(utf32 const delimiter, token_kind_t const kind, } case NEWLINE: - errorf(&pp_token.base.source_position, "newline while parsing %s", context); + errorf(&pp_token.base.pos, "newline while parsing %s", context); break; - case EOF: { - source_position_t source_position; - source_position.input_name = pp_token.base.source_position.input_name; - source_position.lineno = start_linenr; - errorf(&source_position, "EOF while parsing %s", context); + case EOF: + errorf(&pp_token.base.pos, "EOF while parsing %s", context); goto end_of_string; - } default: if (input.c == delimiter) { @@ -878,7 +985,7 @@ restart:; if (current_expansion->expand_pos > 0) info.had_whitespace = saved->had_whitespace; current_expansion->expand_pos = pos; - pp_token.base.source_position = expansion_pos; + pp_token.base.pos = expansion_pos; return true; } @@ -919,7 +1026,7 @@ static void skip_multiline_comment(void) { info.had_whitespace = true; - unsigned start_linenr = input.position.lineno; + position_t const start_pos = input.pos; while (true) { switch (input.c) { case '/': @@ -931,8 +1038,8 @@ static void skip_multiline_comment(void) case '*': next_char(); if (input.c == '/') { - if (input.position.lineno != input.output_line) - info.whitespace_at_line_begin = input.position.colno; + if (input.pos.lineno != input.output_line) + info.whitespace_at_line_begin = input.pos.colno; next_char(); return; } @@ -941,13 +1048,9 @@ static void skip_multiline_comment(void) case NEWLINE: break; - case EOF: { - source_position_t source_position; - source_position.input_name = pp_token.base.source_position.input_name; - source_position.lineno = start_linenr; - errorf(&source_position, "at end of file while looking for comment end"); + case EOF: + errorf(&start_pos, "at end of file while looking for comment end"); return; - } default: next_char(); @@ -1048,6 +1151,17 @@ static inline void eat_token(token_kind_t const kind) next_input_token(); } +static string_encoding_t identify_encoding_prefix(symbol_t *const sym) +{ + if (sym == symbol_L) return STRING_ENCODING_WIDE; + if (c_mode & _C11) { + if (sym == symbol_U) return STRING_ENCODING_CHAR32; + if (sym == symbol_u) return STRING_ENCODING_CHAR16; + if (sym == symbol_u8) return STRING_ENCODING_UTF8; + } + return STRING_ENCODING_CHAR; +} + static void parse_symbol(void) { assert(obstack_object_size(&symbol_obstack) == 0); @@ -1075,12 +1189,12 @@ universal: utf32 const v = parse_universal_char(n); if (!is_universal_char_valid_identifier(v)) { if (is_universal_char_valid(v)) { - errorf(&input.position, + errorf(&input.pos, "universal character \\%c%0*X is not valid in an identifier", n == 4 ? 'u' : 'U', (int)n, v); } - } else if (obstack_object_size(&symbol_obstack) == 0 && !is_universal_char_valid_identifier_start(v)) { - errorf(&input.position, + } else if (obstack_object_size(&symbol_obstack) == 0 && is_universal_char_invalid_identifier_start(v)) { + errorf(&input.pos, "universal character \\%c%0*X is not valid as start of an identifier", n == 4 ? 'u' : 'U', (int)n, v); } else if (resolve_escape_sequences) { @@ -1105,19 +1219,27 @@ end_symbol: obstack_1grow(&symbol_obstack, '\0'); char *string = obstack_finish(&symbol_obstack); - /* might be a wide string or character constant ( L"string"/L'c' ) */ - if (input.c == '"' && string[0] == 'L' && string[1] == '\0') { - obstack_free(&symbol_obstack, string); - parse_string_literal(STRING_ENCODING_WIDE); - return; - } else if (input.c == '\'' && string[0] == 'L' && string[1] == '\0') { - obstack_free(&symbol_obstack, string); - parse_character_constant(STRING_ENCODING_WIDE); - return; - } - symbol_t *symbol = symbol_table_insert(string); + /* Might be a prefixed string or character constant: L/U/u/u8"string". */ + if (input.c == '"') { + string_encoding_t const enc = identify_encoding_prefix(symbol); + if (enc != STRING_ENCODING_CHAR) { + parse_string_literal(enc); + return; + } + } else if (input.c == '\'') { + string_encoding_t const enc = identify_encoding_prefix(symbol); + if (enc != STRING_ENCODING_CHAR) { + if (enc == STRING_ENCODING_UTF8) { + errorf(&pp_token.base.pos, + "'u8' is not a valid encoding for a chracter constant"); + } + parse_character_constant(enc); + return; + } + } + pp_token.kind = symbol->ID; pp_token.base.symbol = symbol; @@ -1200,8 +1322,8 @@ static void next_input_token(void) info.had_whitespace = false; } restart: - pp_token.base.source_position = input.position; - pp_token.base.symbol = NULL; + pp_token.base.pos = input.pos; + pp_token.base.symbol = NULL; switch (input.c) { case ' ': @@ -1384,8 +1506,8 @@ digraph_percentcolon: if (out) fputc('\n', out); if (input.c == (utf32)EOF) - --input.position.lineno; - print_line_directive(&input.position, "2"); + --input.pos.lineno; + print_line_directive(&input.pos, "2"); goto restart; } else { info.at_line_begin = true; @@ -1406,8 +1528,7 @@ digraph_percentcolon: default: dollar_sign: if (error_on_unknown_chars) { - errorf(&pp_token.base.source_position, - "unknown character '%lc' found\n", input.c); + errorf(&pp_token.base.pos, "unknown character '%lc' found", input.c); next_char(); goto restart; } else { @@ -1454,7 +1575,7 @@ static void print_quoted_string(const char *const string) fputc('"', out); } -static void print_line_directive(const source_position_t *pos, const char *add) +static void print_line_directive(const position_t *pos, const char *add) { if (!out) return; @@ -1478,20 +1599,20 @@ static bool emit_newlines(void) if (!out) return true; - unsigned delta = pp_token.base.source_position.lineno - input.output_line; + unsigned delta = pp_token.base.pos.lineno - input.output_line; if (delta == 0) return false; if (delta >= 9) { fputc('\n', out); - print_line_directive(&pp_token.base.source_position, NULL); + print_line_directive(&pp_token.base.pos, NULL); fputc('\n', out); } else { for (unsigned i = 0; i < delta; ++i) { fputc('\n', out); } } - input.output_line = pp_token.base.source_position.lineno; + input.output_line = pp_token.base.pos.lineno; unsigned whitespace = info.whitespace_at_line_begin; /* make sure there is at least 1 whitespace before a (macro-expanded) @@ -1613,14 +1734,13 @@ static bool pp_definitions_equal(const pp_definition_t *definition1, static void missing_macro_param_error(void) { - errorf(&pp_token.base.source_position, - "'#' is not followed by a macro parameter"); + errorf(&pp_token.base.pos, "'#' is not followed by a macro parameter"); } static bool is_defineable_token(char const *const context) { if (info.at_line_begin) { - errorf(&pp_token.base.source_position, "unexpected end of line after %s", context); + errorf(&pp_token.base.pos, "unexpected end of line after %s", context); } symbol_t *const symbol = pp_token.base.symbol; @@ -1635,7 +1755,8 @@ dollar_sign: default: no_ident: - errorf(&pp_token.base.source_position, "expected identifier after %s, got %K", context, &pp_token); + errorf(&pp_token.base.pos, "expected identifier after %s, got %K", + context, &pp_token); return false; } } @@ -1644,7 +1765,8 @@ no_ident: switch (symbol->pp_ID) { /* §6.10.8:4 */ case TP_defined: - errorf(&pp_token.base.source_position, "%K cannot be used as macro name in %s", &pp_token, context); + errorf(&pp_token.base.pos, "%K cannot be used as macro name in %s", + &pp_token, context); return false; default: @@ -1669,8 +1791,8 @@ static void parse_define_directive(void) pp_definition_t *new_definition = obstack_alloc(&pp_obstack, sizeof(new_definition[0])); memset(new_definition, 0, sizeof(new_definition[0])); - new_definition->symbol = symbol; - new_definition->source_position = input.position; + new_definition->symbol = symbol; + new_definition->pos = input.pos; /* this is probably the only place where spaces are significant in the * lexer (except for the fact that they separate tokens). #define b(x) @@ -1685,7 +1807,7 @@ static void parse_define_directive(void) new_definition->is_variadic = true; eat_token(T_DOTDOTDOT); if (pp_token.kind != ')') { - errorf(&input.position, + errorf(&input.pos, "'...' not at end of macro argument list"); goto error_out; } @@ -1694,9 +1816,9 @@ static void parse_define_directive(void) case T_IDENTIFIER: { pp_definition_t parameter; memset(¶meter, 0, sizeof(parameter)); - parameter.source_position = pp_token.base.source_position; - parameter.symbol = pp_token.base.symbol; - parameter.is_parameter = true; + parameter.pos = pp_token.base.pos; + parameter.symbol = pp_token.base.symbol; + parameter.is_parameter = true; obstack_grow(&pp_obstack, ¶meter, sizeof(parameter)); eat_token(T_IDENTIFIER); @@ -1706,7 +1828,7 @@ static void parse_define_directive(void) } if (pp_token.kind != ')') { - errorf(&pp_token.base.source_position, + errorf(&pp_token.base.pos, "expected ',' or ')' after identifier, got %K", &pp_token); goto error_out; @@ -1719,7 +1841,7 @@ static void parse_define_directive(void) goto finish_argument_list; default: - errorf(&pp_token.base.source_position, + errorf(&pp_token.base.pos, "expected identifier, '...' or ')' in #define argument list, got %K", &pp_token); goto error_out; @@ -1733,19 +1855,18 @@ static void parse_define_directive(void) = size / sizeof(new_definition->parameters[0]); new_definition->parameters = obstack_finish(&pp_obstack); for (size_t i = 0; i < new_definition->n_parameters; ++i) { - pp_definition_t *param = &new_definition->parameters[i]; - symbol_t *symbol = param->symbol; - pp_definition_t *previous = symbol->pp_definition; + pp_definition_t *const param = &new_definition->parameters[i]; + symbol_t *const param_sym = param->symbol; + pp_definition_t *const previous = param_sym->pp_definition; if (previous != NULL && previous->function_definition == new_definition) { - errorf(¶m->source_position, - "duplicate macro parameter '%Y'", symbol); + errorf(¶m->pos, "duplicate macro parameter '%Y'", param_sym); param->symbol = sym_anonymous; continue; } param->parent_expansion = previous; param->function_definition = new_definition; - symbol->pp_definition = param; + param_sym->pp_definition = param; } } else { next_input_token(); @@ -1756,8 +1877,7 @@ static void parse_define_directive(void) bool next_must_be_param = false; while (!info.at_line_begin) { if (pp_token.kind == T_IDENTIFIER) { - const symbol_t *symbol = pp_token.base.symbol; - pp_definition_t *definition = symbol->pp_definition; + pp_definition_t *const definition = pp_token.base.symbol->pp_definition; if (definition != NULL && definition->function_definition == new_definition) { pp_token.kind = T_MACRO_PARAMETER; @@ -1784,21 +1904,23 @@ static void parse_define_directive(void) if (new_definition->has_parameters) { for (size_t i = 0; i < new_definition->n_parameters; ++i) { - pp_definition_t *param = &new_definition->parameters[i]; - symbol_t *symbol = param->symbol; - if (symbol == sym_anonymous) + pp_definition_t *const param = &new_definition->parameters[i]; + symbol_t *const param_sym = param->symbol; + if (param_sym == sym_anonymous) continue; - assert(symbol->pp_definition == param); + assert(param_sym->pp_definition == param); assert(param->function_definition == new_definition); - symbol->pp_definition = param->parent_expansion; - param->parent_expansion = NULL; + param_sym->pp_definition = param->parent_expansion; + param->parent_expansion = NULL; } } pp_definition_t *old_definition = symbol->pp_definition; if (old_definition != NULL) { if (!pp_definitions_equal(old_definition, new_definition)) { - warningf(WARN_OTHER, &input.position, "multiple definition of macro '%Y' (first defined %P)", symbol, &old_definition->source_position); + warningf(WARN_OTHER, &input.pos, + "multiple definition of macro '%Y' (first defined %P)", + symbol, &old_definition->pos); } else { /* reuse the old definition */ obstack_free(&pp_obstack, new_definition); @@ -1834,7 +1956,7 @@ static void parse_undef_directive(void) next_input_token(); if (!info.at_line_begin) { - warningf(WARN_OTHER, &input.position, "extra tokens at end of #undef directive"); + warningf(WARN_OTHER, &input.pos, "extra tokens at end of #undef directive"); } eat_pp_directive(); } @@ -1850,8 +1972,8 @@ static const char *parse_headername(bool *system_include) return NULL; } - /* check wether we have a "... or <... headername */ - source_position_t position = input.position; + /* check whether we have a "... or <... headername */ + position_t pos = input.pos; switch (input.c) { { utf32 delimiter; @@ -1868,7 +1990,7 @@ parse_name: char *dummy = obstack_finish(&symbol_obstack); obstack_free(&symbol_obstack, dummy); } - errorf(&pp_token.base.source_position, + errorf(&pp_token.base.pos, "header name without closing '%c'", (char)delimiter); return NULL; @@ -1937,7 +2059,7 @@ error_invalid_input: obstack_free(&symbol_obstack, dummy); } - errorf(&pp_token.base.source_position, + errorf(&pp_token.base.pos, "expected \"FILENAME\" or after #include"); return NULL; } @@ -1947,7 +2069,7 @@ finish_headername: obstack_1grow(&symbol_obstack, '\0'); char *const headername = obstack_finish(&symbol_obstack); const char *identified = identify_string(headername); - pp_token.base.source_position = position; + pp_token.base.pos = pos; return identified; } @@ -1962,7 +2084,7 @@ static bool do_include(bool const bracket_include, bool const include_next, char } else { if (!bracket_include) { /* put dirname of current input on obstack */ - const char *filename = input.position.input_name; + const char *filename = input.pos.input_name; const char *last_slash = strrchr(filename, '/'); const char *full_name; if (last_slash != NULL) { @@ -2029,12 +2151,12 @@ static void parse_include_directive(bool const include_next) bool had_nonwhitespace = skip_till_newline(false); if (had_nonwhitespace) { - warningf(WARN_OTHER, &input.position, + warningf(WARN_OTHER, &input.pos, "extra tokens at end of #include directive"); } if (n_inputs > INCLUDE_LIMIT) { - errorf(&pp_token.base.source_position, "#include nested too deeply"); + errorf(&pp_token.base.pos, "#include nested too deeply"); /* eat \n or EOF */ next_input_token(); return; @@ -2050,7 +2172,7 @@ static void parse_include_directive(bool const include_next) if (res) { next_input_token(); } else { - errorf(&pp_token.base.source_position, "failed including '%s': %s", headername, strerror(errno)); + errorf(&pp_token.base.pos, "failed including '%s': %s", headername, strerror(errno)); pop_restore_input(); } } @@ -2079,9 +2201,9 @@ void check_unclosed_conditionals(void) pp_conditional_t *conditional = conditional_stack; if (conditional->in_else) { - errorf(&conditional->source_position, "unterminated #else"); + errorf(&conditional->pos, "unterminated #else"); } else { - errorf(&conditional->source_position, "unterminated condition"); + errorf(&conditional->pos, "unterminated condition"); } pop_conditional(); } @@ -2095,35 +2217,33 @@ static void parse_ifdef_ifndef_directive(bool const is_ifdef) if (skip_mode) { eat_pp_directive(); pp_conditional_t *conditional = push_conditional(); - conditional->source_position = pp_token.base.source_position; - conditional->skip = true; + conditional->pos = pp_token.base.pos; + conditional->skip = true; return; } if (pp_token.kind != T_IDENTIFIER || info.at_line_begin) { - errorf(&pp_token.base.source_position, - "expected identifier after #%s, got %K", + errorf(&pp_token.base.pos, "expected identifier after #%s, got %K", is_ifdef ? "ifdef" : "ifndef", &pp_token); eat_pp_directive(); /* just take the true case in the hope to avoid further errors */ condition = true; } else { - /* evaluate wether we are in true or false case */ + /* evaluate whether we are in true or false case */ condition = (bool)pp_token.base.symbol->pp_definition == is_ifdef; eat_token(T_IDENTIFIER); if (!info.at_line_begin) { - errorf(&pp_token.base.source_position, - "extra tokens at end of #%s", + errorf(&pp_token.base.pos, "extra tokens at end of #%s", is_ifdef ? "ifdef" : "ifndef"); eat_pp_directive(); } } pp_conditional_t *conditional = push_conditional(); - conditional->source_position = pp_token.base.source_position; - conditional->condition = condition; + conditional->pos = pp_token.base.pos; + conditional->condition = condition; if (!condition) { skip_mode = true; @@ -2136,21 +2256,21 @@ static void parse_else_directive(void) if (!info.at_line_begin) { if (!skip_mode) { - warningf(WARN_OTHER, &pp_token.base.source_position, "extra tokens at end of #else"); + warningf(WARN_OTHER, &pp_token.base.pos, "extra tokens at end of #else"); } eat_pp_directive(); } pp_conditional_t *conditional = conditional_stack; if (conditional == NULL) { - errorf(&pp_token.base.source_position, "#else without prior #if"); + errorf(&pp_token.base.pos, "#else without prior #if"); return; } if (conditional->in_else) { - errorf(&pp_token.base.source_position, + errorf(&pp_token.base.pos, "#else after #else (condition started %P)", - &conditional->source_position); + &conditional->pos); skip_mode = true; return; } @@ -2159,7 +2279,7 @@ static void parse_else_directive(void) if (!conditional->skip) { skip_mode = conditional->condition; } - conditional->source_position = pp_token.base.source_position; + conditional->pos = pp_token.base.pos; } static void parse_endif_directive(void) @@ -2168,14 +2288,14 @@ static void parse_endif_directive(void) if (!info.at_line_begin) { if (!skip_mode) { - warningf(WARN_OTHER, &pp_token.base.source_position, "extra tokens at end of #endif"); + warningf(WARN_OTHER, &pp_token.base.pos, "extra tokens at end of #endif"); } eat_pp_directive(); } pp_conditional_t *conditional = conditional_stack; if (conditional == NULL) { - errorf(&pp_token.base.source_position, "#endif without prior #if"); + errorf(&pp_token.base.pos, "#endif without prior #if"); return; } @@ -2208,7 +2328,7 @@ static void parse_pragma_directive(void) } if (pp_token.kind != T_IDENTIFIER) { - warningf(WARN_UNKNOWN_PRAGMAS, &pp_token.base.source_position, + warningf(WARN_UNKNOWN_PRAGMAS, &pp_token.base.pos, "expected identifier after #pragma"); eat_pp_directive(); return; @@ -2236,13 +2356,13 @@ static void parse_pragma_directive(void) } if (value == STDC_VALUE_UNKNOWN) { kind = STDC_UNKNOWN; - errorf(&pp_token.base.source_position, "bad STDC pragma argument"); + errorf(&pp_token.base.pos, "bad STDC pragma argument"); } } } eat_pp_directive(); if (kind == STDC_UNKNOWN) { - warningf(WARN_UNKNOWN_PRAGMAS, &pp_token.base.source_position, + warningf(WARN_UNKNOWN_PRAGMAS, &pp_token.base.pos, "encountered unknown #pragma"); } } @@ -2257,12 +2377,12 @@ static void parse_line_directive(void) long const line = strtol(pp_token.literal.string.begin, &end, 0); if (*end == '\0') { /* use offset -1 as this is about the next line */ - input.position.lineno = line - 1; + input.pos.lineno = line - 1; /* force output of line */ - input.output_line = input.position.lineno - 20; + input.output_line = input.pos.lineno - 20; } else { if (!skip_mode) { - errorf(&input.position, "'%S' is not a valid line number", + errorf(&input.pos, "'%S' is not a valid line number", &pp_token.literal.string); } } @@ -2272,8 +2392,8 @@ static void parse_line_directive(void) } if (pp_token.kind == T_STRING_LITERAL && pp_token.literal.string.encoding == STRING_ENCODING_CHAR) { - input.position.input_name = pp_token.literal.string.begin; - input.position.is_system_header = false; + input.pos.input_name = pp_token.literal.string.begin; + input.pos.is_system_header = false; next_input_token(); /* attempt to parse numeric flags as outputted by gcc preprocessor */ @@ -2287,7 +2407,7 @@ static void parse_line_directive(void) * currently we're only interested in "3" */ if (streq(pp_token.literal.string.begin, "3")) { - input.position.is_system_header = true; + input.pos.is_system_header = true; } next_input_token(); } @@ -2306,7 +2426,7 @@ static void parse_error_directive(void) bool const old_resolve_escape_sequences = resolve_escape_sequences; resolve_escape_sequences = false; - source_position_t const pos = pp_token.base.source_position; + position_t const pos = pp_token.base.pos; do { if (info.had_whitespace && obstack_object_size(&pp_obstack) != 0) obstack_1grow(&pp_obstack, ' '); @@ -2377,7 +2497,7 @@ line_directive: } else { skip: if (!skip_mode) { - errorf(&pp_token.base.source_position, "invalid preprocessing directive #%K", &pp_token); + errorf(&pp_token.base.pos, "invalid preprocessing directive #%K", &pp_token); } eat_pp_directive(); } @@ -2434,7 +2554,7 @@ restart: if (next_token == '(') { if (current_expansion == NULL) - expansion_pos = pp_token.base.source_position; + expansion_pos = pp_token.base.pos; next_preprocessing_token(); assert(pp_token.kind == '('); @@ -2456,7 +2576,7 @@ restart: } } else { if (current_expansion == NULL) - expansion_pos = pp_token.base.source_position; + expansion_pos = pp_token.base.pos; start_expanding(pp_definition); goto restart; } @@ -2484,7 +2604,7 @@ restart: finish_current_argument(); current_call->expand_pos++; if (current_call->expand_pos >= current_call->n_parameters) { - errorf(&pp_token.base.source_position, + errorf(&pp_token.base.pos, "too many arguments passed for macro '%Y'", current_call->symbol); current_argument = NULL; @@ -2552,7 +2672,7 @@ static void append_env_paths(searchpath_t *paths, const char *envvar) /* skip : */ if (*begin == ':') ++begin; - } while(*c != '\0'); + } while (*c != '\0'); } } @@ -2579,7 +2699,7 @@ static void setup_include_path(void) static void input_error(unsigned const delta_lines, unsigned const delta_cols, char const *const message) { - source_position_t pos = pp_token.base.source_position; + position_t pos = pp_token.base.pos; pos.lineno += delta_lines; pos.colno += delta_cols; errorf(&pos, "%s", message);