[WRAPPERHELPER] Added pragma once support, fixed a preprocessor bug, fixed the wrapperhelper Makefile (#1977)

This commit is contained in:
rajdakin 2024-10-29 16:31:05 +01:00 committed by GitHub
parent 4a440b6f0a
commit 70a6d96748
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
7 changed files with 170 additions and 63 deletions

View File

@ -1399,7 +1399,7 @@ static enum safeness_e get_safeness(type_t *emu_typ, type_t *target_typ, int *ne
}
// needs_S != NULL iff type is return
static int convert_type(string_t *dest, type_t *emu_typ, type_t *target_typ,
static int convert_type(string_t *dest, type_t *emu_typ, type_t *target_typ, int allow_nesting,
_Bool *needs_S, int *needs_D, int *needs_my, khash_t(conv_map) *conv_map, string_t *obj_name) {
if (emu_typ->converted) {
if (!string_add_string(dest, emu_typ->converted)) {
@ -1499,7 +1499,7 @@ static int convert_type(string_t *dest, type_t *emu_typ, type_t *target_typ,
return 1;
}
size_t idx = string_len(dest);
if (!convert_type(dest, emu_typ->val.array.typ, target_typ->val.array.typ, needs_S, needs_D, needs_my, conv_map, obj_name))
if (!convert_type(dest, emu_typ->val.array.typ, target_typ->val.array.typ, allow_nesting, needs_S, needs_D, needs_my, conv_map, obj_name))
return 0;
size_t end = string_len(dest);
if (idx == end) return 1;
@ -1530,13 +1530,13 @@ static int convert_type(string_t *dest, type_t *emu_typ, type_t *target_typ,
return 1;
} else {
if ((emu_typ->val.st->nmembers == 1) && (target_typ->typ == TYPE_STRUCT_UNION) && (target_typ->val.st->nmembers == 1)) {
return convert_type(dest, emu_typ->val.st->members[0].typ, target_typ->val.st->members[0].typ, needs_S, needs_D, needs_my, conv_map, obj_name);
return convert_type(dest, emu_typ->val.st->members[0].typ, target_typ->val.st->members[0].typ, allow_nesting, needs_S, needs_D, needs_my, conv_map, obj_name);
}
printf("Error: TODO: convert_type on structure as argument (%s)\n", string_content(obj_name));
return 0;
}
case TYPE_ENUM:
return convert_type(dest, emu_typ->val.typ, target_typ->val.typ, needs_S, needs_D, needs_my, conv_map, obj_name);
return convert_type(dest, emu_typ->val.typ, target_typ->val.typ, allow_nesting, needs_S, needs_D, needs_my, conv_map, obj_name);
case TYPE_PTR:
switch (get_safeness_ptr(emu_typ->val.typ, target_typ->val.typ, needs_D, needs_my, conv_map, obj_name)) {
default:
@ -1554,6 +1554,15 @@ static int convert_type(string_t *dest, type_t *emu_typ, type_t *target_typ,
return 1;
case SAFE_EXPAND:
if (!allow_nesting) {
// TODO remove this with a better rebuild_wrappers.py
*needs_my = 1;
if (!string_add_char(dest, 'p')) {
printf("Error: failed to add type char for simple pointer\n");
return 0;
}
return 1;
}
if (!string_add_char(dest, emu_typ->is_const ? 'r' : 'b')) {
printf("Error: failed to add start type char for wrapping pointer\n");
return 0;
@ -1564,12 +1573,12 @@ static int convert_type(string_t *dest, type_t *emu_typ, type_t *target_typ,
do_expanded:
switch (emu_typ->typ) {
case TYPE_BUILTIN:
if (!convert_type(dest, emu_typ, target_typ, needs_S, needs_D, needs_my, conv_map, obj_name)) {
if (!convert_type(dest, emu_typ, target_typ, 0, needs_S, needs_D, needs_my, conv_map, obj_name)) {
return 0;
}
break;
case TYPE_ARRAY:
if (!convert_type(dest, emu_typ, target_typ, needs_S, needs_D, needs_my, conv_map, obj_name)) {
if (!convert_type(dest, emu_typ, target_typ, 0, needs_S, needs_D, needs_my, conv_map, obj_name)) {
return 0;
}
break;
@ -1584,7 +1593,7 @@ static int convert_type(string_t *dest, type_t *emu_typ, type_t *target_typ,
goto do_expanded;
}
for (size_t i = 0; i < emu_typ->val.st->nmembers; ++i) {
if (!convert_type(dest, emu_typ->val.st->members[i].typ, target_typ->val.st->members[i].typ, needs_S, needs_D, needs_my, conv_map, obj_name)) {
if (!convert_type(dest, emu_typ->val.st->members[i].typ, target_typ->val.st->members[i].typ, 0, needs_S, needs_D, needs_my, conv_map, obj_name)) {
return 0;
}
}
@ -1592,17 +1601,17 @@ static int convert_type(string_t *dest, type_t *emu_typ, type_t *target_typ,
case TYPE_ENUM:
emu_typ = emu_typ->val.typ;
target_typ = target_typ->val.typ;
if (!convert_type(dest, emu_typ, target_typ, needs_S, needs_D, needs_my, conv_map, obj_name)) {
if (!convert_type(dest, emu_typ, target_typ, 0, needs_S, needs_D, needs_my, conv_map, obj_name)) {
return 0;
}
break;
case TYPE_PTR:
if (!convert_type(dest, emu_typ, target_typ, needs_S, needs_D, needs_my, conv_map, obj_name)) {
if (!convert_type(dest, emu_typ, target_typ, 0, needs_S, needs_D, needs_my, conv_map, obj_name)) {
return 0;
}
break;
case TYPE_FUNCTION:
if (!convert_type(dest, emu_typ, target_typ, needs_S, needs_D, needs_my, conv_map, obj_name)) {
if (!convert_type(dest, emu_typ, target_typ, 0, needs_S, needs_D, needs_my, conv_map, obj_name)) {
return 0;
}
break;
@ -1666,7 +1675,7 @@ int solve_request(request_t *req, type_t *emu_typ, type_t *target_typ, khash_t(c
printf("Error: failed to create function type string\n");
return 0;
}
if (!convert_type(req->val.fun.typ, emu_typ->val.fun.ret, target_typ->val.fun.ret, &req->val.fun.needs_S, &needs_D, &needs_my, conv_map, req->obj_name))
if (!convert_type(req->val.fun.typ, emu_typ->val.fun.ret, target_typ->val.fun.ret, 0, &req->val.fun.needs_S, &needs_D, &needs_my, conv_map, req->obj_name))
goto fun_fail;
idx_conv = string_len(req->val.fun.typ);
if (!string_add_char(req->val.fun.typ, 'F')) {
@ -1692,7 +1701,7 @@ int solve_request(request_t *req, type_t *emu_typ, type_t *target_typ, khash_t(c
}
} else {
for (size_t i = 0; i < emu_typ->val.fun.nargs; ++i) {
if (!convert_type(req->val.fun.typ, emu_typ->val.fun.args[i], target_typ->val.fun.args[i], NULL, &needs_D, &needs_my, conv_map, req->obj_name))
if (!convert_type(req->val.fun.typ, emu_typ->val.fun.args[i], target_typ->val.fun.args[i], 1, NULL, &needs_D, &needs_my, conv_map, req->obj_name))
goto fun_fail;
}
if (emu_typ->val.fun.has_varargs) {

View File

@ -8,6 +8,7 @@
#include "lang.h"
#include "machine.h"
#include "parse.h"
#include "prepare.h"
#include "khash.h"
static void help(char *arg0) {
@ -237,6 +238,7 @@ int main(int argc, char **argv) {
log_error_nopos("failed to parse the file\n");
del_machines();
del_str2kw();
prepare_cleanup();
return 0;
}
@ -246,6 +248,7 @@ int main(int argc, char **argv) {
file_del(emu_content);
del_machines();
del_str2kw();
prepare_cleanup();
return 2;
}
file_t *target_content = parse_file(target, in_file, f); // Takes ownership of f
@ -254,6 +257,7 @@ int main(int argc, char **argv) {
file_del(emu_content);
del_machines();
del_str2kw();
prepare_cleanup();
return 0;
}
@ -264,6 +268,7 @@ int main(int argc, char **argv) {
file_del(target_content);
del_machines();
del_str2kw();
prepare_cleanup();
return 2;
}
VECTOR(references) *refs = references_from_file(ref_file, ref);
@ -272,6 +277,7 @@ int main(int argc, char **argv) {
file_del(target_content);
del_machines();
del_str2kw();
prepare_cleanup();
return 2;
}
// vector_for(references, req, refs) request_print(req);
@ -294,6 +300,7 @@ int main(int argc, char **argv) {
vector_del(references, refs);
del_machines();
del_str2kw();
prepare_cleanup();
return 2;
}
output_from_references(out, refs);
@ -303,6 +310,7 @@ int main(int argc, char **argv) {
file_del(target_content);
del_machines();
del_str2kw();
prepare_cleanup();
return 0; }
case MAIN_PROC: {
@ -315,6 +323,7 @@ int main(int argc, char **argv) {
log_error_nopos("failed to parse the file\n");
del_machines();
del_str2kw();
prepare_cleanup();
return 0;
}
// print content
@ -373,6 +382,7 @@ int main(int argc, char **argv) {
file_del(content);
del_machines();
del_str2kw();
prepare_cleanup();
return 0; }
case MAIN_PREPARE:
@ -380,6 +390,7 @@ int main(int argc, char **argv) {
dump_prepare(in_file, f); // Takes ownership of f
del_machines();
del_str2kw();
prepare_cleanup();
return 0;
case MAIN_PREPROC: {
@ -390,9 +401,13 @@ int main(int argc, char **argv) {
dump_preproc(arch, in_file, f); // Takes ownership of f
del_machines();
del_str2kw();
prepare_cleanup();
return 0; }
}
log_internal_nopos("failed to run mode %u\n", ms);
del_machines();
del_str2kw();
prepare_cleanup();
return 2;
}

View File

@ -2,6 +2,13 @@
#include <string.h>
#include "log.h"
static struct li_filename_s {
char *name;
struct li_filename_s *next;
} *li_filenames = NULL;
typedef struct char_s {
int c;
loginfo_t li;
@ -32,12 +39,21 @@ prepare_t *prepare_new_file(FILE *f, const char *filename) {
return NULL;
}
char *srcn = strdup(filename);
char *srcn = strdup(filename ? filename : "<unknown filename>");
if (!srcn) {
log_memory("failed to duplicate filename\n");
free(ret);
return NULL;
}
struct li_filename_s *new_lifn = malloc(sizeof *new_lifn);
if (!new_lifn) {
log_memory("failed to remember new filename\n");
free(srcn);
free(ret);
return NULL;
}
*new_lifn = (struct li_filename_s){ .name = srcn, .next = li_filenames };
li_filenames = new_lifn;
*ret = (prepare_t){
.f = f,
@ -52,7 +68,6 @@ prepare_t *prepare_new_file(FILE *f, const char *filename) {
void prepare_del(prepare_t *prep) {
if (prep->f) fclose(prep->f);
if (prep->srcn) free(prep->srcn);
free(prep);
}
@ -504,9 +519,21 @@ start_next_token:
void prepare_set_line(prepare_t *src, char *filename, size_t lineno) {
if (filename) {
if (src->srcn) free(filename);
src->srcn = filename;
src->li.filename = filename;
char *srcn = strdup(filename ? filename : "<unknown filename>");
if (!srcn) {
log_memory("failed to duplicate filename from #line command\n");
return;
}
struct li_filename_s *new_lifn = malloc(sizeof *new_lifn);
if (!new_lifn) {
log_memory("failed to remember new filename from #line command\n");
free(srcn);
return;
}
*new_lifn = (struct li_filename_s){ .name = srcn, .next = li_filenames };
li_filenames = new_lifn;
src->srcn = srcn;
src->li.filename = srcn;
}
size_t colno = 1;
for (int i = src->buf_len; i--; ) {
@ -545,3 +572,12 @@ int pre_next_newline_token(prepare_t *src, string_t *buf) {
}
}
}
void prepare_cleanup(void) {
while (li_filenames) {
struct li_filename_s *lifn = li_filenames->next;
free(li_filenames->name);
free(li_filenames);
li_filenames = lifn;
}
}

View File

@ -19,4 +19,6 @@ void prepare_set_line(prepare_t *src, char *filename, size_t lineno); // Takes o
void prepare_mark_nocomment(prepare_t *src); // Change the state (usually from COMMENT) to NONE
int pre_next_newline_token(prepare_t *src, string_t *buf); // In a comment append everything until the EOL or EOF to the buffer
void prepare_cleanup(void); // Frees loginfo filenames
#endif // PREPARE_H

View File

@ -203,6 +203,7 @@ VECTOR_IMPL_STATIC(ppsource, ppsource_del)
struct preproc_s {
machine_t *target;
VECTOR(ppsource) *prep;
VECTOR(ccharp) *pragma_once;
enum preproc_state_e {
PPST_NONE,
PPST_NL,
@ -223,6 +224,7 @@ void preproc_del(preproc_t *src) {
macros_map_del(src->macros_map);
if (src->dirname) free(src->dirname);
if (src->cur_file) free(src->cur_file);
vector_del(ccharp, src->pragma_once);
free(src);
}
@ -350,6 +352,16 @@ preproc_t *preproc_new_file(machine_t *target, FILE *f, char *dirname, const cha
free(ret);
return NULL;
}
ret->pragma_once = vector_new(ccharp);
if (!ret->pragma_once) {
vector_del(ppsource, ret->prep);
kh_destroy(macros_map, ret->macros_map);
kh_destroy(string_set, ret->macros_defined);
kh_destroy(string_set, ret->macros_used);
fclose(f);
free(ret);
return NULL;
}
ret->dirname = NULL;
ret->cur_file = NULL;
// ret can now be deleted by preproc_del
@ -534,45 +546,47 @@ static VECTOR(preproc) *preproc_solve_macro(loginfo_t *li,
#undef ONLYDIGS
}
if (do_add) {
preproc_token_t tok2;
preproc_token_t *tok1 = &mtok->val.tok;
switch (tok1->tokt) {
case PPTOK_INVALID:
case PPTOK_NEWLINE:
case PPTOK_BLANK:
case PPTOK_START_LINE_COMMENT:
case PPTOK_EOF: tok2 = (preproc_token_t){.tokt = tok1->tokt, .loginfo = *li, .tokv.c = tok1->tokv.c}; break;
case PPTOK_SYM: tok2 = (preproc_token_t){.tokt = tok1->tokt, .loginfo = *li, .tokv.sym = tok1->tokv.sym}; break;
case PPTOK_IDENT:
case PPTOK_IDENT_UNEXP:
case PPTOK_NUM: {
string_t *dup = string_dup(tok1->tokv.str);
if (!dup) {
LOG_MEMORY("failed to duplicate string");
if (tok1->tokt != PPTOK_NEWLINE) {
preproc_token_t tok2;
switch (tok1->tokt) {
case PPTOK_INVALID:
case PPTOK_NEWLINE:
case PPTOK_BLANK:
case PPTOK_START_LINE_COMMENT:
case PPTOK_EOF: tok2 = (preproc_token_t){.tokt = tok1->tokt, .loginfo = *li, .tokv.c = tok1->tokv.c}; break;
case PPTOK_SYM: tok2 = (preproc_token_t){.tokt = tok1->tokt, .loginfo = *li, .tokv.sym = tok1->tokv.sym}; break;
case PPTOK_IDENT:
case PPTOK_IDENT_UNEXP:
case PPTOK_NUM: {
string_t *dup = string_dup(tok1->tokv.str);
if (!dup) {
LOG_MEMORY("failed to duplicate string");
vector_del(preproc, ret);
ret = NULL;
goto solve_done;
}
tok2 = (preproc_token_t){.tokt = tok1->tokt, .loginfo = *li, .tokv.str = dup};
break; }
case PPTOK_INCL:
case PPTOK_STRING: {
string_t *dup = string_dup(tok1->tokv.sstr);
if (!dup) {
LOG_MEMORY("failed to duplicate string");
vector_del(preproc, ret);
ret = NULL;
goto solve_done;
}
tok2 = (preproc_token_t){.tokt = tok1->tokt, .loginfo = *li, .tokv.sstr = dup, .tokv.sisstr = tok1->tokv.sisstr};
break; }
}
if (!vector_push(preproc, ret, tok2)) {
LOG_MEMORY("failed to add token to output vector");
preproc_token_del(&tok2);
vector_del(preproc, ret);
ret = NULL;
goto solve_done;
}
tok2 = (preproc_token_t){.tokt = tok1->tokt, .loginfo = *li, .tokv.str = dup};
break; }
case PPTOK_INCL:
case PPTOK_STRING: {
string_t *dup = string_dup(tok1->tokv.sstr);
if (!dup) {
LOG_MEMORY("failed to duplicate string");
vector_del(preproc, ret);
ret = NULL;
goto solve_done;
}
tok2 = (preproc_token_t){.tokt = tok1->tokt, .loginfo = *li, .tokv.sstr = dup, .tokv.sisstr = tok1->tokv.sisstr};
break; }
}
if (!vector_push(preproc, ret, tok2)) {
LOG_MEMORY("failed to add token to output vector");
preproc_token_del(&tok2);
vector_del(preproc, ret);
ret = NULL;
goto solve_done;
}
}
vector_pop_nodel(mtoken, st);
@ -630,7 +644,8 @@ static VECTOR(preproc) *preproc_solve_macro(loginfo_t *li,
}
if (len) {
preproc_token_t tok2;
for (preproc_token_t *tok1 = vector_begin(preproc, toks_to_add) + tta_start; tok1 != vector_end(preproc, toks_to_add); ++tok1){
for (preproc_token_t *tok1 = vector_begin(preproc, toks_to_add) + tta_start; tok1 != vector_end(preproc, toks_to_add); ++tok1) {
if (tok1->tokt == PPTOK_NEWLINE) continue;
switch (tok1->tokt) {
case PPTOK_INVALID:
case PPTOK_NEWLINE:
@ -779,6 +794,7 @@ static VECTOR(preproc) *preproc_do_expand(loginfo_t *li, const khash_t(macros_ma
return NULL;
}
vector_for(preproc, tok, toks) {
if (tok->tokt == PPTOK_NEWLINE) continue;
preproc_token_t tok2;
switch (tok->tokt) {
case PPTOK_INVALID:
@ -2115,7 +2131,7 @@ start_cur_token:
}
marg = vector_new(preproc);
if (!marg) goto solve_err_mem;
} else {
} else if (tok2.tokt != PPTOK_NEWLINE) {
if (!vector_push(preproc, marg, tok2)) {
vector_del(preproc, marg);
goto solve_err_mem;
@ -2409,18 +2425,32 @@ start_cur_token:
}
}
// cur_pathno == 0 if cur_file was from an #include "...", otherwise idx + 1
int has_once = 0;
vector_for(ccharp, fname, src->pragma_once) {
if (!strcmp(*fname, string_content(incl_file))) {
has_once = 1;
break;
}
}
if (has_once) {
#ifdef LOG_INCLUDE
printf("Opening %s as %s from system path %zu\n", string_content(incl_file),
is_sys ? "system header" : "cur header", is_next ? src->cur_pathno : 0);
printf("Skipping opening %s as %s from system path %zu\n", string_content(incl_file),
is_sys ? "system header" : "cur header", is_next ? src->cur_pathno : 0);
#endif
if ((is_sys || !try_open_dir(src, incl_file)) && !try_open_sys(src, incl_file, is_next ? src->cur_pathno : 0)) {
log_error(&li, "failed to open %s\n", string_content(incl_file));
string_del(incl_file);
src->st = PPST_NONE;
ret.tokt = PTOK_INVALID;
ret.loginfo = li;
ret.tokv.c = is_sys ? '<' : '"';
return ret;
} else {
#ifdef LOG_INCLUDE
printf("Opening %s as %s from system path %zu\n", string_content(incl_file),
is_sys ? "system header" : "cur header", is_next ? src->cur_pathno : 0);
#endif
if ((is_sys || !try_open_dir(src, incl_file)) && !try_open_sys(src, incl_file, is_next ? src->cur_pathno : 0)) {
log_error(&li, "failed to open %s\n", string_content(incl_file));
string_del(incl_file);
src->st = PPST_NONE;
ret.tokt = PTOK_INVALID;
ret.loginfo = li;
ret.tokv.c = is_sys ? '<' : '"';
return ret;
}
}
string_del(incl_file);
if (tok.tokt == PPTOK_NEWLINE) goto check_next_token;
@ -2828,6 +2858,19 @@ start_cur_token:
if ((tok.tokt != PPTOK_IDENT) && (tok.tokt != PPTOK_IDENT_UNEXP)) {
log_error(&tok.loginfo, "unknown pragma directive, skipping until EOL\n");
goto preproc_hash_err;
} else if (!strcmp(string_content(tok.tokv.str), "once")) {
const char *fname = tok.loginfo.filename;
if (!vector_push(ccharp, src->pragma_once, fname)) {
log_memory("failed to add filename to #pragma once list\n");
vector_clear(ppsource, src->prep);
ret.tokt = PTOK_INVALID;
ret.loginfo = tok.loginfo;
ret.tokv.c = (char)EOF;
return ret;
}
string_del(tok.tokv.str);
tok = ppsrc_next_token(src);
goto preproc_hash_err;
} else if (!strcmp(string_content(tok.tokv.str), "wrappers")) {
string_del(tok.tokv.str);
tok = ppsrc_next_token(src);

View File

@ -3,6 +3,7 @@
VECTOR_IMPL(voidp, (void))
VECTOR_IMPL(char, (void))
VECTOR_IMPL(charp, (void))
VECTOR_IMPL(ccharp, (void))
static void stringp_del(string_t **s) { return string_del(*s); }
VECTOR_IMPL(string, stringp_del)

View File

@ -208,6 +208,7 @@ int vector_push_vec_impl(VECTOR(voidp) *v1, VECTOR(voidp) *v2, size_t
VECTOR_DECLARE(char, char)
VECTOR_DECLARE(charp, char*)
VECTOR_DECLARE(ccharp, const char*)
VECTOR_DECLARE(string, string_t*)
#endif // VECTOR_H