Tree setup now working on all compilation units
This commit is contained in:
parent
0b4562a95a
commit
45ed17d6ca
@ -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);
|
||||
|
||||
@ -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);
|
||||
|
||||
39
src/input.c
39
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;
|
||||
|
||||
25
src/output.c
25
src/output.c
@ -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;
|
||||
}
|
||||
|
||||
|
||||
16
src/rjp.c
16
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);
|
||||
|
||||
31
src/tree.c
31
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);
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user