From c47313b42596857507e9d514cf9af5a90978381e Mon Sep 17 00:00:00 2001 From: Gediminas Repecka Date: Sun, 28 Apr 2024 21:10:43 +0300 Subject: [PATCH 1/2] add searching by key string --- build.sh | 3 ++- include/gson.h | 65 +++++++++++++++++++++++++++++++++++++++++++++++++- main.c | 5 +++- src/gson.c | 56 +++++++++++++++++-------------------------- tests/tests.c | 1 + 5 files changed, 93 insertions(+), 37 deletions(-) diff --git a/build.sh b/build.sh index ecd1707..396bd8e 100755 --- a/build.sh +++ b/build.sh @@ -2,9 +2,10 @@ set -xe NAME=gson -CCFLAGS="-DDEBUG=0 -Wall -g -O3" +CCFLAGS="-DDEBUG=0 -Wall -g" compile_lib() { + mkdir -pv lib gcc $CCFLAGS -c src/$NAME.c -o lib/$NAME.o gcc $CCFLAGS -c src/debug.c -o lib/debug.o ar rcs lib/lib$NAME.a lib/$NAME.o lib/debug.o diff --git a/include/gson.h b/include/gson.h index e3b376f..2e5d93e 100644 --- a/include/gson.h +++ b/include/gson.h @@ -4,9 +4,72 @@ typedef void Parser; typedef void JSONNode; +typedef enum { + JSON_OBJECT, + JSON_ARRAY, + JSON_STRING, + JSON_NUMBER, + JSON_TRUE_VAL, + JSON_FALSE_VAL, + JSON_NULL_VAL, +} JSONType; + +/* + * initialise parser, which will be passed in gson_parse() + */ extern Parser* parser_init(char* source); + +/* destroy parser */ extern void parser_destroy(Parser *parser); + +/* + * takes parser and NULL as arguments, returns JSONNode type object pointing to the top level json object in the source + */ extern JSONNode* gson_parse(Parser *parser, JSONNode *node); + +/* + * cleanup - destroys the tree of JSONObjects recursively starting from 'node' + */ extern void gson_destroy(JSONNode *node); -#endif +/* + * returns 'node' pointing to the first JSON object with matching 'key' + */ +extern JSONNode* gson_find_by_key(JSONNode *node, char *key); + +/* + * returns 'node' pointing to the first JSON object with matching 'value' + */ +extern JSONNode* gson_find_by_str_val(JSONNode *node, char *value); + +/* + * returns 'node' pointing to the first JSON object with matching 'value' + */ +extern JSONNode* gson_find_by_float_val(JSONNode *node, float value); + +/* + * returns the type of 'node' + */ +extern JSONType gson_get_object_type(JSONNode *node); + +/* + * returns key value 'node' + */ +extern char* gson_get_key_value(JSONNode *node); + +/* + * returns string value 'node' + */ +extern char* gson_get_str_value(JSONNode *node); + +/* + * returns numeric value 'node' + */ +extern float gson_get_float_value(JSONNode *node); + +/* + * returns JSON_FALSE_VAL, JSON_TRUE_VAL or JSON_NULL if the 'node' is of appropriate type + */ +extern JSONType gson_get_bool_value(JSONNode *node); + +#endif // GSON_H diff --git a/main.c b/main.c index 561caa2..a0bab37 100644 --- a/main.c +++ b/main.c @@ -1,4 +1,4 @@ -#include +#include "./include/gson.h" #include #include #include @@ -59,6 +59,9 @@ int main(int argc, char* argv[]) t = clock() - t; double time_taken = ((double)t)/CLOCKS_PER_SEC; // in seconds printf("parsing took %f seconds to execute \n", time_taken); + JSONNode *key = gson_find_by_key(node, "\"gender\""); + if (key != NULL) + printf("Found!\n"); #if DEBUG==1 gson_debug_print_tree(node, 0); #endif diff --git a/src/gson.c b/src/gson.c index 8583ff7..4536c79 100644 --- a/src/gson.c +++ b/src/gson.c @@ -2,7 +2,6 @@ #include #include #include -#include #include "gson_int.h" #if DEBUG==1 #include "debug.h" @@ -774,17 +773,6 @@ JSONNode* gson_true_val(Parser *parser, JSONNode *curr) gson_error(parser, "Error"); return NULL; } - char *val = "true"; - curr->str_val = malloc(sizeof(char) * (strlen(val) + 1)); - if (!curr->str_val) - { - gson_error(parser, "Memory allocation failed\n"); - return curr; - } - strcpy(curr->str_val, val); -#if DEBUG==1 - gson_debug_print_str_val(curr); -#endif return curr; } JSONNode* gson_false_val(Parser *parser, JSONNode *curr) @@ -827,17 +815,6 @@ JSONNode* gson_false_val(Parser *parser, JSONNode *curr) gson_error(parser, "Error"); return NULL; } - char *val = "false"; - curr->str_val = malloc(sizeof(char) * (strlen(val) + 1)); - if (!curr->str_val) - { - gson_error(parser, "Memory allocation failed\n"); - return curr; - } - strcpy(curr->str_val, val); -#if DEBUG==1 - gson_debug_print_str_val(curr); -#endif return curr; } @@ -881,17 +858,6 @@ JSONNode* gson_null_val(Parser *parser, JSONNode *curr) gson_error(parser, "Error"); return NULL; } - char *val = "null"; - curr->str_val = malloc(sizeof(char) * (strlen(val) + 1)); - if (!curr->str_val) - { - gson_error(parser, "Memory allocation failed\n"); - return curr; - } - strcpy(curr->str_val, val); -#if DEBUG==1 - gson_debug_print_str_val(curr); -#endif return curr; } @@ -1031,3 +997,25 @@ gson_debug_general(parser, curr); if (parser->had_error) return NULL; return curr; } + +JSONNode* gson_find_by_key(JSONNode *node, char *key) +{ + if (node == NULL) + return NULL; + + if (node->key && strcmp(key, node->key) == 0) + { + return node; + } + + JSONNode *found_in_child = gson_find_by_key(node->child, key); + if (found_in_child != NULL) + return found_in_child; + + JSONNode *found_in_next = gson_find_by_key(node->next, key); + if (found_in_next != NULL) + return found_in_next; + + return NULL; +} + diff --git a/tests/tests.c b/tests/tests.c index 1a893db..923aaca 100644 --- a/tests/tests.c +++ b/tests/tests.c @@ -114,6 +114,7 @@ int main() gson_destroy(node); } + // print summary if (total == passed) { printf("SUCCESS: %d/%d test PASSED\n", passed, total); From cf4aaf420355bc6c3535e5c412713115746274e5 Mon Sep 17 00:00:00 2001 From: Gediminas Repecka Date: Sun, 28 Apr 2024 21:15:15 +0300 Subject: [PATCH 2/2] update gh actions wf --- .github/workflows/main.yml | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index b358a1a..190832b 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -10,16 +10,11 @@ on: jobs: build: - name: run build + name: run build and tests runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - name: build library run: ./build.sh - test: - name: run tests - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - - name: runtests + - name: run tests run: ./build.sh test