Esempio n. 1
0
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);
}
Esempio n. 2
0
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);
}
Esempio n. 3
0
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);
}
Esempio n. 4
0
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;
}
Esempio n. 5
0
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);
}
Esempio n. 6
0
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();
}
Esempio n. 7
0
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();
}
Esempio n. 8
0
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);
}
Esempio n. 9
0
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);
}
Esempio n. 10
0
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;
}
Esempio n. 11
0
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);
}
Esempio n. 12
0
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);
}
Esempio n. 13
0
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;
}
Esempio n. 14
0
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);
}
Esempio n. 15
0
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);
    }
}
Esempio n. 16
0
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;
}
Esempio n. 17
0
void
CFCBindCore_destroy(CFCBindCore *self) {
    CFCBase_decref((CFCBase*)self->hierarchy);
    FREEMEM(self->c_header);
    FREEMEM(self->c_footer);
    CFCBase_destroy((CFCBase*)self);
}
Esempio n. 18
0
static void
S_destroy(CFCPython *self) {
    CFCBase_decref((CFCBase*)self->hierarchy);
    FREEMEM(self->header);
    FREEMEM(self->footer);
    CFCBase_destroy((CFCBase*)self);
}
Esempio n. 19
0
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();
}
Esempio n. 20
0
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;
}
Esempio n. 21
0
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);
}
Esempio n. 22
0
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();
}
Esempio n. 23
0
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);
    }
}
Esempio n. 24
0
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);
}
Esempio n. 25
0
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);
}
Esempio n. 26
0
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;
}
Esempio n. 27
0
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);
}
Esempio n. 28
0
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);
}
Esempio n. 29
0
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);
}
Esempio n. 30
0
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);
}