Moved to indent as formatter
authorLukas Krickl <lukas@krickl.dev>
Fri, 17 Nov 2023 17:17:29 +0000 (18:17 +0100)
committerLukas Krickl <lukas@krickl.dev>
Fri, 17 Nov 2023 17:17:29 +0000 (18:17 +0100)
.clang-format [deleted file]
.clang-tidy [deleted file]
include/ulas.h
makefile
src/main.c
src/test.c
src/ulas.c

diff --git a/.clang-format b/.clang-format
deleted file mode 100644 (file)
index ac7dcd1..0000000
+++ /dev/null
@@ -1 +0,0 @@
-SortIncludes: false
diff --git a/.clang-tidy b/.clang-tidy
deleted file mode 100644 (file)
index 049204a..0000000
+++ /dev/null
@@ -1,31 +0,0 @@
----
-Checks: "*,
-        -abseil-*,
-        -llvm*,
-       -google*,
-       -modernize-use-trailing-return-type,
-        -readability-else-after-return,
-        -readability-static-accessed-through-instance,
-        -readability-avoid-const-params-in-decls,
-       -misc-unused-parameters,
-       -bugprone-easily-swappable-parameters,
-       -cert-err33-c,
-       -readability-identifier-length,
-       -altera-unroll-loops,
-  -cppcoreguidelines-avoid-non-const-global-variables,
-  -altera-struct-pack-align,
-  -cppcoreguidelines-avoid-magic-numbers,
-  -readability-magic-numbers,
-  -cert-err34-c,
-  -readability-function-cognitive-complexity,
-  -altera-id-dependent-backward-branch,
-  -clang-analyzer-security.insecureAPI.DeprecatedOrUnsafeBufferHandling,
-  -misc-no-recursion,
-  -concurrency-mt-unsafe,
-  -clang-analyzer-unix.Malloc,
-  -modernize-macro-to-enum
-"
-WarningsAsErrors: ''
-HeaderFilterRegex: ''
-FormatStyle:     None
-
index 0ef18029a8adc5523b3ef05ea5b531b1862fedcb..bd4d2181fe36f49139db97b427a924782d079c48 100644 (file)
@@ -312,7 +312,7 @@ void ulas_preprocfree(struct ulas_preproc *pp);
  * returns 0: no error
  *        -1: error
  */
-int ulas_preproc(FILE *dst, FILE *src);
+int ulas_preproc(FILE * dst, FILE * src);
 
 // reads the next line
 // returns 0 if no more data can be read
@@ -320,7 +320,7 @@ int ulas_preproc(FILE *dst, FILE *src);
 //         -1 on error
 // it also places the processed line into pp->line.buf
 // note that this is overwritten by every call!
