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_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);

View File

@ -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);

View File

@ -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;

View File

@ -23,6 +23,7 @@
#include "rjp_internal.h"
#include "memory.h"
#include "strings.h"
#include "tree.h"
#include <string.h> //strlen
#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){
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;
}

View File

@ -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);

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){
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);