CFCDocument* CFCDocument_do_create(CFCDocument *self, const char *path, const char *path_part) { self->path = CFCUtil_strdup(path); self->path_part = CFCUtil_strdup(path_part); if (CHY_DIR_SEP_CHAR != '/') { for (size_t i = 0; self->path_part[i]; i++) { if (self->path_part[i] == '/') { self->path_part[i] = CHY_DIR_SEP_CHAR; } } } const char *last_dir_sep = strrchr(self->path_part, CHY_DIR_SEP_CHAR); if (last_dir_sep) { self->name = CFCUtil_strdup(last_dir_sep + 1); } else { self->name = CFCUtil_strdup(self->path_part); } S_register(self); return self; }
CFCClass* CFCClass_do_create(CFCClass *self, struct CFCParcel *parcel, const char *exposure, const char *class_name, const char *cnick, const char *micro_sym, CFCDocuComment *docucomment, CFCFileSpec *file_spec, const char *parent_class_name, int is_final, int is_inert) { CFCUTIL_NULL_CHECK(class_name); exposure = exposure ? exposure : "parcel"; micro_sym = micro_sym ? micro_sym : "class"; parcel = parcel ? parcel : CFCParcel_default_parcel(); CFCSymbol_init((CFCSymbol*)self, parcel, exposure, class_name, cnick, micro_sym); if (!is_inert && !parent_class_name && strcmp(class_name, "Clownfish::Obj") != 0 ) { parent_class_name = "Clownfish::Obj"; } self->parent = NULL; self->tree_grown = false; self->children = (CFCClass**)CALLOCATE(1, sizeof(CFCClass*)); self->num_kids = 0; self->functions = (CFCFunction**)CALLOCATE(1, sizeof(CFCFunction*)); self->num_functions = 0; self->methods = (CFCMethod**)CALLOCATE(1, sizeof(CFCMethod*)); self->num_methods = 0; self->member_vars = (CFCVariable**)CALLOCATE(1, sizeof(CFCVariable*)); self->num_member_vars = 0; self->inert_vars = (CFCVariable**)CALLOCATE(1, sizeof(CFCVariable*)); self->num_inert_vars = 0; self->parent_class_name = CFCUtil_strdup(parent_class_name); self->docucomment = (CFCDocuComment*)CFCBase_incref((CFCBase*)docucomment); self->file_spec = (CFCFileSpec*)CFCBase_incref((CFCBase*)file_spec); // Cache several derived symbols. const char *last_colon = strrchr(class_name, ':'); self->struct_sym = last_colon ? CFCUtil_strdup(last_colon + 1) : CFCUtil_strdup(class_name); const char *prefix = CFCClass_get_prefix(self); size_t struct_sym_len = strlen(self->struct_sym); self->short_vtable_var = (char*)MALLOCATE(struct_sym_len + 1); size_t i; for (i = 0; i < struct_sym_len; i++) { self->short_vtable_var[i] = toupper(self->struct_sym[i]); } self->short_vtable_var[struct_sym_len] = '\0'; self->full_struct_sym = CFCUtil_sprintf("%s%s", prefix, self->struct_sym); self->ivars_struct = CFCUtil_sprintf("%sIVARS", self->struct_sym); self->full_ivars_struct = CFCUtil_sprintf("%sIVARS", self->full_struct_sym); self->ivars_func = CFCUtil_sprintf("%s_IVARS", CFCClass_get_cnick(self)); self->full_ivars_func = CFCUtil_sprintf("%s%s_IVARS", prefix, CFCClass_get_cnick(self)); self->full_ivars_offset = CFCUtil_sprintf("%s_OFFSET", self->full_ivars_func); size_t full_struct_sym_len = strlen(self->full_struct_sym); self->full_vtable_var = (char*)MALLOCATE(full_struct_sym_len + 1); for (i = 0; self->full_struct_sym[i] != '\0'; i++) { self->full_vtable_var[i] = toupper(self->full_struct_sym[i]); } self->full_vtable_var[i] = '\0'; self->privacy_symbol = CFCUtil_sprintf("C_%s", self->full_vtable_var); // Build the relative path to the autogenerated C header file. if (file_spec) { const char *path_part = CFCFileSpec_get_path_part(self->file_spec); self->include_h = CFCUtil_sprintf("%s.h", path_part); } else { self->include_h = CFCUtil_strdup("class.h"); } self->is_final = !!is_final; self->is_inert = !!is_inert; if (file_spec && CFCFileSpec_included(file_spec)) { if (!CFCParcel_included(parcel)) { CFCUtil_die("Class %s from include dir found in parcel %s from" " source dir", class_name, CFCParcel_get_name(parcel)); } } else { if (CFCParcel_included(parcel)) { CFCUtil_die("Class %s from source dir found in parcel %s from" " include dir", class_name, CFCParcel_get_name(parcel)); } } // Store in registry. S_register(self); return self; }
CFCClass* CFCClass_do_create(CFCClass *self, struct CFCParcel *parcel, const char *exposure, const char *name, const char *nickname, CFCDocuComment *docucomment, CFCFileSpec *file_spec, const char *parent_class_name, int is_final, int is_inert, int is_abstract) { CFCUTIL_NULL_CHECK(parcel); CFCUTIL_NULL_CHECK(name); exposure = exposure ? exposure : "parcel"; // Validate. if (!S_validate_exposure(exposure)) { CFCBase_decref((CFCBase*)self); CFCUtil_die("Invalid exposure: '%s'", exposure); } if (!CFCClass_validate_class_name(name)) { CFCBase_decref((CFCBase*)self); CFCUtil_die("Invalid name: '%s'", name); } const char *last_colon = strrchr(name, ':'); const char *struct_sym = last_colon ? last_colon + 1 : name; // Derive nickname if necessary, then validate. const char *real_nickname = NULL; if (nickname) { real_nickname = nickname; } else { real_nickname = struct_sym; } if (!S_validate_nickname(real_nickname)) { CFCBase_decref((CFCBase*)self); CFCUtil_die("Invalid nickname: '%s'", real_nickname); } // Default parent class name is "Clownfish::Obj". if (!is_inert && !parent_class_name && strcmp(name, "Clownfish::Obj") != 0 ) { parent_class_name = "Clownfish::Obj"; } // Assign. self->parcel = (CFCParcel*)CFCBase_incref((CFCBase*)parcel); self->exposure = CFCUtil_strdup(exposure); self->name = CFCUtil_strdup(name); self->nickname = CFCUtil_strdup(real_nickname); self->tree_grown = false; self->parent = NULL; self->children = (CFCClass**)CALLOCATE(1, sizeof(CFCClass*)); self->num_kids = 0; self->functions = (CFCFunction**)CALLOCATE(1, sizeof(CFCFunction*)); self->num_functions = 0; self->fresh_methods = (CFCMethod**)CALLOCATE(1, sizeof(CFCMethod*)); self->num_fresh_meths = 0; self->methods = NULL; self->num_methods = 0; self->fresh_vars = (CFCVariable**)CALLOCATE(1, sizeof(CFCVariable*)); self->num_fresh_vars = 0; self->member_vars = NULL; self->num_member_vars = 0; self->inert_vars = (CFCVariable**)CALLOCATE(1, sizeof(CFCVariable*)); self->num_inert_vars = 0; self->parent_class_name = CFCUtil_strdup(parent_class_name); self->docucomment = (CFCDocuComment*)CFCBase_incref((CFCBase*)docucomment); self->file_spec = (CFCFileSpec*)CFCBase_incref((CFCBase*)file_spec); // Cache several derived symbols. const char *prefix = CFCClass_get_prefix(self); self->struct_sym = CFCUtil_strdup(struct_sym); self->full_struct_sym = CFCUtil_sprintf("%s%s", prefix, struct_sym); self->ivars_struct = CFCUtil_sprintf("%sIVARS", struct_sym); self->full_ivars_struct = CFCUtil_sprintf("%s%s", prefix, self->ivars_struct); self->ivars_func = CFCUtil_sprintf("%s_IVARS", self->nickname); self->full_ivars_func = CFCUtil_sprintf("%s%s", prefix, self->ivars_func); self->full_ivars_offset = CFCUtil_sprintf("%s_OFFSET", self->full_ivars_func); const char *PREFIX = CFCClass_get_PREFIX(self); size_t struct_sym_len = strlen(struct_sym); char *short_class_var = (char*)MALLOCATE(struct_sym_len + 1); size_t i; for (i = 0; i < struct_sym_len; i++) { short_class_var[i] = toupper(struct_sym[i]); } short_class_var[struct_sym_len] = '\0'; self->short_class_var = short_class_var; self->full_class_var = CFCUtil_sprintf("%s%s", PREFIX, short_class_var); self->privacy_symbol = CFCUtil_sprintf("C_%s", self->full_class_var); // Build the relative path to the autogenerated C header file. if (file_spec) { const char *path_part = CFCFileSpec_get_path_part(self->file_spec); self->include_h = CFCUtil_sprintf("%s.h", path_part); } else { self->include_h = CFCUtil_strdup("class.h"); } self->is_final = !!is_final; self->is_inert = !!is_inert; self->is_abstract = !!is_abstract; // Check for include flag mismatch. if (!CFCClass_included(self) && CFCParcel_included(parcel)) { CFCUtil_die("Class %s from source dir found in parcel %s from" " include dir", name, CFCParcel_get_name(parcel)); } // Skip class if it's from an include dir and the parcel was already // processed in another source or include dir. const char *class_source_dir = CFCClass_get_source_dir(self); const char *parcel_source_dir = CFCParcel_get_source_dir(parcel); if (!CFCClass_included(self) || !class_source_dir || !parcel_source_dir || strcmp(class_source_dir, parcel_source_dir) == 0 ) { char *error; CFCUTIL_TRY { // Store in registry. S_register(self); } CFCUTIL_CATCH(error); if (error) { CFCBase_decref((CFCBase*)self); CFCUtil_rethrow(error); } CFCParcel_add_struct_sym(parcel, self->struct_sym); }