From ebf87a1d15b00d5b64a2b8a5ed3ac566a3b0c462 Mon Sep 17 00:00:00 2001 From: Lukas Krickl Date: Mon, 6 Nov 2023 20:04:54 +0100 Subject: [PATCH] Removed most malloc calls --- include/preproc.h | 16 ++++++++++++- include/ulas.h | 11 +++++---- src/main.c | 2 +- src/preproc.c | 58 +++++++++++++++++++++++++++++++++++++++++++++-- src/test.c | 21 +++++++++-------- src/ulas.c | 52 +++++------------------------------------- 6 files changed, 96 insertions(+), 64 deletions(-) diff --git a/include/preproc.h b/include/preproc.h index 7d069a9..24a04dd 100644 --- a/include/preproc.h +++ b/include/preproc.h @@ -8,6 +8,16 @@ * Preprocessor */ +enum ulas_ppdirs { + ULAS_PPDIR_NONE = 0, + ULAS_PPDIR_DEF, + ULAS_PPDIR_MACRO, + ULAS_PPDIR_ENDMACRO, + ULAS_PPDIR_IFDEF, + ULAS_PPDIR_IFNDEF, + ULAS_PPDIR_ENDIF +}; + enum ulas_ppdefs { ULAS_PP_DEF, ULAS_PP_MACRO, @@ -29,6 +39,10 @@ struct ulas_preproc { /** * Tokenize and apply the preprocessor */ -int ulas_preproc(FILE *dst, const char *dstname, FILE *src, const char *srcname); +int ulas_preproc(FILE *dst, const char *dstname, FILE *src, + const char *srcname); + +// expand preproc into dst line +char *ulas_preprocexpand(char *line, size_t linemax, const char *raw_line, size_t *n); #endif diff --git a/include/ulas.h b/include/ulas.h index 10cf87a..1f6eb37 100644 --- a/include/ulas.h +++ b/include/ulas.h @@ -8,7 +8,10 @@ #define ULAS_PATHMAX 4096 #define ULAS_LINEMAX 4096 -#define ULAS_TOKMAX 512 +#define ULAS_TOKMAX 64 + +// max tokens per line... +#define ULAS_TOKSMAX 64 #define MAX(x, y) (((x) > (y)) ? (x) : (y)) #define MIN(x, y) (((x) < (y)) ? (x) : (y)) @@ -171,9 +174,7 @@ bool ulas_tokrulespace(char current); // returns 0 when no more tokens can be read int ulas_tok(char *dst, const char *line, size_t n, ulas_tokrule rule); -// tokenizes an entire line -char **ulas_tokline(const char *line, size_t *n, ulas_tokrule rule); - -void ulas_toklinefree(char **data, size_t n); +// smae as ulas_tok but modifies line +int ulas_tokline(char *dst, const char **line, size_t n, ulas_tokrule rule); #endif diff --git a/src/main.c b/src/main.c index 90bd1b2..dc94cf9 100644 --- a/src/main.c +++ b/src/main.c @@ -43,7 +43,7 @@ void ulas_getopt(int argc, char **argv, struct ulas_config *cfg) { cfg->verbose = true; break; case 'o': - cfg->output_path = ulas_strndup(optarg, ULAS_PATHMAX); + cfg->output_path = strndup(optarg, ULAS_PATHMAX); break; case '?': break; diff --git a/src/preproc.c b/src/preproc.c index 9d6d619..8dbde7a 100644 --- a/src/preproc.c +++ b/src/preproc.c @@ -1,15 +1,69 @@ #include "preproc.h" #include "ulas.h" +#include +#include #include #include +bool ulas_tokpreproc(char c) { return !isalnum(c); } -int ulas_preprocline(struct ulas_preproc *pp, FILE *dst, const char *line, +char *ulas_preprocexpand(char *line, size_t linemax, const char *raw_line, + size_t *n) { + assert(*n <= linemax); + const char *praw_line = raw_line; + + char tok[ULAS_TOKMAX]; + + // go through all tokens, see if a define matches the token, + // if so expand it + // only expand macros if they match toks[0] though! + // otherwise memcpy the read bytes 1:1 into the new string + while (ulas_tokline(tok, &praw_line, ULAS_TOKMAX, ulas_tokpreproc)) { + } + + // TODO: actually expand here... + strncpy(line, raw_line, *n); + *n = strlen(line); + return line; +} + +int ulas_preprocline(struct ulas_preproc *pp, FILE *dst, const char *raw_line, size_t n) { + if (n > ULAS_LINEMAX) { + ULASERR("%s: line exceeds %d (LINEMAX)\n", raw_line, ULAS_LINEMAX); + return -1; + } + assert(n <= ULAS_LINEMAX); + char line[ULAS_LINEMAX]; + const char *pline = line; + + ulas_preprocexpand(line, ULAS_LINEMAX, raw_line, &n); + const char *dirstrs[] = {"#define", "#macro", "#ifdef", "#ifndef", + "#endif", "#endmacro", NULL}; + enum ulas_ppdirs dirs[] = {ULAS_PPDIR_DEF, ULAS_PPDIR_MACRO, + ULAS_PPDIR_IFDEF, ULAS_PPDIR_IFNDEF, + ULAS_PPDIR_ENDIF, ULAS_PPDIR_ENDMACRO}; + + enum ulas_ppdirs found_dir = ULAS_PPDIR_NONE; + + char tok[ULAS_TOKMAX]; // check if the first token is any of the valid preproc directives + if (ulas_tokline(tok, &pline, ULAS_TOKMAX, ulas_tokpreproc)) { + for (size_t i = 0; dirstrs[i]; i++) { + if (strncmp(dirstrs[i], tok, ULAS_TOKMAX) == 0) { + found_dir = dirs[i]; + goto found; + } + } + } +found: - assert(fwrite(line, 1, n, dst) == n); + if (found_dir) { + // TODO: process directive + } else { + assert(fwrite(line, 1, n, dst) == n); + } return 0; } diff --git a/src/test.c b/src/test.c index aae3cad..32d804d 100644 --- a/src/test.c +++ b/src/test.c @@ -16,15 +16,17 @@ #define assert_tokline(expected_n, line, rule, ...) \ { \ - char *expect[] = __VA_ARGS__; \ - size_t n = 0; \ - char **toks = ulas_tokline(line, &n, rule); \ - assert(toks); \ - assert(n == expected_n); \ - for (size_t i = 0; i < n; i++) { \ - assert(strcmp(toks[i], expect[i]) == 0); \ + const char *expect[] = __VA_ARGS__; \ + size_t n = ULAS_TOKMAX; \ + char buf[n]; \ + memset(buf, 0, n); \ + int i = 0; \ + const char *pline = line; \ + while (ulas_tokline(buf, &pline, n, rule)) { \ + assert(strcmp(buf, expect[i]) == 0); \ + i++; \ } \ - ulas_toklinefree(toks, n); \ + assert(i == expected_n); \ } void test_tok(void) { @@ -57,7 +59,8 @@ void test_tok(void) { void test_preproc(void) { TESTBEGIN("preproc"); - assert_preproc("test", 0, "test"); + // should just echo back line as is + assert_preproc(" test line", 0, " test line"); TESTEND("preproc"); } diff --git a/src/ulas.c b/src/ulas.c index aa5b0a5..3a72d1a 100644 --- a/src/ulas.c +++ b/src/ulas.c @@ -28,13 +28,6 @@ struct ulas_config ulas_cfg_from_env(void) { return cfg; } -char *ulas_strndup(const char *src, size_t n) { - size_t len = MIN(strlen(src), n); - char *dst = malloc(len); - strncpy(dst, src, len); - return dst; -} - int ulas_main(struct ulas_config cfg) { if (cfg.output_path) { ulasout = fopen(cfg.output_path, "we"); @@ -87,44 +80,11 @@ int ulas_tok(char *dst, const char *line, size_t n, ulas_tokrule rule) { return i; } -char **ulas_tokline(const char *line, size_t *n, ulas_tokrule rule) { - char buf[ULAS_TOKMAX]; - - char **dst = NULL; - *n = 0; - - int tokrc = 0; - int read = 0; - while ((tokrc = ulas_tok(buf, line + read, ULAS_TOKMAX, rule)) > 0) { - if (tokrc == -1) { - goto fail; - } - read += tokrc; - - *n = *n + 1; - char **newdst = realloc(dst, sizeof(char *) * (*n)); - if (!newdst) { - goto fail; - } - dst = newdst; - - dst[(*n) - 1] = strndup(buf, ULAS_TOKMAX); - } - - return dst; -fail: - ulas_toklinefree(dst, *n); - *n = 0; - return NULL; -} - -void ulas_toklinefree(char **data, size_t n) { - if (!data) { - return; - } - for (size_t i = 0; i < n; i++) { - free(data[i]); +int ulas_tokline(char *dst, const char **line, size_t n, ulas_tokrule rule) { + int rc = ulas_tok(dst, *line, n, rule); + if (rc == -1) { + return -1; } - - free(data); + *line += rc; + return rc; } -- 2.30.2