aboutsummaryrefslogtreecommitdiff
path: root/tr8as.c
diff options
context:
space:
mode:
authorJuan J. Martinez <jjm@usebox.net>2023-06-05 12:35:05 +0100
committerJuan J. Martinez <jjm@usebox.net>2023-06-05 12:35:05 +0100
commitec64816a2a52d027246cc8df72deb8cab96e12b6 (patch)
treef8b0547f8e88421ec2fd1a205a2eecabd99625e2 /tr8as.c
parent0699a11f0ffcd7c536bdb5ab45d898e3c6eb4a3c (diff)
downloadtr8vm-ec64816a2a52d027246cc8df72deb8cab96e12b6.tar.gz
tr8vm-ec64816a2a52d027246cc8df72deb8cab96e12b6.zip
More efficient management of filenames
Diffstat (limited to 'tr8as.c')
-rw-r--r--tr8as.c55
1 files changed, 40 insertions, 15 deletions
diff --git a/tr8as.c b/tr8as.c
index 36418fa..0981ce9 100644
--- a/tr8as.c
+++ b/tr8as.c
@@ -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;
}