static void S_run_tests(CFCTest *test) { CFCParser *parser = CFCParser_new(); { CFCCBlock *block = CFCCBlock_new("int foo;"); STR_EQ(test, CFCCBlock_get_contents(block), "int foo;", "get_contents"); CFCBase_decref((CFCBase*)block); } { const char *cblock_string = " __C__\n" "#define FOO_BAR 1\n" "__END_C__ "; CFCBase *result = CFCParser_parse(parser, cblock_string); OK(test, result != NULL, "parse cblock"); STR_EQ(test, CFCBase_get_cfc_class(result), "Clownfish::CFC::Model::CBlock", "result class of cblock"); CFCCBlock *block = (CFCCBlock*)result; STR_EQ(test, CFCCBlock_get_contents(block), "#define FOO_BAR 1\n", "parse embed_c"); CFCBase_decref((CFCBase*)block); } CFCBase_decref((CFCBase*)parser); }
static void S_run_void_tests(CFCTest *test) { CFCParser *parser = CFCParser_new(); { CFCType *type = CFCType_new_void(false); STR_EQ(test, CFCType_get_specifier(type), "void", "get_specifier"); STR_EQ(test, CFCType_to_c(type), "void", "to_c"); OK(test, CFCType_is_void(type), "is_void"); CFCBase_decref((CFCBase*)type); } { CFCType *type = CFCType_new_void(true); STR_EQ(test, CFCType_to_c(type), "const void", "'const' in C representation"); CFCBase_decref((CFCBase*)type); } { CFCType *type = CFCTest_parse_type(test, parser, "void"); OK(test, CFCType_is_void(type), "void is_void"); CFCBase_decref((CFCBase*)type); } { CFCType *type = CFCTest_parse_type(test, parser, "const void"); OK(test, CFCType_is_void(type), "const void is_void"); OK(test, CFCType_const(type), "const void is const"); CFCBase_decref((CFCBase*)type); } CFCBase_decref((CFCBase*)parser); }
static void S_run_primitive_tests(CFCTest *test) { CFCParcel *parcel = CFCParcel_new("Parcel", NULL, NULL, NULL); CFCType *type = CFCType_new(CFCTYPE_PRIMITIVE, parcel, "hump_t", 0); OK(test, CFCType_is_primitive(type), "is_primitive"); { CFCType *twin = CFCType_new(CFCTYPE_PRIMITIVE, parcel, "hump_t", 0); OK(test, CFCType_equals(type, twin), "equals"); CFCBase_decref((CFCBase*)twin); } { CFCType *other = CFCType_new(CFCTYPE_PRIMITIVE, parcel, "dump_t", 0); OK(test, !CFCType_equals(type, other), "equals spoiled by specifier"); CFCBase_decref((CFCBase*)other); } { CFCType *other = CFCType_new(CFCTYPE_PRIMITIVE|CFCTYPE_CONST, parcel, "hump_t", 0); OK(test, !CFCType_equals(type, other), "equals spoiled by const"); CFCBase_decref((CFCBase*)other); } CFCBase_decref((CFCBase*)type); CFCBase_decref((CFCBase*)parcel); }
static CFCParcel* S_audition_parcel(const char *version_dir, const char *vstring, CFCVersion *min_version, CFCParcel *best) { CFCVersion *version = CFCVersion_new(vstring); CFCVersion *best_version = best ? CFCParcel_get_version(best) : NULL; // Version must match min_version and be greater than the previous best. if (CFCVersion_compare_to(version, min_version) >= 0 && (best_version == NULL || CFCVersion_compare_to(version, best_version) > 0) ) { // Parse parcel JSON for major version check. CFCFileSpec *file_spec = CFCFileSpec_new(version_dir, "parcel", ".json", true); CFCParcel *parcel = CFCParcel_new_from_file(file_spec); CFCVersion *major_version = CFCParcel_get_major_version(parcel); if (CFCVersion_compare_to(major_version, min_version) <= 0) { CFCBase_decref((CFCBase*)best); best = parcel; } else { CFCBase_decref((CFCBase*)parcel); } CFCBase_decref((CFCBase*)file_spec); } CFCBase_decref((CFCBase*)version); return best; }
void CFCCallable_destroy(CFCCallable *self) { CFCBase_decref((CFCBase*)self->return_type); CFCBase_decref((CFCBase*)self->param_list); CFCBase_decref((CFCBase*)self->docucomment); CFCSymbol_destroy((CFCSymbol*)self); }
static void S_run_parser_tests(CFCTest *test) { CFCParser *parser = CFCParser_new(); CFCParcel *neato_parcel = CFCTest_parse_parcel(test, parser, "parcel Neato;"); CFCParser_set_class_name(parser, "Neato::Obj"); CFCParser_set_class_nickname(parser, "Obj"); { static const char *method_strings[4] = { "public int Do_Foo(Obj *self);", "Obj* Gimme_An_Obj(Obj *self);", "void Do_Whatever(Obj *self, uint32_t a_num, float real);", "Foo* Fetch_Foo(Obj *self, int num);", }; for (int i = 0; i < 4; ++i) { CFCMethod *method = CFCTest_parse_method(test, parser, method_strings[i]); CFCBase_decref((CFCBase*)method); } } { CFCMethod *method = CFCTest_parse_method(test, parser, "public final void The_End(Obj *self);"); OK(test, CFCMethod_final(method), "final"); CFCBase_decref((CFCBase*)method); } CFCBase_decref((CFCBase*)neato_parcel); CFCBase_decref((CFCBase*)parser); CFCParcel_reap_singletons(); }
static void S_run_basic_tests(CFCTest *test) { CFCParcel *neato_parcel = CFCParcel_new("Neato", NULL, NULL, NULL); CFCParcel_register(neato_parcel); CFCType *type = CFCType_new(0, neato_parcel, "mytype_t", 0); OK(test, CFCType_get_parcel(type) == neato_parcel, "get_parcel"); STR_EQ(test, CFCType_to_c(type), "mytype_t", "to_c"); STR_EQ(test, CFCType_get_specifier(type), "mytype_t", "get_specifier"); #define TEST_BOOL_ACCESSOR(type, name) \ OK(test, !CFCType_ ## name(type), #name " false by default"); TEST_BOOL_ACCESSOR(type, const); TEST_BOOL_ACCESSOR(type, nullable); TEST_BOOL_ACCESSOR(type, incremented); TEST_BOOL_ACCESSOR(type, decremented); TEST_BOOL_ACCESSOR(type, is_void); TEST_BOOL_ACCESSOR(type, is_object); TEST_BOOL_ACCESSOR(type, is_primitive); TEST_BOOL_ACCESSOR(type, is_integer); TEST_BOOL_ACCESSOR(type, is_floating); TEST_BOOL_ACCESSOR(type, is_string_type); TEST_BOOL_ACCESSOR(type, is_va_list); TEST_BOOL_ACCESSOR(type, is_arbitrary); TEST_BOOL_ACCESSOR(type, is_composite); CFCBase_decref((CFCBase*)neato_parcel); CFCBase_decref((CFCBase*)type); CFCParcel_reap_singletons(); }
void CFCC_destroy(CFCC *self) { CFCBase_decref((CFCBase*)self->hierarchy); CFCBase_decref((CFCBase*)self->html_gen); FREEMEM(self->c_header); FREEMEM(self->c_footer); FREEMEM(self->man_header); FREEMEM(self->man_footer); CFCBase_destroy((CFCBase*)self); }
void CFCUri_destroy(CFCUri *self) { FREEMEM(self->string); FREEMEM(self->callable); FREEMEM(self->error); CFCBase_decref((CFCBase*)self->doc_class); CFCBase_decref((CFCBase*)self->klass); CFCBase_decref((CFCBase*)self->document); CFCBase_destroy((CFCBase*)self); }
void CFCParcel_reap_singletons(void) { for (size_t i = 0; i < num_registered; i++) { CFCBase_decref((CFCBase*)registry[i]); } FREEMEM(registry); num_registered = 0; registry = NULL; CFCBase_decref((CFCBase*)default_parcel); default_parcel = NULL; }
static void S_CFCGoClass_destroy(CFCGoClass *self) { CFCBase_decref((CFCBase*)self->parcel); CFCBase_decref((CFCBase*)self->client); FREEMEM(self->class_name); for (int i = 0; self->method_bindings[i] != NULL; i++) { CFCBase_decref((CFCBase*)self->method_bindings[i]); } FREEMEM(self->method_bindings); CFCBase_destroy((CFCBase*)self); }
void CFCType_destroy(CFCType *self) { if (self->child) { CFCBase_decref((CFCBase*)self->child); } CFCBase_decref((CFCBase*)self->parcel); FREEMEM(self->specifier); FREEMEM(self->c_string); FREEMEM(self->array); FREEMEM(self->vtable_var); CFCBase_destroy((CFCBase*)self); }
CFCParcel* CFCParcel_clownfish_parcel(void) { CFCParcel *parcel = CFCParcel_fetch("Lucy"); if (!parcel) { CFCVersion *version = CFCVersion_new("v0.3.0"); parcel = CFCParcel_new("Lucy", "Lucy", version); CFCParcel_register(parcel); CFCBase_decref((CFCBase*)version); CFCBase_decref((CFCBase*)parcel); } return parcel; }
static void S_parse_cf_files(CFCHierarchy *self, const char *source_dir, int is_included) { CFCFindFilesContext context; context.ext = ".cfh"; context.paths = (char**)CALLOCATE(1, sizeof(char*)); context.num_paths = 0; CFCUtil_walk(source_dir, S_find_files, &context); // Process any file that has at least one class declaration. for (int i = 0; context.paths[i] != NULL; i++) { // Derive the name of the class that owns the module file. char *source_path = context.paths[i]; char *path_part = S_extract_path_part(source_path, source_dir, ".cfh"); // Ignore hidden files. if (path_part[0] == '.' || strstr(path_part, CHY_DIR_SEP ".") != NULL) { continue; } CFCFileSpec *file_spec = CFCFileSpec_new(source_dir, path_part, ".cfh", is_included); // Slurp and parse file. size_t unused; char *content = CFCUtil_slurp_text(source_path, &unused); CFCFile *file = CFCParser_parse_file(self->parser, content, file_spec); FREEMEM(content); if (!file) { int lineno = CFCParser_get_lineno(self->parser); CFCUtil_die("%s:%d: parser error", source_path, lineno); } // Make sure path_part is unique because the name of the generated // C header is derived from it. CFCFile *existing = S_fetch_file(self, path_part); if (existing) { CFCUtil_die("File %s.cfh found twice in %s and %s", path_part, CFCFile_get_source_dir(existing), source_dir); } S_add_file(self, file); CFCBase_decref((CFCBase*)file); CFCBase_decref((CFCBase*)file_spec); FREEMEM(path_part); } CFCUtil_free_string_array(context.paths); }
static void S_run_integer_tests(CFCTest *test) { { CFCType *type = CFCType_new_integer(CFCTYPE_CONST, "int32_t"); OK(test, CFCType_const(type), "const"); STR_EQ(test, CFCType_get_specifier(type), "int32_t", "get_specifier"); STR_EQ(test, CFCType_to_c(type), "const int32_t", "'const' in C representation"); CFCBase_decref((CFCBase*)type); } { CFCParser *parser = CFCParser_new(); static const char *specifiers[14] = { "bool", "char", "short", "int", "long", "size_t", "int8_t", "int16_t", "int32_t", "int64_t", "uint8_t", "uint16_t", "uint32_t", "uint64_t" }; for (int i = 0; i < 14; ++i) { const char *specifier = specifiers[i]; CFCType *type; type = CFCTest_parse_type(test, parser, specifier); OK(test, CFCType_is_integer(type), "%s is_integer", specifier); CFCBase_decref((CFCBase*)type); char *const_specifier = CFCUtil_sprintf("const %s", specifier); type = CFCTest_parse_type(test, parser, const_specifier); OK(test, CFCType_is_integer(type), "%s is_integer", const_specifier); OK(test, CFCType_const(type), "%s is const", const_specifier); FREEMEM(const_specifier); CFCBase_decref((CFCBase*)type); } CFCBase_decref((CFCBase*)parser); } }
static void S_set_prereqs(CFCParcel *self, CFCJson *node, const char *path) { size_t num_prereqs = CFCJson_get_num_children(node) / 2; CFCJson **children = CFCJson_get_children(node); CFCPrereq **prereqs = (CFCPrereq**)MALLOCATE((num_prereqs + 1) * sizeof(CFCPrereq*)); for (size_t i = 0; i < num_prereqs; ++i) { const char *name = CFCJson_get_string(children[2*i]); CFCJson *value = children[2*i+1]; int value_type = CFCJson_get_type(value); CFCVersion *version = NULL; if (value_type == CFCJSON_STRING) { version = CFCVersion_new(CFCJson_get_string(value)); } else if (value_type != CFCJSON_NULL) { CFCUtil_die("Invalid prereq value (filepath '%s')", path); } prereqs[i] = CFCPrereq_new(name, version); CFCBase_decref((CFCBase*)version); } prereqs[num_prereqs] = NULL; // Assume that prereqs are empty. FREEMEM(self->prereqs); self->prereqs = prereqs; self->num_prereqs = num_prereqs; }
void CFCBindCore_destroy(CFCBindCore *self) { CFCBase_decref((CFCBase*)self->hierarchy); FREEMEM(self->c_header); FREEMEM(self->c_footer); CFCBase_destroy((CFCBase*)self); }
static void S_destroy(CFCPython *self) { CFCBase_decref((CFCBase*)self->hierarchy); FREEMEM(self->header); FREEMEM(self->footer); CFCBase_destroy((CFCBase*)self); }
static void S_run_tests(CFCTest *test) { CFCParser *parser = CFCParser_new(); CFCParcel *neato_parcel = CFCTest_parse_parcel(test, parser, "parcel Neato;"); CFCType *return_type = CFCTest_parse_type(test, parser, "Obj*"); CFCParamList *param_list = CFCTest_parse_param_list(test, parser, "(int32_t some_num)"); { CFCFunction *func = CFCFunction_new(NULL, "return_an_obj", return_type, param_list, NULL, 0); OK(test, func != NULL, "new"); CFCBase_decref((CFCBase*)func); } { CFCFunction *func = NULL; char *error; CFCUTIL_TRY { func = CFCFunction_new(NULL, "Uh_Oh", return_type, param_list, NULL, 0); } CFCUTIL_CATCH(error); OK(test, error && strstr(error, "Uh_Oh"), "invalid name kills constructor"); FREEMEM(error); CFCBase_decref((CFCBase*)func); } { CFCClass *neato_obj = CFCClass_create(neato_parcel, NULL, "Neato::Obj", NULL, NULL, NULL, NULL, false, false, false); CFCParser_set_class(parser, neato_obj); static const char *func_strings[2] = { "inert int running_count(int biscuit);", "public inert Hash* init_fave_hash(int32_t num_buckets," " bool o_rly);" }; for (int i = 0; i < 2; ++i) { CFCFunction *func = CFCTest_parse_function(test, parser, func_strings[i]); CFCBase_decref((CFCBase*)func); } CFCBase_decref((CFCBase*)neato_obj); } CFCBase_decref((CFCBase*)return_type); CFCBase_decref((CFCBase*)param_list); CFCBase_decref((CFCBase*)neato_parcel); CFCBase_decref((CFCBase*)parser); CFCParcel_reap_singletons(); }
void CFCClass_clear_registry(void) { for (size_t i = 0; i < registry_size; i++) { CFCClass *klass = registry[i].klass; if (klass->parent) { // Break circular ref. CFCBase_decref((CFCBase*)klass->parent); klass->parent = NULL; } CFCBase_decref((CFCBase*)klass); FREEMEM(registry[i].key); } FREEMEM(registry); registry_size = 0; registry_cap = 0; registry = NULL; }
void CFCVariable_destroy(CFCVariable *self) { CFCBase_decref((CFCBase*)self->type); FREEMEM(self->local_c); FREEMEM(self->global_c); FREEMEM(self->local_dec); CFCSymbol_destroy((CFCSymbol*)self); }
static void S_run_overridden_tests(CFCTest *test) { CFCParser *parser = CFCParser_new(); CFCParcel *neato_parcel = CFCTest_parse_parcel(test, parser, "parcel Neato;"); CFCType *return_type = CFCTest_parse_type(test, parser, "Obj*"); CFCParamList *param_list = CFCTest_parse_param_list(test, parser, "(Foo *self)"); CFCMethod *orig = CFCMethod_new(neato_parcel, NULL, "Neato::Foo", "Foo", "Return_An_Obj", return_type, param_list, NULL, 0, 0); CFCParamList *overrider_param_list = CFCTest_parse_param_list(test, parser, "(FooJr *self)"); CFCMethod *overrider = CFCMethod_new(neato_parcel, NULL, "Neato::Foo::FooJr", "FooJr", "Return_An_Obj", return_type, overrider_param_list, NULL, 0, 0); CFCMethod_override(overrider, orig); OK(test, !CFCMethod_novel(overrider), "A Method which overrides another is not 'novel'"); CFCBase_decref((CFCBase*)parser); CFCBase_decref((CFCBase*)neato_parcel); CFCBase_decref((CFCBase*)return_type); CFCBase_decref((CFCBase*)param_list); CFCBase_decref((CFCBase*)orig); CFCBase_decref((CFCBase*)overrider_param_list); CFCBase_decref((CFCBase*)overrider); CFCParcel_reap_singletons(); }
static void S_run_va_list_tests(CFCTest *test) { { CFCType *type = CFCType_new_va_list(); STR_EQ(test, CFCType_get_specifier(type), "va_list", "specifier defaults to 'va_list'"); STR_EQ(test, CFCType_to_c(type), "va_list", "to_c"); CFCBase_decref((CFCBase*)type); } { CFCParser *parser = CFCParser_new(); CFCType *type = CFCTest_parse_type(test, parser, "va_list"); OK(test, CFCType_is_va_list(type), "is_va_list"); CFCBase_decref((CFCBase*)type); CFCBase_decref((CFCBase*)parser); } }
void CFCPerl_write_callbacks(CFCPerl *self) { CFCBindCore *core_binding = CFCBindCore_new(self->hierarchy, self->header, self->footer); CFCBindCore_write_callbacks_h(core_binding); CFCBase_decref((CFCBase*)core_binding); S_write_callbacks_c(self); }
void CFCPerlSub_destroy(CFCPerlSub *self) { CFCBase_decref((CFCBase*)self->param_list); FREEMEM(self->class_name); FREEMEM(self->alias); FREEMEM(self->perl_name); FREEMEM(self->c_name); CFCBase_destroy((CFCBase*)self); }
void CFCGoClass_clear_registry(void) { for (size_t i = 0; i < registry_size; i++) { CFCBase_decref((CFCBase*)registry[i]); } FREEMEM(registry); registry_size = 0; registry_cap = 0; registry = NULL; }
void CFCParcel_destroy(CFCParcel *self) { FREEMEM(self->name); FREEMEM(self->cnick); CFCBase_decref((CFCBase*)self->version); FREEMEM(self->prefix); FREEMEM(self->Prefix); FREEMEM(self->PREFIX); CFCBase_destroy((CFCBase*)self); }
void CFCPerlClass_destroy(CFCPerlClass *self) { CFCBase_decref((CFCBase*)self->parcel); CFCBase_decref((CFCBase*)self->client); CFCBase_decref((CFCBase*)self->pod_spec); FREEMEM(self->class_name); FREEMEM(self->xs_code); for (size_t i = 0; i < self->num_cons; i++) { FREEMEM(self->cons_aliases[i]); FREEMEM(self->cons_inits[i]); } FREEMEM(self->cons_aliases); FREEMEM(self->cons_inits); for (size_t i = 0; i < self->num_class_aliases; i++) { FREEMEM(self->class_aliases[i]); } FREEMEM(self->class_aliases); CFCBase_destroy((CFCBase*)self); }
void CFCHierarchy_destroy(CFCHierarchy *self) { for (size_t i = 0; self->trees[i] != NULL; i++) { CFCBase_decref((CFCBase*)self->trees[i]); } for (size_t i = 0; self->files[i] != NULL; i++) { CFCBase_decref((CFCBase*)self->files[i]); } CFCUtil_free_string_array(self->sources); CFCUtil_free_string_array(self->includes); CFCUtil_free_string_array(self->prereqs); FREEMEM(self->trees); FREEMEM(self->files); FREEMEM(self->dest); FREEMEM(self->inc_dest); FREEMEM(self->src_dest); CFCBase_decref((CFCBase*)self->parser); CFCBase_destroy((CFCBase*)self); }
void CFCSymbol_destroy(CFCSymbol *self) { CFCBase_decref((CFCBase*)self->parcel); FREEMEM(self->exposure); FREEMEM(self->class_name); FREEMEM(self->class_cnick); FREEMEM(self->micro_sym); FREEMEM(self->short_sym); FREEMEM(self->full_sym); CFCBase_destroy((CFCBase*)self); }