diff --git a/3p/include/llhs.h b/3p/include/llhs.h deleted file mode 100644 index 27d7019..0000000 --- a/3p/include/llhs.h +++ /dev/null @@ -1,80 +0,0 @@ - -#define MAX_HEADERS 16 -#define MAX_URI 4096 -#define MAX_BODY (1024 * 1024) -#define MAX_HNAME 128 -#define MAX_HBODY 1024 - -#define BUFFER_INIT_SIZE 256 -#define BUFFER_GROW_FACTOR 2 -#define BUFFER_GROW_ADDEND 0 - -#define BACKLOG 128 -#define POLL_TIMEOUT 5000 -#define MAX_POLL_EVENTS 64 -#define IMPLICIT_LENGTH 1 - -#define MAX_CLIENTS 256 -#define MAX_ALIVE 64 - -typedef void llhs_response; - -typedef enum { - llhs_HTTP_0_9, - llhs_HTTP_1_0, - llhs_HTTP_1_1, -} llhs_version; - -typedef enum { - llhs_GET, - llhs_PUT, - llhs_POST, - llhs_HEAD, - llhs_TRACE, - llhs_PATCH, - llhs_DELETE, - llhs_OPTIONS, - llhs_CONNECT, -} llhs_method; - -typedef struct { - const char *name; - const char *body; - int namel; - int bodyl; -} llhs_header; - -typedef struct { - llhs_version version; - llhs_method method; - const char *URI; - int URIl; - llhs_header headers[MAX_HEADERS]; - int headerc; - const void *body; - int bodyl; -} llhs_request; - -typedef struct { - _Bool occurred; - char message[256]; - int length; - const char *file, - *func; - int line; -} llhs_error; - -typedef void (*llhs_callback)(void *userp, const llhs_request *req, llhs_response *res); -typedef void (*llhs_logger )(void *userp, const char *level, const char *msg); - -_Bool llhs_serve(unsigned short port, void *userp, llhs_callback callback, llhs_logger logger, llhs_error *error); - -_Bool llhs_match (const char *x, const char *y); -_Bool llhs_match2(const char *x, const char *y, int xl, int yl); -const char *llhs_getheader(llhs_request *res, const char *name); - -void llhs_setcode (llhs_response *res, int code); -_Bool llhs_setbody (llhs_response *res, const void *body, int size); -void llhs_setbody2 (llhs_response *res, void *body, int bodyl, void (*free)(void *addr)); -_Bool llhs_setheader (llhs_response *res, const char *name, const char *body); -_Bool llhs_setheader2(llhs_response *res, const char *name, int body); diff --git a/3p/include/xjson.h b/3p/include/xjson.h deleted file mode 100644 index 30eadcf..0000000 --- a/3p/include/xjson.h +++ /dev/null @@ -1,217 +0,0 @@ - -#ifndef XJSON_H -#define XJSON_H - -#include -#include - -enum { - xj_INT = (1 << 0), - xj_BOOL = (1 << 1), - xj_NULL = (1 << 2), - xj_FLOAT = (1 << 3), - xj_ARRAY = (1 << 4), - xj_OBJECT = (1 << 5), - xj_STRING = (1 << 6), - xj_BIG_INT = (1 << 7), - xj_BIG_FLOAT = (1 << 8), -}; - -typedef enum { - - xj_E0000 = 0, // No error. - - - // --------------------------- // - // --- Internal errors ------- // - // --------------------------- // - - xj_E0001, // Maximum depth reached. - xj_E0002, // Out of memory. - xj_E0003, // Not implemented. - - - // --------------------------- // - // --- Input errors ---------- // - // --------------------------- // - - // (Unexpexted end of source inside object) // - - xj_E1000, // End of source inside object, - // right after the starting { - - xj_E1001, // End of source inside object, - // right after a key string. Was - // expected : - - xj_E1002, // End of source inside object, - // right after a key-value separator :. - // Was expected a value expression - - xj_E1003, // End of source inside object, - // right after value expression. - // Were expected , or } - - xj_E1004, // End of source inside object, - // right after value-key separator ,. - // Was expected a key string - - // (Unexpected end of source inside array) // - - xj_E1100, // End of source inside array, - // right after the starting [ - - xj_E1101, // End of source inside array, - // right after a value expression - - xj_E1102, // End of source inside array, - // right after value separator ,. - // Was expected a new value - // expression - - // (Unexpected end of source inside number) // - - xj_E1200, // End of source inside numeric - // expression, right after minus - // sign. Was expected a digit - - // (Unexpected end of source inside string) // - xj_E1300, // End of source inside string expression - xj_E1301, // End of source inside string expression, right after a backslash - - // (Unexpected character inside object) // - xj_E2000, // Unexpected character in place of an object key string. Was expected " - xj_E2001, // Unexpected character in place of an object key-value separator. Was expected : - xj_E2002, // Unexpected character inside object, right after value expression. Were expected , or } - - // (Unexpected character inside array) // - xj_E2100, // Unexpected character inside array, right after value expression. Were expecter ] or , - - // (Unexpected character inside number) // - xj_E2200, // Unexpected character inside number expression, right after minus sign. Was expected a digit after it - - // (Unexpected character inside string) // - xj_E2300, // Unexpected character inside string expression, right after backslash. The only escapable characters are \, /, ", n, t, r, f, b and u. - xj_E2301, // Unexpected character inside string expression, after \u. Was expected a hex digit - - xj_E2302, // Unexpected character inside string expression, right after unicode codepoint. Was expected an auxiliary codepoint - xj_E2303, // Unexpected character inside string expression, right after \\. Was expected an auxiliary codepoint - - xj_E2304, // Invalid symbol - xj_E2305, // Invalid auxiliary symbol - xj_E2306, // Invalid codepoint - - // (Unexpected end of source inside value expression) // - xj_E2400, // Unexpected character in place of a value expression. Were expected {, [, ", n, t, f or a digit. - - // (Other) // - xj_E2500, // Unexpected character after root value expression - xj_E2501, // Source string is empty (null pointer) - xj_E2502, // Source string is empty - xj_E2503, // Duplicate key in object - - // Decodef errors - xj_E3000, // Bad format - - // Query errors - xj_E4000, // End of source after dot. - xj_E4001, // Invalid character after dot. - xj_E4002, // End of source after [. - xj_E4003, // Float used as index. - xj_E4004, // Index too big. - xj_E4005, // Invalid character after [. - xj_E4006, // End of source instead of closing ]. - xj_E4007, // Invalid character instead of closing ]. - xj_E4008, // Invalid character instead of dot and [. - xj_E4009, // Missing node. - - // (i|f|b|s|a|o)Query errors - xj_E4100, // Queried int is too big so it's not representable. - xj_E4101, // Queried value is not an int. - xj_E4102, // Queried float is too big, so it's not representable. - xj_E4103, // Queried value is not a float. - xj_E4104, // Queried value is not a string. - xj_E4105, // Queried value is not a bool. - xj_E4106, // Queried value is not an array. - xj_E4107, // Queried value is not an object. - - xj_ECOUNT, -} xj_code; - -typedef struct { - - const char *src; - - _Bool occurred; - xj_code code; - - char text[128]; - - int offset, - lineno; - - const char *cfile, - *cfunc; - int cline; -} xj_error; - -typedef void xj_alloc; - -typedef struct xj_value xj_value; -struct xj_value { - int offset, length, type, size; - char *key; - union { - long long as_int; - _Bool as_bool; - double as_float; - xj_value* as_array; - xj_value* as_object; - char* as_string; - }; - xj_value *next; -}; - -xj_alloc* xj_init (unsigned int default_chunk_size); -void xj_free (xj_alloc *alloc); -void* xj_malloc(xj_alloc *alloc, unsigned int size); - -void xj_set_malloc(void *(*malloc)(void*, unsigned int)); -void* xj_sys_malloc(unsigned int size); -void xj_set_free(void (*free)(void*, void*)); -void xj_sys_free(void *ptr); -void xj_set_userp(void *userp); - -int xj_snprintf (char *buff, int buffsz, const char *fmt, ...); -int xj_vsnprintf(char *buff, int buffsz, const char *fmt, va_list args); - -xj_value* xj_query (xj_error *error, xj_value *root, const char *text, int len); -_Bool xj_nquery(xj_error *error, xj_value *root, const char *text, int len); -int xj_iquery(xj_error *error, xj_value *root, const char *text, int len); -double xj_fquery(xj_error *error, xj_value *root, const char *text, int len); -_Bool xj_bquery(xj_error *error, xj_value *root, const char *text, int len); -char *xj_squery(xj_error *error, xj_value *root, const char *text, int len, int *count); -xj_value *xj_aquery(xj_error *error, xj_value *root, const char *text, int len, int *count); -xj_value *xj_oquery(xj_error *error, xj_value *root, const char *text, int len, int *count); - -xj_value* xj_decode (xj_error *error, xj_alloc **alloc, const char *text, int len); -xj_value* xj_decodef (xj_error *error, xj_alloc **alloc, const char *format, ...); -xj_value* xj_vdecodef(xj_error *error, xj_alloc **alloc, const char *format, va_list args); - -char* xj_encode (const xj_value *value, int *len); -char* xj_sencode(const char *src, int *len); -char* xj_aencode(const xj_value *head, int *len); -char* xj_oencode(const xj_value *head, int *len); - -char* xj_encode2 (const xj_value *value, char *buff, unsigned int bufflen, int *len); -char* xj_sencode2(const char *src, char *buff, unsigned int bufflen, int *len); -char* xj_aencode2(const xj_value *head, char *buff, unsigned int bufflen, int *len); -char* xj_oencode2(const xj_value *head, char *buff, unsigned int bufflen, int *len); - -_Bool xj_compare(const xj_value *a, const xj_value *b); -xj_value* xj_get_by_name (const xj_value *parent, const char *name, int len); -xj_value* xj_get_by_index(const xj_value *parent, unsigned int index); -_Bool xj_is_error_internal(const xj_error *error); -const char *xj_typename(int type); -void xj_stats(FILE *fp); -#endif \ No newline at end of file diff --git a/3p/libs/libllhs.a b/3p/libs/libllhs.a deleted file mode 100644 index 167b5c2..0000000 Binary files a/3p/libs/libllhs.a and /dev/null differ diff --git a/3p/libs/libxjson.a b/3p/libs/libxjson.a deleted file mode 100644 index cd3e287..0000000 Binary files a/3p/libs/libxjson.a and /dev/null differ diff --git a/build.sh b/build.sh index 03ca4f3..2df7311 100755 --- a/build.sh +++ b/build.sh @@ -40,7 +40,6 @@ gcc -c src/objects/objects.c -o temp/objects/objects.o $FLAGS mkdir temp/compiler gcc -c src/compiler/parse.c -o temp/compiler/parse.o $FLAGS gcc -c src/compiler/compile.c -o temp/compiler/compile.o $FLAGS -gcc -c src/compiler/serialize.c -o temp/compiler/serialize.o $FLAGS mkdir temp/common gcc -c src/common/executable.c -o temp/common/executable.o $FLAGS @@ -62,52 +61,51 @@ rm -rf build mkdir build ar rcs build/libnoja-objects.a \ - temp/objects/heap.o \ - temp/objects/o_int.o \ + temp/objects/heap.o \ + temp/objects/o_int.o \ temp/objects/o_float.o \ temp/objects/objects.o \ temp/utils/error.o ar rcs build/libnoja-compile.a \ - temp/compiler/parse.o \ + temp/compiler/parse.o \ temp/compiler/compile.o \ - temp/compiler/serialize.o \ - temp/utils/bpalloc.o \ - temp/utils/error.o \ + temp/utils/bpalloc.o \ + temp/utils/error.o \ temp/utils/source.o ar rcs build/libnoja-runtime.a \ - temp/runtime/runtime.o \ + temp/runtime/runtime.o \ temp/runtime/runtime_error.o \ - temp/runtime/o_func.o \ + temp/runtime/o_func.o \ build/libnoja-compile.a \ build/libnoja-objects.a -gcc src/main.c \ - src/noja.c \ - temp/o_staticmap.o \ - temp/utils/hash.o \ - temp/utils/stack.o \ - temp/utils/source.o \ - temp/utils/promise.o \ - temp/utils/bucketlist.o \ - temp/objects/o_map.o \ - temp/objects/o_none.o \ - temp/objects/o_list.o \ - temp/objects/o_file.o \ - temp/objects/o_dir.o \ - temp/objects/o_bool.o \ - temp/objects/o_buffer.o \ - temp/objects/o_string.o \ - temp/objects/o_closure.o \ - temp/runtime/runtime.o \ - temp/runtime/runtime_error.o \ - temp/runtime/o_nfunc.o \ - temp/runtime/o_func.o \ - temp/builtins/basic.o \ - temp/builtins/file.o \ - temp/builtins/math.o \ - temp/common/executable.o \ - -o build/noja $FLAGS -Lbuild/ -lnoja-compile -lnoja-objects -lxjson -lm +gcc src/main.c \ + src/noja.c \ + temp/o_staticmap.o \ + temp/utils/hash.o \ + temp/utils/stack.o \ + temp/utils/source.o \ + temp/utils/promise.o \ + temp/utils/bucketlist.o \ + temp/objects/o_map.o \ + temp/objects/o_none.o \ + temp/objects/o_list.o \ + temp/objects/o_file.o \ + temp/objects/o_dir.o \ + temp/objects/o_bool.o \ + temp/objects/o_buffer.o \ + temp/objects/o_string.o \ + temp/objects/o_closure.o \ + temp/runtime/runtime.o \ + temp/runtime/runtime_error.o \ + temp/runtime/o_nfunc.o \ + temp/runtime/o_func.o \ + temp/builtins/basic.o \ + temp/builtins/file.o \ + temp/builtins/math.o \ + temp/common/executable.o \ + -o build/noja $FLAGS -Lbuild/ -lnoja-compile -lnoja-objects -lm rm -rf temp diff --git a/src/compiler/serialize.c b/src/compiler/serialize.c deleted file mode 100644 index 8f339c7..0000000 --- a/src/compiler/serialize.c +++ /dev/null @@ -1,201 +0,0 @@ - -/* WHAT IS THIS FILE? -** -** This file implements the routines that serialize the AST -** into JSON format. The JSON manipulation is handled by the -** third party library xJSON (written by me, still). -** -** The serialization functionality is exposed through the -** `serialize` function, that takes as an `AST` as argument -** and outputs a string of valid JSON. Therefore the xJSON -** dependency isn't exposed to the caller and can be regarded -** as an implementation detail. -** -** The way the serialization occurres is by converting the -** AST's representation native to the compiler to one native -** to xJSON, an then calling xj_encode on the converted AST. -** -*/ - -#include -#include -#include "serialize.h" -#include "ASTi.h" - -#define UNREACHABLE assert(0) - -static xj_value *convert_node(Node *node, xj_error *error, xj_alloc **alloc); - -char *serialize(AST *ast, int *len) -{ - xj_alloc *alloc = NULL; - xj_error error; - - xj_value *value = convert_node(ast->root, &error, &alloc); - - if(value == NULL) - { - xj_free(alloc); - return NULL; - } - else - { - char *serialized = xj_encode(value, len); - xj_free(alloc); - return serialized; - } -} - -static const char *expr_kind_name(ExprNode *expr) -{ - switch(expr->kind) - { - case EXPR_POS: return "pos"; - case EXPR_NEG: return "neg"; - case EXPR_ADD: return "add"; - case EXPR_SUB: return "sub"; - case EXPR_MUL: return "mul"; - case EXPR_DIV: return "div"; - case EXPR_INT: return "int"; - case EXPR_FLOAT: return "float"; - case EXPR_STRING: return "string"; - case EXPR_IDENT: return "ident"; - - default: - UNREACHABLE; - return NULL; - } - - UNREACHABLE; - return NULL; -} - -static xj_value *convert_node_list(Node *head, xj_error *error, xj_alloc **alloc); - -static xj_value *convert_node(Node *node, xj_error *error, xj_alloc **alloc) -{ - switch(node->kind) - { - case NODE_EXPR: - ExprNode *expr = (ExprNode*) node; - switch(expr->kind) - { - case EXPR_POS: - case EXPR_NEG: - case EXPR_ADD: - case EXPR_SUB: - case EXPR_MUL: - case EXPR_DIV: - { - OperExprNode *oper = (OperExprNode*) expr; - - xj_value *operands = NULL; - - if(oper->count > 0) - { - operands = convert_node_list((Node*) oper->head, error, alloc); - - if(operands == NULL) - return NULL; - } - - return xj_decodef(error, alloc, - "{" - "\t\"node-kind\": \"expr\", \n" - "\t\"expr-kind\": %Q, \n" - "\t\"operands\": %L\n" - "}", expr_kind_name(expr), operands); - } - - case EXPR_INT: - return xj_decodef(error, alloc, - "{" - "\t\"node-kind\": \"expr\", \n" - "\t\"expr-kind\": %Q, \n" - "\t\"value\": %d\n" - "}", expr_kind_name(expr), ((IntExprNode*) expr)->val); - - case EXPR_FLOAT: - return xj_decodef(error, alloc, - "{" - "\t\"node-kind\": \"expr\", \n" - "\t\"expr-kind\": %Q, \n" - "\t\"value\": %f\n" - "}", expr_kind_name(expr), ((FloatExprNode*) expr)->val); - - case EXPR_STRING: - return xj_decodef(error, alloc, - "{" - "\t\"node-kind\": \"expr\", \n" - "\t\"expr-kind\": %Q, \n" - "\t\"value\": %Q\n" - "}", expr_kind_name(expr), ((StringExprNode*) expr)->val); - - case EXPR_IDENT: - return xj_decodef(error, alloc, - "{" - "\t\"node-kind\": \"expr\", \n" - "\t\"expr-kind\": %Q, \n" - "\t\"value\": %Q\n" - "}", expr_kind_name(expr), ((IdentExprNode*) expr)->val); - - default: - UNREACHABLE; - break; - } - break; - - case NODE_IFELSE: - { - IfElseNode *ifelse = (IfElseNode*) node; - - xj_value *condition = convert_node(ifelse->condition, error, alloc); - if(condition == NULL) return NULL; - - xj_value *true_branch = convert_node(ifelse->true_branch, error, alloc); - if(true_branch == NULL) return NULL; - - xj_value *false_branch = convert_node(ifelse->false_branch, error, alloc); - if(false_branch == NULL) return NULL; - - return xj_decodef(error, alloc, - "{" - "\t\"node-kind\": \"if-else\", \n" - "\t\"condition\": %v, \n" - "\t\"true-branch\": %v, \n" - "\t\"false-branch\": %v\n" - "}", condition, true_branch, false_branch); - } - - default: - UNREACHABLE; - break; - } - - UNREACHABLE; - return NULL; -} - -static xj_value *convert_node_list(Node *head, xj_error *error, xj_alloc **alloc) -{ - xj_value *json_head = NULL; - xj_value **json_tail = &json_head; - - Node *curs = head; - while(curs) - { - xj_value *temp = convert_node(curs, error, alloc); - - if(temp == NULL) - return NULL; - - temp->next = NULL; - - *json_tail = temp; - json_tail = &temp->next; - - curs = curs->next; - } - - return json_head; -} \ No newline at end of file diff --git a/src/compiler/serialize.h b/src/compiler/serialize.h deleted file mode 100644 index f691054..0000000 --- a/src/compiler/serialize.h +++ /dev/null @@ -1,5 +0,0 @@ -#ifndef SERIALIZE_H -#define SERIALIZE_H -#include "AST.h" -char *serialize(AST *ast, int *len); -#endif \ No newline at end of file diff --git a/src/noja.c b/src/noja.c index 3e3a96f..bc3e8ba 100644 --- a/src/noja.c +++ b/src/noja.c @@ -4,7 +4,6 @@ #include #include "o_staticmap.h" #include "compiler/parse.h" -#include "compiler/serialize.h" #include "compiler/compile.h" #include "runtime/runtime.h" #include "runtime/runtime_error.h" diff --git a/tests/aux/parsing-tests.json b/tests/aux/parsing-tests.json deleted file mode 100644 index a11d780..0000000 --- a/tests/aux/parsing-tests.json +++ /dev/null @@ -1,104 +0,0 @@ -[ - { - "source": "1", - "expect": { - "node-kind": "expr", - "expr-kind": "int", - "value": 1 - } - }, - { - "source": "1.1", - "expect": { - "node-kind": "expr", - "expr-kind": "float", - "value": 1.1 - } - }, - { - "source": "1+1", - "expect": { - "node-kind": "expr", - "expr-kind": "add", - "operands": [ - {"node-kind": "expr", "expr-kind": "int", "value": 1}, - {"node-kind": "expr", "expr-kind": "int", "value": 1} - ] - } - }, - { - "source": "1-1", - "expect": { - "node-kind": "expr", - "expr-kind": "sub", - "operands": [ - {"node-kind": "expr", "expr-kind": "int", "value": 1}, - {"node-kind": "expr", "expr-kind": "int", "value": 1} - ] - } - }, - { - "source": "1*1", - "expect": { - "node-kind": "expr", - "expr-kind": "mul", - "operands": [ - {"node-kind": "expr", "expr-kind": "int", "value": 1}, - {"node-kind": "expr", "expr-kind": "int", "value": 1} - ] - } - }, - { - "source": "1-+1", - "expect": { - "node-kind": "expr", - "expr-kind": "sub", - "operands": [ - {"node-kind": "expr", "expr-kind": "int", "value": 1}, - { - "node-kind": "expr", - "expr-kind": "pos", - "operands": [ - {"node-kind": "expr", "expr-kind": "int", "value": 1} - ] - } - ] - } - }, - { - "source": "+1", - "expect": { - "node-kind": "expr", - "expr-kind": "pos", - "operands": [ - {"node-kind": "expr", "expr-kind": "int", "value": 1} - ] - } - }, - { - "source": "-1", - "expect": { - "node-kind": "expr", - "expr-kind": "neg", - "operands": [ - {"node-kind": "expr", "expr-kind": "int", "value": 1} - ] - } - }, - { - "source": "hello", - "expect": {"node-kind": "expr", "expr-kind": "ident", "value": "hello"} - }, - { - "source": "'hello'", - "expect": {"node-kind": "expr", "expr-kind": "string", "value": "hello"} - }, - { - "source": "-'hello'", - "expect": {"node-kind": "expr", "expr-kind": "neg", "operands": [{"node-kind": "expr", "expr-kind": "string", "value": "hello"}]} - }, - { - "source": "-'hel\\nlo'", - "expect": {"node-kind": "expr", "expr-kind": "neg", "operands": [{"node-kind": "expr", "expr-kind": "string", "value": "hel\\nlo"}]} - } -] \ No newline at end of file diff --git a/tests/src/test-objects.c b/tests/src/test-objects.c deleted file mode 100644 index 2e85472..0000000 --- a/tests/src/test-objects.c +++ /dev/null @@ -1,86 +0,0 @@ -#include -#include -#include "../../src/objects/objects.h" - -#define tassert(exp) if(!(exp)) goto done; -#define tdone done: if(1) - -static _Bool test_int() -{ - _Bool passed = 0; - - Heap *heap = Heap_New(-1); - assert(heap != NULL); - - Error error; - Error_Init(&error); - - // Test [Object_FromInt], [Object_ToInt]. - - int n = -3; // Just any value. - - Object *obj = Object_FromInt(n, heap, &error); - - tassert(obj != 0); - tassert(error.occurred == 0); - - int k = Object_ToInt(obj, &error); - - tassert(k == n); - tassert(error.occurred == 0); - - passed = 1; - - tdone { - Error_Free(&error); - Heap_Free(heap); - return passed; - } -} - -static _Bool test_float() -{ - _Bool passed = 0; - - Heap *heap = Heap_New(-1); - assert(heap != NULL); - - Error error; - Error_Init(&error); - - // Test [Object_FromFloat], [Object_ToFloat]. - - double n = -3.4; // Just any value. - - Object *obj = Object_FromFloat(n, heap, &error); - - if(obj == 0) - goto done; - - double k = Object_ToFloat(obj, &error); - - if(k != n) - goto done; - - // ... - - passed = 1; -done: - Error_Free(&error); - Heap_Free(heap); - return passed; -} - -int main() -{ - typedef _Bool (*test_t)(); - static const test_t tests[] = { - test_int, - test_float, - }; - - for(int i = 0; i < (int) (sizeof(tests) / sizeof(tests[0])); i += 1) - printf("TEST %d: %s\n", i, test_int() ? "Passed" : "Failed"); - - return 0; -} \ No newline at end of file diff --git a/tests/src/test-parse.c b/tests/src/test-parse.c deleted file mode 100644 index 0d16718..0000000 --- a/tests/src/test-parse.c +++ /dev/null @@ -1,281 +0,0 @@ -#include -#include -#include -#include -#include -#include "../../src/compiler/parse.h" -#include "../../src/compiler/serialize.h" - -typedef enum { PASSED, FAILED, IGNORED } result_t; - -static _Bool compare(const char *s, xj_value *v) -{ - xj_alloc *alloc = NULL; - xj_error error; - xj_value *doc; - - doc = xj_decode(&error, &alloc, s, -1); - assert(doc != NULL); - - _Bool same = xj_compare(doc, v); - - xj_free(alloc); - return same; -} - -result_t runtest(xj_value *value, int testno) -{ - int raw_sourcel; - char *raw_source; - xj_value *expect; - - { - xj_error error; - xj_value *source2 = xj_query(&error, value, ".source", -1); - - if(source2 == NULL) - { - if(error.code == xj_E4009) - fprintf(stderr, "WARNING: Field \"source\" is missing\n"); - else - fprintf(stderr, "WARNING: Internal failure (%s)\n", error.text); - return IGNORED; - } - - if(source2->type != xj_STRING) - { - fprintf(stderr, "WARNING: Field \"source\" is not a string\n"); - return IGNORED; - } - - raw_source = source2->as_string; - raw_sourcel = source2->size; - - expect = xj_query(&error, value, ".expect", -1); - - if(expect == NULL) - { - if(error.code == xj_E4009) - fprintf(stderr, "WARNING: Field \"expect\" is missing\n"); - else - fprintf(stderr, "WARNING: Internal failure (%s)\n", error.text); - return IGNORED; - } - - if(expect->type != xj_OBJECT) - { - fprintf(stderr, "WARNING: Field \"expect\" is not an object\n"); - return IGNORED; - } - } - - Source *source; - { - Error error; - Error_Init(&error); - - char temp[64]; - int k = snprintf(temp, sizeof(temp), "(Test %d's source)", testno); - - assert(k >= 0); - assert((unsigned int) k < sizeof(temp)); - - source = Source_FromString(temp, raw_source, raw_sourcel, &error); - - if(source == NULL) - { - fprintf(stderr, "WARNING: Internal failure (%s)\n", error.message); - return IGNORED; - } - } - - _Bool passed; - { - Error error; - BPAlloc *alloc; - char buffer[65536]; - - Error_Init(&error); - - alloc = BPAlloc_Init3(buffer, sizeof(buffer), -1, NULL, NULL, NULL); - - if(alloc == NULL) - { - fprintf(stderr, "WARNING: Internal failure (Failed to instanciate BPAlloc)\n"); - return IGNORED; - } - - AST *ast = parse(source, alloc, &error); - - if(ast == NULL) - { - fprintf(stderr, "WARNING: Internal failure (Failed to compile: %s; reported in %s at %s:%d)\n", error.message, error.func, error.file, error.line); - - Error_Free(&error); - BPAlloc_Free(alloc); - return IGNORED; - } - - char *serialized = serialize(ast, NULL); - - if(serialized == NULL) - { - fprintf(stderr, "WARNING: Internal failure (Failed to serialize AST)\n"); - - Error_Free(&error); - BPAlloc_Free(alloc); - return IGNORED; - } - - /* - printf("SERIALIZED :: %s\n", serialized); - { - char *temp = xj_encode(expect, NULL); - printf("SERIALIZED 2 :: %s\n", temp); - xj_sys_free(temp); - } - */ - - passed = compare(serialized, expect); - - Error_Free(&error); - BPAlloc_Free(alloc); - xj_sys_free(serialized); - } - - return passed ? PASSED : FAILED; -} - -static char *loadfile(const char *file, int *size); - -int main(int argc, char **argv) -{ - if(argc == 1) - { - fprintf(stderr, "ERROR: Missing file name\n"); - return 1; - } - - int filesize; - char *filename = argv[1]; - char *filetext = loadfile(filename, &filesize); - - if(filetext == NULL) - { - fprintf(stderr, "ERROR: Couldn't open \"%s\"\n", filename); - return 1; - } - - xj_alloc *alloc = NULL; - xj_error error; - xj_value *document; - - document = xj_decode(&error, &alloc, filetext, filesize); - - free(filetext); - - if(document == NULL) - { - assert(error.occurred == 1); - fprintf(stderr, "ERROR: Failed to parse \"%s\" as JSON: %s\n", - filename, error.text); - xj_free(alloc); - return 1; - } - - if(document->type != xj_ARRAY) - { - fprintf(stderr, "ERROR: Was expected an array as JSON document root\n"); - xj_free(alloc); - return 1; - } - - xj_value *cursor = document->as_array; - - int passed = 0, ignored = 0; - int total = document->size; - int index = 1; - - while(cursor) - { - result_t result = runtest(cursor, index); - - #define KNRM "\x1B[0m" - #define KRED "\x1B[31m" - #define KGRN "\x1B[32m" - #define KYEL "\x1B[33m" - #define KBLU "\x1B[34m" - #define KMAG "\x1B[35m" - #define KCYN "\x1B[36m" - #define KWHT "\x1B[37m" - #define RESET "\033[0m" - - switch(result) - { - case PASSED: - printf("TEST %-2d :: " KGRN "PASSED" RESET "\n", index); - passed += 1; - break; - - case FAILED: - printf("TEST %-2d :: " KRED "FAILED" RESET "\n", index); - break; - - case IGNORED: - printf("TEST %-2d :: " KYEL "IGNORED" RESET "\n", index); - ignored += 1; - break; - - default: assert(0); - } - - index += 1; - cursor = cursor->next; - } - - printf("\n ... %d passed, %d failed and %d ignored.\n", passed, total - passed - ignored, ignored); - - xj_free(alloc); - return 0; -} - -static char *loadfile(const char *file, int *size) -{ - char *body = NULL; - int _size; - - FILE *fp = fopen(file, "rb"); - - if(fp == NULL) - return NULL; - - if(fseek(fp, 0, SEEK_END)) - goto done; - - _size = ftell(fp); - - if(_size < 0) - goto done; - - if(size) - *size = _size; - - body = malloc(_size + 1); - - if(body == NULL) - goto done; - - if(fseek(fp, 0, SEEK_SET)) - goto done; - - int k = fread(body, 1, _size, fp); - - if(k != _size) - goto done; - - body[_size] = '\0'; - -done: - fclose(fp); - return body; -} \ No newline at end of file