Tree setup now working on all compilation units

This commit is contained in:
rexy712 2020-01-17 14:22:15 -08:00
parent 0b4562a95a
commit 45ed17d6ca
6 changed files with 73 additions and 43 deletions

View File

@ -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_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_current(RJP_object_iterator* it);
RJP_value* rjp_object_iterator_next(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); void rjp_free_object_iterator(RJP_object_iterator* it);
//Return number of members in the object //Return number of members in the object
RJP_index rjp_num_members(const RJP_value* object); RJP_index rjp_num_members(const RJP_value* object);

View File

@ -46,12 +46,11 @@ typedef struct RJP_tree_stack{
}RJP_tree_stack; }RJP_tree_stack;
typedef struct RJP_object_iterator{ typedef struct RJP_object_iterator{
RJP_tree_stack stack; RJP_tree_stack stack;
RJP_tree_node* current;
}RJP_object_iterator; }RJP_object_iterator;
RJP_tree_node* irjp_new_node(RJP_object_member* value); 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_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_tree_search_value(RJP_tree_node* root, const char* key);
RJP_tree_node* irjp_copy_tree(const RJP_tree_node* root); 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); int irjp_init_object_iterator(RJP_object_iterator* it, const RJP_tree_node* root);
void irjp_delete_object_iterator(RJP_object_iterator* it); 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_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); RJP_tree_node* irjp_object_iterator_current(RJP_object_iterator* it);
void irjp_dbg_print_tree(RJP_tree_node* root); void irjp_dbg_print_tree(RJP_tree_node* root);

View File

