diff --git a/.gitignore b/.gitignore
index 3f2b273..2e64bed 100644
--- a/.gitignore
+++ b/.gitignore
@@ -79,6 +79,10 @@ libkc3_window/sdl2/demo/macos/kc3_window_sdl2_demo_debug.app/
*.lo
macos/kc3-v*
*.o
+test/ekc3/*.diff
+test/ekc3/*.err
+test/ekc3/*.out
+test/ekc3/*.ret
test/facts_test_dump_file.facts
test/facts_test_log_add.facts
test/facts_test_log_remove.facts
diff --git a/Makefile b/Makefile
index 3cb2358..962d3a2 100644
--- a/Makefile
+++ b/Makefile
@@ -219,10 +219,23 @@ test_debug:
${MAKE} -C ikc3 debug
${MAKE} -C test test_debug
+test_ekc3: build
+ ${MAKE} -C test test_ekc3
+
+test_ekc3_asan: asan
+ ${MAKE} -C test test_ekc3_asan
+
+test_ekc3_cov: cov
+ ${MAKE} -C test test_ekc3_cov
+
+test_ekc3_debug: debug
+ ${MAKE} -C test test_ekc3_debug
+
test_gcovr:
${MAKE} clean_cov
${MAKE} test_libkc3_cov
${MAKE} test_ikc3_cov
+ ${MAKE} test_ekc3_cov
${MAKE} gcovr
test_ikc3: build
diff --git a/ikc3/ikc3.c b/ikc3/ikc3.c
index f882a81..29ec996 100644
--- a/ikc3/ikc3.c
+++ b/ikc3/ikc3.c
@@ -94,16 +94,13 @@ int main (int argc, char **argv)
s_tag input;
char o[BUF_SIZE];
s_buf out;
+ s_str path;
sw r;
s_tag result;
if (argc < 1)
return usage(argv[0]);
if (! kc3_init(NULL, &argc, &argv))
return 1;
- if (argv && ! strcmp("--quit", argv[0])) {
- kc3_clean(NULL);
- return 0;
- }
buf_init(&in, false, sizeof(i), i);
#if HAVE_WINEDITLINE
buf_wineditline_open_r(&in, "ikc3> ", ".ikc3_history");
@@ -113,6 +110,32 @@ int main (int argc, char **argv)
in.line = 0;
buf_init(&out, false, sizeof(o), o);
buf_file_open_w(&out, stdout);
+ while (argc) {
+ if (! strncmp("--load", *argv, 6) ||
+ ! strncmp("-l", *argv, 2)) {
+ if (argc < 2) {
+ err_write_1("ikc3: ");
+ err_write_1(*argv);
+ err_write_1(" without an argument\n");
+ assert(! "env_init: -l or --load without an argument");
+ r = 1;
+ goto clean;
+ }
+ str_init_1(&path, NULL, argv[1]);
+ if (! env_load(&g_kc3_env, &path)) {
+ r = 1;
+ goto clean;
+ }
+ argc -= 2;
+ argv += 2;
+ }
+ else if (argc == 1 && ! strcmp("--quit", *argv)) {
+ r = 0;
+ goto clean;
+ }
+ else
+ break;
+ }
while ((r = ikc3_buf_ignore_spaces(&out, &in)) >= 0) {
if ((r = buf_parse_tag(&in, &input)) > 0) {
if (! eval_tag(&input, &result)) {
@@ -135,6 +158,8 @@ int main (int argc, char **argv)
(r = buf_ignore_character(&in)) <= 0))
break;
}
+ r = 0;
+ clean:
#if HAVE_WINEDITLINE
buf_wineditline_close(&in, ".ikc3_history");
#else
@@ -142,7 +167,7 @@ int main (int argc, char **argv)
#endif
buf_file_close(&out);
kc3_clean(NULL);
- return 0;
+ return r;
}
int usage (char *argv0)
diff --git a/kc3s/kc3s.c b/kc3s/kc3s.c
index 32ad311..f366534 100644
--- a/kc3s/kc3s.c
+++ b/kc3s/kc3s.c
@@ -65,20 +65,43 @@ int main (int argc, char **argv)
s_tag input;
char o[BUF_SIZE];
s_buf out;
+ s_str path;
sw r;
s_tag result;
if (argc < 1)
return usage(argv[0]);
if (! kc3_init(NULL, &argc, &argv))
return 1;
- if (argv && ! strcmp("--quit", argv[0])) {
- kc3_clean(NULL);
- return 0;
- }
buf_init(&in, false, sizeof(i), i);
buf_file_open_r(&in, stdin);
buf_init(&out, false, sizeof(o), o);
buf_file_open_w(&out, stdout);
+ while (argc) {
+ if (! strncmp("--load", *argv, 6) ||
+ ! strncmp("-l", *argv, 2)) {
+ if (argc < 2) {
+ err_write_1("ikc3: ");
+ err_write_1(*argv);
+ err_write_1(" without an argument\n");
+ assert(! "env_init: -l or --load without an argument");
+ r = 1;
+ goto clean;
+ }
+ str_init_1(&path, NULL, argv[1]);
+ if (! env_load(&g_kc3_env, &path)) {
+ r = 1;
+ goto clean;
+ }
+ argc -= 2;
+ argv += 2;
+ }
+ else if (argc == 1 && ! strcmp("--quit", *argv)) {
+ r = 0;
+ goto clean;
+ }
+ else
+ break;
+ }
while ((r = buf_ignore_spaces(&in)) >= 0) {
if ((r = buf_parse_tag(&in, &input)) > 0) {
if (! eval_tag(&input, &result)) {
@@ -101,10 +124,12 @@ int main (int argc, char **argv)
(r = buf_ignore_character(&in)) <= 0))
break;
}
+ r = 0;
+ clean:
buf_readline_close(&in);
buf_file_close(&out);
kc3_clean(NULL);
- return 0;
+ return r;
}
int usage (char *argv0)
diff --git a/lib/kc3/0.1/kc3.facts b/lib/kc3/0.1/kc3.facts
index a80ab8e..fa30580 100644
--- a/lib/kc3/0.1/kc3.facts
+++ b/lib/kc3/0.1/kc3.facts
@@ -250,6 +250,6 @@ replace {KC3.let, :arity, 2}
replace {KC3.let, :is_a, :special_operator}
replace {KC3.let, :symbol_value, cfn Tag "kc3_let" (Tag, Block, Result)}
add {KC3, :symbol, KC3.puts}
-replace {KC3.puts, :symbol_value, cfn Sw "io_inspect_tag" (Tag)}
+replace {KC3.puts, :symbol_value, cfn Sw "kc3_puts" (Tag)}
add {KC3, :symbol, KC3.load}
replace {KC3.load, :symbol_value, cfn Bool "kc3_load" (Str)}
diff --git a/libkc3/env.c b/libkc3/env.c
index c1fdcf5..6896e84 100644
--- a/libkc3/env.c
+++ b/libkc3/env.c
@@ -1979,30 +1979,6 @@ s_env * env_init (s_env *env, int *argc, char ***argv)
env_clean(env);
return NULL;
}
- if (argc) {
- while (*argc) {
- if (! strcmp("--load", **argv) ||
- ! strcmp("-l", **argv)) {
- if (*argc < 2) {
- err_write_1("env_init: ");
- err_write_1(**argv);
- err_write_1(" without an argument\n");
- assert(! "env_init: -l or --load without an argument");
- env_clean(env);
- return NULL;
- }
- str_init_1(&path, NULL, (*argv)[1]);
- if (! env_load(env, &path)) {
- env_clean(env);
- return NULL;
- }
- *argc -= 2;
- *argv += 2;
- }
- else
- break;
- }
- }
return env;
}
diff --git a/libkc3/io.c b/libkc3/io.c
index cf98b1a..56ebd27 100644
--- a/libkc3/io.c
+++ b/libkc3/io.c
@@ -74,6 +74,14 @@ sw err_write_1 (const char *x)
return r;
}
+sw err_write_str (const s_str *x)
+{
+ sw r;
+ if ((r = buf_write_str(&g_kc3_env.err, x)) > 0)
+ buf_flush(&g_kc3_env.err);
+ return r;
+}
+
sw io_inspect (const s_tag *x)
{
sw r;
@@ -115,6 +123,14 @@ sw io_write_1 (const char *x)
return r;
}
+sw io_write_str (const s_str *x)
+{
+ sw r;
+ if ((r = buf_write_str(&g_kc3_env.out, x)) > 0)
+ buf_flush(&g_kc3_env.out);
+ return r;
+}
+
DEF_ERR_IO_INSPECT(array, const s_array *)
DEF_ERR_IO_INSPECT(call, const s_call *)
DEF_ERR_IO_INSPECT(character, const character *)
diff --git a/libkc3/io.h b/libkc3/io.h
index 53c0a1d..8d6489d 100644
--- a/libkc3/io.h
+++ b/libkc3/io.h
@@ -29,11 +29,13 @@
sw err_inspect (const s_tag *x);
sw err_puts (const char *x);
sw err_write_1 (const char *x);
+sw err_write_str (const s_str *x);
/* standard output */
sw io_inspect (const s_tag *x);
sw io_puts (const char *x);
sw io_write_1 (const char *x);
+sw io_write_str (const s_str *x);
PROTOTYPES_ERR_IO_INSPECT(array, const s_array *);
PROTOTYPES_ERR_IO_INSPECT(bool, const bool *);
diff --git a/libkc3/kc3.c b/libkc3/kc3.c
index 8bad2a5..b711935 100644
--- a/libkc3/kc3.c
+++ b/libkc3/kc3.c
@@ -202,6 +202,25 @@ s_tag * kc3_pin (const s_tag *a, s_tag *dest)
return dest;
}
+sw kc3_puts (const s_tag *tag)
+{
+ sw r;
+ sw result = 0;
+ if (tag->type == TAG_STR) {
+ if ((r = io_write_str(&tag->data.str)) < 0)
+ return r;
+ }
+ else {
+ if ((r = io_inspect_tag(tag)) < 0)
+ return r;
+ }
+ result += r;
+ if ((r = io_write_1("\n")) < 0)
+ return r;
+ result += r;
+ return result;
+}
+
s_list ** kc3_search_modules (s_list **dest)
{
return env_search_modules(&g_kc3_env, dest);
diff --git a/libkc3/kc3_main.h b/libkc3/kc3_main.h
index 042c1b2..f48d1f0 100644
--- a/libkc3/kc3_main.h
+++ b/libkc3/kc3_main.h
@@ -34,6 +34,7 @@ uw * kc3_facts_next_id (uw *dest);
s_str * kc3_getenv (const s_str *name, s_str *dest);
void kc3_license (void);
const s_sym ** kc3_module (const s_sym **dest);
+sw kc3_puts (const s_tag *tag);
/* Operators. */
s_tag * kc3_access (const s_tag *tag, const s_sym * const *sym,
diff --git a/test/Makefile b/test/Makefile
index 36dee53..f8bb43a 100644
--- a/test/Makefile
+++ b/test/Makefile
@@ -76,18 +76,34 @@ lldb_test: debug
test: libkc3_test
time ./libkc3_test
IKC3=${SRC_TOP}/ikc3/ikc3 time ./ikc3_test
+ KC3S=${SRC_TOP}/kc3s/kc3s time ./ekc3_test
test_asan: libkc3_test_asan
time ./libkc3_test_asan
IKC3=${SRC_TOP}/ikc3/ikc3_asan time ./ikc3_test
+ KC3S=${SRC_TOP}/kc3s/kc3s_asan time ./ekc3_test
test_cov:
time ./libkc3_test_cov
IKC3=${SRC_TOP}/ikc3/ikc3_cov time ./ikc3_test
+ KC3S=${SRC_TOP}/kc3s/kc3s_cov time ./ekc3_test
test_debug: libkc3_test_debug
time ./libkc3_test_debug
IKC3=${SRC_TOP}/ikc3/ikc3_debug time ./ikc3_test
+ KC3S=${SRC_TOP}/kc3s/kc3s_debug time ./ekc3_test
+
+test_ekc3:
+ KC3S=${SRC_TOP}/kc3s/kc3s time ./ekc3_test
+
+test_ekc3_asan:
+ KC3S=${SRC_TOP}/kc3s/kc3s_asan time ./ekc3_test
+
+test_ekc3_cov:
+ KC3S=${SRC_TOP}/kc3s/kc3s_cov time ./ekc3_test
+
+test_ekc3_debug:
+ KC3S=${SRC_TOP}/kc3s/kc3s_debug time ./ekc3_test
test_ikc3:
IKC3=${SRC_TOP}/ikc3/ikc3 time ./ikc3_test
diff --git a/test/ekc3/title.kc3 b/test/ekc3/title.kc3
index 4a422c6..b95124b 100644
--- a/test/ekc3/title.kc3
+++ b/test/ekc3/title.kc3
@@ -1,2 +1,2 @@
-puts EKC3.render(__DIR__ + "/title.html.ekc3",
- %{title: "EKC3 test title"})
+puts(EKC3.render(__DIR__ + "/title.html.ekc3",
+ %{title: "EKC3 test title"}))
diff --git a/test/ikc3/puts.in b/test/ikc3/puts.in
new file mode 100644
index 0000000..8a8fe27
--- /dev/null
+++ b/test/ikc3/puts.in
@@ -0,0 +1,4 @@
+quote puts("Test")
+puts("Test")
+quote puts(%{hello: "World !"})
+puts(%{hello: "World !"})
diff --git a/test/ikc3/puts.out.expected b/test/ikc3/puts.out.expected
new file mode 100644
index 0000000..3a24fa1
--- /dev/null
+++ b/test/ikc3/puts.out.expected
@@ -0,0 +1,6 @@
+puts("Test")
+Test
+5
+puts(%{hello: "World !"})
+%{hello: "World !"}
+20
diff --git a/test/ikc3/puts.ret.expected b/test/ikc3/puts.ret.expected
new file mode 100644
index 0000000..573541a
--- /dev/null
+++ b/test/ikc3/puts.ret.expected
@@ -0,0 +1 @@
+0