WIP: ifdef
authorLukas Krickl <lukas@krickl.dev>
Sun, 12 Nov 2023 15:53:05 +0000 (16:53 +0100)
committerLukas Krickl <lukas@krickl.dev>
Sun, 12 Nov 2023 15:53:05 +0000 (16:53 +0100)
include/ulas.h
src/test.c
src/ulas.c

index 4b55b7af4108a1377614c5fa70875fcd5116ecf5..6992f72b7e8a9f4667c7d813eb72f5fe6c7b2ecc 100644 (file)
@@ -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);
 
index c8a845bc31a92761a0af916d0e1fbb8b3060f0a4..366f8249e9a9028bf94a0fc12e75b71ba77f42e6 100644 (file)
@@ -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");
 }
 
index aae8605d115cfc0a6f6c939580c52878d5dffc48..a9b82b502ea9406c98842653f0897851d8c97c3b 100644 (file)
@@ -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");