struct jx * jx_eval( struct jx *j, struct jx *context ) { if(!j) return 0; switch(j->type) { case JX_SYMBOL: if(context) { struct jx *result = jx_lookup(context,j->u.symbol_name); if(result) return jx_copy(result); } return jx_null(); case JX_DOUBLE: case JX_BOOLEAN: case JX_INTEGER: case JX_STRING: case JX_NULL: return jx_copy(j); case JX_ARRAY: return jx_array(jx_eval_item(j->u.items,context)); case JX_OBJECT: return jx_object(jx_eval_pair(j->u.pairs,context)); case JX_OPERATOR: return jx_eval_operator(&j->u.oper,context); } /* not reachable, but some compilers complain. */ return 0; }
struct jx *jx_copy( struct jx *j ) { if(!j) return 0; switch(j->type) { case JX_NULL: return jx_null(); case JX_DOUBLE: return jx_double(j->u.double_value); case JX_BOOLEAN: return jx_boolean(j->u.boolean_value); case JX_INTEGER: return jx_integer(j->u.integer_value); case JX_SYMBOL: return jx_symbol(j->u.symbol_name); case JX_STRING: return jx_string(j->u.string_value); case JX_ARRAY: return jx_array(jx_item_copy(j->u.items)); case JX_OBJECT: return jx_object(jx_pair_copy(j->u.pairs)); case JX_OPERATOR: return jx_operator(j->u.oper.type,jx_copy(j->u.oper.left),jx_copy(j->u.oper.right)); case JX_FUNCTION: return jx_function(j->u.func.function, jx_copy(j->u.func.arguments)); case JX_ERROR: return jx_error(jx_copy(j->u.err)); } /* not reachable, but some compilers complain. */ return 0; }
static struct jx * jx_eval_lookup( struct jx *left, struct jx *right ) { if(left->type==JX_OBJECT && right->type==JX_STRING) { struct jx *r = jx_lookup(left,right->u.string_value); if(r) { return jx_copy(r); } else { return jx_null(); } } else if(left->type==JX_ARRAY && right->type==JX_INTEGER) { struct jx_item *item = left->u.items; int count = right->u.integer_value; if(count<0) return jx_null(); while(count>0) { if(!item) return jx_null(); item = item->next; count--; } if(item) { return jx_copy(item->value); } else { return jx_null(); } } else { return jx_null(); } }
struct jx_pair * jx_pair_copy( struct jx_pair *p ) { if(!p) return 0; struct jx_pair *pair = malloc(sizeof(*pair)); pair->key = jx_copy(p->key); pair->value = jx_copy(p->value); pair->next = jx_pair_copy(p->next); return pair; }
struct jx *jx_merge(struct jx *j, ...) { va_list ap; va_start (ap, j); struct jx *result = jx_object(NULL); for (struct jx *next = j; jx_istype(next, JX_OBJECT); next = va_arg(ap, struct jx *)) { for (struct jx_pair *p = next->u.pairs; p; p = p->next) { jx_delete(jx_remove(result, p->key)); jx_insert(result, jx_copy(p->key), jx_copy(p->value)); } } va_end(ap); return result; }
struct jx *catalog_query_read(struct catalog_query *q, time_t stoptime) { while(q && q->current) { int keepit = 1; if(q->filter_expr) { struct jx * b; b = jx_eval(q->filter_expr,q->current->value); if(jx_istype(b, JX_BOOLEAN) && b->u.boolean_value) { keepit = 1; } else { keepit = 0; } jx_delete(b); } else { keepit = 1; } if(keepit) { struct jx *result = jx_copy(q->current->value); q->current = q->current->next; return result; } q->current = q->current->next; } return 0; }
struct jx_item * jx_item_copy( struct jx_item *i ) { if(!i) return 0; struct jx_item *item = malloc(sizeof(*item)); item->value = jx_copy(i->value); item->next = jx_item_copy(i->next); return item; }
void rmsummary_print(FILE *stream, struct rmsummary *s, struct jx *verbatim_fields) { struct jx *jsum = rmsummary_to_json(s, 0); if(verbatim_fields) { if(!jx_istype(verbatim_fields, JX_OBJECT)) { fatal("Vebatim fields are not a json object."); } struct jx_pair *head = verbatim_fields->u.pairs; while(head) { jx_insert(jsum, jx_copy(head->key), jx_copy(head->value)); head = head->next; } } jx_pretty_print_stream(jsum, stream); jx_delete(jsum); }
/** Sets the envlist of batch_task. Uses jx_copy to create a deep copy. */ void batch_task_set_envlist(struct batch_task *t, struct jx *envlist) { jx_delete(t->envlist); t->envlist = jx_copy(envlist); }