summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorStephen Dolan <mu@netsoc.tcd.ie>2012-09-18 22:17:13 +0100
committerStephen Dolan <mu@netsoc.tcd.ie>2012-09-18 22:17:13 +0100
commit20e45f363c91ef4a305eff5709212f1b2fb43523 (patch)
tree5fad025d47663b801d15a7cb805562cf6264a044
parent46af5238ce3e9327e0268d18373d07f67eed58b8 (diff)
Separate the tests and the main program.
-rw-r--r--Makefile21
-rw-r--r--execute.c25
-rw-r--r--execute.h13
-rw-r--r--jq_test.c (renamed from jv_test.c)100
-rw-r--r--main.c99
5 files changed, 141 insertions, 117 deletions
diff --git a/Makefile b/Makefile
index db63b777..7348b292 100644
--- a/Makefile
+++ b/Makefile
@@ -8,8 +8,6 @@ clean:
sed 's/.*`\(.*\)'\''.*/\1/' | grep -v '^all$$' | \
xargs rm
-jv_utf8_tables.gen.h: gen_utf8_tables.py
- python $^ > $@
lexer.gen.c: lexer.l
flex -o lexer.gen.c --header-file=lexer.gen.h lexer.l
@@ -19,21 +17,20 @@ parser.gen.c: parser.y lexer.gen.h
bison -W -d parser.y -v --report-file=parser.gen.info -o $@
parser.gen.h: parser.gen.c
+jv_utf8_tables.gen.h: gen_utf8_tables.py
+ python $^ > $@
jv_unicode.c: jv_utf8_tables.gen.h
-parsertest: parser.gen.c lexer.gen.c main.c opcode.c bytecode.c compile.c execute.c builtin.c jv.c jv_parse.c jv_print.c jv_dtoa.c jv_unicode.c
- $(CC) -DJQ_DEBUG=1 -o $@ $^
+JQ_SRC=parser.gen.c lexer.gen.c opcode.c bytecode.c compile.c execute.c builtin.c jv.c jv_parse.c jv_print.c jv_dtoa.c jv_unicode.c
-jq: parser.gen.c lexer.gen.c main.c opcode.c bytecode.c compile.c execute.c builtin.c jv.c jv_parse.c jv_print.c jv_dtoa.c jv_unicode.c
- $(CC) -DJQ_DEBUG=0 -o $@ $^
-jv_test: jv_test.c jv.c jv_print.c jv_dtoa.c jv_unicode.c
- $(CC) -DNO_JANSSON -o $@ $^
+jq_test: $(JQ_SRC) jq_test.c
+ $(CC) -DJQ_DEBUG=1 -o $@ $^
-jv_parse: jv_parse.c jv.c jv_print.c jv_dtoa.c
- $(CC) -DNO_JANSSON -o $@ $^ -DJV_PARSE_MAIN
+jq: $(JQ_SRC) main.c
+ $(CC) -DJQ_DEBUG=0 -o $@ $^
-test: jv_test
- valgrind --error-exitcode=1 -q --leak-check=full ./jv_test
+test: jq_test
+ valgrind --error-exitcode=1 -q --leak-check=full ./jq_test >/dev/null
diff --git a/execute.c b/execute.c
index 6b0948c5..93aefc0e 100644
--- a/execute.c
+++ b/execute.c
@@ -3,6 +3,8 @@
#include <stdlib.h>
#include <stdint.h>
+#include "execute.h"
+
#include "opcode.h"
#include "bytecode.h"
#include "compile.h"
@@ -10,8 +12,10 @@
#include "forkable_stack.h"
#include "frame_layout.h"
+#include "locfile.h"
#include "jv.h"
-
+#include "parser.h"
+#include "builtin.h"
typedef struct {
jv value;
@@ -500,3 +504,22 @@ void jq_teardown() {
pathbuf = 0;
pathsize = 0;
}
+
+struct bytecode* jq_compile(const char* str) {
+ struct locfile locations;
+ locfile_init(&locations, str, strlen(str));
+ block program;
+ struct bytecode* bc = 0;
+ int nerrors = jq_parse(&locations, &program);
+ if (nerrors == 0) {
+ block_append(&program, block_join(gen_op_simple(YIELD), gen_op_simple(BACKTRACK)));
+ program = builtins_bind(program);
+ nerrors = block_compile(program, &locations, &bc);
+ block_free(program);
+ }
+ if (nerrors) {
+ fprintf(stderr, "%d compile %s\n", nerrors, nerrors > 1 ? "errors" : "error");
+ }
+ locfile_free(&locations);
+ return bc;
+}
diff --git a/execute.h b/execute.h
new file mode 100644
index 00000000..bf31e5e8
--- /dev/null
+++ b/execute.h
@@ -0,0 +1,13 @@
+#ifndef EXECUTE_H
+#define EXECUTE_H
+#include "bytecode.h"
+
+
+struct bytecode* jq_compile(const char* str);
+
+void jq_init(struct bytecode* bc, jv value);
+jv jq_next();
+void jq_teardown();
+
+
+#endif
diff --git a/jv_test.c b/jq_test.c
index 725e5aba..b4674c81 100644
--- a/jv_test.c
+++ b/jq_test.c
@@ -1,9 +1,97 @@
#include <assert.h>
#include <stdio.h>
#include <string.h>
+#include <stdlib.h>
#include "jv.h"
+#include "execute.h"
-int main(){
+static void jv_test();
+static void run_jq_tests();
+
+int main() {
+ jv_test();
+ run_jq_tests();
+}
+
+
+
+
+static int skipline(const char* buf) {
+ int p = 0;
+ while (buf[p] == ' ' || buf[p] == '\t') p++;
+ if (buf[p] == '#' || buf[p] == '\n' || buf[p] == 0) return 1;
+ return 0;
+}
+
+static void run_jq_tests() {
+ FILE* testdata = fopen("testdata","r");
+ char buf[4096];
+ int tests = 0, passed = 0;
+
+ while (1) {
+ if (!fgets(buf, sizeof(buf), testdata)) break;
+ if (skipline(buf)) continue;
+ printf("Testing %s\n", buf);
+ int pass = 1;
+ struct bytecode* bc = jq_compile(buf);
+ assert(bc);
+ printf("Disassembly:\n");
+ dump_disassembly(2, bc);
+ printf("\n");
+ fgets(buf, sizeof(buf), testdata);
+ jv input = jv_parse(buf);
+ assert(jv_is_valid(input));
+ jq_init(bc, input);
+
+ while (fgets(buf, sizeof(buf), testdata)) {
+ if (skipline(buf)) break;
+ jv expected = jv_parse(buf);
+ assert(jv_is_valid(expected));
+ jv actual = jq_next();
+ if (!jv_is_valid(actual)) {
+ jv_free(actual);
+ printf("Insufficient results\n");
+ pass = 0;
+ break;
+ } else if (!jv_equal(jv_copy(expected), jv_copy(actual))) {
+ printf("Expected ");
+ jv_dump(jv_copy(expected), 0);
+ printf(", but got ");
+ jv_dump(jv_copy(actual), 0);
+ printf("\n");
+ pass = 0;
+ }
+ jv as_string = jv_dump_string(jv_copy(expected), rand());
+ jv reparsed = jv_parse_sized(jv_string_value(as_string), jv_string_length(jv_copy(as_string)));
+ assert(jv_equal(jv_copy(expected), jv_copy(reparsed)));
+ jv_free(as_string);
+ jv_free(reparsed);
+ jv_free(expected);
+ jv_free(actual);
+ }
+ if (pass) {
+ jv extra = jq_next();
+ if (jv_is_valid(extra)) {
+ printf("Superfluous result: ");
+ jv_dump(extra, 0);
+ printf("\n");
+ pass = 0;
+ } else {
+ jv_free(extra);
+ }
+ }
+ jq_teardown();
+ bytecode_free(bc);
+ tests++;
+ passed+=pass;
+ }
+ fclose(testdata);
+ printf("%d of %d tests passed\n", passed,tests);
+ if (passed != tests) exit(1);
+}
+
+
+static void jv_test() {
/// Arrays and numbers
{
jv a = jv_array();
@@ -82,7 +170,7 @@ int main(){
assert(jv_array_length(jv_array_get(jv_copy(a), 1)) == 1);
- jv_dump(jv_copy(a)); printf("\n");
+ jv_dump(jv_copy(a), 0); printf("\n");
jv_free(a);
}
@@ -92,8 +180,8 @@ int main(){
assert(jv_equal(jv_string("foo"), jv_string_sized("foo", 3)));
char nasty[] = "foo\0";
jv shortstr = jv_string(nasty), longstr = jv_string_sized(nasty, sizeof(nasty));
- assert(jv_string_length(shortstr) == strlen(nasty));
- assert(jv_string_length(longstr) == sizeof(nasty));
+ assert(jv_string_length(shortstr) == (int)strlen(nasty));
+ assert(jv_string_length(longstr) == (int)sizeof(nasty));
char a1s[] = "hello", a2s[] = "hello", bs[] = "goodbye";
@@ -111,7 +199,7 @@ int main(){
assert(jv_equal(jv_string("hello42!"), jv_string_fmt("hello%d%s", 42, "!")));
char big[20000];
- for (int i=0; i<sizeof(big); i++) big[i] = 'a';
+ for (int i=0; i<(int)sizeof(big); i++) big[i] = 'a';
big[sizeof(big)-1] = 0;
jv str = jv_string_fmt("%s", big);
assert(jv_string_length(jv_copy(str)) == sizeof(big) - 1);
@@ -135,7 +223,7 @@ int main(){
jv_free(o1);
assert(jv_number_value(jv_object_get(jv_copy(o2), jv_string("bar"))) == 240);
- jv_dump(jv_copy(o2)); printf("\n");
+ jv_dump(jv_copy(o2), 0); printf("\n");
jv_free(o2);
}
diff --git a/main.c b/main.c
index 0a9eefe8..776c9575 100644
--- a/main.c
+++ b/main.c
@@ -6,106 +6,9 @@
#include "jv_parse.h"
#include "locfile.h"
#include "parser.h"
-
-
-void jq_init(struct bytecode* bc, jv value);
-jv jq_next();
-void jq_teardown();
-
-struct bytecode* jq_compile(const char* str) {
- struct locfile locations;
- locfile_init(&locations, str, strlen(str));
- block program;
- struct bytecode* bc = 0;
- int nerrors = jq_parse(&locations, &program);
- if (nerrors == 0) {
- block_append(&program, block_join(gen_op_simple(YIELD), gen_op_simple(BACKTRACK)));
- program = builtins_bind(program);
- nerrors = block_compile(program, &locations, &bc);
- block_free(program);
- }
- if (nerrors) {
- fprintf(stderr, "%d compile %s\n", nerrors, nerrors > 1 ? "errors" : "error");
- }
- locfile_free(&locations);
- return bc;
-}
-
-int skipline(const char* buf) {
- int p = 0;
- while (buf[p] == ' ' || buf[p] == '\t') p++;
- if (buf[p] == '#' || buf[p] == '\n' || buf[p] == 0) return 1;
- return 0;
-}
-
-void run_tests() {
- FILE* testdata = fopen("testdata","r");
- char buf[4096];
- int tests = 0, passed = 0;
-
- while (1) {
- if (!fgets(buf, sizeof(buf), testdata)) break;
- if (skipline(buf)) continue;
- printf("Testing %s\n", buf);
- int pass = 1;
- struct bytecode* bc = jq_compile(buf);
- assert(bc);
- printf("Disassembly:\n");
- dump_disassembly(2, bc);
- printf("\n");
- fgets(buf, sizeof(buf), testdata);
- jv input = jv_parse(buf);
- assert(jv_is_valid(input));
- jq_init(bc, input);
-
- while (fgets(buf, sizeof(buf), testdata)) {
- if (skipline(buf)) break;
- jv expected = jv_parse(buf);
- assert(jv_is_valid(expected));
- jv actual = jq_next();
- if (!jv_is_valid(actual)) {
- jv_free(actual);
- printf("Insufficient results\n");
- pass = 0;
- break;
- } else if (!jv_equal(jv_copy(expected), jv_copy(actual))) {
- printf("Expected ");
- jv_dump(jv_copy(expected), 0);
- printf(", but got ");
- jv_dump(jv_copy(actual), 0);
- printf("\n");
- pass = 0;
- }
- jv as_string = jv_dump_string(jv_copy(expected), rand());
- jv reparsed = jv_parse_sized(jv_string_value(as_string), jv_string_length(jv_copy(as_string)));
- assert(jv_equal(jv_copy(expected), jv_copy(reparsed)));
- jv_free(as_string);
- jv_free(reparsed);
- jv_free(expected);
- jv_free(actual);
- }
- if (pass) {
- jv extra = jq_next();
- if (jv_is_valid(extra)) {
- printf("Superfluous result: ");
- jv_dump(extra, 0);
- printf("\n");
- pass = 0;
- } else {
- jv_free(extra);
- }
- }
- jq_teardown();
- bytecode_free(bc);
- tests++;
- passed+=pass;
- }
- fclose(testdata);
- printf("%d of %d tests passed\n", passed,tests);
-}
+#include "execute.h"
int main(int argc, char* argv[]) {
- if (argc == 1) { run_tests(); return 0; }
struct bytecode* bc = jq_compile(argv[1]);
if (!bc) return 1;