From: Lukas Krickl Date: Sun, 12 Nov 2023 15:53:05 +0000 (+0100) Subject: WIP: ifdef X-Git-Url: https://git.krickl.dev/?a=commitdiff_plain;h=242f92e48f22556933019d9fa7139b5bb394c771;p=ulas%2F.git WIP: ifdef --- diff --git a/include/ulas.h b/include/ulas.h index 4b55b7a..6992f72 100644 --- a/include/ulas.h +++ b/include/ulas.h @@ -275,6 +275,8 @@ int ulas_preprocnext(struct ulas_preproc *pp, FILE *dst, FILE *src, char *buf, // returns: 0 when a regular line was read // enum ulas_ppdirs id for preprocessor directive // -1 on error +// Warning: calling this recursively may clobber pp buffers and those should +// not be called in the caller after recursvion finishes! int ulas_preprocline(struct ulas_preproc *pp, FILE *dst, FILE *src, const char *raw_line, size_t n); diff --git a/src/test.c b/src/test.c index c8a845b..366f824 100644 --- a/src/test.c +++ b/src/test.c @@ -120,6 +120,9 @@ void test_preproc(void) { "#macro test\nnested macro $1\n#macro " "nested\ncontent $1\n#endmacro\nafter\nnested n1\n#endmacro\ntest t1"); + assert_preproc("test defined!\n", 0, + "#define test\n#ifdef test\ntest defined!\n#endif"); + TESTEND("preproc"); } diff --git a/src/ulas.c b/src/ulas.c index aae8605..a9b82b5 100644 --- a/src/ulas.c +++ b/src/ulas.c @@ -524,13 +524,47 @@ found: goto dirdone; } + case ULAS_PPDIR_ENDIF: case ULAS_PPDIR_ENDMACRO: break; case ULAS_PPDIR_IFDEF: - case ULAS_PPDIR_IFNDEF: - case ULAS_PPDIR_ENDIF: - // TODO: implement - ULASPANIC("Preproc directive is not implemented!\n"); + 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; + } + + // 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; + } + + char buf[ULAS_LINEMAX]; + memset(buf, 0, ULAS_LINEMAX); + + FILE *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 #endmacro directive + pp->line.buf[0] = '\0'; + break; + } + } + + 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");