-int ulas_preprocnext(struct ulas_preproc *pp, FILE *dst, FILE *src, char *buf,
+int ulas_preprocnext(struct ulas_preproc *pp, FILE * dst, FILE * src, char *buf,
                      int n);
 
 // process a line of preproc
@@ -331,7 +331,7 @@ int ulas_preprocnext(struct ulas_preproc *pp, FILE *dst, FILE *src, char *buf,
 //  not be used in the caller after recursvion finishes!
 //  or initialize a new preproc object if the old state is important!
 //  (preprocinit and preprocfree)
-int ulas_preprocline(struct ulas_preproc *pp, FILE *dst, FILE *src,
+int ulas_preprocline(struct ulas_preproc *pp, FILE * dst, FILE * src,
                      const char *raw_line, unsigned long n);
 
 // expand preproc into dst line
@@ -359,8 +359,8 @@ void ulas_tokbuffree(struct ulas_tokbuf *tb);
 // returns 0 if no more data can be read
 //         > 0 if data was read
 //         -1 on error
-int ulas_asmnext(FILE *dst, FILE *src, char *buf, int n);
-int ulas_asm(FILE *dst, FILE *src);
+int ulas_asmnext(FILE * dst, FILE * src, char *buf, int n);
+int ulas_asm(FILE * dst, FILE * src);
 
 // parses and executes a 32 bit signed int math expressions
 int ulas_intexpr(const char **line, unsigned long n, int *rc);
index e2755f7fce6f9f66f973ebb3ed76ce2196841db0..09adfd9d1349bc097e717ad0ba398c53a1c5bac7 100644 (file)
--- a/makefile
+++ b/makefile
@@ -55,17 +55,13 @@ install:
 tags:
        ctags --recurse=yes --exclude=.git --exclude=bin --exclude=obj --extras=*  --fields=*  --c-kinds=* --language-force=C 
 
-.PHONY:
-ccmds:
-       bear -- make SHELL="sh -x -e" --always-make
-
 .PHONY: format
 format:
-       clang-format -i ./src/*.c ./include/*.h
+       VERSION_CONTROL=none indent -kr -ci2 -cli2 -i2 -l80 -nut -brf src/*.c $(IDIR)/*.h
 
-.PHONY: lint 
+.PHONY: lint
 lint:
-       clang-tidy ./include/*.h ./src/*.c
+       splint src/*.c -I$(IDIR) -warnposix
 
 .PHONY: runtest
 runtest:
index bb38dee0bea1b8e388864552c48a0a55b410c867..72dbe510dca16e4c2006a9cbf9027fe44b1e488b 100644 (file)
@@ -26,36 +26,38 @@ void ulas_help(void) {
   ULAS_HELP("o=path", "Output file");
 }
 
-void ulas_version(void) { printf("%s version %s\n", ULAS_NAME, ULAS_VER); }
+void ulas_version(void) {
+  printf("%s version %s\n", ULAS_NAME, ULAS_VER);
+}
 
 void ulas_getopt(int argc, char **argv, struct ulas_config *cfg) {
   int c = 0;
   while ((c = getopt(argc, argv, ULAS_OPTS ULAS_OPTS_ARG)) != -1) {
     switch (c) {
-    case 'h':
-      ulas_help();
-      exit(0);
-      break;
-    case 'V':
-      ulas_version();
-      exit(0);
-      break;
-    case 'v':
-      cfg->verbose = 1;
-      break;
-    case 'o':
-      cfg->output_path = strndup(optarg, ULAS_PATHMAX);
-      break;
-    case 'p':
-      cfg->preproc_only = 1;
-      break;
-    case '?':
-      break;
-    default:
-      printf("%s: invalid option '%c'\nTry '%s -h' for more information.\n",
-             ULAS_NAME, c, ULAS_NAME);
-      exit(-1);
-      break;
+      case 'h':
+        ulas_help();
+        exit(0);
+        break;
+      case 'V':
+        ulas_version();
+        exit(0);
+        break;
+      case 'v':
+        cfg->verbose = 1;
+        break;
+      case 'o':
+        cfg->output_path = strndup(optarg, ULAS_PATHMAX);
+        break;
+      case 'p':
+        cfg->preproc_only = 1;
+        break;
+      case '?':
+        break;
+      default:
+        printf("%s: invalid option '%c'\nTry '%s -h' for more information.\n",
+               ULAS_NAME, c, ULAS_NAME);
+        exit(-1);
+        break;
     }
   }
 
index 5295c94190a1c5ee177b2b7fc47a8d300c7e600c..19ef051986f19253ac8743dde5d57fcf1a65dcf7 100644 (file)
 void test_tok(void) {
   TESTBEGIN("tok");
 
-  assert_tok("  test  tokens   with,   line / * + - , ; $1",
-             {"test", "tokens", "with", ",", "line", "/", "*", "+", "-", ",",
-              ";", "$1", NULL});
+  assert_tok("  test  tokens   with,   line / * + - , ; $1", {
+             "test", "tokens", "with", ",", "line", "/", "*", "+", "-", ",",
+             ";", "$1", NULL});
 
-  assert_tokuntil(" this is a, test for tok , until", ',',
-                  {"this is a", "test for tok ", "until", NULL});
+  assert_tokuntil(" this is a, test for tok , until", ',', {
+                  "this is a", "test for tok ", "until", NULL});
 
   TESTEND("tok");
 }
@@ -108,22 +108,20 @@ void test_preproc(void) {
                  "#define test 123\ntest\n#undefine test\ntest");
 
   // macro
-  assert_preproc(
-      "  line p1 1 label01,2 3\n  line p2 2\n  line p3 3 p1, p2, p3\n", 0,
-      "#macro test\n  line $1 1 label$$$$,$$ $$\n  line $2 2\n  line $3 3 "
-      "$0\n#endmacro\ntest p1, p2, p3");
+  assert_preproc
+    ("  line p1 1 label01,2 3\n  line p2 2\n  line p3 3 p1, p2, p3\n", 0,
+     "#macro test\n  line $1 1 label$$$$,$$ $$\n  line $2 2\n  line $3 3 "
+     "$0\n#endmacro\ntest p1, p2, p3");
   assert_preproc("test macro with no args\n", 0,
                  "#macro test\ntest macro with no args\n#endmacro\ntest");
   assert_preproc("", -1, "#macro test\n not terminated\n");
-  assert_preproc(
-      "nested macro t1\nafter\ncontent n1\n", 0,
-      "#macro test\nnested macro $1\n#macro "
-      "nested\ncontent $1\n#endmacro\nafter\nnested n1\n#endmacro\ntest t1");
+  assert_preproc("nested macro t1\nafter\ncontent n1\n", 0,
+                 "#macro test\nnested macro $1\n#macro "
+                 "nested\ncontent $1\n#endmacro\nafter\nnested n1\n#endmacro\ntest t1");
 
   // ifdef
-  assert_preproc(
-      "before\nifdeftest defined!\nafter", 0,
-      "before\n#define test\n#ifdef test\nifdeftest defined!\n#endif\nafter");
+  assert_preproc("before\nifdeftest defined!\nafter", 0,
+                 "before\n#define test\n#ifdef test\nifdeftest defined!\n#endif\nafter");
   assert_preproc("before\nafter", 0,
                  "before\n#ifdef test\nifdeftest defined!\n#endif\nafter");
   assert_preproc("ifdeftest defined!\n", -1,
@@ -132,9 +130,8 @@ void test_preproc(void) {
   // ifndef
   assert_preproc("before\nifndeftest defined!\nafter", 0,
                  "before\n#ifndef test\nifndeftest defined!\n#endif\nafter");
-  assert_preproc(
-      "before\nafter", 0,
-      "before\n#define test\n#ifndef test\nifndeftest defined!\n#endif\nafter");
+  assert_preproc("before\nafter", 0,
+                 "before\n#define test\n#ifndef test\nifndeftest defined!\n#endif\nafter");
   assert_preproc("ifndeftest defined!\n", -1,
                  "#ifndef test\nifndeftest defined!\n");
 
@@ -184,7 +181,7 @@ void test_totok(void) {
 
   // string token
   ASSERT_STR_TOTOK("test", 0, "\"test\"");
-  
+
   ASSERT_STR_TOTOK("test\n\"123\"", 0, "\"test\\n\\\"123\\\"\"");
 
   TESTEND("totok");
@@ -194,8 +191,8 @@ int main(int arc, char **argv) {
   ulas_init(ulas_cfg_from_env());
 
   /*if (!ulascfg.verbose) {
-    fclose(stderr);
-  }*/
+     fclose(stderr);
+     } */
 
   test_tok();
   test_strbuf();
index 5ddb9bd3adfecd38d18da87a241b409bc550b397..197915d89cf01449d35056eb0cf509a7a3e6827b 100644 (file)
@@ -41,7 +41,9 @@ void ulas_free(void) {
   ulas_tokbuffree(&ulas.toks);
 }
 
-int ulas_icntr(void) { return ulas.icntr++; }
+int ulas_icntr(void) {
+  return ulas.icntr++;
+}
 
 struct ulas_config ulas_cfg_from_env(void) {
   struct ulas_config cfg;
@@ -143,37 +145,37 @@ int ulas_tok(struct ulas_str *dst, const char **out_line, unsigned long n) {
     char c = line[i];
 
     switch (c) {
-    case ',':
-    case '+':
-    case '-':
-    case '*':
-    case '/':
-    case '\\':
-    case ULAS_TOK_COMMENT:
-      if (WELD_TOKISTERM) {
-        goto tokdone;
-      }
-      // single char tokens
-      dst->buf[write++] = line[i++];
-      goto tokdone;
-    case '$':
-      if (WELD_TOKISTERM) {
+      case ',':
+      case '+':
+      case '-':
+      case '*':
+      case '/':
+      case '\\':
+      case ULAS_TOK_COMMENT:
+        if (WELD_TOKISTERM) {
+          goto tokdone;
+        }
+        // single char tokens
+        dst->buf[write++] = line[i++];
         goto tokdone;
-      }
-      // special var for preprocessor
-      // make sure we have enough space in buffer
-      ulas_strensr(dst, write + 2);
-      // escape char tokens
-      dst->buf[write++] = line[i++];
-      dst->buf[write++] = line[i++];
-      goto tokdone;
-    default:
-      if (isspace(line[i])) {
+      case '$':
+        if (WELD_TOKISTERM) {
+          goto tokdone;
+        }
+        // special var for preprocessor
+        // make sure we have enough space in buffer
+        ulas_strensr(dst, write + 2);
+        // escape char tokens
+        dst->buf[write++] = line[i++];
+        dst->buf[write++] = line[i++];
         goto tokdone;
-      }
-      dst->buf[write] = line[i];
-      write++;
-      break;
+      default:
+        if (isspace(line[i])) {
+          goto tokdone;
+        }
+        dst->buf[write] = line[i];
+        write++;
+        break;
     }
     i++;
   }
@@ -218,28 +220,28 @@ int ulas_tokuntil(struct ulas_str *dst, char c, const char **out_line,
 
 int ulas_unescape(char c, int *rc) {
   switch (c) {
-  case '\'':
-  case '\\':
-  case '"':
-    return c;
-  case 'n':
-    return '\n';
-  case 'a':
-    return '\a';
-  case 'b':
-    return '\b';
-  case 'f':
-    return '\f';
-  case 'r':
-    return '\r';
-  case '?':
-    return '\?';
-  case '0':
-    return '\0';
-  default:
-    ULASERR("Unexpected esxcape sequence: \\%c\n", c);
-    *rc = -1;
-    break;
+    case '\'':
+    case '\\':
+    case '"':
+      return c;
+    case 'n':
+      return '\n';
+    case 'a':
+      return '\a';
+    case 'b':
+      return '\b';
+    case 'f':
+      return '\f';
+    case 'r':
+      return '\r';
+    case '?':
+      return '\?';
+    case '0':
+      return '\0';
+    default:
+      ULASERR("Unexpected esxcape sequence: \\%c\n", c);
+      *rc = -1;
+      break;
   }
 
   return '\0';
@@ -258,97 +260,97 @@ struct ulas_tok ulas_totok(char *buf, unsigned long n, int *rc) {
   buf++;
 
   switch (first) {
-  case '+':
-  case '-':
-  case '*':
-  case '/':
-  case '!':
-  case '~':
-  case '|':
-  case '&':
-  case '%':
-  case '(':
-  case ')':
-  case '[':
-  case ']':
-  case ',':
-  case ';':
-    // single char tokens
-    tok.type = first;
-    goto end;
-  case '"':
-    // string
-    tok.type = ULAS_TOKLITERAL;
-    tok.lit.type = ULAS_STR;
-
-    // FIXME: this likely mallocs a few extra bytes
-    // but honestly its probably fine
-    tok.lit.val.strv = malloc(n * sizeof(char) + 1);
-    memset(tok.lit.val.strv, 0, n);
-
-    long i = 0;
-    while (*buf && *buf != '\"') {
-      if (*buf == '\\') {
-        buf++;
-        tok.lit.val.strv[i] = ulas_unescape(*buf, rc);
-      } else {
-        tok.lit.val.strv[i] = *buf;
-      }
-      i++;
-      buf++;
-    }
-    tok.lit.val.strv[i] = '\0';
-
-    if (*buf != '\"') {
-      *rc = -1;
-      ULASERR("Unterminated string sequence\n");
+    case '+':
+    case '-':
+    case '*':
+    case '/':
+    case '!':
+    case '~':
+    case '|':
+    case '&':
+    case '%':
+    case '(':
+    case ')':
+    case '[':
+    case ']':
+    case ',':
+    case ';':
+      // single char tokens
+      tok.type = first;
       goto end;
-    }
-    buf++;
-    break;
-  default:
-    if (isdigit(first)) {
-      // integer
+    case '"':
+      // string
       tok.type = ULAS_TOKLITERAL;
-      tok.lit.type = ULAS_INT;
+      tok.lit.type = ULAS_STR;
 
-      // 0b prefix is not supported in strtol... so we implement it by hand
-      if (*buf == 'b') {
+      // FIXME: this likely mallocs a few extra bytes
+      // but honestly its probably fine
+      tok.lit.val.strv = malloc(n * sizeof(char) + 1);
+      memset(tok.lit.val.strv, 0, n);
+
+      long i = 0;
+      while (*buf && *buf != '\"') {
+        if (*buf == '\\') {
+          buf++;
+          tok.lit.val.strv[i] = ulas_unescape(*buf, rc);
+        } else {
+          tok.lit.val.strv[i] = *buf;
+        }
+        i++;
         buf++;
-        tok.lit.val.intv = (int)strtol(buf, &buf, 2);
-      } else {
-        tok.lit.val.intv = (int)strtol(buf - 1, &buf, 0);
       }
-    } else if (first == '\'') {
-      tok.type = ULAS_TOKLITERAL;
-      tok.lit.type = ULAS_INT;
-      if (*buf == '\\') {
-        buf++;
-        tok.lit.val.intv = ulas_unescape(*buf, rc);
-      } else {
-        tok.lit.val.intv = (int)*buf;
+      tok.lit.val.strv[i] = '\0';
+
+      if (*buf != '\"') {
+        *rc = -1;
+        ULASERR("Unterminated string sequence\n");
+        goto end;
       }
       buf++;
-      if (*buf != '\'') {
+      break;
+    default:
+      if (isdigit(first)) {
+        // integer
+        tok.type = ULAS_TOKLITERAL;
+        tok.lit.type = ULAS_INT;
+
+        // 0b prefix is not supported in strtol... so we implement it by hand
+        if (*buf == 'b') {
+          buf++;
+          tok.lit.val.intv = (int) strtol(buf, &buf, 2);
+        } else {
+          tok.lit.val.intv = (int) strtol(buf - 1, &buf, 0);
+        }
+      } else if (first == '\'') {
+        tok.type = ULAS_TOKLITERAL;
+        tok.lit.type = ULAS_INT;
+        if (*buf == '\\') {
+          buf++;
+          tok.lit.val.intv = ulas_unescape(*buf, rc);
+        } else {
+          tok.lit.val.intv = (int) *buf;
+        }
+        buf++;
+        if (*buf != '\'') {
+          *rc = -1;
+          ULASERR("Unterminated character sequence\n");
+          goto end;
+        }
+        buf++;
+        break;
+      } else if (ulas_isname(buf, n)) {
+        // literal. we can resolve it now
+        // because literals need to be able to be resolved
+        // for every line, unless they are a label!
+        // TODO: read and unescape striing between " and "
+        tok.type = ULAS_TOKSYMBOL;
+        tok.lit.type = ULAS_STR;
+      } else {
+        ULASERR("Unexpected token: %s\n", buf);
         *rc = -1;
-        ULASERR("Unterminated character sequence\n");
         goto end;
       }
-      buf++;
       break;
-    } else if (ulas_isname(buf, n)) {
-      // literal. we can resolve it now
-      // because literals need to be able to be resolved
-      // for every line, unless they are a label!
-      // TODO: read and unescape striing between " and "
-      tok.type = ULAS_TOKSYMBOL;
-      tok.lit.type = ULAS_STR;
-    } else {
-      ULASERR("Unexpected token: %s\n", buf);
-      *rc = -1;
-      goto end;
-    }
-    break;
   }
 
 end:
@@ -364,7 +366,7 @@ end:
 #undef WLED_TOKISTERM
 
 struct ulas_str ulas_str(unsigned long n) {
-  struct ulas_str str = {malloc(n), n};
+  struct ulas_str str = { malloc(n), n };
   return str;
 }
 
@@ -447,130 +449,134 @@ char *ulas_preprocexpand(struct ulas_preproc *pp, const char *raw_line,
     first_tok = 0;
 
     struct ulas_ppdef *def =
-        ulas_preprocgetdef(pp, pp->tok.buf, pp->tok.maxlen);
+      ulas_preprocgetdef(pp, pp->tok.buf, pp->tok.maxlen);
     if (def) {
       // if so... expand now and leave
       switch (def->type) {
-      case ULAS_PPDEF: {
-        unsigned long val_len = strlen(def->value);
-        int wsi = ulas_preproclws(pp, praw_line - read, *n);
-        if (val_len) {
-          // make sure to include leading white space
-          // adjust total length
-          *n -= strlen(pp->tok.buf);
-          *n += val_len;
-          ulas_strensr(&pp->line, (*n) + 1 + wsi);
-
-          // only remove the first white space char if the lenght of value
-          // is greater than 1, otherwise just leave it be...
-          if (val_len > 1) {
-            strncat(pp->line.buf, def->value + 1, val_len - 1);
-          } else {
-            strncat(pp->line.buf, def->value, val_len);
+        case ULAS_PPDEF:{
+            unsigned long val_len = strlen(def->value);
+            int wsi = ulas_preproclws(pp, praw_line - read, *n);
+            if (val_len) {
+              // make sure to include leading white space
+              // adjust total length
+              *n -= strlen(pp->tok.buf);
+              *n += val_len;
+              ulas_strensr(&pp->line, (*n) + 1 + wsi);
+
+              // only remove the first white space char if the lenght of value
+              // is greater than 1, otherwise just leave it be...
+              if (val_len > 1) {
+                strncat(pp->line.buf, def->value + 1, val_len - 1);
+              } else {
+                strncat(pp->line.buf, def->value, val_len);
+              }
+            }
+            break;
           }
-        }
-        break;
-      }
-      case ULAS_PPMACRO: {
-        // TODO: i am sure we can optimize the resize of line buffers here...
-
-        // get 9 comma separated values.
-        // $1-$9 will reference the respective arg
-        // $0 will reference the entire line after the macro name
-        // there can be more than 9 args, but anything after the 9th arg can
-        // only be accessed via $0
-        const char *line = praw_line;
-        unsigned long linelen = strlen(praw_line);
-        // clear all params from previous attempt
-        for (unsigned long i = 0; i < ULAS_MACROPARAMMAX; i++) {
-          pp->macroparam[i].buf[0] = '\0';
-        }
+        case ULAS_PPMACRO:{
+            // TODO: i am sure we can optimize the resize of line buffers here...
+
+            // get 9 comma separated values.
+            // $1-$9 will reference the respective arg
+            // $0 will reference the entire line after the macro name
+            // there can be more than 9 args, but anything after the 9th arg can
+            // only be accessed via $0
+            const char *line = praw_line;
+            unsigned long linelen = strlen(praw_line);
+            // clear all params from previous attempt
+            for (unsigned long i = 0; i < ULAS_MACROPARAMMAX; i++) {
+              pp->macroparam[i].buf[0] = '\0';
+            }
 
-        // loop until 9 args are found or the line ends
-        int paramc = 0;
-        while (paramc < ULAS_MACROPARAMMAX &&
-               ulas_tokuntil(&pp->macroparam[paramc], ',', &praw_line, *n) >
+            // loop until 9 args are found or the line ends
+            int paramc = 0;
+            while (paramc < ULAS_MACROPARAMMAX &&
+                   ulas_tokuntil(&pp->macroparam[paramc], ',', &praw_line, *n) >
                    0) {
-          // trim new lines from the end of macro params
-          ulas_trimend('\n', pp->macroparam[paramc].buf,
-                       strlen(pp->macroparam[paramc].buf));
-          paramc++;
-        }
-        ulas_strensr(&pp->line, strlen(def->value) + 2);
-
-        const char *macro_argname[ULAS_MACROPARAMMAX] = {
-            "$1", "$2", "$3", "$4", "$5", "$6", "$7", "$8", "$9"};
-
-        const char *val = def->value;
-        unsigned long vallen = strlen(def->value);
-        unsigned long valread = 0;
-
-        // the pointer to tocat will be the variable's value if any
-        // exists
-        const char *tocat = NULL;
-        unsigned long tocatlen = 0;
-
-        // now tokenize the macro's value and look for $0-$9
-        // and replace those instances
-        // eveyrthing else will just be copied as is
-        while ((valread = ulas_tok(&pp->macrobuf, &val, vallen)) > 0) {
-          tocat = NULL;
-          char numbuf[128];
-
-          // decide what tocat should be
-          for (unsigned long mi = 0; mi < ULAS_MACROPARAMMAX; mi++) {
-            const char *name = macro_argname[mi];
-            if (pp->macroparam[mi].buf[0] &&
-                strncmp((name), pp->macrobuf.buf, pp->macrobuf.maxlen) == 0) {
-              ulas_strensr(&pp->line, strnlen(pp->line.buf, pp->line.maxlen) +
-                                          strnlen(pp->macroparam[mi].buf,
-                                                  pp->macroparam[mi].maxlen) +
-                                          1);
-
-              tocat = pp->macroparam[mi].buf;
-              tocatlen = pp->macroparam[mi].maxlen;
-
-              break;
+              // trim new lines from the end of macro params
+              ulas_trimend('\n', pp->macroparam[paramc].buf,
+                           strlen(pp->macroparam[paramc].buf));
+              paramc++;
             }
-          }
-
-          if (linelen &&
-              strncmp("$0", pp->macrobuf.buf, pp->macrobuf.maxlen) == 0) {
-            ulas_strensr(&pp->line,
-                         strnlen(pp->line.buf, pp->line.maxlen) + linelen + 1);
-
-            if (linelen > 1) {
-              // this skips the separating token which is usually a space
-              // all further spaces are included though!
-              tocat = line + 1;
-              tocatlen = linelen - 1;
-            } else {
-              // do not do this if the line is literally empty!
-              tocat = line;
-              tocatlen = linelen;
+            ulas_strensr(&pp->line, strlen(def->value) + 2);
+
+            const char *macro_argname[ULAS_MACROPARAMMAX] = {
+              "$1", "$2", "$3", "$4", "$5", "$6", "$7", "$8", "$9"
+            };
+
+            const char *val = def->value;
+            unsigned long vallen = strlen(def->value);
+            unsigned long valread = 0;
+
+            // the pointer to tocat will be the variable's value if any
+            // exists
+            const char *tocat = NULL;
+            unsigned long tocatlen = 0;
+
+            // now tokenize the macro's value and look for $0-$9
+            // and replace those instances
+            // eveyrthing else will just be copied as is
+            while ((valread = ulas_tok(&pp->macrobuf, &val, vallen)) > 0) {
+              tocat = NULL;
+              char numbuf[128];
+
+              // decide what tocat should be
+              for (unsigned long mi = 0; mi < ULAS_MACROPARAMMAX; mi++) {
+                const char *name = macro_argname[mi];
+                if (pp->macroparam[mi].buf[0] &&
+                    strncmp((name), pp->macrobuf.buf,
+                            pp->macrobuf.maxlen) == 0) {
+                  ulas_strensr(&pp->line,
+                               strnlen(pp->line.buf,
+                                       pp->line.maxlen) +
+                               strnlen(pp->macroparam[mi].buf,
+                                       pp->macroparam[mi].maxlen) + 1);
+
+                  tocat = pp->macroparam[mi].buf;
+                  tocatlen = pp->macroparam[mi].maxlen;
+
+                  break;
+                }
+              }
+
+              if (linelen &&
+                  strncmp("$0", pp->macrobuf.buf, pp->macrobuf.maxlen) == 0) {
+                ulas_strensr(&pp->line,
+                             strnlen(pp->line.buf,
+                                     pp->line.maxlen) + linelen + 1);
+
+                if (linelen > 1) {
+                  // this skips the separating token which is usually a space
+                  // all further spaces are included though!
+                  tocat = line + 1;
+                  tocatlen = linelen - 1;
+                } else {
+                  // do not do this if the line is literally empty!
+                  tocat = line;
+                  tocatlen = linelen;
+                }
+              } else if (linelen && strncmp("$$", pp->macrobuf.buf,
+                                            pp->macrobuf.maxlen) == 0) {
+                sprintf(numbuf, "%x", ulas_icntr());
+                ulas_strensr(&pp->line,
+                             strnlen(pp->line.buf, pp->line.maxlen) + 128 + 1);
+                tocat = numbuf;
+                tocatlen = 128;
+              }
+
+              if (!tocat) {
+                ulas_strensr(&pp->line, valread + 1);
+                strncat(pp->line.buf, val - valread, valread);
+              } else {
+                // make sure to include leading white space
+                int wsi = ulas_preproclws(pp, val - valread, vallen);
+                ulas_strensr(&pp->line, strnlen(pp->line.buf, pp->line.maxlen) +
+                             tocatlen + wsi + 1);
+                strncat(pp->line.buf, tocat, tocatlen);
+              }
             }
-          } else if (linelen && strncmp("$$", pp->macrobuf.buf,
-                                        pp->macrobuf.maxlen) == 0) {
-            sprintf(numbuf, "%x", ulas_icntr());
-            ulas_strensr(&pp->line,
-                         strnlen(pp->line.buf, pp->line.maxlen) + 128 + 1);
-            tocat = numbuf;
-            tocatlen = 128;
-          }
-
-          if (!tocat) {
-            ulas_strensr(&pp->line, valread + 1);
-            strncat(pp->line.buf, val - valread, valread);
-          } else {
-            // make sure to include leading white space
-            int wsi = ulas_preproclws(pp, val - valread, vallen);
-            ulas_strensr(&pp->line, strnlen(pp->line.buf, pp->line.maxlen) +
-                                        tocatlen + wsi + 1);
-            strncat(pp->line.buf, tocat, tocatlen);
+            goto end;
           }
-        }
-        goto end;
-      }
       }
 
     } else {
@@ -608,14 +614,16 @@ int ulas_preprocline(struct ulas_preproc *pp, FILE *dst, FILE *src,
   char *line = ulas_preprocexpand(pp, raw_line, &n);
   const char *pline = line;
 
-  const char *dirstrs[] = {ULAS_PPSTR_DEF,   ULAS_PPSTR_MACRO,
-                           ULAS_PPSTR_IFDEF, ULAS_PPSTR_IFNDEF,
-                           ULAS_PPSTR_ENDIF, ULAS_PPSTR_ENDMACRO,
-                           ULAS_PPSTR_UNDEF, NULL};
-  enum ulas_ppdirs dirs[] = {ULAS_PPDIR_DEF,   ULAS_PPDIR_MACRO,
-                             ULAS_PPDIR_IFDEF, ULAS_PPDIR_IFNDEF,
-                             ULAS_PPDIR_ENDIF, ULAS_PPDIR_ENDMACRO,
-                             ULAS_PPDIR_UNDEF};
+  const char *dirstrs[] = { ULAS_PPSTR_DEF, ULAS_PPSTR_MACRO,
+    ULAS_PPSTR_IFDEF, ULAS_PPSTR_IFNDEF,
+    ULAS_PPSTR_ENDIF, ULAS_PPSTR_ENDMACRO,
+    ULAS_PPSTR_UNDEF, NULL
+  };
+  enum ulas_ppdirs dirs[] = { ULAS_PPDIR_DEF, ULAS_PPDIR_MACRO,
+    ULAS_PPDIR_IFDEF, ULAS_PPDIR_IFNDEF,
+    ULAS_PPDIR_ENDIF, ULAS_PPDIR_ENDMACRO,
+    ULAS_PPDIR_UNDEF
+  };
 
   enum ulas_ppdirs found_dir = ULAS_PPDIR_NONE;
 
@@ -640,134 +648,135 @@ found:
   if (found_dir != ULAS_PPDIR_NONE) {
     ulas_trimend('\n', line, strlen(line));
     switch (found_dir) {
-    case ULAS_PPDIR_DEF: {
-      // next token is a name
-      // and then the entire remainder of the line is a value
-      if (ulas_tok(&pp->tok, &pline, n) == 0) {
-        ULASERR("Expected name for #define\n");
-        return -1;
-      }
-
-      if (!ulas_isname(pp->tok.buf, strlen(pp->tok.buf))) {
-        ULASERR("'%s' is not a valid #define name!\n", pp->tok.buf);
-        return -1;
-      }
+      case ULAS_PPDIR_DEF:{
+          // next token is a name
+          // and then the entire remainder of the line is a value
+          if (ulas_tok(&pp->tok, &pline, n) == 0) {
+            ULASERR("Expected name for #define\n");
+            return -1;
+          }
 
-      struct ulas_ppdef def = {ULAS_PPDEF, strdup(pp->tok.buf), strdup(pline),
-                               0};
-      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!
-      goto dirdone;
-    }
-    case ULAS_PPDIR_MACRO: {
-      // 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 #macro\n");
-        return -1;
-      }
+          if (!ulas_isname(pp->tok.buf, strlen(pp->tok.buf))) {
+            ULASERR("'%s' is not a valid #define name!\n", pp->tok.buf);
+            return -1;
+          }
 
-      if (!ulas_isname(pp->tok.buf, strlen(pp->tok.buf))) {
-        ULASERR("'%s' is not a valid #macro name!\n", pp->tok.buf);
-        return -1;
-      }
-      char *name = strdup(pp->tok.buf);
-
-      struct ulas_str val = ulas_str(32);
-      memset(val.buf, 0, 32);
-
-      char buf[ULAS_LINEMAX];
-      memset(buf, 0, ULAS_LINEMAX);
-
-      // consume lines until #endmacro is read
-      // if reaching end of input without #endmacro we have an unterminated
-      // macro. pass NULL as dst to consume lines that are being read instead of
-      // echoing them back
-      int rc = 0;
-      while ((rc = ulas_preprocnext(pp, NULL, src, buf, ULAS_LINEMAX)) > 0) {
-        if (rc == ULAS_PPDIR_ENDMACRO) {
-          // we need to clear the line buffer to now echo back
-          // the #endmacro directive
-          pp->line.buf[0] = '\0';
-          break;
+          struct ulas_ppdef def =
+            { ULAS_PPDEF, strdup(pp->tok.buf), strdup(pline),
+            0
+          };
+          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!
+          goto dirdone;
         }
+      case ULAS_PPDIR_MACRO:{
+          // 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 #macro\n");
+            return -1;
+          }
 
-        unsigned long len = strnlen(pp->line.buf, pp->line.maxlen);
-        ulas_strensr(&val, strnlen(val.buf, val.maxlen) + len + 1);
-        strncat(val.buf, pp->line.buf, val.maxlen);
-      }
+          if (!ulas_isname(pp->tok.buf, strlen(pp->tok.buf))) {
+            ULASERR("'%s' is not a valid #macro name!\n", pp->tok.buf);
+            return -1;
+          }
+          char *name = strdup(pp->tok.buf);
+
+          struct ulas_str val = ulas_str(32);
+          memset(val.buf, 0, 32);
+
+          char buf[ULAS_LINEMAX];
+          memset(buf, 0, ULAS_LINEMAX);
+
+          // consume lines until #endmacro is read
+          // if reaching end of input without #endmacro we have an unterminated
+          // macro. pass NULL as dst to consume lines that are being read instead of
+          // echoing them back
+          int rc = 0;
+          while ((rc = ulas_preprocnext(pp, NULL, src, buf, ULAS_LINEMAX)) > 0) {
+            if (rc == ULAS_PPDIR_ENDMACRO) {
+              // we need to clear the line buffer to now echo back
+              // the #endmacro directive
+              pp->line.buf[0] = '\0';
+              break;
+            }
 
-      if (rc != ULAS_PPDIR_ENDMACRO) {
-        ULASERR("Unterminated macro directive\n");
-        ulas_strfree(&val);
-        free(name);
-        return -1;
-      }
+            unsigned long len = strnlen(pp->line.buf, pp->line.maxlen);
+            ulas_strensr(&val, strnlen(val.buf, val.maxlen) + len + 1);
+            strncat(val.buf, pp->line.buf, val.maxlen);
+          }
 
-      // we leak the str's buffer into the def now
-      // this is ok because we call free for it later anyway
-      struct ulas_ppdef def = {ULAS_PPMACRO, name, val.buf, 0};
-      ulas_preprocdef(pp, def);
+          if (rc != ULAS_PPDIR_ENDMACRO) {
+            ULASERR("Unterminated macro directive\n");
+            ulas_strfree(&val);
+            free(name);
+            return -1;
+          }
+          // we leak the str's buffer into the def now
+          // this is ok because we call free for it later anyway
+          struct ulas_ppdef def = { ULAS_PPMACRO, name, val.buf, 0 };
+          ulas_preprocdef(pp, def);
 
-      goto dirdone;
-    }
-    case ULAS_PPDIR_ENDIF:
-    case ULAS_PPDIR_ENDMACRO:
-      break;
-    case ULAS_PPDIR_IFDEF:
-    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;
-      }
-      struct ulas_ppdef *def =
-          ulas_preprocgetdef(pp, pp->tok.buf, pp->tok.maxlen);
+          goto dirdone;
+        }
+      case ULAS_PPDIR_ENDIF:
+      case ULAS_PPDIR_ENDMACRO:
+        break;
+      case ULAS_PPDIR_IFDEF:
+      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;
+          }
+          struct ulas_ppdef *def =
+            ulas_preprocgetdef(pp, pp->tok.buf, pp->tok.maxlen);
 
-      char buf[ULAS_LINEMAX];
-      memset(buf, 0, ULAS_LINEMAX);
+          char buf[ULAS_LINEMAX];
+          memset(buf, 0, ULAS_LINEMAX);
 
-      FILE *defdst = NULL;
-      if ((def && found_dir == ULAS_PPDIR_IFDEF) ||
-          (!def && found_dir == ULAS_PPDIR_IFNDEF)) {
-        defdst = dst;
-      }
+          FILE *defdst = NULL;
+          if ((def && found_dir == ULAS_PPDIR_IFDEF) ||
+              (!def && found_dir == ULAS_PPDIR_IFNDEF)) {
+            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 #endif directive
+              pp->line.buf[0] = '\0';
+              break;
+            }
+          }
 
-      // 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 #endif directive
-          pp->line.buf[0] = '\0';
-          break;
+          if (rc != ULAS_PPDIR_ENDIF) {
+            ULASERR("Unterminated if(n)def directive\n");
+            return -1;
+          }
+          goto dirdone;
         }
-      }
-
-      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");
-        return -1;
-      }
-      struct ulas_ppdef *def = NULL;
-      while ((def = ulas_preprocgetdef(pp, pp->tok.buf, pp->tok.maxlen))) {
-        def->undef = 1;
-      }
+      case ULAS_PPDIR_UNDEF:{
+          if (ulas_tok(&pp->tok, &pline, n) == 0) {
+            ULASERR("Expected name for #undef\n");
+            return -1;
+          }
+          struct ulas_ppdef *def = NULL;
+          while ((def = ulas_preprocgetdef(pp, pp->tok.buf, pp->tok.maxlen))) {
+            def->undef = 1;
+          }
 
-      break;
-    }
-    default:
-      // this should not happen!
-      break;
+          break;
+        }
+      default:
+        // this should not happen!
+        break;
     }
 
   dirdone:
@@ -796,7 +805,7 @@ int ulas_preprocnext(struct ulas_preproc *pp, FILE *dst, FILE *src, char *buf,
 }
 
 struct ulas_preproc ulas_preprocinit(void) {
-  struct ulas_preproc pp = {NULL, 0, ulas_str(1), ulas_str(1)};
+  struct ulas_preproc pp = { NULL, 0, ulas_str(1), ulas_str(1) };
   for (unsigned long i = 0; i < ULAS_MACROPARAMMAX; i++) {
     pp.macroparam[i] = ulas_str(8);
   }
@@ -842,7 +851,6 @@ int ulas_preproc(FILE *dst, FILE *src) {
     if (ulascfg.preproc_only) {
       continue;
     }
-
     // after each preproc line we assembly it by reading it back
     // from the temporary buffer
     fseek(asmsrc, prevseek, SEEK_SET);
@@ -908,9 +916,13 @@ void ulas_tokbufpush(struct ulas_tokbuf *tb, struct ulas_tok tok) {
   tb->len++;
 }
 
-void ulas_tokbufclear(struct ulas_tokbuf *tb) { tb->len = 0; }
+void ulas_tokbufclear(struct ulas_tokbuf *tb) {
+  tb->len = 0;
+}
 
-void ulas_tokbuffree(struct ulas_tokbuf *tb) { free(tb->buf); }
+void ulas_tokbuffree(struct ulas_tokbuf *tb) {
+  free(tb->buf);
+}
 
 /**
  * Assembly step
@@ -925,7 +937,6 @@ int ulas_intexpr(const char **line, unsigned long n, int *rc) {
       *rc = -1;
       goto fail;
     }
-
     // interpret the token
   }
 
@@ -944,11 +955,13 @@ int ulas_asmline(FILE *dst, FILE *src, const char *line, unsigned long n) {
 
   if (ulas.tok.buf[0] == ULAS_TOK_ASMDIR_BEGIN) {
     const char *dirstrs[] = {
-        ULAS_ASMSTR_ORG,  ULAS_ASMSTR_SET, ULAS_ASMSTR_BYTE,   ULAS_ASMSTR_STR,
-        ULAS_ASMSTR_FILL, ULAS_ASMSTR_PAD, ULAS_ASMSTR_INCBIN, NULL};
+      ULAS_ASMSTR_ORG, ULAS_ASMSTR_SET, ULAS_ASMSTR_BYTE, ULAS_ASMSTR_STR,
+      ULAS_ASMSTR_FILL, ULAS_ASMSTR_PAD, ULAS_ASMSTR_INCBIN, NULL
+    };
     enum ulas_asmdir dirs[] = {
-        ULAS_ASMDIR_ORG,  ULAS_ASMDIR_SET, ULAS_ASMDIR_BYTE,  ULAS_ASMDIR_STR,
-        ULAS_ASMDIR_FILL, ULAS_ASMDIR_PAD, ULAS_ASMDIR_INCBIN};
+      ULAS_ASMDIR_ORG, ULAS_ASMDIR_SET, ULAS_ASMDIR_BYTE, ULAS_ASMDIR_STR,
+      ULAS_ASMDIR_FILL, ULAS_ASMDIR_PAD, ULAS_ASMDIR_INCBIN
+    };
 
     enum ulas_asmdir dir = ULAS_ASMDIR_NONE;
 
@@ -966,18 +979,18 @@ int ulas_asmline(FILE *dst, FILE *src, const char *line, unsigned long n) {
     }
 
     switch (dir) {
-    case ULAS_ASMDIR_NONE:
-    case ULAS_ASMDIR_ORG:
-      ulas.address = ulas_intexpr(&line, strnlen(start, n), &rc);
-      break;
-    case ULAS_ASMDIR_SET:
-    case ULAS_ASMDIR_BYTE:
-    case ULAS_ASMDIR_STR:
-    case ULAS_ASMDIR_FILL:
-    case ULAS_ASMDIR_PAD:
-    case ULAS_ASMDIR_INCBIN:
-      ULASPANIC("asmdir not implemented\n");
-      break;
+      case ULAS_ASMDIR_NONE:
+      case ULAS_ASMDIR_ORG:
+        ulas.address = ulas_intexpr(&line, strnlen(start, n), &rc);
+        break;
+      case ULAS_ASMDIR_SET:
+      case ULAS_ASMDIR_BYTE:
+      case ULAS_ASMDIR_STR:
+      case ULAS_ASMDIR_FILL:
+      case ULAS_ASMDIR_PAD:
+      case ULAS_ASMDIR_INCBIN:
+        ULASPANIC("asmdir not implemented\n");
+        break;
     }
 
   } else {