From cca0792839393b596b19b4492131523fbc8400de Mon Sep 17 00:00:00 2001 From: Lukas Krickl Date: Sat, 11 Nov 2023 17:13:20 +0100 Subject: [PATCH] Added #undef directive --- include/ulas.h | 1 + src/test.c | 10 ++++++++++ src/ulas.c | 36 ++++++++++++++++++++++++++++-------- 3 files changed, 39 insertions(+), 8 deletions(-) diff --git a/include/ulas.h b/include/ulas.h index ebc779c..7369010 100644 --- a/include/ulas.h +++ b/include/ulas.h @@ -26,6 +26,7 @@ #define ULAS_PPSTR_ENDIF "#endif" #define ULAS_PPSTR_IFNDEF "#ifndef" #define ULAS_PPSTR_ENDMACRO "#endmacro" +#define ULAS_PPSTR_UNDEF "#undefine" // configurable tokens #define ULAS_TOK_COMMENT ';' diff --git a/src/test.c b/src/test.c index 4827502..4968d4f 100644 --- a/src/test.c +++ b/src/test.c @@ -92,11 +92,21 @@ void test_strbuf(void) { void test_preproc(void) { TESTBEGIN("preproc"); + // no directive assert_preproc(" test line", 0, " test line"); + + // define assert_preproc(" 123", 0, " #define test 123\ntest"); assert_preproc("", -1, " #define 1test 123\n"); + assert_preproc("", -1, " #define\n"); assert_preproc("this is a 123 for defs", 0, " #define test 123\nthis is a test for defs"); + + // undefined + assert_preproc(" 123\ntest", 0, + "#define test 123\ntest\n#undefine test\ntest"); + + // macro assert_preproc(" line p1 1\n line p2 2\n line p3 3 p1, p2, p3\n", 0, "#macro test\n line $1 1\n line $2 2\n line $3 3 " "$0\n#endmacro\ntest p1, p2, p3"); diff --git a/src/ulas.c b/src/ulas.c index 30411c1..f6b04bf 100644 --- a/src/ulas.c +++ b/src/ulas.c @@ -204,12 +204,21 @@ char *ulas_preprocexpand(struct ulas_preproc *pp, const char *raw_line, memset(pp->line.buf, 0, pp->line.maxlen); int read = 0; + int first_tok = 1; // 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 ((read = ulas_tok(&pp->tok, &praw_line, *n))) { + // if it is the first token, and it begins with a # do not process at all! + if (first_tok && pp->tok.buf[0] == ULAS_TOK_PREPROC_BEGIN) { + ulas_strensr(&pp->line, (*n) + 1); + strncat(pp->line.buf, raw_line, *n); + break; + } + first_tok = 0; + struct ulas_ppdef *def = ulas_preprocgetdef(pp, pp->tok.buf, pp->tok.maxlen); if (def) { @@ -337,16 +346,14 @@ 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, - NULL}; + 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_ENDIF, ULAS_PPDIR_ENDMACRO, + ULAS_PPDIR_UNDEF}; enum ulas_ppdirs found_dir = ULAS_PPDIR_NONE; @@ -456,7 +463,19 @@ found: case ULAS_PPDIR_ENDIF: // TODO: implement ULASPANIC("Preproc directive is not implemented!\n"); + 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; + printf("name: %s\n", pp->tok.buf); + while ((def = ulas_preprocgetdef(pp, pp->tok.buf, pp->tok.maxlen))) { + def->undef = 1; + } + break; + } default: // this should not happen! break; @@ -464,6 +483,7 @@ found: // the end of a directive should have no further tokens! if (ulas_preprochasstray(pp, pline, n)) { + ULASERR("Stray token at end of preprocessor directive!"); return -1; } dirdone: -- 2.30.2