diff options
Diffstat (limited to 'wrapperhelper/src/generator.c')
| -rw-r--r-- | wrapperhelper/src/generator.c | 192 |
1 files changed, 140 insertions, 52 deletions
diff --git a/wrapperhelper/src/generator.c b/wrapperhelper/src/generator.c index 3df744cb..98e254ed 100644 --- a/wrapperhelper/src/generator.c +++ b/wrapperhelper/src/generator.c @@ -136,7 +136,7 @@ void request_print_check(request_t *req) { } } } -void request_del(request_t *req) { +static void request_del(request_t *req) { string_del(req->obj_name); if (req->has_default) { switch (req->def.rty) { @@ -163,6 +163,16 @@ void request_del(request_t *req) { } } } +static void reference_del(reference_t *ref) { + switch (ref->typ) { + case REF_REQ: + request_del(&ref->req); + break; + case REF_LINE: + string_del(ref->line); + break; + } +} static int valid_reqtype(string_t *t) { const char *s = string_content(t); @@ -244,23 +254,34 @@ static void request_output(FILE *f, request_t *req) { } } } -void output_from_requests(FILE *f, VECTOR(requests) *reqs) { +static void reference_output(FILE *f, reference_t *ref) { + switch (ref->typ) { + case REF_REQ: + request_output(f, &ref->req); + break; + case REF_LINE: + fputs(string_content(ref->line), f); + fputc('\n', f); + break; + } +} +void output_from_references(FILE *f, VECTOR(references) *reqs) { fprintf(f, "#if !(defined(GO) && defined(GOM) && defined(GO2) && defined(DATA))\n#error Meh...\n#endif\n\n"); - vector_for(requests, req, reqs) { - request_output(f, req); + vector_for(references, req, reqs) { + reference_output(f, req); } } -VECTOR_IMPL(requests, request_del) +VECTOR_IMPL(references, reference_del) -VECTOR(requests) *requests_from_file(const char *filename, FILE *f) { +VECTOR(references) *references_from_file(const char *filename, FILE *f) { prepare_t *prep = prepare_new_file(f, filename); if (!prep) { - printf("Failed to create the prepare structure for the requests file\n"); + printf("Failed to create the prepare structure for the reference file\n"); return NULL; } - VECTOR(requests) *ret = vector_new(requests); + VECTOR(references) *ret = vector_new(references); if (!ret) { prepare_del(prep); return NULL; @@ -273,40 +294,80 @@ VECTOR(requests) *requests_from_file(const char *filename, FILE *f) { do { tok = pre_next_token(prep, 0); if (tok.tokt == PPTOK_NEWLINE) ++lineno; + else preproc_token_del(&tok); // NEWLINE has no destructor } while (!preproc_token_isend(&tok) && (lineno < 4)); // TODO: better conditionals handling // Also, for now assume we have no definition int if_depth = 0, entered_depth = 0; + string_t *line = string_new(); + if (!line) { + printf("Error: failed to allocate new string for new reference line\n"); + } + +#define ADD_CHAR(c, has_destr, what) \ + if (!string_add_char(line, c)) { \ + printf("Error: failed to add " what "\n"); \ + if (has_destr) preproc_token_del(&tok); \ + goto failed; \ + } +#define ADD_CSTR(cstr, has_destr, what) \ + if (!string_add_cstr(line, cstr)) { \ + printf("Error: failed to add " what "\n"); \ + if (has_destr) preproc_token_del(&tok); \ + goto failed; \ + } +#define ADD_STR(str, has_destr, what) \ + if (!string_add_string(line, str)) { \ + printf("Error: failed to add " what "\n"); \ + if (has_destr) preproc_token_del(&tok); \ + goto failed; \ + } +#define PUSH_LINE(has_destr) \ + string_trim(line); \ + if (!vector_push(references, ret, ((reference_t){.typ = REF_LINE, .line = line}))) { \ + printf("Error: failed to memorize reference line %d\n", lineno); \ + if (has_destr) preproc_token_del(&tok); \ + goto failed; \ + } \ + line = string_new(); \ + if (!line) { \ + printf("Error: failed to allocate new string for new reference line\n"); \ + } + while (1) { int is_comment = 0; tok = pre_next_token(prep, 1); - while (tok.tokt == PPTOK_START_LINE_COMMENT) { + if (tok.tokt == PPTOK_START_LINE_COMMENT) { + ADD_CSTR("//", 0, "start of comment") is_comment = 1; // Empty destructor - tok = pre_next_token(prep, 1); + tok = pre_next_token(prep, 0); // tok is IDENT, NEWLINE, INVALID or BLANK + while ((tok.tokt == PPTOK_BLANK) && ((tok.tokv.c == ' ') || (tok.tokv.c == '\t'))) { + ADD_CHAR(tok.tokv.c, 0, "start of comment") + // Empty destructor + tok = pre_next_token(prep, 0); // tok is IDENT, NEWLINE, INVALID or BLANK + } } if ((tok.tokt == PPTOK_SYM) && (tok.tokv.sym == SYM_HASH)) { - if (is_comment) { - preproc_token_del(&tok); - tok = pre_next_newline_token(prep); // Returns a newline - ++lineno; - continue; - } + ADD_CHAR('#', 0, "start of preprocessor command") tok = pre_next_token(prep, 0); if (tok.tokt != PPTOK_IDENT) { - printf("Error: invalid requests file: invalid preprocessor line\n"); + printf("Error: invalid reference file: invalid preprocessor line\n"); preproc_token_del(&tok); goto failed; } + ADD_STR(tok.tokv.str, 1, "preprocessor command") if (!strcmp(string_content(tok.tokv.str), "ifdef")) { string_del(tok.tokv.str); tok = pre_next_token(prep, 0); if (tok.tokt != PPTOK_IDENT) { - printf("Error: invalid requests file: invalid '#ifdef' line\n"); + printf("Error: invalid reference file: invalid '#ifdef' line\n"); preproc_token_del(&tok); goto failed; } + ADD_CHAR(' ', 1, "preprocessor command") + ADD_STR(tok.tokv.str, 1, "preprocessor command") ++if_depth; string_del(tok.tokv.str); tok = pre_next_token(prep, 0); @@ -314,10 +375,12 @@ VECTOR(requests) *requests_from_file(const char *filename, FILE *f) { string_del(tok.tokv.str); tok = pre_next_token(prep, 0); if (tok.tokt != PPTOK_IDENT) { - printf("Error: invalid requests file: invalid '#ifndef' line\n"); + printf("Error: invalid reference file: invalid '#ifndef' line\n"); preproc_token_del(&tok); goto failed; } + ADD_CHAR(' ', 1, "preprocessor command") + ADD_STR(tok.tokv.str, 1, "preprocessor command") if (if_depth == entered_depth) ++entered_depth; ++if_depth; string_del(tok.tokv.str); @@ -333,7 +396,7 @@ VECTOR(requests) *requests_from_file(const char *filename, FILE *f) { if (if_depth == entered_depth) --entered_depth; --if_depth; } else { - printf("Error: invalid requests file: invalid preprocessor command '%s'\n", string_content(tok.tokv.str)); + printf("Error: invalid reference file: invalid preprocessor command '%s'\n", string_content(tok.tokv.str)); string_del(tok.tokv.str); goto failed; } @@ -341,6 +404,7 @@ VECTOR(requests) *requests_from_file(const char *filename, FILE *f) { preproc_token_del(&tok); tok = pre_next_token(prep, 0); } + PUSH_LINE(0) ++lineno; if (preproc_token_isend(&tok)) { if (tok.tokt == PPTOK_EOF) goto success; @@ -350,6 +414,7 @@ VECTOR(requests) *requests_from_file(const char *filename, FILE *f) { } } } else if (tok.tokt == PPTOK_NEWLINE) { + PUSH_LINE(0) ++lineno; } else if (tok.tokt == PPTOK_EOF) { goto success; @@ -362,6 +427,8 @@ VECTOR(requests) *requests_from_file(const char *filename, FILE *f) { || !strcmp(string_content(tok.tokv.str), "GOW2") || !strcmp(string_content(tok.tokv.str), "GOWD") || !strcmp(string_content(tok.tokv.str), "GOWM"))) { + string_clear(line); + if (is_comment) prepare_mark_nocomment(prep); int isweak = (string_content(tok.tokv.str)[2] == 'W'); request_t req = { .has_default = 0, @@ -381,14 +448,14 @@ VECTOR(requests) *requests_from_file(const char *filename, FILE *f) { string_del(tok.tokv.str); tok = pre_next_token(prep, 0); if ((tok.tokt != PPTOK_SYM) || (tok.tokv.sym != SYM_LPAREN)) { - printf("Error: invalid requests file: invalid GO line %d (lparen)\n", lineno); + printf("Error: invalid reference file: invalid GO line %d (lparen)\n", lineno); preproc_token_del(&tok); goto failed; } // Empty destructor tok = pre_next_token(prep, 0); if (tok.tokt != PPTOK_IDENT) { - printf("Error: invalid requests file: invalid GO line %d (obj_name)\n", lineno); + printf("Error: invalid reference file: invalid GO line %d (obj_name)\n", lineno); preproc_token_del(&tok); goto failed; } @@ -396,7 +463,7 @@ VECTOR(requests) *requests_from_file(const char *filename, FILE *f) { // Token moved tok = pre_next_token(prep, 0); if ((tok.tokt != PPTOK_SYM) || (tok.tokv.sym != SYM_COMMA)) { - printf("Error: invalid requests file: invalid GO line %d (comma)\n", lineno); + printf("Error: invalid reference file: invalid GO line %d (comma)\n", lineno); string_del(req.obj_name); preproc_token_del(&tok); goto failed; @@ -410,7 +477,7 @@ VECTOR(requests) *requests_from_file(const char *filename, FILE *f) { tok = pre_next_token(prep, 0); if ((req.def.rty == RQT_FUN_2) || (req.def.rty == RQT_FUN_D)) { if ((tok.tokt != PPTOK_SYM) || (tok.tokv.sym != SYM_COMMA)) { - printf("Error: invalid requests file: invalid GO line %d (comma 2)\n", lineno); + printf("Error: invalid reference file: invalid GO line %d (comma 2)\n", lineno); string_del(req.obj_name); string_del(req.def.fun.typ); preproc_token_del(&tok); @@ -419,7 +486,7 @@ VECTOR(requests) *requests_from_file(const char *filename, FILE *f) { // Empty destructor tok = pre_next_token(prep, 0); if (tok.tokt != PPTOK_IDENT) { - printf("Error: invalid requests file: invalid GO line %d (redirect)\n", lineno); + printf("Error: invalid reference file: invalid GO line %d (redirect)\n", lineno); string_del(req.obj_name); string_del(req.def.fun.typ); preproc_token_del(&tok); @@ -430,7 +497,7 @@ VECTOR(requests) *requests_from_file(const char *filename, FILE *f) { tok = pre_next_token(prep, 0); } if ((tok.tokt != PPTOK_SYM) || (tok.tokv.sym != SYM_RPAREN)) { - printf("Error: invalid requests file: invalid GO line %d (rparen)\n", lineno); + printf("Error: invalid reference file: invalid GO line %d (rparen)\n", lineno); string_del(req.obj_name); string_del(req.def.fun.typ); if (req.def.fun.fun2) string_del(req.def.fun.fun2); @@ -441,7 +508,7 @@ VECTOR(requests) *requests_from_file(const char *filename, FILE *f) { tok = pre_next_token(prep, 0); } if (tok.tokt != PPTOK_NEWLINE) { - printf("Error: invalid requests file: invalid GO line %d (newline)\n", lineno); + printf("Error: invalid reference file: invalid GO line %d (newline)\n", lineno); string_del(req.obj_name); if (req.def.fun.typ) string_del(req.def.fun.typ); if (req.def.fun.fun2) string_del(req.def.fun.fun2); @@ -449,14 +516,16 @@ VECTOR(requests) *requests_from_file(const char *filename, FILE *f) { goto failed; } if (if_depth == entered_depth) { - if (!vector_push(requests, ret, req)) { - printf("Error: failed to add request for %s\n", string_content(req.obj_name)); + if (!vector_push(references, ret, ((reference_t){.typ = REF_REQ, .req = req}))) { + printf("Error: failed to add reference for %s\n", string_content(req.obj_name)); string_del(req.obj_name); if (req.def.fun.typ) string_del(req.def.fun.typ); if (req.def.fun.fun2) string_del(req.def.fun.fun2); // Empty destructor goto failed; } + } else { + request_del(&req); } ++lineno; } else if ((tok.tokt == PPTOK_IDENT) @@ -464,6 +533,8 @@ VECTOR(requests) *requests_from_file(const char *filename, FILE *f) { || !strcmp(string_content(tok.tokv.str), "DATAV") || !strcmp(string_content(tok.tokv.str), "DATAB") || !strcmp(string_content(tok.tokv.str), "DATAM"))) { + string_clear(line); + if (is_comment) prepare_mark_nocomment(prep); request_t req = { .has_default = 1, .default_comment = is_comment, @@ -482,14 +553,14 @@ VECTOR(requests) *requests_from_file(const char *filename, FILE *f) { string_del(tok.tokv.str); tok = pre_next_token(prep, 0); if ((tok.tokt != PPTOK_SYM) || (tok.tokv.sym != SYM_LPAREN)) { - printf("Error: invalid requests file: invalid DATA line %d (lparen)\n", lineno); + printf("Error: invalid reference file: invalid DATA line %d (lparen)\n", lineno); preproc_token_del(&tok); goto failed; } // Empty destructor tok = pre_next_token(prep, 0); if (tok.tokt != PPTOK_IDENT) { - printf("Error: invalid requests file: invalid DATA line %d (obj_name)\n", lineno); + printf("Error: invalid reference file: invalid DATA line %d (obj_name)\n", lineno); preproc_token_del(&tok); goto failed; } @@ -497,7 +568,7 @@ VECTOR(requests) *requests_from_file(const char *filename, FILE *f) { // Token moved tok = pre_next_token(prep, 0); if ((tok.tokt != PPTOK_SYM) || (tok.tokv.sym != SYM_COMMA)) { - printf("Error: invalid requests file: invalid DATA line %d (comma)\n", lineno); + printf("Error: invalid reference file: invalid DATA line %d (comma)\n", lineno); string_del(req.obj_name); preproc_token_del(&tok); goto failed; @@ -507,7 +578,7 @@ VECTOR(requests) *requests_from_file(const char *filename, FILE *f) { if (tok.tokt == PPTOK_NUM) { num_constant_t cst; if (!num_constant_convert(tok.tokv.str, &cst)) { - printf("Error: invalid requests file: invalid DATA line %d (num conversion)\n", lineno); + printf("Error: invalid reference file: invalid DATA line %d (num conversion)\n", lineno); string_del(req.obj_name); preproc_token_del(&tok); goto failed; @@ -516,9 +587,9 @@ VECTOR(requests) *requests_from_file(const char *filename, FILE *f) { case NCT_FLOAT: case NCT_DOUBLE: case NCT_LDOUBLE: - printf("Error: invalid requests file: invalid DATA line %d (num conversion)\n", lineno); + printf("Error: invalid reference file: invalid DATA line %d (num conversion)\n", lineno); string_del(req.obj_name); - preproc_token_del(&tok); + string_del(tok.tokv.str); goto failed; case NCT_INT32: req.def.dat.sz = (size_t)cst.val.i32; break; case NCT_UINT32: req.def.dat.sz = (size_t)cst.val.u32; break; @@ -526,10 +597,10 @@ VECTOR(requests) *requests_from_file(const char *filename, FILE *f) { case NCT_UINT64: req.def.dat.sz = (size_t)cst.val.u64; break; } req.def.dat.has_size = 1; - // Token moved + string_del(tok.tokv.str); // Delete token tok = pre_next_token(prep, 0); if ((tok.tokt != PPTOK_SYM) || (tok.tokv.sym != SYM_RPAREN)) { - printf("Error: invalid requests file: invalid DATA line %d (rparen)\n", lineno); + printf("Error: invalid reference file: invalid DATA line %d (rparen)\n", lineno); string_del(req.obj_name); preproc_token_del(&tok); goto failed; @@ -538,28 +609,41 @@ VECTOR(requests) *requests_from_file(const char *filename, FILE *f) { tok = pre_next_token(prep, 0); } if (tok.tokt != PPTOK_NEWLINE) { - printf("Error: invalid requests file: invalid DATA line %d (newline)\n", lineno); + printf("Error: invalid reference file: invalid DATA line %d (newline)\n", lineno); string_del(req.obj_name); preproc_token_del(&tok); goto failed; } if (if_depth == entered_depth) { - if (!vector_push(requests, ret, req)) { - printf("Error: failed to add request for %s\n", string_content(req.obj_name)); - string_del(req.obj_name); + if (!vector_push(references, ret, ((reference_t){.typ = REF_REQ, .req = req}))) { + printf("Error: failed to add reference for %s\n", string_content(req.obj_name)); + request_del(&req); // Empty destructor goto failed; } + } else { + request_del(&req); } ++lineno; - } else { - if (is_comment) { + } else if (is_comment) { + if (tok.tokt == PPTOK_IDENT) { + ADD_STR(tok.tokv.str, 1, "comment content") + string_del(tok.tokv.str); + } else if (tok.tokt == PPTOK_BLANK) { + ADD_CHAR(tok.tokv.c, 0, "comment content") + } else { + printf("Error: unknown token type in comment %u\n", tok.tokt); preproc_token_del(&tok); - tok = pre_next_newline_token(prep); // Returns a newline - ++lineno; - continue; + goto failed; } - printf("Error: invalid requests file: invalid token:\n"); + if (!pre_next_newline_token(prep, line)) { + printf("Error: failed to add comment content\n"); + goto failed; + } + PUSH_LINE(0) + ++lineno; + } else { + printf("Error: invalid reference file: invalid token:\n"); preproc_token_print(&tok); preproc_token_del(&tok); goto failed; @@ -567,11 +651,13 @@ VECTOR(requests) *requests_from_file(const char *filename, FILE *f) { } failed: + string_del(line); prepare_del(prep); - vector_del(requests, ret); + vector_del(references, ret); return NULL; success: + string_del(line); prepare_del(prep); return ret; } @@ -692,7 +778,7 @@ static int convert_type(string_t *dest, type_t *typ, int is_ret, int *needs_D, i case BTT_LONGDOUBLE: *needs_D = 1; has_char = 1; c = 'D'; break; case BTT_CLONGDOUBLE: *needs_D = 1; has_char = 1; c = 'Y'; break; case BTT_ILONGDOUBLE: *needs_D = 1; has_char = 1; c = 'D'; break; - case BTT_VA_LIST: has_char = 1; c = 'A'; break; + case BTT_VA_LIST: *needs_my = 1; has_char = 1; c = 'A'; break; default: printf("Error: convert_type on unknown builtin %u\n", typ->val.builtin); return 0; @@ -847,6 +933,7 @@ int solve_request(request_t *req, type_t *typ) { if (!convert_type(req->val.fun.typ, typ->val.fun.args[i], 0, &needs_D, &needs_my, req->obj_name)) goto fun_fail; } if (typ->val.fun.has_varargs) { + needs_my = 1; if (!string_add_char(req->val.fun.typ, 'V')) { printf("Error: failed to add type char for %s\n", builtin2str[typ->val.builtin]); goto fun_fail; @@ -913,10 +1000,11 @@ int solve_request_map(request_t *req, khash_t(type_map) *decl_map) { } return solve_request(req, kh_val(decl_map, it)); } -int solve_requests(VECTOR(requests) *reqs, khash_t(type_map) *decl_map) { +int solve_references(VECTOR(references) *refs, khash_t(type_map) *decl_map) { int ret = 1; - vector_for(requests, req, reqs) { - if (!solve_request_map(req, decl_map)) ret = 0; + vector_for(references, ref, refs) { + if (ref->typ != REF_REQ) continue; + if (!solve_request_map(&ref->req, decl_map)) ret = 0; } return ret; } |