From aad5d59312a6e5c7abf55bd938d8e2c390a89ab7 Mon Sep 17 00:00:00 2001 From: Lukas Krickl Date: Fri, 17 Nov 2023 18:17:29 +0100 Subject: [PATCH] Moved to indent as formatter --- .clang-format | 1 - .clang-tidy | 31 -- include/ulas.h | 10 +- makefile | 10 +- src/main.c | 52 ++-- src/test.c | 41 ++- src/ulas.c | 799 +++++++++++++++++++++++++------------------------ 7 files changed, 460 insertions(+), 484 deletions(-) delete mode 100644 .clang-format delete mode 100644 .clang-tidy diff --git a/.clang-format b/.clang-format deleted file mode 100644 index ac7dcd1..0000000 --- a/.clang-format +++ /dev/null @@ -1 +0,0 @@ -SortIncludes: false diff --git a/.clang-tidy b/.clang-tidy deleted file mode 100644 index 049204a..0000000 --- a/.clang-tidy +++ /dev/null @@ -1,31 +0,0 @@ ---- -Checks: "*, - -abseil-*, - -llvm*, - -google*, - -modernize-use-trailing-return-type, - -readability-else-after-return, - -readability-static-accessed-through-instance, - -readability-avoid-const-params-in-decls, - -misc-unused-parameters, - -bugprone-easily-swappable-parameters, - -cert-err33-c, - -readability-identifier-length, - -altera-unroll-loops, - -cppcoreguidelines-avoid-non-const-global-variables, - -altera-struct-pack-align, - -cppcoreguidelines-avoid-magic-numbers, - -readability-magic-numbers, - -cert-err34-c, - -readability-function-cognitive-complexity, - -altera-id-dependent-backward-branch, - -clang-analyzer-security.insecureAPI.DeprecatedOrUnsafeBufferHandling, - -misc-no-recursion, - -concurrency-mt-unsafe, - -clang-analyzer-unix.Malloc, - -modernize-macro-to-enum -" -WarningsAsErrors: '' -HeaderFilterRegex: '' -FormatStyle: None - diff --git a/include/ulas.h b/include/ulas.h index 0ef1802..bd4d218 100644 --- a/include/ulas.h +++ b/include/ulas.h @@ -312,7 +312,7 @@ void ulas_preprocfree(struct ulas_preproc *pp); * returns 0: no error * -1: error */ -int ulas_preproc(FILE *dst, FILE *src); +int ulas_preproc(FILE * dst, FILE * src); // reads the next line // returns 0 if no more data can be read @@ -320,7 +320,7 @@ int ulas_preproc(FILE *dst, FILE *src); // -1 on error // it also places the processed line into pp->line.buf // note that this is overwritten by every call! -int ulas_preprocnext(struct ulas_preproc *pp, FILE *dst, FILE *src, char *buf, +int ulas_preprocnext(struct ulas_preproc *pp, FILE * dst, FILE * src, char *buf, int n); // process a line of preproc @@ -331,7 +331,7 @@ int ulas_preprocnext(struct ulas_preproc *pp, FILE *dst, FILE *src, char *buf, // not be used in the caller after recursvion finishes! // or initialize a new preproc object if the old state is important! // (preprocinit and preprocfree) -int ulas_preprocline(struct ulas_preproc *pp, FILE *dst, FILE *src, +int ulas_preprocline(struct ulas_preproc *pp, FILE * dst, FILE * src, const char *raw_line, unsigned long n); // expand preproc into dst line @@ -359,8 +359,8 @@ void ulas_tokbuffree(struct ulas_tokbuf *tb); // returns 0 if no more data can be read // > 0 if data was read // -1 on error -int ulas_asmnext(FILE *dst, FILE *src, char *buf, int n); -int ulas_asm(FILE *dst, FILE *src); +int ulas_asmnext(FILE * dst, FILE * src, char *buf, int n); +int ulas_asm(FILE * dst, FILE * src); // parses and executes a 32 bit signed int math expressions int ulas_intexpr(const char **line, unsigned long n, int *rc); diff --git a/makefile b/makefile index e2755f7..09adfd9 100644 --- a/makefile +++ b/makefile @@ -55,17 +55,13 @@ install: tags: ctags --recurse=yes --exclude=.git --exclude=bin --exclude=obj --extras=* --fields=* --c-kinds=* --language-force=C -.PHONY: -ccmds: - bear -- make SHELL="sh -x -e" --always-make - .PHONY: format format: - clang-format -i ./src/*.c ./include/*.h + VERSION_CONTROL=none indent -kr -ci2 -cli2 -i2 -l80 -nut -brf src/*.c $(IDIR)/*.h -.PHONY: lint +.PHONY: lint lint: - clang-tidy ./include/*.h ./src/*.c + splint src/*.c -I$(IDIR) -warnposix .PHONY: runtest runtest: diff --git a/src/main.c b/src/main.c index bb38dee..72dbe51 100644 --- a/src/main.c +++ b/src/main.c @@ -26,36 +26,38 @@ void ulas_help(void) { ULAS_HELP("o=path", "Output file"); } -void ulas_version(void) { printf("%s version %s\n", ULAS_NAME, ULAS_VER); } +void ulas_version(void) { + printf("%s version %s\n", ULAS_NAME, ULAS_VER); +} void ulas_getopt(int argc, char **argv, struct ulas_config *cfg) { int c = 0; while ((c = getopt(argc, argv, ULAS_OPTS ULAS_OPTS_ARG)) != -1) { switch (c) { - case 'h': - ulas_help(); - exit(0); - break; - case 'V': - ulas_version(); - exit(0); - break; - case 'v': - cfg->verbose = 1; - break; - case 'o': - cfg->output_path = strndup(optarg, ULAS_PATHMAX); - break; - case 'p': - cfg->preproc_only = 1; - break; - case '?': - break; - default: - printf("%s: invalid option '%c'\nTry '%s -h' for more information.\n", - ULAS_NAME, c, ULAS_NAME); - exit(-1); - break; + case 'h': + ulas_help(); + exit(0); + break; + case 'V': + ulas_version(); + exit(0); + break; + case 'v': + cfg->verbose = 1; + break; + case 'o': + cfg->output_path = strndup(optarg, ULAS_PATHMAX); + break; + case 'p': + cfg->preproc_only = 1; + break; + case '?': + break; + default: + printf("%s: invalid option '%c'\nTry '%s -h' for more information.\n", + ULAS_NAME, c, ULAS_NAME); + exit(-1); + break; } } diff --git a/src/test.c b/src/test.c index 5295c94..19ef051 100644 --- a/src/test.c +++ b/src/test.c @@ -50,12 +50,12 @@ void test_tok(void) { TESTBEGIN("tok"); - assert_tok(" test tokens with, line / * + - , ; $1", - {"test", "tokens", "with", ",", "line", "/", "*", "+", "-", ",", - ";", "$1", NULL}); + assert_tok(" test tokens with, line / * + - , ; $1", { + "test", "tokens", "with", ",", "line", "/", "*", "+", "-", ",", + ";", "$1", NULL}); - assert_tokuntil(" this is a, test for tok , until", ',', - {"this is a", "test for tok ", "until", NULL}); + assert_tokuntil(" this is a, test for tok , until", ',', { + "this is a", "test for tok ", "until", NULL}); TESTEND("tok"); } @@ -108,22 +108,20 @@ void test_preproc(void) { "#define test 123\ntest\n#undefine test\ntest"); // macro - assert_preproc( - " line p1 1 label01,2 3\n line p2 2\n line p3 3 p1, p2, p3\n", 0, - "#macro test\n line $1 1 label$$$$,$$ $$\n line $2 2\n line $3 3 " - "$0\n#endmacro\ntest p1, p2, p3"); + assert_preproc + (" line p1 1 label01,2 3\n line p2 2\n line p3 3 p1, p2, p3\n", 0, + "#macro test\n line $1 1 label$$$$,$$ $$\n line $2 2\n line $3 3 " + "$0\n#endmacro\ntest p1, p2, p3"); assert_preproc("test macro with no args\n", 0, "#macro test\ntest macro with no args\n#endmacro\ntest"); assert_preproc("", -1, "#macro test\n not terminated\n"); - assert_preproc( - "nested macro t1\nafter\ncontent n1\n", 0, - "#macro test\nnested macro $1\n#macro " - "nested\ncontent $1\n#endmacro\nafter\nnested n1\n#endmacro\ntest t1"); + assert_preproc("nested macro t1\nafter\ncontent n1\n", 0, + "#macro test\nnested macro $1\n#macro " + "nested\ncontent $1\n#endmacro\nafter\nnested n1\n#endmacro\ntest t1"); // ifdef - assert_preproc( - "before\nifdeftest defined!\nafter", 0, - "before\n#define test\n#ifdef test\nifdeftest defined!\n#endif\nafter"); + assert_preproc("before\nifdeftest defined!\nafter", 0, + "before\n#define test\n#ifdef test\nifdeftest defined!\n#endif\nafter"); assert_preproc("before\nafter", 0, "before\n#ifdef test\nifdeftest defined!\n#endif\nafter"); assert_preproc("ifdeftest defined!\n", -1, @@ -132,9 +130,8 @@ void test_preproc(void) { // ifndef assert_preproc("before\nifndeftest defined!\nafter", 0, "before\n#ifndef test\nifndeftest defined!\n#endif\nafter"); - assert_preproc( - "before\nafter", 0, - "before\n#define test\n#ifndef test\nifndeftest defined!\n#endif\nafter"); + assert_preproc("before\nafter", 0, + "before\n#define test\n#ifndef test\nifndeftest defined!\n#endif\nafter"); assert_preproc("ifndeftest defined!\n", -1, "#ifndef test\nifndeftest defined!\n"); @@ -184,7 +181,7 @@ void test_totok(void) { // string token ASSERT_STR_TOTOK("test", 0, "\"test\""); - + ASSERT_STR_TOTOK("test\n\"123\"", 0, "\"test\\n\\\"123\\\"\""); TESTEND("totok"); @@ -194,8 +191,8 @@ int main(int arc, char **argv) { ulas_init(ulas_cfg_from_env()); /*if (!ulascfg.verbose) { - fclose(stderr); - }*/ + fclose(stderr); + } */ test_tok(); test_strbuf(); diff --git a/src/ulas.c b/src/ulas.c index 5ddb9bd..197915d 100644 --- a/src/ulas.c +++ b/src/ulas.c @@ -41,7 +41,9 @@ void ulas_free(void) { ulas_tokbuffree(&ulas.toks); } -int ulas_icntr(void) { return ulas.icntr++; } +int ulas_icntr(void) { + return ulas.icntr++; +} struct ulas_config ulas_cfg_from_env(void) { struct ulas_config cfg; @@ -143,37 +145,37 @@ int ulas_tok(struct ulas_str *dst, const char **out_line, unsigned long n) { char c = line[i]; switch (c) { - case ',': - case '+': - case '-': - case '*': - case '/': - case '\\': - case ULAS_TOK_COMMENT: - if (WELD_TOKISTERM) { - goto tokdone; - } - // single char tokens - dst->buf[write++] = line[i++]; - goto tokdone; - case '$': - if (WELD_TOKISTERM) { + case ',': + case '+': + case '-': + case '*': + case '/': + case '\\': + case ULAS_TOK_COMMENT: + if (WELD_TOKISTERM) { + goto tokdone; + } + // single char tokens + dst->buf[write++] = line[i++]; goto tokdone; - } - // special var for preprocessor - // make sure we have enough space in buffer - ulas_strensr(dst, write + 2); - // escape char tokens - dst->buf[write++] = line[i++]; - dst->buf[write++] = line[i++]; - goto tokdone; - default: - if (isspace(line[i])) { + case '$': + if (WELD_TOKISTERM) { + goto tokdone; + } + // special var for preprocessor + // make sure we have enough space in buffer + ulas_strensr(dst, write + 2); + // escape char tokens + dst->buf[write++] = line[i++]; + dst->buf[write++] = line[i++]; goto tokdone; - } - dst->buf[write] = line[i]; - write++; - break; + default: + if (isspace(line[i])) { + goto tokdone; + } + dst->buf[write] = line[i]; + write++; + break; } i++; } @@ -218,28 +220,28 @@ int ulas_tokuntil(struct ulas_str *dst, char c, const char **out_line, int ulas_unescape(char c, int *rc) { switch (c) { - case '\'': - case '\\': - case '"': - return c; - case 'n': - return '\n'; - case 'a': - return '\a'; - case 'b': - return '\b'; - case 'f': - return '\f'; - case 'r': - return '\r'; - case '?': - return '\?'; - case '0': - return '\0'; - default: - ULASERR("Unexpected esxcape sequence: \\%c\n", c); - *rc = -1; - break; + case '\'': + case '\\': + case '"': + return c; + case 'n': + return '\n'; + case 'a': + return '\a'; + case 'b': + return '\b'; + case 'f': + return '\f'; + case 'r': + return '\r'; + case '?': + return '\?'; + case '0': + return '\0'; + default: + ULASERR("Unexpected esxcape sequence: \\%c\n", c); + *rc = -1; + break; } return '\0'; @@ -258,97 +260,97 @@ struct ulas_tok ulas_totok(char *buf, unsigned long n, int *rc) { buf++; switch (first) { - case '+': - case '-': - case '*': - case '/': - case '!': - case '~': - case '|': - case '&': - case '%': - case '(': - case ')': - case '[': - case ']': - case ',': - case ';': - // single char tokens - tok.type = first; - goto end; - case '"': - // string - tok.type = ULAS_TOKLITERAL; - tok.lit.type = ULAS_STR; - - // FIXME: this likely mallocs a few extra bytes - // but honestly its probably fine - tok.lit.val.strv = malloc(n * sizeof(char) + 1); - memset(tok.lit.val.strv, 0, n); - - long i = 0; - while (*buf && *buf != '\"') { - if (*buf == '\\') { - buf++; - tok.lit.val.strv[i] = ulas_unescape(*buf, rc); - } else { - tok.lit.val.strv[i] = *buf; - } - i++; - buf++; - } - tok.lit.val.strv[i] = '\0'; - - if (*buf != '\"') { - *rc = -1; - ULASERR("Unterminated string sequence\n"); + case '+': + case '-': + case '*': + case '/': + case '!': + case '~': + case '|': + case '&': + case '%': + case '(': + case ')': + case '[': + case ']': + case ',': + case ';': + // single char tokens + tok.type = first; goto end; - } - buf++; - break; - default: - if (isdigit(first)) { - // integer + case '"': + // string tok.type = ULAS_TOKLITERAL; - tok.lit.type = ULAS_INT; + tok.lit.type = ULAS_STR; - // 0b prefix is not supported in strtol... so we implement it by hand - if (*buf == 'b') { + // FIXME: this likely mallocs a few extra bytes + // but honestly its probably fine + tok.lit.val.strv = malloc(n * sizeof(char) + 1); + memset(tok.lit.val.strv, 0, n); + + long i = 0; + while (*buf && *buf != '\"') { + if (*buf == '\\') { + buf++; + tok.lit.val.strv[i] = ulas_unescape(*buf, rc); + } else { + tok.lit.val.strv[i] = *buf; + } + i++; buf++; - tok.lit.val.intv = (int)strtol(buf, &buf, 2); - } else { - tok.lit.val.intv = (int)strtol(buf - 1, &buf, 0); } - } else if (first == '\'') { - tok.type = ULAS_TOKLITERAL; - tok.lit.type = ULAS_INT; - if (*buf == '\\') { - buf++; - tok.lit.val.intv = ulas_unescape(*buf, rc); - } else { - tok.lit.val.intv = (int)*buf; + tok.lit.val.strv[i] = '\0'; + + if (*buf != '\"') { + *rc = -1; + ULASERR("Unterminated string sequence\n"); + goto end; } buf++; - if (*buf != '\'') { + break; + default: + if (isdigit(first)) { + // integer + tok.type = ULAS_TOKLITERAL; + tok.lit.type = ULAS_INT; + + // 0b prefix is not supported in strtol... so we implement it by hand + if (*buf == 'b') { + buf++; + tok.lit.val.intv = (int) strtol(buf, &buf, 2); + } else { + tok.lit.val.intv = (int) strtol(buf - 1, &buf, 0); + } + } else if (first == '\'') { + tok.type = ULAS_TOKLITERAL; + tok.lit.type = ULAS_INT; + if (*buf == '\\') { + buf++; + tok.lit.val.intv = ulas_unescape(*buf, rc); + } else { + tok.lit.val.intv = (int) *buf; + } + buf++; + if (*buf != '\'') { + *rc = -1; + ULASERR("Unterminated character sequence\n"); + goto end; + } + buf++; + break; + } else if (ulas_isname(buf, n)) { + // literal. we can resolve it now + // because literals need to be able to be resolved + // for every line, unless they are a label! + // TODO: read and unescape striing between " and " + tok.type = ULAS_TOKSYMBOL; + tok.lit.type = ULAS_STR; + } else { + ULASERR("Unexpected token: %s\n", buf); *rc = -1; - ULASERR("Unterminated character sequence\n"); goto end; } - buf++; break; - } else if (ulas_isname(buf, n)) { - // literal. we can resolve it now - // because literals need to be able to be resolved - // for every line, unless they are a label! - // TODO: read and unescape striing between " and " - tok.type = ULAS_TOKSYMBOL; - tok.lit.type = ULAS_STR; - } else { - ULASERR("Unexpected token: %s\n", buf); - *rc = -1; - goto end; - } - break; } end: @@ -364,7 +366,7 @@ end: #undef WLED_TOKISTERM struct ulas_str ulas_str(unsigned long n) { - struct ulas_str str = {malloc(n), n}; + struct ulas_str str = { malloc(n), n }; return str; } @@ -447,130 +449,134 @@ char *ulas_preprocexpand(struct ulas_preproc *pp, const char *raw_line, first_tok = 0; struct ulas_ppdef *def = - ulas_preprocgetdef(pp, pp->tok.buf, pp->tok.maxlen); + ulas_preprocgetdef(pp, pp->tok.buf, pp->tok.maxlen); if (def) { // if so... expand now and leave switch (def->type) { - case ULAS_PPDEF: { - unsigned long val_len = strlen(def->value); - int wsi = ulas_preproclws(pp, praw_line - read, *n); - if (val_len) { - // make sure to include leading white space - // adjust total length - *n -= strlen(pp->tok.buf); - *n += val_len; - ulas_strensr(&pp->line, (*n) + 1 + wsi); - - // only remove the first white space char if the lenght of value - // is greater than 1, otherwise just leave it be... - if (val_len > 1) { - strncat(pp->line.buf, def->value + 1, val_len - 1); - } else { - strncat(pp->line.buf, def->value, val_len); + case ULAS_PPDEF:{ + unsigned long val_len = strlen(def->value); + int wsi = ulas_preproclws(pp, praw_line - read, *n); + if (val_len) { + // make sure to include leading white space + // adjust total length + *n -= strlen(pp->tok.buf); + *n += val_len; + ulas_strensr(&pp->line, (*n) + 1 + wsi); + + // only remove the first white space char if the lenght of value + // is greater than 1, otherwise just leave it be... + if (val_len > 1) { + strncat(pp->line.buf, def->value + 1, val_len - 1); + } else { + strncat(pp->line.buf, def->value, val_len); + } + } + break; } - } - break; - } - case ULAS_PPMACRO: { - // TODO: i am sure we can optimize the resize of line buffers here... - - // get 9 comma separated values. - // $1-$9 will reference the respective arg - // $0 will reference the entire line after the macro name - // there can be more than 9 args, but anything after the 9th arg can - // only be accessed via $0 - const char *line = praw_line; - unsigned long linelen = strlen(praw_line); - // clear all params from previous attempt - for (unsigned long i = 0; i < ULAS_MACROPARAMMAX; i++) { - pp->macroparam[i].buf[0] = '\0'; - } + case ULAS_PPMACRO:{ + // TODO: i am sure we can optimize the resize of line buffers here... + + // get 9 comma separated values. + // $1-$9 will reference the respective arg + // $0 will reference the entire line after the macro name + // there can be more than 9 args, but anything after the 9th arg can + // only be accessed via $0 + const char *line = praw_line; + unsigned long linelen = strlen(praw_line); + // clear all params from previous attempt + for (unsigned long i = 0; i < ULAS_MACROPARAMMAX; i++) { + pp->macroparam[i].buf[0] = '\0'; + } - // loop until 9 args are found or the line ends - int paramc = 0; - while (paramc < ULAS_MACROPARAMMAX && - ulas_tokuntil(&pp->macroparam[paramc], ',', &praw_line, *n) > + // loop until 9 args are found or the line ends + int paramc = 0; + while (paramc < ULAS_MACROPARAMMAX && + ulas_tokuntil(&pp->macroparam[paramc], ',', &praw_line, *n) > 0) { - // trim new lines from the end of macro params - ulas_trimend('\n', pp->macroparam[paramc].buf, - strlen(pp->macroparam[paramc].buf)); - paramc++; - } - ulas_strensr(&pp->line, strlen(def->value) + 2); - - const char *macro_argname[ULAS_MACROPARAMMAX] = { - "$1", "$2", "$3", "$4", "$5", "$6", "$7", "$8", "$9"}; - - const char *val = def->value; - unsigned long vallen = strlen(def->value); - unsigned long valread = 0; - - // the pointer to tocat will be the variable's value if any - // exists - const char *tocat = NULL; - unsigned long tocatlen = 0; - - // now tokenize the macro's value and look for $0-$9 - // and replace those instances - // eveyrthing else will just be copied as is - while ((valread = ulas_tok(&pp->macrobuf, &val, vallen)) > 0) { - tocat = NULL; - char numbuf[128]; - - // decide what tocat should be - for (unsigned long mi = 0; mi < ULAS_MACROPARAMMAX; mi++) { - const char *name = macro_argname[mi]; - if (pp->macroparam[mi].buf[0] && - strncmp((name), pp->macrobuf.buf, pp->macrobuf.maxlen) == 0) { - ulas_strensr(&pp->line, strnlen(pp->line.buf, pp->line.maxlen) + - strnlen(pp->macroparam[mi].buf, - pp->macroparam[mi].maxlen) + - 1); - - tocat = pp->macroparam[mi].buf; - tocatlen = pp->macroparam[mi].maxlen; - - break; + // trim new lines from the end of macro params + ulas_trimend('\n', pp->macroparam[paramc].buf, + strlen(pp->macroparam[paramc].buf)); + paramc++; } - } - - if (linelen && - strncmp("$0", pp->macrobuf.buf, pp->macrobuf.maxlen) == 0) { - ulas_strensr(&pp->line, - strnlen(pp->line.buf, pp->line.maxlen) + linelen + 1); - - if (linelen > 1) { - // this skips the separating token which is usually a space - // all further spaces are included though! - tocat = line + 1; - tocatlen = linelen - 1; - } else { - // do not do this if the line is literally empty! - tocat = line; - tocatlen = linelen; + ulas_strensr(&pp->line, strlen(def->value) + 2); + + const char *macro_argname[ULAS_MACROPARAMMAX] = { + "$1", "$2", "$3", "$4", "$5", "$6", "$7", "$8", "$9" + }; + + const char *val = def->value; + unsigned long vallen = strlen(def->value); + unsigned long valread = 0; + + // the pointer to tocat will be the variable's value if any + // exists + const char *tocat = NULL; + unsigned long tocatlen = 0; + + // now tokenize the macro's value and look for $0-$9 + // and replace those instances + // eveyrthing else will just be copied as is + while ((valread = ulas_tok(&pp->macrobuf, &val, vallen)) > 0) { + tocat = NULL; + char numbuf[128]; + + // decide what tocat should be + for (unsigned long mi = 0; mi < ULAS_MACROPARAMMAX; mi++) { + const char *name = macro_argname[mi]; + if (pp->macroparam[mi].buf[0] && + strncmp((name), pp->macrobuf.buf, + pp->macrobuf.maxlen) == 0) { + ulas_strensr(&pp->line, + strnlen(pp->line.buf, + pp->line.maxlen) + + strnlen(pp->macroparam[mi].buf, + pp->macroparam[mi].maxlen) + 1); + + tocat = pp->macroparam[mi].buf; + tocatlen = pp->macroparam[mi].maxlen; + + break; + } + } + + if (linelen && + strncmp("$0", pp->macrobuf.buf, pp->macrobuf.maxlen) == 0) { + ulas_strensr(&pp->line, + strnlen(pp->line.buf, + pp->line.maxlen) + linelen + 1); + + if (linelen > 1) { + // this skips the separating token which is usually a space + // all further spaces are included though! + tocat = line + 1; + tocatlen = linelen - 1; + } else { + // do not do this if the line is literally empty! + tocat = line; + tocatlen = linelen; + } + } else if (linelen && strncmp("$$", pp->macrobuf.buf, + pp->macrobuf.maxlen) == 0) { + sprintf(numbuf, "%x", ulas_icntr()); + ulas_strensr(&pp->line, + strnlen(pp->line.buf, pp->line.maxlen) + 128 + 1); + tocat = numbuf; + tocatlen = 128; + } + + if (!tocat) { + ulas_strensr(&pp->line, valread + 1); + strncat(pp->line.buf, val - valread, valread); + } else { + // make sure to include leading white space + int wsi = ulas_preproclws(pp, val - valread, vallen); + ulas_strensr(&pp->line, strnlen(pp->line.buf, pp->line.maxlen) + + tocatlen + wsi + 1); + strncat(pp->line.buf, tocat, tocatlen); + } } - } else if (linelen && strncmp("$$", pp->macrobuf.buf, - pp->macrobuf.maxlen) == 0) { - sprintf(numbuf, "%x", ulas_icntr()); - ulas_strensr(&pp->line, - strnlen(pp->line.buf, pp->line.maxlen) + 128 + 1); - tocat = numbuf; - tocatlen = 128; - } - - if (!tocat) { - ulas_strensr(&pp->line, valread + 1); - strncat(pp->line.buf, val - valread, valread); - } else { - // make sure to include leading white space - int wsi = ulas_preproclws(pp, val - valread, vallen); - ulas_strensr(&pp->line, strnlen(pp->line.buf, pp->line.maxlen) + - tocatlen + wsi + 1); - strncat(pp->line.buf, tocat, tocatlen); + goto end; } - } - goto end; - } } } else { @@ -608,14 +614,16 @@ int ulas_preprocline(struct ulas_preproc *pp, FILE *dst, FILE *src, char *line = ulas_preprocexpand(pp, raw_line, &n); const char *pline = line; - const char *dirstrs[] = {ULAS_PPSTR_DEF, ULAS_PPSTR_MACRO, - ULAS_PPSTR_IFDEF, ULAS_PPSTR_IFNDEF, - ULAS_PPSTR_ENDIF, ULAS_PPSTR_ENDMACRO, - ULAS_PPSTR_UNDEF, NULL}; - enum ulas_ppdirs dirs[] = {ULAS_PPDIR_DEF, ULAS_PPDIR_MACRO, - ULAS_PPDIR_IFDEF, ULAS_PPDIR_IFNDEF, - ULAS_PPDIR_ENDIF, ULAS_PPDIR_ENDMACRO, - ULAS_PPDIR_UNDEF}; + const char *dirstrs[] = { ULAS_PPSTR_DEF, ULAS_PPSTR_MACRO, + ULAS_PPSTR_IFDEF, ULAS_PPSTR_IFNDEF, + ULAS_PPSTR_ENDIF, ULAS_PPSTR_ENDMACRO, + ULAS_PPSTR_UNDEF, NULL + }; + enum ulas_ppdirs dirs[] = { ULAS_PPDIR_DEF, ULAS_PPDIR_MACRO, + ULAS_PPDIR_IFDEF, ULAS_PPDIR_IFNDEF, + ULAS_PPDIR_ENDIF, ULAS_PPDIR_ENDMACRO, + ULAS_PPDIR_UNDEF + }; enum ulas_ppdirs found_dir = ULAS_PPDIR_NONE; @@ -640,134 +648,135 @@ found: if (found_dir != ULAS_PPDIR_NONE) { ulas_trimend('\n', line, strlen(line)); switch (found_dir) { - case ULAS_PPDIR_DEF: { - // next token is a name - // and then the entire remainder of the line is a value - if (ulas_tok(&pp->tok, &pline, n) == 0) { - ULASERR("Expected name for #define\n"); - return -1; - } - - if (!ulas_isname(pp->tok.buf, strlen(pp->tok.buf))) { - ULASERR("'%s' is not a valid #define name!\n", pp->tok.buf); - return -1; - } + case ULAS_PPDIR_DEF:{ + // next token is a name + // and then the entire remainder of the line is a value + if (ulas_tok(&pp->tok, &pline, n) == 0) { + ULASERR("Expected name for #define\n"); + return -1; + } - struct ulas_ppdef def = {ULAS_PPDEF, strdup(pp->tok.buf), strdup(pline), - 0}; - ulas_preprocdef(pp, def); - // define short-circuits the rest of the logic - // because it just takes the entire rest of the line as a value! - goto dirdone; - } - case ULAS_PPDIR_MACRO: { - // get a name, ensure no more tokens come after - // and then consume lines until ENDMACRO is seen - if (ulas_tok(&pp->tok, &pline, n) == 0) { - ULASERR("Expected name for #macro\n"); - return -1; - } + if (!ulas_isname(pp->tok.buf, strlen(pp->tok.buf))) { + ULASERR("'%s' is not a valid #define name!\n", pp->tok.buf); + return -1; + } - if (!ulas_isname(pp->tok.buf, strlen(pp->tok.buf))) { - ULASERR("'%s' is not a valid #macro name!\n", pp->tok.buf); - return -1; - } - char *name = strdup(pp->tok.buf); - - struct ulas_str val = ulas_str(32); - memset(val.buf, 0, 32); - - char buf[ULAS_LINEMAX]; - memset(buf, 0, ULAS_LINEMAX); - - // consume lines until #endmacro is read - // if reaching end of input without #endmacro we have an unterminated - // macro. pass NULL as dst to consume lines that are being read instead of - // echoing them back - int rc = 0; - while ((rc = ulas_preprocnext(pp, NULL, src, buf, ULAS_LINEMAX)) > 0) { - if (rc == ULAS_PPDIR_ENDMACRO) { - // we need to clear the line buffer to now echo back - // the #endmacro directive - pp->line.buf[0] = '\0'; - break; + struct ulas_ppdef def = + { ULAS_PPDEF, strdup(pp->tok.buf), strdup(pline), + 0 + }; + ulas_preprocdef(pp, def); + // define short-circuits the rest of the logic + // because it just takes the entire rest of the line as a value! + goto dirdone; } + case ULAS_PPDIR_MACRO:{ + // get a name, ensure no more tokens come after + // and then consume lines until ENDMACRO is seen + if (ulas_tok(&pp->tok, &pline, n) == 0) { + ULASERR("Expected name for #macro\n"); + return -1; + } - unsigned long len = strnlen(pp->line.buf, pp->line.maxlen); - ulas_strensr(&val, strnlen(val.buf, val.maxlen) + len + 1); - strncat(val.buf, pp->line.buf, val.maxlen); - } + if (!ulas_isname(pp->tok.buf, strlen(pp->tok.buf))) { + ULASERR("'%s' is not a valid #macro name!\n", pp->tok.buf); + return -1; + } + char *name = strdup(pp->tok.buf); + + struct ulas_str val = ulas_str(32); + memset(val.buf, 0, 32); + + char buf[ULAS_LINEMAX]; + memset(buf, 0, ULAS_LINEMAX); + + // consume lines until #endmacro is read + // if reaching end of input without #endmacro we have an unterminated + // macro. pass NULL as dst to consume lines that are being read instead of + // echoing them back + int rc = 0; + while ((rc = ulas_preprocnext(pp, NULL, src, buf, ULAS_LINEMAX)) > 0) { + if (rc == ULAS_PPDIR_ENDMACRO) { + // we need to clear the line buffer to now echo back + // the #endmacro directive + pp->line.buf[0] = '\0'; + break; + } - if (rc != ULAS_PPDIR_ENDMACRO) { - ULASERR("Unterminated macro directive\n"); - ulas_strfree(&val); - free(name); - return -1; - } + unsigned long len = strnlen(pp->line.buf, pp->line.maxlen); + ulas_strensr(&val, strnlen(val.buf, val.maxlen) + len + 1); + strncat(val.buf, pp->line.buf, val.maxlen); + } - // we leak the str's buffer into the def now - // this is ok because we call free for it later anyway - struct ulas_ppdef def = {ULAS_PPMACRO, name, val.buf, 0}; - ulas_preprocdef(pp, def); + if (rc != ULAS_PPDIR_ENDMACRO) { + ULASERR("Unterminated macro directive\n"); + ulas_strfree(&val); + free(name); + return -1; + } + // we leak the str's buffer into the def now + // this is ok because we call free for it later anyway + struct ulas_ppdef def = { ULAS_PPMACRO, name, val.buf, 0 }; + ulas_preprocdef(pp, def); - goto dirdone; - } - case ULAS_PPDIR_ENDIF: - case ULAS_PPDIR_ENDMACRO: - break; - case ULAS_PPDIR_IFDEF: - case ULAS_PPDIR_IFNDEF: { - // get the name - // get a name, ensure no more tokens come after - // and then consume lines until ENDMACRO is seen - if (ulas_tok(&pp->tok, &pline, n) == 0) { - ULASERR("Expected name for #if(n)def\n"); - return -1; - } - struct ulas_ppdef *def = - ulas_preprocgetdef(pp, pp->tok.buf, pp->tok.maxlen); + goto dirdone; + } + case ULAS_PPDIR_ENDIF: + case ULAS_PPDIR_ENDMACRO: + break; + case ULAS_PPDIR_IFDEF: + case ULAS_PPDIR_IFNDEF:{ + // get the name + // get a name, ensure no more tokens come after + // and then consume lines until ENDMACRO is seen + if (ulas_tok(&pp->tok, &pline, n) == 0) { + ULASERR("Expected name for #if(n)def\n"); + return -1; + } + struct ulas_ppdef *def = + ulas_preprocgetdef(pp, pp->tok.buf, pp->tok.maxlen); - char buf[ULAS_LINEMAX]; - memset(buf, 0, ULAS_LINEMAX); + char buf[ULAS_LINEMAX]; + memset(buf, 0, ULAS_LINEMAX); - FILE *defdst = NULL; - if ((def && found_dir == ULAS_PPDIR_IFDEF) || - (!def && found_dir == ULAS_PPDIR_IFNDEF)) { - defdst = dst; - } + FILE *defdst = NULL; + if ((def && found_dir == ULAS_PPDIR_IFDEF) || + (!def && found_dir == ULAS_PPDIR_IFNDEF)) { + defdst = dst; + } + // loop until end of line or endif + int rc = 0; + while ((rc = + ulas_preprocnext(pp, defdst, src, buf, ULAS_LINEMAX)) > 0) { + if (rc == ULAS_PPDIR_ENDIF) { + // we need to clear the line buffer to now echo back + // the #endif directive + pp->line.buf[0] = '\0'; + break; + } + } - // loop until end of line or endif - int rc = 0; - while ((rc = ulas_preprocnext(pp, defdst, src, buf, ULAS_LINEMAX)) > 0) { - if (rc == ULAS_PPDIR_ENDIF) { - // we need to clear the line buffer to now echo back - // the #endif directive - pp->line.buf[0] = '\0'; - break; + if (rc != ULAS_PPDIR_ENDIF) { + ULASERR("Unterminated if(n)def directive\n"); + return -1; + } + goto dirdone; } - } - - if (rc != ULAS_PPDIR_ENDIF) { - ULASERR("Unterminated if(n)def directive\n"); - return -1; - } - goto dirdone; - } - case ULAS_PPDIR_UNDEF: { - if (ulas_tok(&pp->tok, &pline, n) == 0) { - ULASERR("Expected name for #undef\n"); - return -1; - } - struct ulas_ppdef *def = NULL; - while ((def = ulas_preprocgetdef(pp, pp->tok.buf, pp->tok.maxlen))) { - def->undef = 1; - } + case ULAS_PPDIR_UNDEF:{ + if (ulas_tok(&pp->tok, &pline, n) == 0) { + ULASERR("Expected name for #undef\n"); + return -1; + } + struct ulas_ppdef *def = NULL; + while ((def = ulas_preprocgetdef(pp, pp->tok.buf, pp->tok.maxlen))) { + def->undef = 1; + } - break; - } - default: - // this should not happen! - break; + break; + } + default: + // this should not happen! + break; } dirdone: @@ -796,7 +805,7 @@ int ulas_preprocnext(struct ulas_preproc *pp, FILE *dst, FILE *src, char *buf, } struct ulas_preproc ulas_preprocinit(void) { - struct ulas_preproc pp = {NULL, 0, ulas_str(1), ulas_str(1)}; + struct ulas_preproc pp = { NULL, 0, ulas_str(1), ulas_str(1) }; for (unsigned long i = 0; i < ULAS_MACROPARAMMAX; i++) { pp.macroparam[i] = ulas_str(8); } @@ -842,7 +851,6 @@ int ulas_preproc(FILE *dst, FILE *src) { if (ulascfg.preproc_only) { continue; } - // after each preproc line we assembly it by reading it back // from the temporary buffer fseek(asmsrc, prevseek, SEEK_SET); @@ -908,9 +916,13 @@ void ulas_tokbufpush(struct ulas_tokbuf *tb, struct ulas_tok tok) { tb->len++; } -void ulas_tokbufclear(struct ulas_tokbuf *tb) { tb->len = 0; } +void ulas_tokbufclear(struct ulas_tokbuf *tb) { + tb->len = 0; +} -void ulas_tokbuffree(struct ulas_tokbuf *tb) { free(tb->buf); } +void ulas_tokbuffree(struct ulas_tokbuf *tb) { + free(tb->buf); +} /** * Assembly step @@ -925,7 +937,6 @@ int ulas_intexpr(const char **line, unsigned long n, int *rc) { *rc = -1; goto fail; } - // interpret the token } @@ -944,11 +955,13 @@ int ulas_asmline(FILE *dst, FILE *src, const char *line, unsigned long n) { if (ulas.tok.buf[0] == ULAS_TOK_ASMDIR_BEGIN) { const char *dirstrs[] = { - ULAS_ASMSTR_ORG, ULAS_ASMSTR_SET, ULAS_ASMSTR_BYTE, ULAS_ASMSTR_STR, - ULAS_ASMSTR_FILL, ULAS_ASMSTR_PAD, ULAS_ASMSTR_INCBIN, NULL}; + ULAS_ASMSTR_ORG, ULAS_ASMSTR_SET, ULAS_ASMSTR_BYTE, ULAS_ASMSTR_STR, + ULAS_ASMSTR_FILL, ULAS_ASMSTR_PAD, ULAS_ASMSTR_INCBIN, NULL + }; enum ulas_asmdir dirs[] = { - ULAS_ASMDIR_ORG, ULAS_ASMDIR_SET, ULAS_ASMDIR_BYTE, ULAS_ASMDIR_STR, - ULAS_ASMDIR_FILL, ULAS_ASMDIR_PAD, ULAS_ASMDIR_INCBIN}; + ULAS_ASMDIR_ORG, ULAS_ASMDIR_SET, ULAS_ASMDIR_BYTE, ULAS_ASMDIR_STR, + ULAS_ASMDIR_FILL, ULAS_ASMDIR_PAD, ULAS_ASMDIR_INCBIN + }; enum ulas_asmdir dir = ULAS_ASMDIR_NONE; @@ -966,18 +979,18 @@ int ulas_asmline(FILE *dst, FILE *src, const char *line, unsigned long n) { } switch (dir) { - case ULAS_ASMDIR_NONE: - case ULAS_ASMDIR_ORG: - ulas.address = ulas_intexpr(&line, strnlen(start, n), &rc); - break; - case ULAS_ASMDIR_SET: - case ULAS_ASMDIR_BYTE: - case ULAS_ASMDIR_STR: - case ULAS_ASMDIR_FILL: - case ULAS_ASMDIR_PAD: - case ULAS_ASMDIR_INCBIN: - ULASPANIC("asmdir not implemented\n"); - break; + case ULAS_ASMDIR_NONE: + case ULAS_ASMDIR_ORG: + ulas.address = ulas_intexpr(&line, strnlen(start, n), &rc); + break; + case ULAS_ASMDIR_SET: + case ULAS_ASMDIR_BYTE: + case ULAS_ASMDIR_STR: + case ULAS_ASMDIR_FILL: + case ULAS_ASMDIR_PAD: + case ULAS_ASMDIR_INCBIN: + ULASPANIC("asmdir not implemented\n"); + break; } } else { -- 2.30.2