summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorpeter <peter@pmikkelsen.com>2026-08-22 19:51:13 +0000
committerpeter <peter@pmikkelsen.com>2026-08-22 19:51:13 +0000
commit956cfb9ac26f44d05ffc446f30f84174865685a4 (patch)
treebdfb6203b99809575ec18b3564d73ba75aed290a
parentdc9b7f961d1c5f39a07085c9dbad8d94bbacde70 (diff)
Start work on a way to test #! scripts
FossilOrigin-Name: 0637c5749d38b540e2a174b5248bf704098fd4ead61aa1d6e84d4495430c7149
-rw-r--r--CMakeLists.txt25
-rw-r--r--src/bin/main.c97
-rw-r--r--src/include/aplwc.h1
-rw-r--r--src/lib/main.c11
-rwxr-xr-xtests/scripts/1.aplwc3
-rwxr-xr-xtests/scripts/2.aplwc9
6 files changed, 134 insertions, 12 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 089ab7c..f59b019 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -88,33 +88,46 @@ foreach(source ${TEST_SOURCES})
endif()
endforeach()
-add_test(NAME "aplwc-repl-tiny" COMMAND "aplwc-repl")
+file(GLOB TEST_SCRIPTS CONFIGURE_DEPENDS "tests/scripts/*.aplwc")
+foreach(script ${TEST_SCRIPTS})
+ add_test(NAME "${script}" COMMAND "${script}")
+ set_tests_properties("${script}" PROPERTIES
+ ENVIRONMENT "APLWC_MEM=64000;PATH=$<TARGET_FILE_DIR:aplwc-repl>"
+ )
+
+ add_test(NAME "aplwc-repl ${script}" COMMAND "aplwc-repl" "${script}")
+ set_tests_properties("aplwc-repl ${script}" PROPERTIES
+ ENVIRONMENT "APLWC_MEM=64000;PATH=$<TARGET_FILE_DIR:aplwc-repl>"
+ )
+endforeach()
+
+add_test(NAME "aplwc-repl-tiny" COMMAND "aplwc-repl" "-x")
set_tests_properties("aplwc-repl-tiny" PROPERTIES
ENVIRONMENT "APLWC_MEM=16"
WILL_FAIL TRUE
)
-add_test(NAME "aplwc-repl-large" COMMAND "aplwc-repl")
+add_test(NAME "aplwc-repl-large" COMMAND "aplwc-repl" "-x")
set_tests_properties("aplwc-repl-large" PROPERTIES
ENVIRONMENT "APLWC_MEM=64000"
)
-add_test(NAME "aplwc-repl-emptyvar" COMMAND "aplwc-repl")
+add_test(NAME "aplwc-repl-emptyvar" COMMAND "aplwc-repl" "-x")
set_tests_properties("aplwc-repl-emptyvar" PROPERTIES
ENVIRONMENT "APLWC_MEM="
)
-add_test(NAME "aplwc-repl-badvar" COMMAND "aplwc-repl")
+add_test(NAME "aplwc-repl-badvar" COMMAND "aplwc-repl" "-x")
set_tests_properties("aplwc-repl-badvar" PROPERTIES
ENVIRONMENT "APLWC_MEM=1M"
)
-add_test(NAME "aplwc-repl" COMMAND "aplwc-repl")
+add_test(NAME "aplwc-repl" COMMAND "aplwc-repl" "-x")
set(REQUIRED_MALLOCS 1)
foreach(i RANGE 0 ${REQUIRED_MALLOCS})
set(name "aplwc-repl-${i}-${REQUIRED_MALLOCS}")
- add_test(NAME "${name}" COMMAND "aplwc-repl")
+ add_test(NAME "${name}" COMMAND "aplwc-repl" "-x")
set_tests_properties("${name}" PROPERTIES
ENVIRONMENT "APLWC_MALLOC_FAIL_AFTER=${i}"
)
diff --git a/src/bin/main.c b/src/bin/main.c
index 80b2ee0..93d28c0 100644
--- a/src/bin/main.c
+++ b/src/bin/main.c
@@ -1,13 +1,53 @@
+#define _POSIX_C_SOURCE 200809L
#include <stdio.h>
+#include <unistd.h>
+#include <errno.h>
#include "aplwc_repl.h"
int
-main(void)
+main(int argc, char *argv[])
{
struct aplwc *aplwc;
+ struct aplwc_line *line;
+ struct aplwc_value *value;
uint8_t *data;
- int ret;
- size_t memsize;
+ char *input;
+ int ret, exit_code, line_number;
+ size_t memsize, input_size;
+ int opt, xflag, input_file;
+ FILE *f;
+
+ input = NULL;
+ line = NULL;
+ value = NULL;
+ xflag = 0;
+ input_file = 0;
+ exit_code = 0;
+ line_number = 0;
+
+ while((opt = getopt(argc, argv, "x")) != -1){
+ switch(opt){
+ case 'x':
+ xflag = 1;
+ break;
+ default:
+usage:
+ fprintf(stderr, "Usage: %s [-x] [file]\n", argv[0]);
+ return 1;
+ }
+ }
+
+ if((optind+1) == argc){
+ input_file = 1;
+ f = fopen(argv[optind], "r");
+ if(f == NULL){
+ fprintf(stderr, "Could not open file: %s: %s\n", argv[optind], strerror(errno));
+ return 1;
+ }
+ }else if(optind == argc)
+ f = stdin;
+ else
+ goto usage;
memsize = getenv_ulong("APLWC_MEM", APLWC_MIN_MEM);
@@ -24,9 +64,54 @@ main(void)
return 1;
}
- aplwc_destroy(aplwc);
+ if(xflag)
+ goto exit;
- free(data);
+ for(;;){
+ if(input)
+ free(input);
+ if(line)
+ aplwc_free_line(line);
+ if(value)
+ aplwc_free_value(value);
- return 0;
+ input = NULL;
+ if(getline(&input, &input_size, f) < 0){
+ free(input);
+ break;
+ }else{
+ line_number++;
+ if(input_file && (line_number == 1)){
+ if((strlen(input) > 2) && (input[0] == '#') && (input[1] == '!'))
+ continue;
+ }
+
+ line = aplwc_read(aplwc, input);
+ if(line == NULL){
+line_error:
+ fprintf(stderr, "error on line %d: %s: %s\n", line_number, aplwc_errstr(aplwc), input);
+ if(input_file){
+ exit_code = 1;
+ goto exit;
+ }
+ continue;
+ }
+ value = aplwc_eval(line);
+ if(value == NULL)
+ goto line_error;
+ fprintf(stdout, "%s\n", aplwc_value_string(value));
+ }
+ }
+
+exit:
+ if(input)
+ free(input);
+ if(line)
+ aplwc_free_line(line);
+ if(value)
+ aplwc_free_value(value);
+
+ aplwc_destroy(aplwc);
+ free(data);
+ return exit_code;
}
diff --git a/src/include/aplwc.h b/src/include/aplwc.h
index 61c7e9f..58db819 100644
--- a/src/include/aplwc.h
+++ b/src/include/aplwc.h
@@ -27,6 +27,7 @@ struct aplwc_line *aplwc_read(struct aplwc *, const char *);
void aplwc_free_line(struct aplwc_line *);
struct aplwc_value *aplwc_eval(struct aplwc_line *);
void aplwc_free_value(struct aplwc_value *);
+const char *aplwc_value_string(struct aplwc_value *);
#define APLWC_MIN_MEM (64)
diff --git a/src/lib/main.c b/src/lib/main.c
index 7456958..e9d33cb 100644
--- a/src/lib/main.c
+++ b/src/lib/main.c
@@ -113,3 +113,14 @@ aplwc_free_value(struct aplwc_value *value)
return;
memory_free_aplwc_value(&value->aplwc->memory, value);
}
+
+const char *
+aplwc_value_string(struct aplwc_value *value)
+{
+ assert(value != NULL);
+
+ switch(value->tag){
+ default:
+ return "???";
+ }
+}
diff --git a/tests/scripts/1.aplwc b/tests/scripts/1.aplwc
new file mode 100755
index 0000000..77104b2
--- /dev/null
+++ b/tests/scripts/1.aplwc
@@ -0,0 +1,3 @@
+#!/usr/bin/env aplwc-repl
+
+⎕←40 + 2
diff --git a/tests/scripts/2.aplwc b/tests/scripts/2.aplwc
new file mode 100755
index 0000000..e60e717
--- /dev/null
+++ b/tests/scripts/2.aplwc
@@ -0,0 +1,9 @@
+#!/usr/bin/env aplwc-repl
+
+∇ run
+ foo 123
+∇
+
+∇ foo x
+ ⎕←x+x
+∇