Three places that skip (and store) tokens in some fashion can be factored a bit.
Unified · Split
| @@ -5902,6 +5902,42 @@ static void block(int *bsym, int *csym, int is_expr) · 5901 unmodified lines | ||
| 5902 | 5902 | } |
| 5903 | 5903 | } |
| 5904 | 5904 | |
| 5905 | +/* This skips over a stream of tokens containing balanced {} and () | |
| 5906 | + pairs, stopping at outer ',' ';' and '}'. If STR then allocates | |
| 5907 | + and stores the skipped tokens in *STR. This doesn't check if | |
| 5908 | + () and {} are nested correctly, i.e. "({)}" is accepted. */ | |
| 5909 | +static void skip_or_save_block(TokenString **str) | |
| 5910 | +{ | |
| 5911 | + int level = 0; | |
| 5912 | + if (str) | |
| 5913 | + *str = tok_str_alloc(); | |
| 5914 | + | |
| 5915 | + while ((level > 0 || (tok != '}' && tok != ',' && tok != ';'))) { | |
| 5916 | + int t; | |
| 5917 | + if (tok == TOK_EOF) { | |
| 5918 | + if (str || level > 0) | |
| 5919 | + tcc_error("unexpected end of file"); | |
| 5920 | + else | |
| 5921 | + break; | |
| 5922 | + } | |
| 5923 | + if (str) | |
| 5924 | + tok_str_add_tok(*str); | |
| 5925 | + t = tok; | |
| 5926 | + next(); | |
| 5927 | + if (t == '{' || t == '(') { | |
| 5928 | + level++; | |
| 5929 | + } else if (t == '}' || t == ')') { | |
| 5930 | + level--; | |
| 5931 | + if (level == 0) | |
| 5932 | + break; | |
| 5933 | + } | |
| 5934 | + } | |
| 5935 | + if (str) { | |
| 5936 | + tok_str_add(*str, -1); | |
| 5937 | + tok_str_add(*str, 0); | |
| 5938 | + } | |
| 5939 | +} | |
| 5940 | + | |
| 5905 | 5941 | #define EXPR_CONST 1 |
| 5906 | 5942 | #define EXPR_ANY 2 |
| 5907 | 5943 | |
| @@ -6256,7 +6292,7 @@ static void init_putz(Section *sec, unsigned long c, int size) · 348 unmodified lines | ||
| 6256 | 6292 | static void decl_initializer(CType *type, Section *sec, unsigned long c, |
| 6257 | 6293 | int first, int size_only) |
| 6258 | 6294 | { |
| 6259 | − int index, array_length, n, no_oblock, nb, parlevel, parlevel1, i; | |
| 6295 | + int index, array_length, n, no_oblock, nb, i; | |
| 6260 | 6296 | int size1, align1; |
| 6261 | 6297 | int have_elem; |
| 6262 | 6298 | Sym *s, *f; |
| @@ -6429,25 +6465,9 @@ static void decl_initializer(CType *type, Section *sec, unsigned long c, · 166 unmodified lines | ||
| 6429 | 6465 | But GNU C supports it, so we need to recurse even into |
| 6430 | 6466 | subfields of structs and arrays when size_only is set. */ |
| 6431 | 6467 | /* just skip expression */ |
| 6432 | − parlevel = parlevel1 = 0; | |
| 6433 | − while ((parlevel > 0 || parlevel1 > 0 || | |
| 6434 | − (tok != '}' && tok != ',')) && tok != -1) { | |
| 6435 | − if (tok == '(') | |
| 6436 | − parlevel++; | |
| 6437 | − else if (tok == ')') { | |
| 6438 | − if (parlevel == 0 && parlevel1 == 0) | |
| 6439 | − break; | |
| 6440 | − parlevel--; | |
| 6441 | − } | |
| 6442 | − else if (tok == '{') | |
| 6443 | − parlevel1++; | |
| 6444 | − else if (tok == '}') { | |
| 6445 | − if (parlevel == 0 && parlevel1 == 0) | |
| 6446 | − break; | |
| 6447 | − parlevel1--; | |
| 6448 | − } | |
| 6449 | − next(); | |
| 6450 | − } | |
| 6468 | + do { | |
| 6469 | + skip_or_save_block(NULL); | |
| 6470 | + } while (tok != '}' && tok != ',' && tok != -1); | |
| 6451 | 6471 | } else { |
| 6452 | 6472 | if (!have_elem) { |
| 6453 | 6473 | /* This should happen only when we haven't parsed |
| @@ -6472,7 +6492,6 @@ static void decl_initializer_alloc(CType *type, AttributeDef *ad, int r, · 18 unmodified lines | ||
| 6472 | 6492 | int has_init, int v, int scope) |
| 6473 | 6493 | { |
| 6474 | 6494 | int size, align, addr, data_offset; |
| 6475 | − int level; | |
| 6476 | 6495 | ParseState saved_parse_state = {0}; |
| 6477 | 6496 | TokenString *init_str = NULL; |
| 6478 | 6497 | Section *sec; |
| @@ -6500,33 +6519,18 @@ static void decl_initializer_alloc(CType *type, AttributeDef *ad, int r, · 21 unmodified lines | ||
| 6500 | 6519 | if (!has_init) |
| 6501 | 6520 | tcc_error("unknown type size"); |
| 6502 | 6521 | /* get all init string */ |
| 6503 | − init_str = tok_str_alloc(); | |
| 6504 | 6522 | if (has_init == 2) { |
| 6523 | + init_str = tok_str_alloc(); | |
| 6505 | 6524 | /* only get strings */ |
| 6506 | 6525 | while (tok == TOK_STR || tok == TOK_LSTR) { |
| 6507 | 6526 | tok_str_add_tok(init_str); |
| 6508 | 6527 | next(); |
| 6509 | 6528 | } |
| 6529 | + tok_str_add(init_str, -1); | |
| 6530 | + tok_str_add(init_str, 0); | |
| 6510 | 6531 | } else { |
| 6511 | − level = 0; | |
| 6512 | − while (level > 0 || (tok != ',' && tok != ';')) { | |
| 6513 | − if (tok < 0) | |
| 6514 | − tcc_error("unexpected end of file in initializer"); | |
| 6515 | − tok_str_add_tok(init_str); | |
| 6516 | − if (tok == '{') | |
| 6517 | − level++; | |
| 6518 | − else if (tok == '}') { | |
| 6519 | − level--; | |
| 6520 | − if (level <= 0) { | |
| 6521 | − next(); | |
| 6522 | − break; | |
| 6523 | − } | |
| 6524 | − } | |
| 6525 | − next(); | |
| 6526 | − } | |
| 6532 | + skip_or_save_block(&init_str); | |
| 6527 | 6533 | } |
| 6528 | − tok_str_add(init_str, -1); | |
| 6529 | − tok_str_add(init_str, 0); | |
| 6530 | 6534 | |
| 6531 | 6535 | /* compute size */ |
| 6532 | 6536 | save_parse_state(&saved_parse_state); |
| @@ -7029,7 +7033,6 @@ static int decl0(int l, int is_for_loop_init) · 496 unmodified lines | ||
| 7029 | 7033 | the compilation unit only if they are used */ |
| 7030 | 7034 | if ((type.t & (VT_INLINE | VT_STATIC)) == |
| 7031 | 7035 | (VT_INLINE | VT_STATIC)) { |
| 7032 | − int block_level; | |
| 7033 | 7036 | struct InlineFunc *fn; |
| 7034 | 7037 | const char *filename; |
| 7035 | 7038 | |
| @@ -7037,28 +7040,9 @@ static int decl0(int l, int is_for_loop_init) · 1 unmodified line | ||
| 7037 | 7040 | fn = tcc_malloc(sizeof *fn + strlen(filename)); |
| 7038 | 7041 | strcpy(fn->filename, filename); |
| 7039 | 7042 | fn->sym = sym; |
| 7040 | − fn->func_str = tok_str_alloc(); | |
| 7041 | − | |
| 7042 | − block_level = 0; | |
| 7043 | − for(;;) { | |
| 7044 | − int t; | |
| 7045 | − if (tok == TOK_EOF) | |
| 7046 | − tcc_error("unexpected end of file"); | |
| 7047 | − tok_str_add_tok(fn->func_str); | |
| 7048 | − t = tok; | |
| 7049 | − next(); | |
| 7050 | − if (t == '{') { | |
| 7051 | − block_level++; | |
| 7052 | − } else if (t == '}') { | |
| 7053 | − block_level--; | |
| 7054 | − if (block_level == 0) | |
| 7055 | − break; | |
| 7056 | − } | |
| 7057 | − } | |
| 7058 | − tok_str_add(fn->func_str, -1); | |
| 7059 | − tok_str_add(fn->func_str, 0); | |
| 7060 | − dynarray_add(&tcc_state->inline_fns, &tcc_state->nb_inline_fns, fn); | |
| 7061 | − | |
| 7043 | + skip_or_save_block(&fn->func_str); | |
| 7044 | + dynarray_add(&tcc_state->inline_fns, | |
| 7045 | + &tcc_state->nb_inline_fns, fn); | |
| 7062 | 7046 | } else { |
| 7063 | 7047 | /* compute text section */ |
| 7064 | 7048 | cur_text_section = ad.section; |