Split up preproc call to allow recursive calls in preprocline
authorLukas Krickl <lukas@krickl.dev>
Tue, 7 Nov 2023 19:16:54 +0000 (20:16 +0100)
committerLukas Krickl <lukas@krickl.dev>
Tue, 7 Nov 2023 19:16:54 +0000 (20:16 +0100)
include/ulas.h
src/ulas.c

index 8707ebc7b93b23b2c62dfa4ca1e70bc79a62fef2..14c10f06cb0828b7099895fa6988f75d962fa8f9 100644 (file)
 #define ULAS_CFG_FMT_BLUE "\x1B[34m"
 #define ULAS_CFG_FMT_RESET "\x1B[0m"
 
+#define ULAS_PPSTR_DEF "#define"
+#define ULAS_PPSTR_MACRO "#macro"
+#define ULAS_PPSTR_IFDEF "#ifdef"
+#define ULAS_PPSTR_ENDIF "#endif"
+#define ULAS_PPSTR_IFNDEF "#ifndef"
+#define ULAS_PPSTR_ENDMACRO "#endmacro"
+
 // configurable tokens
 #define ULAS_TOK_COMMENT ';'
 // start of as directives such as .org
@@ -233,9 +240,25 @@ void ulas_strfree(struct ulas_str *s);
 
 /**
  * Tokenize and apply the preprocessor
+ * returns 0: no error
+ *        -1: error
  */
 int ulas_preproc(FILE *dst, FILE *src);
 
+// reads the next line
+// returns 0 if no more data can be read
+//         1 if data was read
+//         -1 on error
+int ulas_preprocnext(struct ulas_preproc *pp, FILE *dst, FILE *src, char *buf,
+                     int n);
+
+// process a line of preproc
+// returns: 0 when a regular line was read
+//          enum ulas_ppdirs id for preprocessor directive
+//          -1 on error
+int ulas_preprocline(struct ulas_preproc *pp, FILE *dst, FILE *src,
+                     const char *raw_line, size_t n);
+
 // expand preproc into dst line
 char *ulas_preprocexpand(struct ulas_preproc *pp, const char *raw_line,
                          size_t *n);
index d41af4fb0a297aa3308f07a3fa7bac5ebba32c99..a53a4866963b3fcde00e0c9babbee4b19055963b 100644 (file)
@@ -207,13 +207,18 @@ int ulas_preprocdef(struct ulas_preproc *pp, struct ulas_ppdef def) {
   return 0;
 }
 
-int ulas_preprocline(struct ulas_preproc *pp, FILE *dst, const char *raw_line,
-                     size_t n) {
+int ulas_preprocline(struct ulas_preproc *pp, FILE *dst, FILE *src,
+                     const char *raw_line, size_t n) {
   char *line = ulas_preprocexpand(pp, raw_line, &n);
   const char *pline = line;
 
-  const char *dirstrs[] = {"#define", "#macro",    "#ifdef", "#ifndef",
-                           "#endif",  "#endmacro", NULL};
+  const char *dirstrs[] = {ULAS_PPSTR_DEF,
+                           ULAS_PPSTR_MACRO,
+                           ULAS_PPSTR_IFDEF,
+                           ULAS_PPSTR_IFNDEF,
+                           ULAS_PPSTR_ENDIF,
+                           ULAS_PPSTR_ENDMACRO,
+                           NULL};
   enum ulas_ppdirs dirs[] = {ULAS_PPDIR_DEF,   ULAS_PPDIR_MACRO,
                              ULAS_PPDIR_IFDEF, ULAS_PPDIR_IFNDEF,
                              ULAS_PPDIR_ENDIF, ULAS_PPDIR_ENDMACRO};
@@ -264,7 +269,7 @@ found:
       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!
-      return 0;
+      goto dirdone;
     }
     case ULAS_PPDIR_MACRO:
     case ULAS_PPDIR_ENDMACRO:
@@ -285,7 +290,8 @@ found:
               pp->tok.buf);
       return -1;
     }
-
+  dirdone:
+    return found_dir;
   } else {
     fwrite(line, 1, n, dst);
   }
@@ -293,6 +299,21 @@ found:
   return 0;
 }
 
+int ulas_preprocnext(struct ulas_preproc *pp, FILE *dst, FILE *src, char *buf,
+                     int n) {
+  int rc = 1;
+  if (fgets(buf, n, src) != NULL) {
+    ulas.line++;
+    if (ulas_preprocline(pp, dst, src, buf, strlen(buf)) == -1) {
+      rc = -1;
+    }
+  } else {
+    rc = 0;
+  }
+
+  return rc;
+}
+
 int ulas_preproc(FILE *dst, FILE *src) {
   char buf[ULAS_LINEMAX];
   memset(buf, 0, ULAS_LINEMAX);
@@ -300,15 +321,9 @@ int ulas_preproc(FILE *dst, FILE *src) {
 
   struct ulas_preproc pp = {NULL, 0, ulas_str(1), ulas_str(1)};
 
-  while (fgets(buf, ULAS_LINEMAX, src) != NULL) {
-    ulas.line++;
-    if (ulas_preprocline(&pp, dst, buf, strlen(buf)) == -1) {
-      rc = -1;
-      goto fail;
-    }
+  while ((rc = ulas_preprocnext(&pp, dst, src, buf, ULAS_LINEMAX)) > 0) {
   }
 
-fail:
   ulas_strfree(&pp.line);
   ulas_strfree(&pp.tok);