diff options
author | Stephen Dolan <mu@netsoc.tcd.ie> | 2012-09-18 22:17:13 +0100 |
---|---|---|
committer | Stephen Dolan <mu@netsoc.tcd.ie> | 2012-09-18 22:17:13 +0100 |
commit | 20e45f363c91ef4a305eff5709212f1b2fb43523 (patch) | |
tree | 5fad025d47663b801d15a7cb805562cf6264a044 | |
parent | 46af5238ce3e9327e0268d18373d07f67eed58b8 (diff) |
Separate the tests and the main program.
-rw-r--r-- | Makefile | 21 | ||||
-rw-r--r-- | execute.c | 25 | ||||
-rw-r--r-- | execute.h | 13 | ||||
-rw-r--r-- | jq_test.c (renamed from jv_test.c) | 100 | ||||
-rw-r--r-- | main.c | 99 |
5 files changed, 141 insertions, 117 deletions
@@ -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 @@ -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 @@ -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); } @@ -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; |