static void test_show_object_compound_compact(void) { JsonElement *json = JsonObjectCreate(10); JsonObjectAppendString(json, "first", "one"); { JsonElement *inner = JsonObjectCreate(10); JsonObjectAppendString(inner, "third", "three"); JsonObjectAppendObject(json, "second", inner); } { JsonElement *inner = JsonObjectCreate(10); JsonObjectAppendString(inner, "fifth", "five"); JsonObjectAppendObject(json, "fourth", inner); } Writer *writer = StringWriter(); JsonWriteCompact(writer, json); char *output = StringWriterClose(writer); assert_string_equal("{\"first\":\"one\",\"second\":{\"third\":\"three\"},\"fourth\":{\"fifth\":\"five\"}}", output); JsonDestroy(json); free(output); }
static void test_show_object_compound(void **state) { JsonElement *json = JsonObjectCreate(10); JsonObjectAppendString(json, "first", "one"); { JsonElement *inner = JsonObjectCreate(10); JsonObjectAppendString(inner, "third", "three"); JsonObjectAppendObject(json, "second", inner); } { JsonElement *inner = JsonObjectCreate(10); JsonObjectAppendString(inner, "fifth", "five"); JsonObjectAppendObject(json, "fourth", inner); } Writer *writer = StringWriter(); JsonElementPrint(writer, json, 0); assert_string_equal(OBJECT_COMPOUND, StringWriterData(writer)); JsonElementDestroy(json); }
static void test_show_object_compound(void) { JsonElement *json = JsonObjectCreate(10); JsonObjectAppendString(json, "first", "one"); { JsonElement *inner = JsonObjectCreate(10); JsonObjectAppendString(inner, "third", "three"); JsonObjectAppendObject(json, "second", inner); } { JsonElement *inner = JsonObjectCreate(10); JsonObjectAppendString(inner, "fifth", "five"); JsonObjectAppendObject(json, "fourth", inner); } Writer *writer = StringWriter(); JsonWrite(writer, json, 0); char *output = StringWriterClose(writer); assert_string_equal(OBJECT_COMPOUND, output); JsonDestroy(json); free(output); }
static JsonElement *ExportAttributesSyntaxAsJson(const ConstraintSyntax attributes[]) { JsonElement *json = JsonObjectCreate(10); int i = 0; if (attributes == NULL) { return json; } for (i = 0; attributes[i].lval != NULL; i++) { if (attributes[i].range.validation_string == CF_BUNDLE) { /* TODO: must handle edit_line somehow */ continue; } else if (attributes[i].dtype == DATA_TYPE_BODY) { JsonElement *json_attributes = ExportAttributesSyntaxAsJson(attributes[i].range.body_type_syntax->constraints); JsonObjectAppendObject(json, attributes[i].lval, json_attributes); } else { JsonElement *attribute = JsonObjectCreate(10); JsonObjectAppendString(attribute, "datatype", CF_DATATYPES[attributes[i].dtype]); if (strlen(attributes[i].range.validation_string) == 0) { JsonObjectAppendString(attribute, "pcre-range", ".*"); } else if (attributes[i].dtype == DATA_TYPE_OPTION || attributes[i].dtype == DATA_TYPE_OPTION_LIST) { JsonElement *options = JsonArrayCreate(10); char options_buffer[CF_BUFSIZE]; char *option = NULL; strcpy(options_buffer, attributes[i].range.validation_string); for (option = strtok(options_buffer, ","); option != NULL; option = strtok(NULL, ",")) { JsonArrayAppendString(options, option); } JsonObjectAppendArray(attribute, "pcre-range", options); } else { char *pcre_range = PCREStringToJsonString(attributes[i].range.validation_string); JsonObjectAppendString(attribute, "pcre-range", pcre_range); } JsonObjectAppendObject(json, attributes[i].lval, attribute); } } return json; }
void SyntaxPrintAsJson(Writer *writer) { JsonElement *syntax_tree = JsonObjectCreate(10); { JsonElement *control_bodies = ExportControlBodiesSyntaxAsJson(); JsonObjectAppendObject(syntax_tree, "control-bodies", control_bodies); } { JsonElement *bundle_types = JsonObjectCreate(10); int i = 0; for (i = 0; CONTROL_BODIES[i].body_type != NULL; i++) { JsonElement *bundle_type = ExportBundleTypeSyntaxAsJson(CONTROL_BODIES[i].body_type); JsonObjectAppendObject(bundle_types, CONTROL_BODIES[i].body_type, bundle_type); } JsonObjectAppendObject(syntax_tree, "bundle-types", bundle_types); } JsonElementPrint(writer, syntax_tree, 0); JsonElementDestroy(syntax_tree); }
JsonElement *SyntaxToJson(void) { JsonElement *syntax_tree = JsonObjectCreate(3); JsonObjectAppendObject(syntax_tree, "bundleTypes", BundleTypesToJson()); JsonObjectAppendObject(syntax_tree, "promiseTypes", PromiseTypesToJson()); JsonObjectAppendObject(syntax_tree, "bodyTypes", BodyTypesToJson()); JsonObjectAppendObject(syntax_tree, "functions", FunctionsToJson()); return syntax_tree; }
static JsonElement *BodyTypesToJson(void) { JsonElement *body_types = JsonObjectCreate(50); for (int module_index = 0; module_index < CF3_MODULES; module_index++) { for (int promise_type_index = 0; CF_ALL_PROMISE_TYPES[module_index][promise_type_index].promise_type; promise_type_index++) { const PromiseTypeSyntax *promise_type_syntax = &CF_ALL_PROMISE_TYPES[module_index][promise_type_index]; for (int constraint_index = 0; promise_type_syntax->constraints[constraint_index].lval; constraint_index++) { const ConstraintSyntax *constraint_syntax = &promise_type_syntax->constraints[constraint_index]; if (constraint_syntax->dtype != CF_DATA_TYPE_BODY) { continue; } if (constraint_syntax->status == SYNTAX_STATUS_REMOVED) { continue; } const BodySyntax *body_syntax = constraint_syntax->range.body_type_syntax; JsonElement *body_type = JsonObjectGet(body_types, body_syntax->body_type); if (!body_type) { JsonElement *body_type = BodySyntaxToJson(body_syntax); JsonObjectAppendObject(body_types, body_syntax->body_type, body_type); } } } } for (int i = 0; CONTROL_BODIES[i].body_type; i++) { const BodySyntax *body_syntax = &CONTROL_BODIES[i]; if (body_syntax->status == SYNTAX_STATUS_REMOVED) { continue; } JsonElement *body_type = JsonObjectGet(body_types, body_syntax->body_type); if (!body_type) { JsonElement *body_type = BodySyntaxToJson(body_syntax); JsonObjectAppendObject(body_types, body_syntax->body_type, body_type); } } return body_types; }
static JsonElement *ExportBundleClassesAsJson(Promise *promises) { JsonElement *json_contexts = JsonArrayCreate(10); JsonElement *json_promises = JsonArrayCreate(10); char *current_context = "any"; size_t context_offset_start = -1; size_t context_offset_end = -1; Promise *pp = NULL; for (pp = promises; pp != NULL; pp = pp->next) { JsonElement *json_promise = JsonObjectCreate(10); JsonObjectAppendInteger(json_promise, "offset", pp->offset.start); { JsonElement *json_promise_attributes = JsonArrayCreate(10); Constraint *cp = NULL; for (cp = pp->conlist; cp != NULL; cp = cp->next) { JsonElement *json_attribute = JsonObjectCreate(10); JsonObjectAppendInteger(json_attribute, "offset", cp->offset.start); JsonObjectAppendInteger(json_attribute, "offset-end", cp->offset.end); context_offset_end = cp->offset.end; JsonObjectAppendString(json_attribute, "lval", cp->lval); JsonObjectAppendObject(json_attribute, "rval", ExportAttributeValueAsJson(cp->rval)); JsonArrayAppendObject(json_promise_attributes, json_attribute); } JsonObjectAppendInteger(json_promise, "offset-end", context_offset_end); JsonObjectAppendString(json_promise, "promiser", pp->promiser); /* FIXME: does not work for lists */ if (pp->promisee.rtype == CF_SCALAR || pp->promisee.rtype == CF_NOPROMISEE) { JsonObjectAppendString(json_promise, "promisee", pp->promisee.item); } JsonObjectAppendArray(json_promise, "attributes", json_promise_attributes); } JsonArrayAppendObject(json_promises, json_promise); if (pp->next == NULL || strcmp(current_context, pp->next->classes) != 0) { JsonArrayAppendObject(json_contexts, CreateContextAsJson(current_context, context_offset_start, context_offset_end, "promises", json_promises)); current_context = pp->classes; } } return json_contexts; }
static JsonElement *JsonPromiseTypeNew(SyntaxStatus status) { JsonElement *promise_type = JsonObjectCreate(2); JsonObjectAppendString(promise_type, "status", SyntaxStatusToString(status)); JsonObjectAppendObject(promise_type, "attributes", JsonObjectCreate(50)); return promise_type; }
static JsonElement *DefaultTemplateData(const EvalContext *ctx) { JsonElement *hash = JsonObjectCreate(10); { ClassTableIterator *it = EvalContextClassTableIteratorNewGlobal(ctx, NULL, true, true); Class *cls = NULL; while ((cls = ClassTableIteratorNext(it))) { char *key = ClassRefToString(cls->ns, cls->name); JsonObjectAppendBool(hash, key, true); free(key); } ClassTableIteratorDestroy(it); } { ClassTableIterator *it = EvalContextClassTableIteratorNewLocal(ctx); Class *cls = NULL; while ((cls = ClassTableIteratorNext(it))) { char *key = ClassRefToString(cls->ns, cls->name); JsonObjectAppendBool(hash, key, true); free(key); } ClassTableIteratorDestroy(it); } { VariableTableIterator *it = EvalContextVariableTableIteratorNew(ctx, NULL, NULL, NULL); Variable *var = NULL; while ((var = VariableTableIteratorNext(it))) { // TODO: need to get a CallRef, this is bad char *scope_key = ClassRefToString(var->ref->ns, var->ref->scope); JsonElement *scope_obj = JsonObjectGetAsObject(hash, scope_key); if (!scope_obj) { scope_obj = JsonObjectCreate(50); JsonObjectAppendObject(hash, scope_key, scope_obj); } free(scope_key); char *lval_key = VarRefToString(var->ref, false); JsonObjectAppendElement(scope_obj, lval_key, RvalToJson(var->rval)); free(lval_key); } VariableTableIteratorDestroy(it); } return hash; }
static JsonElement *ExportControlBodiesSyntaxAsJson() { JsonElement *control_bodies = JsonObjectCreate(10); int i = 0; for (i = 0; CONTROL_BODIES[i].body_type != NULL; i++) { JsonElement *attributes = ExportAttributesSyntaxAsJson(CONTROL_BODIES[i].constraints); JsonObjectAppendObject(control_bodies, CONTROL_BODIES[i].body_type, attributes); } return control_bodies; }
static JsonElement *BodySyntaxToJson(const BodySyntax *body_syntax) { JsonElement *json_body = JsonObjectCreate(2); JsonObjectAppendString(json_body, "status", SyntaxStatusToString(body_syntax->status)); { JsonElement *attributes = JsonObjectCreate(50); for (int i = 0; body_syntax->constraints[i].lval; i++) { const ConstraintSyntax *constraint_syntax = &body_syntax->constraints[i]; if (constraint_syntax->status != SYNTAX_STATUS_REMOVED) { JsonElement *json_constraint = ConstraintSyntaxToJson(constraint_syntax); JsonObjectAppendString(json_constraint, "visibility", "body"); JsonObjectAppendObject(attributes, constraint_syntax->lval, json_constraint); } } JsonObjectAppendObject(json_body, "attributes", attributes); } return json_body; }
static JsonElement *FunctionsToJson(void) { JsonElement *functions = JsonObjectCreate(500); for (int i = 0; CF_FNCALL_TYPES[i].name; i++) { const FnCallType *fn_syntax = &CF_FNCALL_TYPES[i]; if (fn_syntax->status == SYNTAX_STATUS_REMOVED) { continue; } JsonObjectAppendObject(functions, fn_syntax->name, FnCallTypeToJson(fn_syntax)); } return functions; }
static JsonElement *ExportBundleTypeSyntaxAsJson(const char *bundle_type) { JsonElement *json = JsonObjectCreate(10); const PromiseTypeSyntax *st; int i = 0, j = 0; for (i = 0; i < CF3_MODULES; i++) { st = CF_ALL_PROMISE_TYPES[i]; for (j = 0; st[j].bundle_type != NULL; j++) { if (strcmp(bundle_type, st[j].bundle_type) == 0 || strcmp("*", st[j].bundle_type) == 0) { JsonElement *attributes = ExportAttributesSyntaxAsJson(st[j].constraints); JsonObjectAppendObject(json, st[j].promise_type, attributes); } } } return json; }
static JsonElement *ExportBodyClassesAsJson(Constraint *constraints) { JsonElement *json_contexts = JsonArrayCreate(10); JsonElement *json_attributes = JsonArrayCreate(10); char *current_context = "any"; size_t context_offset_start = -1; size_t context_offset_end = -1; Constraint *cp = NULL; for (cp = constraints; cp != NULL; cp = cp->next) { JsonElement *json_attribute = JsonObjectCreate(10); JsonObjectAppendInteger(json_attribute, "offset", cp->offset.start); JsonObjectAppendInteger(json_attribute, "offset-end", cp->offset.end); context_offset_start = cp->offset.context; context_offset_end = cp->offset.end; JsonObjectAppendString(json_attribute, "lval", cp->lval); JsonObjectAppendObject(json_attribute, "rval", ExportAttributeValueAsJson(cp->rval)); JsonArrayAppendObject(json_attributes, json_attribute); if (cp->next == NULL || strcmp(current_context, cp->next->classes) != 0) { JsonArrayAppendObject(json_contexts, CreateContextAsJson(current_context, context_offset_start, context_offset_end, "attributes", json_attributes)); current_context = cp->classes; } } return json_contexts; }
static JsonElement *PromiseTypesToJson(void) { JsonElement *promise_types = JsonObjectCreate(50); const PromiseTypeSyntax *global_promise_type = PromiseTypeSyntaxGet("*", "*"); for (int module_index = 0; module_index < CF3_MODULES; module_index++) { for (int promise_type_index = 0; CF_ALL_PROMISE_TYPES[module_index][promise_type_index].promise_type; promise_type_index++) { const PromiseTypeSyntax *promise_type_syntax = &CF_ALL_PROMISE_TYPES[module_index][promise_type_index]; // skip global and bundle-local common constraints if (strcmp("*", promise_type_syntax->promise_type) == 0) { continue; } if (promise_type_syntax->status == SYNTAX_STATUS_REMOVED) { continue; } JsonElement *promise_type = JsonObjectGet(promise_types, promise_type_syntax->promise_type); if (!promise_type) { promise_type = JsonPromiseTypeNew(promise_type_syntax->status); JsonObjectAppendObject(promise_types, promise_type_syntax->promise_type, promise_type); } assert(promise_type); JsonElement *attributes = JsonObjectGet(promise_type, "attributes"); assert(attributes); for (int i = 0; promise_type_syntax->constraints[i].lval; i++) { const ConstraintSyntax *constraint_syntax = &promise_type_syntax->constraints[i]; JsonElement *json_constraint = ConstraintSyntaxToJson(constraint_syntax); JsonObjectAppendString(json_constraint, "visibility", "promiseType"); JsonObjectAppendObject(attributes, constraint_syntax->lval, json_constraint); } // append bundle common constraints const PromiseTypeSyntax *bundle_promise_type = PromiseTypeSyntaxGet(promise_type_syntax->bundle_type, "*"); if (strcmp("*", bundle_promise_type->bundle_type) != 0) { for (int i = 0; bundle_promise_type->constraints[i].lval; i++) { const ConstraintSyntax *constraint_syntax = &bundle_promise_type->constraints[i]; JsonElement *json_constraint = ConstraintSyntaxToJson(constraint_syntax); JsonObjectAppendString(json_constraint, "visibility", "bundle"); JsonObjectAppendObject(attributes, constraint_syntax->lval, json_constraint); } } // append global common constraints for (int i = 0; global_promise_type->constraints[i].lval; i++) { const ConstraintSyntax *constraint_syntax = &global_promise_type->constraints[i]; JsonElement *json_constraint = ConstraintSyntaxToJson(constraint_syntax); JsonObjectAppendString(json_constraint, "visibility", "global"); JsonObjectAppendObject(attributes, constraint_syntax->lval, json_constraint); } } } return promise_types; }
static JsonElement *BundleTypesToJson(void) { JsonElement *bundle_types = JsonObjectCreate(50); Seq *common_promise_types = SeqNew(50, free); for (int module_index = 0; module_index < CF3_MODULES; module_index++) { for (int promise_type_index = 0; CF_ALL_PROMISE_TYPES[module_index][promise_type_index].promise_type; promise_type_index++) { const PromiseTypeSyntax *promise_type_syntax = &CF_ALL_PROMISE_TYPES[module_index][promise_type_index]; // skip global constraints if (strcmp("*", promise_type_syntax->promise_type) == 0) { continue; } // collect common promise types to be appended at the end if (strcmp("*", promise_type_syntax->bundle_type) == 0) { SeqAppend(common_promise_types, xstrdup(promise_type_syntax->promise_type)); continue; } if (promise_type_syntax->status == SYNTAX_STATUS_REMOVED) { continue; } JsonElement *bundle_type = JsonObjectGet(bundle_types, promise_type_syntax->bundle_type); if (!bundle_type) { bundle_type = JsonBundleTypeNew(); JsonObjectAppendObject(bundle_types, promise_type_syntax->bundle_type, bundle_type); } assert(bundle_type); JsonElement *promise_types = JsonObjectGet(bundle_type, "promiseTypes"); assert(promise_types); JsonArrayAppendString(promise_types, promise_type_syntax->promise_type); } } // Append the common bundle, which has only common promise types, but is not declared in syntax { JsonElement *bundle_type = JsonBundleTypeNew(); JsonObjectAppendObject(bundle_types, "common", bundle_type); } JsonIterator it = JsonIteratorInit(bundle_types); const char *bundle_type = NULL; while ((bundle_type = JsonIteratorNextKey(&it))) { JsonElement *promise_types = JsonObjectGetAsArray(JsonObjectGetAsObject(bundle_types, bundle_type), "promiseTypes"); for (int i = 0; i < SeqLength(common_promise_types); i++) { const char *common_promise_type = SeqAt(common_promise_types, i); JsonArrayAppendString(promise_types, common_promise_type); } } SeqDestroy(common_promise_types); return bundle_types; }