@ -37,7 +37,7 @@ typedef enum rjp_json_search_target{
rjp_json_target_none rjp_json_target_none
}json_search_target; }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; new_val.parent = curr;
if(!curr){ if(!curr){
curr = rjp_calloc(1, sizeof(RJP_value)); 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; curr->array.last->value = new_val;
return &curr->array.last->value; return &curr->array.last->value;
} }
curr->object.last->value = new_val; *lastadded = new_val;
return &curr->object.last->value; return lastadded;
} }
#define MAX_DEPTH 16 #define MAX_DEPTH 16
@ -68,6 +68,7 @@ typedef struct RJP_numeral_state{
typedef struct RJP_parse_state{ typedef struct RJP_parse_state{
RJP_value* root; RJP_value* root;
RJP_value* curr; RJP_value* curr;
RJP_value* lastadded;
union{ union{
RJP_string_state str_state; RJP_string_state str_state;
RJP_numeral_state num_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); syntax_error("Cannot have empty key name!", state);
return -1; 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; *state->target = rjp_json_target_colon;
return inclen+2; return inclen+2;
//end of this object (object is empty) //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; char c = *str;
if(c == '{'){ if(c == '{'){
if(!state->root){ 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->curr = state->root;
*state->target = rjp_json_target_key; *state->target = rjp_json_target_key;
}else{ }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 = rjp_json_target_comma;
++state->target; ++state->target;
*state->target = rjp_json_target_key; *state->target = rjp_json_target_key;
@ -207,11 +208,11 @@ int irjp_handle_value(const char* str, RJP_parse_state* state){
} }
else if(c == '['){ else if(c == '['){
if(!state->root){ if(!state->root){
state->root = irjp_add_value(NULL, rjp_array()); state->root = irjp_add_value(NULL, NULL, rjp_array());
state->curr = state->root; state->curr = state->root;
}else{ }else{
state->curr = irjp_add_value(state->curr, rjp_array()); state->curr = irjp_add_value(state->curr, state->lastadded, rjp_array());
} }
return 1; return 1;
} }
@ -231,7 +232,7 @@ int irjp_handle_value(const char* str, RJP_parse_state* state){
return -1; 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; *state->target = rjp_json_target_comma;
return inclen+2; return inclen+2;
} }
@ -263,15 +264,15 @@ int irjp_handle_value(const char* str, RJP_parse_state* state){
} }
if(floating){ if(floating){
if(!state->root){ 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{ }else{
irjp_add_value(state->curr, rjp_dfloat(strtod(str, NULL))); irjp_add_value(state->curr, state->lastadded, rjp_dfloat(strtod(str, NULL)));
} }
}else{ }else{
if(!state->root){ 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{ }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; state->column += numlen;
@ -281,30 +282,30 @@ int irjp_handle_value(const char* str, RJP_parse_state* state){
else if(!strncmp(str, "true", 4)){ else if(!strncmp(str, "true", 4)){
if(!state->curr){ if(!state->curr){
*state->target = rjp_json_target_none; *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{ }else{
*state->target = rjp_json_target_comma; *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; state->column += 3;
return 4; return 4;
}else if(!strncmp(str, "false", 5)){ }else if(!strncmp(str, "false", 5)){
if(!state->curr){ if(!state->curr){
*state->target = rjp_json_target_none; *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{ }else{
*state->target = rjp_json_target_comma; *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; state->column += 4;
return 5; return 5;
}else if(!strncmp(str, "null", 4)){ }else if(!strncmp(str, "null", 4)){
if(!state->curr){ if(!state->curr){
*state->target = rjp_json_target_none; *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{ }else{
*state->target = rjp_json_target_comma; *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; state->column += 3;
return 4; return 4;

View File

@ -23,6 +23,7 @@
#include "rjp_internal.h" #include "rjp_internal.h"
#include "memory.h" #include "memory.h"
#include "strings.h" #include "strings.h"
#include "tree.h"
#include <string.h> //strlen #include <string.h> //strlen
#include <stdio.h> //sprintf #include <stdio.h> //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){ 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* 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; size_t pos = 2;
sprintf(dest, "{\n"); 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) for(int i = 0;i < (depth+1);++i)
pos += sprintf(dest+pos, "\t"); pos += sprintf(dest+pos, "\t");
pos += sprintf(dest+pos, "\"%s\": ", member_list->name.value); pos += sprintf(dest+pos, "\"%s\": ", n->data.name.value);
pos += irjp_write_value_pretty(dest+pos, &member_list->value, depth+1); 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, ",");
pos += sprintf(dest+pos, "\n"); pos += sprintf(dest+pos, "\n");
} }
for(int i = 0;i < depth;++i) for(int i = 0;i < depth;++i)
pos += sprintf(dest+pos, "\t"); pos += sprintf(dest+pos, "\t");
pos += sprintf(dest+pos, "}"); pos += sprintf(dest+pos, "}");
irjp_delete_object_iterator(&it);
return pos; return pos;
} }
static size_t irjp_write_value_pretty(char* dest, const RJP_value* val, int depth){ 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){ size_t rjp_dump_object(const RJP_value* root, char* dest){
const RJP_object* root_obj = &root->object; 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; size_t pos = 1;
sprintf(dest, "{"); sprintf(dest, "{");
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)){
pos += sprintf(dest+pos, "\"%s\":", member_list->name.value); pos += sprintf(dest+pos, "\"%s\":", n->data.name.value);
pos += irjp_write_value(dest+pos, &member_list->value); pos += irjp_write_value(dest+pos, &n->data.value);
if(member_list->next) if(irjp_object_iterator_peek(&it))
pos += sprintf(dest+pos, ","); pos += sprintf(dest+pos, ",");
else else
break; break;
} }
pos += sprintf(dest+pos, "}"); pos += sprintf(dest+pos, "}");
irjp_delete_object_iterator(&it);
return pos; return pos;
} }

View File

@ -44,7 +44,9 @@ RJP_value* rjp_add_member(RJP_value* dest, const char* key, RJP_index keylen, RJ
mem.value = value; mem.value = value;
int status; 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){ RJP_value* rjp_add_member_no_alloc(RJP_value* dest, char* key, RJP_index keylen, RJP_value value){
if(!keylen) if(!keylen)
@ -55,7 +57,9 @@ RJP_value* rjp_add_member_no_alloc(RJP_value* dest, char* key, RJP_index keylen,
mem.value = value; mem.value = value;
int status; 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){ RJP_value* rjp_remove_member_by_key(RJP_value* obj, const char* key){
int status; int status;
@ -133,7 +137,7 @@ RJP_value rjp_array(void){
RJP_value* rjp_get_member(RJP_object_iterator* it){ 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* rjp_get_object_iterator(const RJP_value* object){
RJP_object_iterator* it = rjp_alloc(sizeof(RJP_object_iterator)); 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 NULL;
return &n->data.value; 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){ void rjp_free_object_iterator(RJP_object_iterator* it){
irjp_delete_object_iterator(it); irjp_delete_object_iterator(it);
rjp_free(it); rjp_free(it);

View File

@ -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){ static RJP_tree_node* irjp_peek_tree_stack(RJP_tree_stack* stack){
return (stack->pos > 0) ? (stack->data[stack->pos-1]) : NULL; 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 */ /* TREE ITERATOR */
//Iterator construction / destruction //Iterator construction / destruction
int irjp_init_object_iterator(RJP_object_iterator* it, const RJP_tree_node* root){ int irjp_init_object_iterator(RJP_object_iterator* it, const RJP_tree_node* root){
irjp_init_tree_stack(&it->stack); irjp_init_tree_stack(&it->stack);
it->current = (RJP_tree_node*)root; RJP_tree_node* current = (RJP_tree_node*)root;
while(it->current){ while(current){
irjp_push_tree_stack(&it->stack, it->current); irjp_push_tree_stack(&it->stack, current);
it->current = it->current->left; current = current->left;
} }
it->current = irjp_peek_tree_stack(&it->stack);
return 0; return 0;
} }
void irjp_delete_object_iterator(RJP_object_iterator* it){ 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){ if(last->right){
irjp_push_tree_stack(&it->stack, 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){ RJP_tree_node* irjp_object_iterator_current(RJP_object_iterator* it){
return it->current; return irjp_peek_tree_stack(&it->stack);
} }
/* TREE */ /* TREE */
@ -243,13 +251,18 @@ void irjp_free_tree(RJP_tree_node* root){
irjp_free_node(root); irjp_free_node(root);
} }
//Tree operations //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; *status = RJP_TREE_SUCCESS;
if(!root){ if(!root){
root = irjp_new_node(value); root = irjp_new_node(value);
if(added)
*added = &root->data.value;
return root; 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){ static RJP_tree_node* irjp_tree_insert_node(RJP_tree_node *restrict root, RJP_tree_node *restrict newnode){
irjp_tree_insert_impl(root, newnode); irjp_tree_insert_impl(root, newnode);