node *alias_target(const node *alias) { PRECOND_NONNULL_ELSE_NULL(alias); PRECOND_ELSE_NULL(ALIAS == node_kind(alias)); return alias->content.target; }
node *document_root(const node *document) { PRECOND_NONNULL_ELSE_NULL(document); PRECOND_ELSE_NULL(DOCUMENT == node_kind(document)); return document->content.target; }
uint8_t *scalar_value(const node *scalar) { PRECOND_NONNULL_ELSE_NULL(scalar); PRECOND_ELSE_NULL(SCALAR == node_kind(scalar)); return scalar->content.scalar.value; }
node *sequence_get(const node *sequence, size_t index) { PRECOND_NONNULL_ELSE_NULL(sequence); PRECOND_ELSE_NULL(SEQUENCE == node_kind(sequence)); PRECOND_ELSE_NULL(index < node_size(sequence)); return vector_get(sequence->content.sequence, index); }
bool mapping_contains(const node *mapping, uint8_t *scalar, size_t length) { PRECOND_NONNULL_ELSE_FALSE(mapping, scalar); PRECOND_ELSE_FALSE(MAPPING == node_kind(mapping), 0 < length); node *key = make_scalar_node(scalar, length, SCALAR_STRING); bool result = hashtable_contains(mapping->content.mapping, key); node_free(key); return result; }
bool sequence_iterate(const node *sequence, sequence_iterator iterator, void *context) { PRECOND_NONNULL_ELSE_FALSE(sequence, iterator); PRECOND_ELSE_FALSE(SEQUENCE == node_kind(sequence)); context_adapter adapter = {.iterator.sequence=iterator, .context=context }; return vector_iterate(sequence->content.sequence, sequence_iterator_adpater, &adapter); } node *mapping_get(const node *mapping, uint8_t *scalar, size_t length) { PRECOND_NONNULL_ELSE_NULL(mapping, scalar); PRECOND_ELSE_NULL(MAPPING == node_kind(mapping)); PRECOND_ELSE_NULL(0 < length); node *key = make_scalar_node(scalar, length, SCALAR_STRING); node *result = hashtable_get(mapping->content.mapping, key); node_free(key); return result; }
/* %F Calls the user callback associated with the event of closing a folder %i h : tree's handle. %o returns IUP_DEFAULT to close the branch or not defined IUP_IGNORE to keep the branch opened */ int treecallBranchCloseCb(Ihandle* h, Node n) { IFni cb = (IFni)IupGetCallback(h,IUP_BRANCHCLOSE_CB); if (cb && node_kind(n) == BRANCH && node_state(n) == EXPANDED) { int id = treefindNodeId(h, n); return cb(h,id); } return IUP_DEFAULT; }
/* %F Calls the user callback associated with the event of opening a folder %i h : tree's handle. %o returns IUP_DEFAULT to open the branch or not defined IUP_IGNORE to keep the branch closed */ int treecallBranchOpenCb(Ihandle* h, Node n ) { IFni cb = (IFni)IupGetCallback(h,IUP_BRANCHOPEN_CB); if (cb && node_kind(n) == BRANCH && node_state(n) == COLLAPSED) { int id = treefindNodeId(h, n); return cb(h,id); } return IUP_DEFAULT; }
bool emit_node(node *each, void *argument) { emit_context *context = (emit_context *)argument; bool result = true; switch(node_kind(each)) { case DOCUMENT: log_trace("shell", "emitting document"); result = emit_node(document_root(each), NULL); break; case SCALAR: result = emit_scalar(each); EMIT("\n"); break; case SEQUENCE: log_trace("shell", "emitting seqence"); MAYBE_EMIT("("); result = sequence_iterate(each, emit_sequence_item, NULL); MAYBE_EMIT(")"); EMIT("\n"); break; case MAPPING: log_trace("shell", "emitting mapping"); MAYBE_EMIT("("); result = mapping_iterate(each, context->emit_mapping_item, NULL); MAYBE_EMIT(")"); EMIT("\n"); break; case ALIAS: log_trace("shell", "resolving alias"); result = emit_node(alias_target(each), NULL); break; } fflush(stdout); return result; }
/* * Compute the truth table for bit x * - if x is known, we take it from tt * - otherwise, we use the dat */ static uint32_t dag_truth_table(bit_t x) { node_t v; uint32_t left, right, aux; if (fresh_bit(x)) { v = node_of_bit(x); switch (node_kind(&dag, v)) { case OR_NODE: left = dag_truth_table(left_child_of_node(&dag, v)); right = dag_truth_table(right_child_of_node(&dag, v)); aux = left | right; break; case XOR_NODE: left = dag_truth_table(left_child_of_node(&dag, v)); right = dag_truth_table(right_child_of_node(&dag, v)); aux = left ^ right; break; case UNUSED_NODE: case CONSTANT_NODE: case VARIABLE_NODE: default: printf("*** BUG: invalid node in DAG ***\n"); fflush(stdout); abort(); } if (bit_is_neg(x)) { aux = ~aux; } return aux; } else { return tt[x]; } }
static bool emit_node(node *each, void *context) { bool result = true; switch(node_kind(each)) { case DOCUMENT: result = emit_document(each, context); break; case SCALAR: result = emit_scalar(each, context); break; case SEQUENCE: result = emit_sequence(each, context); break; case MAPPING: result = emit_mapping(each, context); break; case ALIAS: result = emit_node(alias_target(each), context); break; } return result; }
bool mapping_iterate(const node *mapping, mapping_iterator iterator, void *context) { PRECOND_NONNULL_ELSE_FALSE(mapping, iterator); PRECOND_ELSE_FALSE(MAPPING == node_kind(mapping)); context_adapter adapter = {.iterator.mapping=iterator, .context=context}; return hashtable_iterate(mapping->content.mapping, mapping_iterator_adpater, &adapter); } bool node_equals(const node *one, const node *two) { if(one == two) { return true; } if((NULL == one && NULL != two) || (NULL != one && NULL == two)) { return false; } bool result = node_kind(one) == node_kind(two) && tag_equals(node_name(one), node_name(two)) && node_size(one) == node_size(two); if(!result) { return result; } switch(node_kind(one)) { case DOCUMENT: result &= node_equals(document_root(one), document_root(two)); break; case SCALAR: result &= scalar_equals(one, two); break; case SEQUENCE: result &= sequence_equals(one, two); break; case MAPPING: result &= mapping_equals(one, two); break; case ALIAS: result &= node_equals(alias_target(one), alias_target(two)); break; } return result; } static bool scalar_equals(const node *one, const node *two) { size_t n1 = node_size(one); size_t n2 = node_size(two); if(n1 != n2) { return false; } return memcmp(scalar_value(one), scalar_value(two), n1) == 0; }