diff options
author | Juan J. Martinez <jjm@usebox.net> | 2023-06-05 12:35:05 +0100 |
---|---|---|
committer | Juan J. Martinez <jjm@usebox.net> | 2023-06-05 12:35:05 +0100 |
commit | ec64816a2a52d027246cc8df72deb8cab96e12b6 (patch) | |
tree | f8b0547f8e88421ec2fd1a205a2eecabd99625e2 | |
parent | 0699a11f0ffcd7c536bdb5ab45d898e3c6eb4a3c (diff) | |
download | tr8vm-ec64816a2a52d027246cc8df72deb8cab96e12b6.tar.gz tr8vm-ec64816a2a52d027246cc8df72deb8cab96e12b6.zip |
More efficient management of filenames
-rw-r--r-- | tr8as.c | 55 |
1 files changed, 40 insertions, 15 deletions
@@ -36,6 +36,7 @@ #define MAX_LABELS 0x200 #define MAX_REFS 0x1000 #define MAX_DEFS 0x200 +#define MAX_FILES 0xff #define FHH 2 #define FHL 1 @@ -94,6 +95,9 @@ typedef struct Define defs[MAX_DEFS]; uint16_t dcnt; + + const char *files[MAX_FILES]; + uint8_t fcnt; } As; typedef struct @@ -147,6 +151,28 @@ static uint8_t error(const char *msg, const char *reason) return 0; } +static uint8_t new_file(As *as, const char *filename, const char **dst) +{ + uint8_t i; + + if (as->fcnt == MAX_FILES) + return error_l("Too many files", &as->loc, filename); + + for (i = 0; i < as->fcnt; i++) + if (!strcmp(filename, as->files[i])) + { + *dst = as->files[i]; + return 0; + } + + as->files[as->fcnt] = mstrdup(filename); + if (!as->files[as->fcnt]) + error("new-file", "failed to allocate memory"); + + *dst = as->files[as->fcnt++]; + return 1; +} + static uint32_t str_hash(char const *str) { uint32_t m = 0x5bd1e995u; @@ -246,7 +272,7 @@ static uint8_t new_define(As *as, char *id, char *value) as->defs[as->dcnt].id = str_hash(id); strcpy(as->defs[as->dcnt].value, value); - as->defs[as->dcnt].loc.filename = mstrdup(as->loc.filename); + as->defs[as->dcnt].loc.filename = as->loc.filename; as->defs[as->dcnt++].loc.line = as->loc.line; if (as->dcnt == MAX_DEFS) @@ -394,7 +420,7 @@ static uint8_t new_label(As *as, char *word) as->labels[as->lcnt].id = str_hash(word); - as->labels[as->lcnt].loc.filename = mstrdup(as->loc.filename); + as->labels[as->lcnt].loc.filename = as->loc.filename; as->labels[as->lcnt].loc.line = as->loc.line; as->labels[as->lcnt++].addr = as->addr; @@ -430,7 +456,7 @@ static uint8_t new_ref(As *as, char *word, uint16_t mask, uint16_t addr) strcpy(as->refs[as->rcnt].label, pt); as->refs[as->rcnt].mod = mod; as->refs[as->rcnt].mask = mask; - as->refs[as->rcnt].loc.filename = mstrdup(as->loc.filename); + as->refs[as->rcnt].loc.filename = as->loc.filename; as->refs[as->rcnt].loc.line = as->loc.line; as->refs[as->rcnt++].addr = addr; @@ -548,7 +574,8 @@ static uint8_t parse_include(As *as, char **c) old.filename = as->loc.filename; old.line = as->loc.line; - as->loc.filename = word; + if (!new_file(as, word, &as->loc.filename)) + return 0; as->loc.line = 0; while (fgets(line, MAX_LINE - 1, fd)) @@ -1650,12 +1677,13 @@ static uint8_t parse(As *as, char *c) static uint8_t asm(As *as, const char *filename, FILE *in) { - uint16_t i; + uint8_t i; uint8_t rc; char line[MAX_LINE]; memset(as, 0, sizeof(As)); - as->loc.filename = filename; + if (!new_file(as, filename, &as->loc.filename)) + return 0; while (fgets(line, MAX_LINE - 1, in)) { @@ -1666,15 +1694,12 @@ static uint8_t asm(As *as, const char *filename, FILE *in) rc = resolve(as); - for (i = 0; i < as->rcnt; i++) - if (as->refs[i].loc.filename) - free((void *)as->refs[i].loc.filename); - for (i = 0; i < as->dcnt; i++) - if (as->defs[i].loc.filename) - free((void *)as->defs[i].loc.filename); - for (i = 0; i < as->lcnt; i++) - if (as->labels[i].loc.filename) - free((void *)as->labels[i].loc.filename); + for (i = 0; i < as->fcnt; i++) + if (as->files[i]) + { + free((void *)as->files[i]); + as->files[i] = NULL; + } return rc; } |