/* * print all assertions related to a given name */ static void print_assert(void *va) { struct assert *a = va; size_t i; for (i = 0; i < a->nbval; i ++) { fprintf(emit_output, "#assert %s(", HASH_ITEM_NAME(a)); print_token_fifo(a->val + i); fprintf(emit_output, ")\n"); } }
/* * print the content of a macro, in #define form */ static void print_macro(void *vm) { struct macro *m = vm; char *mname = HASH_ITEM_NAME(m); int x = check_special_macro(mname); size_t i; if (x != MAC_NONE) { fprintf(emit_output, "/* #define %s */ /* special */\n", mname); return; } fprintf(emit_output, "#define %s", mname); if (m->narg >= 0) { fprintf(emit_output, "("); for (i = 0; i < (size_t)(m->narg); i ++) { fprintf(emit_output, i ? ", %s" : "%s", m->arg[i]); } if (m->vaarg) { fputs(m->narg ? ", ..." : "...", emit_output); } fprintf(emit_output, ")"); } if (m->cval.length == 0) { fputc('\n', emit_output); return; } fputc(' ', emit_output); for (i = 0; i < m->cval.length;) { int tt = m->cval.t[i ++]; if (tt == MACROARG) { unsigned anum = m->cval.t[i]; if (anum >= 128) anum = ((anum & 127U) << 8) | m->cval.t[++ i]; if (anum == (unsigned)m->narg) fputs("__VA_ARGS__", emit_output); else fputs(m->arg[anum], emit_output); i ++; } else if (S_TOKEN(tt)) { fputs((char *)(m->cval.t + i), emit_output); i += 1 + strlen((char *)(m->cval.t + i)); } else fputs(operators_name[tt], emit_output); } fputc('\n', emit_output); }
/* * for #unassert */ int handle_unassert(struct lexer_state *ls) { int ltww; struct ucpp_token t; struct token_fifo atl; struct assert *a; int ret = -1; long l = ls->line; int nnp; size_t i; atl.art = atl.nt = 0; while (!next_token(ls)) { if (ls->ctok->type == NEWLINE) break; if (ttMWS(ls->ctok->type)) continue; if (ls->ctok->type == NAME) { if (!(a = HTT_get(&assertions, ls->ctok->name))) { ret = 0; goto handle_unassert_warp; } goto handle_unassert_next; } error(l, "illegal assertion name for #unassert"); goto handle_unassert_warp; } goto handle_unassert_trunc; handle_unassert_next: while (!next_token(ls)) { if (ls->ctok->type == NEWLINE) break; if (ttMWS(ls->ctok->type)) continue; if (ls->ctok->type != LPAR) { error(l, "syntax error in #unassert"); goto handle_unassert_warp; } goto handle_unassert_next2; } if (emit_assertions) fprintf(emit_output, "#unassert %s\n", HASH_ITEM_NAME(a)); HTT_del(&assertions, HASH_ITEM_NAME(a)); return 0; handle_unassert_next2: for (nnp = 1, ltww = 1; nnp && !next_token(ls);) { if (ls->ctok->type == NEWLINE) break; if (ltww && ttMWS(ls->ctok->type)) continue; ltww = ttMWS(ls->ctok->type); if (ls->ctok->type == LPAR) nnp ++; else if (ls->ctok->type == RPAR) { if (!(-- nnp)) goto handle_unassert_next3; } t.type = ls->ctok->type; if (S_TOKEN(t.type)) t.name = sdup(ls->ctok->name); aol(atl.t, atl.nt, t, TOKEN_LIST_MEMG); } goto handle_unassert_trunc; handle_unassert_next3: while (!next_token(ls) && ls->ctok->type != NEWLINE) { if (!ttWHI(ls->ctok->type) && (ls->flags & WARN_STANDARD)) { warning(l, "trailing garbage in #unassert"); } } if (atl.nt && ttMWS(atl.t[atl.nt - 1].type) && (-- atl.nt) == 0) freemem(atl.t); if (atl.nt == 0) { error(l, "void assertion in #unassert"); return ret; } for (i = 0; i < a->nbval && cmp_token_list(&atl, a->val + i); i ++); if (i != a->nbval) { /* we have it, undefine it */ del_token_fifo(a->val + i); if (i < (a->nbval - 1)) mmvwo(a->val + i, a->val + i + 1, (a->nbval - i - 1) * sizeof(struct token_fifo)); if ((-- a->nbval) == 0) freemem(a->val); if (emit_assertions) { fprintf(emit_output, "#unassert %s(", HASH_ITEM_NAME(a)); print_token_fifo(&atl); fputs(")\n", emit_output); } } ret = 0; goto handle_unassert_finish; handle_unassert_trunc: error(l, "unfinished #unassert"); handle_unassert_finish: if (atl.nt) del_token_fifo(&atl); return ret; handle_unassert_warp: while (!next_token(ls) && ls->ctok->type != NEWLINE); return ret; }
/* * for #assert * Assertions are not part of the ISO-C89 standard, but they are sometimes * encountered, for instance in Solaris standard include files. */ int handle_assert(struct lexer_state *ls) { int ina = 0, ltww; struct ucpp_token t; struct token_fifo *atl = 0; struct assert *a; char *aname; int ret = -1; long l = ls->line; int nnp; size_t i; while (!next_token(ls)) { if (ls->ctok->type == NEWLINE) break; if (ttMWS(ls->ctok->type)) continue; if (ls->ctok->type == NAME) { if (!(a = HTT_get(&assertions, ls->ctok->name))) { a = new_assertion(); aname = sdup(ls->ctok->name); ina = 1; } goto handle_assert_next; } error(l, "illegal assertion name for #assert"); goto handle_assert_warp_ign; } goto handle_assert_trunc; handle_assert_next: while (!next_token(ls)) { if (ls->ctok->type == NEWLINE) break; if (ttMWS(ls->ctok->type)) continue; if (ls->ctok->type != LPAR) { error(l, "syntax error in #assert"); goto handle_assert_warp_ign; } goto handle_assert_next2; } goto handle_assert_trunc; handle_assert_next2: atl = getmem(sizeof(struct token_fifo)); atl->art = atl->nt = 0; for (nnp = 1, ltww = 1; nnp && !next_token(ls);) { if (ls->ctok->type == NEWLINE) break; if (ltww && ttMWS(ls->ctok->type)) continue; ltww = ttMWS(ls->ctok->type); if (ls->ctok->type == LPAR) nnp ++; else if (ls->ctok->type == RPAR) { if (!(-- nnp)) goto handle_assert_next3; } t.type = ls->ctok->type; if (S_TOKEN(t.type)) t.name = sdup(ls->ctok->name); aol(atl->t, atl->nt, t, TOKEN_LIST_MEMG); } goto handle_assert_trunc; handle_assert_next3: while (!next_token(ls) && ls->ctok->type != NEWLINE) { if (!ttWHI(ls->ctok->type) && (ls->flags & WARN_STANDARD)) { warning(l, "trailing garbage in #assert"); } } if (atl->nt && ttMWS(atl->t[atl->nt - 1].type) && (-- atl->nt) == 0) freemem(atl->t); if (atl->nt == 0) { error(l, "void assertion in #assert"); goto handle_assert_error; } for (i = 0; i < a->nbval && cmp_token_list(atl, a->val + i); i ++); if (i != a->nbval) { /* we already have it */ ret = 0; goto handle_assert_error; } /* This is a new assertion. Let's keep it. */ aol(a->val, a->nbval, *atl, TOKEN_LIST_MEMG); if (ina) { HTT_put(&assertions, a, aname); freemem(aname); } if (emit_assertions) { fprintf(emit_output, "#assert %s(", HASH_ITEM_NAME(a)); print_token_fifo(atl); fputs(")\n", emit_output); } freemem(atl); return 0; handle_assert_trunc: error(l, "unfinished #assert"); handle_assert_error: if (atl) { del_token_fifo(atl); freemem(atl); } if (ina) { freemem(aname); freemem(a); } return ret; handle_assert_warp_ign: while (!next_token(ls) && ls->ctok->type != NEWLINE); if (ina) { freemem(aname); freemem(a); } return ret; }