From 45ed17d6ca65dabc93e9b6571fd9628b74baba84 Mon Sep 17 00:00:00 2001 From: rexy712 Date: Fri, 17 Jan 2020 14:22:15 -0800 Subject: [PATCH] Tree setup now working on all compilation units --- include/rjp.h | 1 + include/tree.h | 4 ++-- src/input.c | 39 ++++++++++++++++++++------------------- src/output.c | 25 +++++++++++++++---------- src/rjp.c | 16 +++++++++++++--- src/tree.c | 31 ++++++++++++++++++++++--------- 6 files changed, 73 insertions(+), 43 deletions(-) diff --git a/include/rjp.h b/include/rjp.h index b886d44..3cdd235 100644 --- a/include/rjp.h +++ b/include/rjp.h @@ -161,6 +161,7 @@ RJP_value* rjp_get_member(RJP_object_iterator* object); RJP_object_iterator* rjp_get_object_iterator(const RJP_value* object); RJP_value* rjp_object_iterator_current(RJP_object_iterator* it); RJP_value* rjp_object_iterator_next(RJP_object_iterator* it); +RJP_value* rjp_object_iterator_peek(RJP_object_iterator* it); void rjp_free_object_iterator(RJP_object_iterator* it); //Return number of members in the object RJP_index rjp_num_members(const RJP_value* object); diff --git a/include/tree.h b/include/tree.h index 0257860..4bdfca8 100644 --- a/include/tree.h +++ b/include/tree.h @@ -46,12 +46,11 @@ typedef struct RJP_tree_stack{ }RJP_tree_stack; typedef struct RJP_object_iterator{ RJP_tree_stack stack; - RJP_tree_node* current; }RJP_object_iterator; RJP_tree_node* irjp_new_node(RJP_object_member* value); -RJP_tree_node* irjp_tree_insert_value(RJP_tree_node* root, RJP_object_member* value, int* status); +RJP_tree_node* irjp_tree_insert_value(RJP_tree_node* root, RJP_object_member* value, RJP_value** added, int* status); RJP_tree_node* irjp_tree_remove_value(RJP_tree_node* root, const char* key, int* status); RJP_tree_node* irjp_tree_search_value(RJP_tree_node* root, const char* key); RJP_tree_node* irjp_copy_tree(const RJP_tree_node* root); @@ -60,6 +59,7 @@ void irjp_free_tree(RJP_tree_node* root); int irjp_init_object_iterator(RJP_object_iterator* it, const RJP_tree_node* root); void irjp_delete_object_iterator(RJP_object_iterator* it); RJP_tree_node* irjp_object_iterator_next(RJP_object_iterator* it); +RJP_tree_node* irjp_object_iterator_peek(RJP_object_iterator* it); RJP_tree_node* irjp_object_iterator_current(RJP_object_iterator* it); void irjp_dbg_print_tree(RJP_tree_node* root); diff --git a/src/input.c b/src/input.c index ed7f1e8..3afd846 100644 --- a/src/input.c +++ b/src/input.c @@ -37,7 +37,7 @@ typedef enum rjp_json_search_target{ rjp_json_target_none }json_search_target; -static RJP_value* irjp_add_value(RJP_value* curr, RJP_value new_val){ +static RJP_value* irjp_add_value(RJP_value* curr, RJP_value* lastadded, RJP_value new_val){ new_val.parent = curr; if(!curr){ curr = rjp_calloc(1, sizeof(RJP_value)); @@ -49,8 +49,8 @@ static RJP_value* irjp_add_value(RJP_value* curr, RJP_value new_val){ curr->array.last->value = new_val; return &curr->array.last->value; } - curr->object.last->value = new_val; - return &curr->object.last->value; + *lastadded = new_val; + return lastadded; } #define MAX_DEPTH 16 @@ -68,6 +68,7 @@ typedef struct RJP_numeral_state{ typedef struct RJP_parse_state{ RJP_value* root; RJP_value* curr; + RJP_value* lastadded; union{ RJP_string_state str_state; RJP_numeral_state num_state; @@ -133,7 +134,7 @@ int irjp_handle_key(const char* str, RJP_parse_state* state){ syntax_error("Cannot have empty key name!", state); return -1; } - irjp_add_member_no_alloc(&(state->curr->object), new_string, keylen); + state->lastadded = rjp_add_member_no_alloc(state->curr, new_string, keylen, (RJP_value){0}); *state->target = rjp_json_target_colon; return inclen+2; //end of this object (object is empty) @@ -194,11 +195,11 @@ int irjp_handle_value(const char* str, RJP_parse_state* state){ char c = *str; if(c == '{'){ if(!state->root){ - state->root = irjp_add_value(NULL, rjp_object()); + state->root = irjp_add_value(NULL, NULL, rjp_object()); state->curr = state->root; *state->target = rjp_json_target_key; }else{ - state->curr = irjp_add_value(state->curr, rjp_object()); + state->curr = irjp_add_value(state->curr, state->lastadded, rjp_object()); *state->target = rjp_json_target_comma; ++state->target; *state->target = rjp_json_target_key; @@ -207,11 +208,11 @@ int irjp_handle_value(const char* str, RJP_parse_state* state){ } else if(c == '['){ if(!state->root){ - state->root = irjp_add_value(NULL, rjp_array()); + state->root = irjp_add_value(NULL, NULL, rjp_array()); state->curr = state->root; }else{ - state->curr = irjp_add_value(state->curr, rjp_array()); + state->curr = irjp_add_value(state->curr, state->lastadded, rjp_array()); } return 1; } @@ -231,7 +232,7 @@ int irjp_handle_value(const char* str, RJP_parse_state* state){ return -1; } } - irjp_add_value(state->curr, rjp_string(new_string, vallen)); + irjp_add_value(state->curr, state->lastadded, rjp_string(new_string, vallen)); *state->target = rjp_json_target_comma; return inclen+2; } @@ -263,15 +264,15 @@ int irjp_handle_value(const char* str, RJP_parse_state* state){ } if(floating){ if(!state->root){ - state->root = state->curr = irjp_add_value(NULL, rjp_dfloat(strtod(str, NULL))); + state->root = state->curr = irjp_add_value(NULL, NULL, rjp_dfloat(strtod(str, NULL))); }else{ - irjp_add_value(state->curr, rjp_dfloat(strtod(str, NULL))); + irjp_add_value(state->curr, state->lastadded, rjp_dfloat(strtod(str, NULL))); } }else{ if(!state->root){ - state->root = state->curr = irjp_add_value(NULL, rjp_integer(strtoll(str, NULL, 10))); + state->root = state->curr = irjp_add_value(NULL, NULL, rjp_integer(strtoll(str, NULL, 10))); }else{ - irjp_add_value(state->curr, rjp_integer(strtoll(str, NULL, 10))); + irjp_add_value(state->curr, state->lastadded, rjp_integer(strtoll(str, NULL, 10))); } } state->column += numlen; @@ -281,30 +282,30 @@ int irjp_handle_value(const char* str, RJP_parse_state* state){ else if(!strncmp(str, "true", 4)){ if(!state->curr){ *state->target = rjp_json_target_none; - state->root = state->curr = irjp_add_value(state->curr, rjp_boolean(1)); + state->root = state->curr = irjp_add_value(state->curr, NULL, rjp_boolean(1)); }else{ *state->target = rjp_json_target_comma; - irjp_add_value(state->curr, rjp_boolean(1)); + irjp_add_value(state->curr, state->lastadded, rjp_boolean(1)); } state->column += 3; return 4; }else if(!strncmp(str, "false", 5)){ if(!state->curr){ *state->target = rjp_json_target_none; - state->root = state->curr = irjp_add_value(state->curr, rjp_boolean(0)); + state->root = state->curr = irjp_add_value(state->curr, NULL, rjp_boolean(0)); }else{ *state->target = rjp_json_target_comma; - irjp_add_value(state->curr, rjp_boolean(0)); + irjp_add_value(state->curr, state->lastadded, rjp_boolean(0)); } state->column += 4; return 5; }else if(!strncmp(str, "null", 4)){ if(!state->curr){ *state->target = rjp_json_target_none; - state->root = state->curr = irjp_add_value(state->curr, rjp_null()); + state->root = state->curr = irjp_add_value(state->curr, NULL, rjp_null()); }else{ *state->target = rjp_json_target_comma; - irjp_add_value(state->curr, rjp_null()); + irjp_add_value(state->curr, state->lastadded, rjp_null()); } state->column += 3; return 4; diff --git a/src/output.c b/src/output.c index 2aaa78c..e03f872 100644 --- a/src/output.c +++ b/src/output.c @@ -23,6 +23,7 @@ #include "rjp_internal.h" #include "memory.h" #include "strings.h" +#include "tree.h" #include //strlen #include //sprintf @@ -89,23 +90,25 @@ static size_t irjp_dump_array_pretty(const RJP_value* arr, char* dest, int depth } static size_t irjp_dump_object_pretty(const RJP_value* root, char* dest, int depth){ const RJP_object* root_obj = &root->object; - const RJP_object_member* member_list = root_obj->members; + RJP_object_iterator it; + irjp_init_object_iterator(&it, root_obj->root); size_t pos = 2; sprintf(dest, "{\n"); - for(;member_list;member_list = member_list->next){ + for(RJP_tree_node* n = irjp_object_iterator_current(&it);irjp_object_iterator_current(&it);n = irjp_object_iterator_next(&it)){ for(int i = 0;i < (depth+1);++i) pos += sprintf(dest+pos, "\t"); - pos += sprintf(dest+pos, "\"%s\": ", member_list->name.value); - pos += irjp_write_value_pretty(dest+pos, &member_list->value, depth+1); + pos += sprintf(dest+pos, "\"%s\": ", n->data.name.value); + pos += irjp_write_value_pretty(dest+pos, &n->data.value, depth+1); - if(member_list->next) + if(irjp_object_iterator_peek(&it)) pos += sprintf(dest+pos, ","); pos += sprintf(dest+pos, "\n"); } for(int i = 0;i < depth;++i) pos += sprintf(dest+pos, "\t"); pos += sprintf(dest+pos, "}"); + irjp_delete_object_iterator(&it); return pos; } static size_t irjp_write_value_pretty(char* dest, const RJP_value* val, int depth){ @@ -158,20 +161,22 @@ size_t rjp_dump_array(const RJP_value* arr, char* dest){ size_t rjp_dump_object(const RJP_value* root, char* dest){ const RJP_object* root_obj = &root->object; - const RJP_object_member* member_list = root_obj->members; + RJP_object_iterator it; + irjp_init_object_iterator(&it, root_obj->root); size_t pos = 1; sprintf(dest, "{"); - for(;member_list;member_list = member_list->next){ - pos += sprintf(dest+pos, "\"%s\":", member_list->name.value); - pos += irjp_write_value(dest+pos, &member_list->value); + for(RJP_tree_node* n = irjp_object_iterator_current(&it);irjp_object_iterator_current(&it);n = irjp_object_iterator_next(&it)){ + pos += sprintf(dest+pos, "\"%s\":", n->data.name.value); + pos += irjp_write_value(dest+pos, &n->data.value); - if(member_list->next) + if(irjp_object_iterator_peek(&it)) pos += sprintf(dest+pos, ","); else break; } pos += sprintf(dest+pos, "}"); + irjp_delete_object_iterator(&it); return pos; } diff --git a/src/rjp.c b/src/rjp.c index 5b2e456..f07798e 100644 --- a/src/rjp.c +++ b/src/rjp.c @@ -44,7 +44,9 @@ RJP_value* rjp_add_member(RJP_value* dest, const char* key, RJP_index keylen, RJ mem.value = value; int status; - return &(dest->object.root = irjp_tree_insert_value(dest->object.root, &mem, &status))->data.value; + RJP_value* retval; + dest->object.root = irjp_tree_insert_value(dest->object.root, &mem, &retval, &status); + return retval; } RJP_value* rjp_add_member_no_alloc(RJP_value* dest, char* key, RJP_index keylen, RJP_value value){ if(!keylen) @@ -55,7 +57,9 @@ RJP_value* rjp_add_member_no_alloc(RJP_value* dest, char* key, RJP_index keylen, mem.value = value; int status; - return &(dest->object.root = irjp_tree_insert_value(dest->object.root, &mem, &status))->data.value; + RJP_value* retval; + dest->object.root = irjp_tree_insert_value(dest->object.root, &mem, &retval, &status); + return retval; } RJP_value* rjp_remove_member_by_key(RJP_value* obj, const char* key){ int status; @@ -133,7 +137,7 @@ RJP_value rjp_array(void){ RJP_value* rjp_get_member(RJP_object_iterator* it){ - return &it->current->data.value; + return &irjp_object_iterator_current(it)->data.value; } RJP_object_iterator* rjp_get_object_iterator(const RJP_value* object){ RJP_object_iterator* it = rjp_alloc(sizeof(RJP_object_iterator)); @@ -152,6 +156,12 @@ RJP_value* rjp_object_iterator_next(RJP_object_iterator* it){ return NULL; return &n->data.value; } +RJP_value* rjp_object_iterator_peek(RJP_object_iterator* it){ + RJP_tree_node* n = irjp_object_iterator_peek(it); + if(!n) + return NULL; + return &n->data.value; +} void rjp_free_object_iterator(RJP_object_iterator* it){ irjp_delete_object_iterator(it); rjp_free(it); diff --git a/src/tree.c b/src/tree.c index 22d085d..0fcda3d 100644 --- a/src/tree.c +++ b/src/tree.c @@ -202,17 +202,19 @@ static RJP_tree_node* irjp_pop_tree_stack(RJP_tree_stack* stack){ static RJP_tree_node* irjp_peek_tree_stack(RJP_tree_stack* stack){ return (stack->pos > 0) ? (stack->data[stack->pos-1]) : NULL; } +static RJP_tree_node* irjp_double_peek_tree_stack(RJP_tree_stack* stack){ + return (stack->pos > 1) ? (stack->data[stack->pos-2]) : NULL; +} /* TREE ITERATOR */ //Iterator construction / destruction int irjp_init_object_iterator(RJP_object_iterator* it, const RJP_tree_node* root){ irjp_init_tree_stack(&it->stack); - it->current = (RJP_tree_node*)root; - while(it->current){ - irjp_push_tree_stack(&it->stack, it->current); - it->current = it->current->left; + RJP_tree_node* current = (RJP_tree_node*)root; + while(current){ + irjp_push_tree_stack(&it->stack, current); + current = current->left; } - it->current = irjp_peek_tree_stack(&it->stack); return 0; } void irjp_delete_object_iterator(RJP_object_iterator* it){ @@ -224,10 +226,16 @@ RJP_tree_node* irjp_object_iterator_next(RJP_object_iterator* it){ if(last->right){ irjp_push_tree_stack(&it->stack, last->right); } - return (it->current = irjp_peek_tree_stack(&it->stack)); + return irjp_object_iterator_current(it); +} +RJP_tree_node* irjp_object_iterator_peek(RJP_object_iterator* it){ + RJP_tree_node* n = irjp_peek_tree_stack(&it->stack)->right; + if(n) + return n; + return irjp_double_peek_tree_stack(&it->stack); } RJP_tree_node* irjp_object_iterator_current(RJP_object_iterator* it){ - return it->current; + return irjp_peek_tree_stack(&it->stack); } /* TREE */ @@ -243,13 +251,18 @@ void irjp_free_tree(RJP_tree_node* root){ irjp_free_node(root); } //Tree operations -RJP_tree_node* irjp_tree_insert_value(RJP_tree_node* root, RJP_object_member* value, int* status){ +RJP_tree_node* irjp_tree_insert_value(RJP_tree_node* root, RJP_object_member* value, RJP_value** added, int* status){ *status = RJP_TREE_SUCCESS; if(!root){ root = irjp_new_node(value); + if(added) + *added = &root->data.value; return root; } - return irjp_tree_insert_node(root, irjp_new_node(value)); + RJP_tree_node* newnode = irjp_new_node(value); + if(added) + *added = &newnode->data.value; + return irjp_tree_insert_node(root, newnode); } static RJP_tree_node* irjp_tree_insert_node(RJP_tree_node *restrict root, RJP_tree_node *restrict newnode){ irjp_tree_insert_impl(root, newnode);