aboutsummaryrefslogtreecommitdiff
path: root/tccgen.c
diff options
context:
space:
mode:
authorMichael Matz <matz@suse.de>2017-03-06 21:43:48 +0100
committerMichael Matz <matz@suse.de>2017-05-02 03:07:37 +0200
commit21b12ea10d3c04d66c81633b67be29c42d5dcb3a (patch)
tree97dd50f5be597e72a58eb881e130374d4aa7237c /tccgen.c
parent328b06a3fc0984b80ac94fb653ca1002bf915a4e (diff)
downloadtinycc-21b12ea10d3c04d66c81633b67be29c42d5dcb3a.tar.gz
tinycc-21b12ea10d3c04d66c81633b67be29c42d5dcb3a.tar.bz2
Factor some code
Three places that skip (and store) tokens in some fashion can be factored a bit.
Diffstat (limited to 'tccgen.c')
-rw-r--r--tccgen.c110
1 files changed, 47 insertions, 63 deletions
diff --git a/tccgen.c b/tccgen.c
index e34f452..e3ba5cc 100644
--- a/tccgen.c
+++ b/tccgen.c
@@ -5902,6 +5902,42 @@ static void block(int *bsym, int *csym, int is_expr)
}
}
+/* This skips over a stream of tokens containing balanced {} and ()
+ pairs, stopping at outer ',' ';' and '}'. If STR then allocates
+ and stores the skipped tokens in *STR. This doesn't check if
+ () and {} are nested correctly, i.e. "({)}" is accepted. */
+static void skip_or_save_block(TokenString **str)
+{
+ int level = 0;
+ if (str)
+ *str = tok_str_alloc();
+
+ while ((level > 0 || (tok != '}' && tok != ',' && tok != ';'))) {
+ int t;
+ if (tok == TOK_EOF) {
+ if (str || level > 0)
+ tcc_error("unexpected end of file");
+ else
+ break;
+ }
+ if (str)
+ tok_str_add_tok(*str);
+ t = tok;
+ next();
+ if (t == '{' || t == '(') {
+ level++;
+ } else if (t == '}' || t == ')') {
+ level--;
+ if (level == 0)
+ break;
+ }
+ }
+ if (str) {
+ tok_str_add(*str, -1);
+ tok_str_add(*str, 0);
+ }
+}
+
#define EXPR_CONST 1
#define EXPR_ANY 2
@@ -6256,7 +6292,7 @@ static void init_putz(Section *sec, unsigned long c, int size)
static void decl_initializer(CType *type, Section *sec, unsigned long c,
int first, int size_only)
{
- int index, array_length, n, no_oblock, nb, parlevel, parlevel1, i;
+ int index, array_length, n, no_oblock, nb, i;
int size1, align1;
int have_elem;
Sym *s, *f;
@@ -6429,25 +6465,9 @@ static void decl_initializer(CType *type, Section *sec, unsigned long c,
But GNU C supports it, so we need to recurse even into
subfields of structs and arrays when size_only is set. */
/* just skip expression */
- parlevel = parlevel1 = 0;
- while ((parlevel > 0 || parlevel1 > 0 ||
- (tok != '}' && tok != ',')) && tok != -1) {
- if (tok == '(')
- parlevel++;
- else if (tok == ')') {
- if (parlevel == 0 && parlevel1 == 0)
- break;
- parlevel--;
- }
- else if (tok == '{')
- parlevel1++;
- else if (tok == '}') {
- if (parlevel == 0 && parlevel1 == 0)
- break;
- parlevel1--;
- }
- next();
- }
+ do {
+ skip_or_save_block(NULL);
+ } while (tok != '}' && tok != ',' && tok != -1);
} else {
if (!have_elem) {
/* This should happen only when we haven't parsed
@@ -6472,7 +6492,6 @@ static void decl_initializer_alloc(CType *type, AttributeDef *ad, int r,
int has_init, int v, int scope)
{
int size, align, addr, data_offset;
- int level;
ParseState saved_parse_state = {0};
TokenString *init_str = NULL;
Section *sec;
@@ -6500,33 +6519,18 @@ static void decl_initializer_alloc(CType *type, AttributeDef *ad, int r,
if (!has_init)
tcc_error("unknown type size");
/* get all init string */
- init_str = tok_str_alloc();
if (has_init == 2) {
+ init_str = tok_str_alloc();
/* only get strings */
while (tok == TOK_STR || tok == TOK_LSTR) {
tok_str_add_tok(init_str);
next();
}
+ tok_str_add(init_str, -1);
+ tok_str_add(init_str, 0);
} else {
- level = 0;
- while (level > 0 || (tok != ',' && tok != ';')) {
- if (tok < 0)
- tcc_error("unexpected end of file in initializer");
- tok_str_add_tok(init_str);
- if (tok == '{')
- level++;
- else if (tok == '}') {
- level--;
- if (level <= 0) {
- next();
- break;
- }
- }
- next();
- }
+ skip_or_save_block(&init_str);
}
- tok_str_add(init_str, -1);
- tok_str_add(init_str, 0);
/* compute size */
save_parse_state(&saved_parse_state);
@@ -7029,7 +7033,6 @@ static int decl0(int l, int is_for_loop_init)
the compilation unit only if they are used */
if ((type.t & (VT_INLINE | VT_STATIC)) ==
(VT_INLINE | VT_STATIC)) {
- int block_level;
struct InlineFunc *fn;
const char *filename;
@@ -7037,28 +7040,9 @@ static int decl0(int l, int is_for_loop_init)
fn = tcc_malloc(sizeof *fn + strlen(filename));
strcpy(fn->filename, filename);
fn->sym = sym;
- fn->func_str = tok_str_alloc();
-
- block_level = 0;
- for(;;) {
- int t;
- if (tok == TOK_EOF)
- tcc_error("unexpected end of file");
- tok_str_add_tok(fn->func_str);
- t = tok;
- next();
- if (t == '{') {
- block_level++;
- } else if (t == '}') {
- block_level--;
- if (block_level == 0)
- break;
- }
- }
- tok_str_add(fn->func_str, -1);
- tok_str_add(fn->func_str, 0);
- dynarray_add(&tcc_state->inline_fns, &tcc_state->nb_inline_fns, fn);
-
+ skip_or_save_block(&fn->func_str);
+ dynarray_add(&tcc_state->inline_fns,
+ &tcc_state->nb_inline_fns, fn);
} else {
/* compute text section */
cur_text_section = ad.section;