Removed most malloc calls
authorLukas Krickl <lukas@krickl.dev>
Mon, 6 Nov 2023 19:04:54 +0000 (20:04 +0100)
committerLukas Krickl <lukas@krickl.dev>
Mon, 6 Nov 2023 19:04:54 +0000 (20:04 +0100)
include/preproc.h
include/ulas.h
src/main.c
src/preproc.c
src/test.c
src/ulas.c

index 7d069a9bbdc021f1360f67af2969a11d9be9f228..24a04dd901b291e5760927fe7e9704c50d14f9af 100644 (file)
@@ -8,6 +8,16 @@
  * Preprocessor
  */
 
+enum ulas_ppdirs {
+  ULAS_PPDIR_NONE = 0,
+  ULAS_PPDIR_DEF,
+  ULAS_PPDIR_MACRO,
+  ULAS_PPDIR_ENDMACRO,
+  ULAS_PPDIR_IFDEF,
+  ULAS_PPDIR_IFNDEF,
+  ULAS_PPDIR_ENDIF
+};
+
 enum ulas_ppdefs {
   ULAS_PP_DEF,
   ULAS_PP_MACRO,
@@ -29,6 +39,10 @@ struct ulas_preproc {
 /**
  * Tokenize and apply the preprocessor
  */
-int ulas_preproc(FILE *dst, const char *dstname, FILE *src, const char *srcname);
+int ulas_preproc(FILE *dst, const char *dstname, FILE *src,
+                 const char *srcname);
+
+// expand preproc into dst line 
+char *ulas_preprocexpand(char *line, size_t linemax, const char *raw_line, size_t *n);
 
 #endif
index 10cf87a99ebd2843f67160df6c16cfb3af0a21a5..1f6eb37c918b22ef47538e20044bb9749e64c5bc 100644 (file)
@@ -8,7 +8,10 @@
 
 #define ULAS_PATHMAX 4096
 #define ULAS_LINEMAX 4096
-#define ULAS_TOKMAX 512
+#define ULAS_TOKMAX 64
+
+// max tokens per line...
+#define ULAS_TOKSMAX 64
 
 #define MAX(x, y) (((x) > (y)) ? (x) : (y))
 #define MIN(x, y) (((x) < (y)) ? (x) : (y))
@@ -171,9 +174,7 @@ bool ulas_tokrulespace(char current);
 // returns 0 when no more tokens can be read
 int ulas_tok(char *dst, const char *line, size_t n, ulas_tokrule rule);
 
-// tokenizes an entire line
-char **ulas_tokline(const char *line, size_t *n, ulas_tokrule rule);
-
-void ulas_toklinefree(char **data, size_t n);
+// smae as ulas_tok but modifies line
+int ulas_tokline(char *dst, const char **line, size_t n, ulas_tokrule rule);
 
 #endif
index 90bd1b22afd3f2d631623fc49eda82c45c457daf..dc94cf99adeb373f94401b7b7553655a9920ac8b 100644 (file)
@@ -43,7 +43,7 @@ void ulas_getopt(int argc, char **argv, struct ulas_config *cfg) {
       cfg->verbose = true;
       break;
     case 'o':
-      cfg->output_path = ulas_strndup(optarg, ULAS_PATHMAX);
+      cfg->output_path = strndup(optarg, ULAS_PATHMAX);
       break;
     case '?':
       break;
index 9d6d6193faa20ab7d59d0088f2ffeb2e177878d4..8dbde7aa881be1779281c475c048b4a186fdf64d 100644 (file)
@@ -1,15 +1,69 @@
 #include "preproc.h"
 #include "ulas.h"
+#include <ctype.h>
+#include <stdbool.h>
 #include <stdio.h>
 #include <assert.h>
 
+bool ulas_tokpreproc(char c) { return !isalnum(c); }
 
-int ulas_preprocline(struct ulas_preproc *pp, FILE *dst, const char *line,
+char *ulas_preprocexpand(char *line, size_t linemax, const char *raw_line,
+                         size_t *n) {
+  assert(*n <= linemax);
+  const char *praw_line = raw_line;
+
+  char tok[ULAS_TOKMAX];
+
+  // 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 (ulas_tokline(tok, &praw_line, ULAS_TOKMAX, ulas_tokpreproc)) {
+  }
+
+  // TODO: actually expand here...
+  strncpy(line, raw_line, *n);
+  *n = strlen(line);
+  return line;
+}
+
+int ulas_preprocline(struct ulas_preproc *pp, FILE *dst, const char *raw_line,
                      size_t n) {
+  if (n > ULAS_LINEMAX) {
+    ULASERR("%s: line exceeds %d (LINEMAX)\n", raw_line, ULAS_LINEMAX);
+    return -1;
+  }
+  assert(n <= ULAS_LINEMAX);
+  char line[ULAS_LINEMAX];
+  const char *pline = line;
+
+  ulas_preprocexpand(line, ULAS_LINEMAX, raw_line, &n);
+  const char *dirstrs[] = {"#define", "#macro",    "#ifdef", "#ifndef",
+                           "#endif",  "#endmacro", NULL};
+  enum ulas_ppdirs dirs[] = {ULAS_PPDIR_DEF,   ULAS_PPDIR_MACRO,
+                             ULAS_PPDIR_IFDEF, ULAS_PPDIR_IFNDEF,
+                             ULAS_PPDIR_ENDIF, ULAS_PPDIR_ENDMACRO};
+
+  enum ulas_ppdirs found_dir = ULAS_PPDIR_NONE;
+
+  char tok[ULAS_TOKMAX];
 
   // check if the first token is any of the valid preproc directives
+  if (ulas_tokline(tok, &pline, ULAS_TOKMAX, ulas_tokpreproc)) {
+    for (size_t i = 0; dirstrs[i]; i++) {
+      if (strncmp(dirstrs[i], tok, ULAS_TOKMAX) == 0) {
+        found_dir = dirs[i];
+        goto found;
+      }
+    }
+  }
+found:
 
-  assert(fwrite(line, 1, n, dst) == n);
+  if (found_dir) {
+    // TODO: process directive
+  } else {
+    assert(fwrite(line, 1, n, dst) == n);
+  }
 
   return 0;
 }
index aae3cad5a8263d5290f0b3306f32c55f1df260ea..32d804d1e08eca3bbede590bc81d3bad0b364a2b 100644 (file)
 
 #define assert_tokline(expected_n, line, rule, ...)                            \
   {                                                                            \
-    char *expect[] = __VA_ARGS__;                                              \
-    size_t n = 0;                                                              \
-    char **toks = ulas_tokline(line, &n, rule);                                \
-    assert(toks);                                                              \
-    assert(n == expected_n);                                                   \
-    for (size_t i = 0; i < n; i++) {                                           \
-      assert(strcmp(toks[i], expect[i]) == 0);                                 \
+    const char *expect[] = __VA_ARGS__;                                        \
+    size_t n = ULAS_TOKMAX;                                                    \
+    char buf[n];                                                               \
+    memset(buf, 0, n);                                                         \
+    int i = 0;                                                                 \
+    const char *pline = line;                                                  \
+    while (ulas_tokline(buf, &pline, n, rule)) {                               \
+      assert(strcmp(buf, expect[i]) == 0);                                     \
+      i++;                                                                     \
     }                                                                          \
-    ulas_toklinefree(toks, n);                                                 \
+    assert(i == expected_n);                                                   \
   }
 
 void test_tok(void) {
@@ -57,7 +59,8 @@ void test_tok(void) {
 void test_preproc(void) {
   TESTBEGIN("preproc");
 
-  assert_preproc("test", 0, "test");
+  // should just echo back line as is
+  assert_preproc("  test line", 0, "  test line");
 
   TESTEND("preproc");
 }
index aa5b0a52d7fa1cae5e1e5ca94172ebe9f8560eed..3a72d1abbc873c6db27451b23b8cf8b0452fd0f1 100644 (file)
@@ -28,13 +28,6 @@ struct ulas_config ulas_cfg_from_env(void) {
   return cfg;
 }
 
-char *ulas_strndup(const char *src, size_t n) {
-  size_t len = MIN(strlen(src), n);
-  char *dst = malloc(len);
-  strncpy(dst, src, len);
-  return dst;
-}
-
 int ulas_main(struct ulas_config cfg) {
   if (cfg.output_path) {
     ulasout = fopen(cfg.output_path, "we");
@@ -87,44 +80,11 @@ int ulas_tok(char *dst, const char *line, size_t n, ulas_tokrule rule) {
   return i;
 }
 
-char **ulas_tokline(const char *line, size_t *n, ulas_tokrule rule) {
-  char buf[ULAS_TOKMAX];
-
-  char **dst = NULL;
-  *n = 0;
-
-  int tokrc = 0;
-  int read = 0;
-  while ((tokrc = ulas_tok(buf, line + read, ULAS_TOKMAX, rule)) > 0) {
-    if (tokrc == -1) {
-      goto fail;
-    }
-    read += tokrc;
-
-    *n = *n + 1;
-    char **newdst = realloc(dst, sizeof(char *) * (*n));
-    if (!newdst) {
-      goto fail;
-    }
-    dst = newdst;
-
-    dst[(*n) - 1] = strndup(buf, ULAS_TOKMAX);
-  }
-
-  return dst;
-fail:
-  ulas_toklinefree(dst, *n);
-  *n = 0;
-  return NULL;
-}
-
-void ulas_toklinefree(char **data, size_t n) {
-  if (!data) {
-    return;
-  }
-  for (size_t i = 0; i < n; i++) {
-    free(data[i]);
+int ulas_tokline(char *dst, const char **line, size_t n, ulas_tokrule rule) {
+  int rc = ulas_tok(dst, *line, n, rule);
+  if (rc == -1) {
+    return -1;
   }
-
-  free(data);
+  *line += rc;
+  return rc;
 }