Added basic preprocessor to cli
authorLukas Krickl <lukas@krickl.dev>
Sun, 12 Nov 2023 17:16:49 +0000 (18:16 +0100)
committerLukas Krickl <lukas@krickl.dev>
Sun, 12 Nov 2023 17:16:49 +0000 (18:16 +0100)
include/ulas.h
src/main.c
src/ulas.c

index e5d5ac8a273af6afeabbd8763922d37b29f0fbbe..fc6738d8828af81a6e7ea48a515ef7e3cd539507 100644 (file)
@@ -78,6 +78,7 @@ struct ulas_config {
   char *output_path;
 
   int verbose;
+  int preproc_only;
 };
 
 /**
index cdc11b77649583a2017c1022a7650ea71f43b89b..48c959fbd454fea8cd00799e86128c704a0e1f3f 100644 (file)
@@ -9,7 +9,7 @@
 #define ULAS_VER "0.0.1"
 
 // args without value
-#define ULAS_OPTS "hvV"
+#define ULAS_OPTS "hvVp"
 
 // args with value
 #define ULAS_OPTS_ARG "o:"
@@ -22,6 +22,7 @@ void ulas_help(void) {
   ULAS_HELP("h", "display this help and exit");
   ULAS_HELP("V", "display version info and exit");
   ULAS_HELP("v", "verbose output");
+  ULAS_HELP("p", "Stop after preprocessor");
   ULAS_HELP("o=path", "Output file");
 }
 
@@ -45,6 +46,9 @@ void ulas_getopt(int argc, char **argv, struct ulas_config *cfg) {
     case 'o':
       cfg->output_path = strndup(optarg, ULAS_PATHMAX);
       break;
+    case 'p':
+      cfg->preproc_only = 1;
+      break;
     case '?':
       break;
     default:
index 24a34668ac0ddff97f5b264cba8b7197f0496604..6c92348ee1aade2e2d3b09a415105a6c5538632f 100644 (file)
@@ -35,6 +35,7 @@ struct ulas_config ulas_cfg_from_env(void) {
 }
 
 int ulas_main(struct ulas_config cfg) {
+  int rc = 0;
   if (cfg.output_path) {
     ulasout = fopen(cfg.output_path, "we");
     if (!ulasout) {
@@ -44,15 +45,50 @@ int ulas_main(struct ulas_config cfg) {
     }
   }
 
+  if (cfg.argc > 0) {
+    ulasin = fopen(cfg.argv[0], "re");
+    if (!ulasin) {
+      fprintf(ulaserr, "%s: %s\n", cfg.argv[0], strerror(errno));
+      return -1;
+    }
+  }
+
   ulas_init(cfg);
 
+  FILE *preprocdst = NULL;
+
+  if (cfg.preproc_only) {
+    preprocdst = ulasout;
+  } else {
+    preprocdst = tmpfile();
+  }
+
+  if (ulas_preproc(preprocdst, ulasin) == -1) {
+    rc = -1;
+    goto cleanup;
+  }
+
+  if (cfg.preproc_only) {
+    goto cleanup;
+  }
+
+  // TODO: rest of steps here
+
+cleanup:
+  if (!cfg.preproc_only) {
+    fclose(preprocdst);
+  }
+
   if (cfg.output_path) {
     fclose(ulasout);
     free(cfg.output_path);
-    return -1;
   }
 
-  return 0;
+  if (cfg.argc > 0) {
+    fclose(ulasin);
+  }
+
+  return rc;
 }
 
 int ulas_isname(const char *tok, size_t n) {
@@ -412,6 +448,7 @@ void ulas_trimend(char c, char *buf, size_t n) {
 int ulas_preprocline(struct ulas_preproc *pp, FILE *dst, FILE *src,
                      const char *raw_line, size_t n) {
   /**
+   * Footgun warning:
    * We do use raw pointers to the line here... which is fine
    * as long as it is never used after a recursive call to the preprocessor!
    * never use this pointer after such a recursive call!