From a3f6adcbfc1ac48756b8b09f401a7096b4ebd6ea Mon Sep 17 00:00:00 2001
From: Wesley Moore <wes@wezm.net>
Date: Sun, 9 Mar 2025 21:01:58 +1000
Subject: [PATCH] WIP2

---
 Makefile          |  2 +-
 calc.h            |  9 ++++++---
 tests/charness.c  | 34 +++++++++++++++++++++++-----------
 tests/harness.s   | 14 ++++++++++++--
 tests/test_fmt.sh |  4 ++--
 5 files changed, 44 insertions(+), 19 deletions(-)

diff --git a/Makefile b/Makefile
index 887cb7b..62c3862 100644
--- a/Makefile
+++ b/Makefile
@@ -57,7 +57,7 @@ tests/btohex.elf: mem.o hex.o debug.o tests/btohex.o
 tests/tohex.elf: hex.o tests/tohex.o
 	$(LD) -m elf32lriscv -T link.ld $^ -o $@
 
-tests/harness.elf: tests/harness.o tests/charness.o
+tests/harness.elf: math.o fmt.o tests/harness.o tests/charness.o
 	$(LD) -m elf32lriscv -T link.ld $^ -o $@
 
 %.o : %.s
diff --git a/calc.h b/calc.h
index eb78553..cef5d77 100644
--- a/calc.h
+++ b/calc.h
@@ -1,9 +1,12 @@
 #ifndef CALC_H
 #define CALC_H
 
-typedef unsigned char bool;
-#define true 1;
-#define false 0;
+#include <stddef.h>
+#include <stdbool.h>
+
+// typedef unsigned char bool;
+// #define true 1;
+// #define false 0;
 
 typedef unsigned char u8;
 typedef unsigned int uint;
diff --git a/tests/charness.c b/tests/charness.c
index 6dc0fea..48e4059 100644
--- a/tests/charness.c
+++ b/tests/charness.c
@@ -2,11 +2,12 @@
 
 #define BUF_SIZE 80
 
-#define make_str(s) { sizeof(s), (const u8 *)s }
+#define make_str(s) { sizeof(s) - 1, (const u8 *)s }
 #define make_test(name) { make_str(#name), name }
 
 extern bool streq(const u8 *, uint, const u8 *, uint);
 extern int read(u8 *, uint); // read from stdin
+extern void exit(int);
 
 // Tests
 extern void count_digits(void);
@@ -15,16 +16,20 @@ extern void fmt_decimal(void);
 typedef struct {
   u8 len;
   const u8 *data;
-} str;
+} Str;
 
-typedef void (*testfn)(void);
+typedef void (*Testfn)(void);
 
 typedef struct {
-  str name;
-  testfn fn;
-} test;
+  Str name;
+  Testfn fn;
+} Test;
 
-static str tests[2] = {make_test(count_digits), make_test(fmt_decimal)};
+static Test tests[3] = {
+  make_test(count_digits),
+  make_test(fmt_decimal),
+  { { 0, NULL }, NULL }
+};
 
 void _start(void) {
         u8 buf[BUF_SIZE];
@@ -33,11 +38,18 @@ void _start(void) {
                 for(;;); // TODO: add abort function
         }
         uint nread = (uint)nread0;
+        if (nread > 0 && buf[nread - 1] == '\n') {
+          nread--; // ignore trailing newline
+        }
 
-        for(uint i = 0; i < sizeof(tests); i++) {
-                const str s = tests[i];
-                if (streq(buf, nread, s.data, s.len)) {
-                    
+        Test t;
+        uint i;
+        for(i = 0, t = tests[i]; t.name.data != NULL; i++, t = tests[i]) {
+                if (streq(buf, nread, t.name.data, t.name.len)) {
+                    t.fn();
+                    exit(0);
                 }
         }
+
+        exit(2);
 }
diff --git a/tests/harness.s b/tests/harness.s
index 2c2f84e..f89a207 100644
--- a/tests/harness.s
+++ b/tests/harness.s
@@ -5,6 +5,7 @@
 # Provide program starting address to linker
 .global read
 .global streq
+.global exit
 
 # .extern fmt_decimal
 
@@ -48,7 +49,6 @@ _start2:
 #       a1: number of bytes to read
 #    return:
 #       a0: count of bytes read, or error if < 0
-
 read:
     li t0, SYSREAD      # "read" syscall
     mv a2, a1           # bytes to read
@@ -58,6 +58,16 @@ read:
     ret
 
 
+# Exit with status
+#    arguments:
+#       a0: exit status
+#    return:
+#       none
+exit:
+    li t0, SYSEXIT      # "exit" syscall
+    ecall               # invoke syscall to terminate the program
+
+
 # Determine if two strings are equal
 #    arguments:
 #       a0: address of first string
@@ -67,7 +77,7 @@ read:
 #    return:
 #       a0: 1 if equal, 0 otherwise
 streq:
-    bne a1, a2, 2f      # If the lengths are not the same then the strings are different
+    bne a1, a3, 2f      # If the lengths are not the same then the strings are different
 1:
     beqz a1, 3f         # If the remaining length is zero, string are the same
     lbu a4, 0(a0)       # load byte from string 1
diff --git a/tests/test_fmt.sh b/tests/test_fmt.sh
index c090da2..2ed82c9 100644
--- a/tests/test_fmt.sh
+++ b/tests/test_fmt.sh
@@ -1,7 +1,7 @@
 #!/bin/sh
 
 test_count_digits() {
-  result=$("${QEMU}" -B 0x80000000 -s 2k tests/fmt_count_digits.elf)
+  result=$(echo "count_digits" | "${QEMU}" -B 0x80000000 -s 2k tests/harness.elf)
   expected=$(cat << END
 00000001
 00000001
@@ -21,7 +21,7 @@ END
 }
 
 test_fmt_decimal() {
-  result=$("${QEMU}" -B 0x80000000 -s 2k tests/fmt_decimal.elf)
+  result=$(echo "fmt_decimal" | "${QEMU}" -B 0x80000000 -s 2k tests/harness.elf)
   expected=$(cat << END
 0
 1