static void S_add_novel_meth(CFCBindSpecs *self, CFCMethod *method, CFCClass *klass, int meth_index) { const char *meth_name = CFCMethod_get_name(method); const char *sep = meth_index == 0 ? "" : ",\n"; char *full_override_sym; if (!CFCMethod_final(method) && !CFCMethod_excluded_from_host(method)) { full_override_sym = CFCMethod_full_override_sym(method, klass); } else { full_override_sym = CFCUtil_strdup("NULL"); } char *imp_func = CFCMethod_imp_func(method, klass); char *full_offset_sym = CFCMethod_full_offset_sym(method, klass); char pattern[] = " {\n" " &%s, /* offset */\n" " \"%s\", /* name */\n" " (cfish_method_t)%s, /* func */\n" " (cfish_method_t)%s /* callback_func */\n" " }"; char *def = CFCUtil_sprintf(pattern, full_offset_sym, meth_name, imp_func, full_override_sym); self->novel_specs = CFCUtil_cat(self->novel_specs, sep, def, NULL); FREEMEM(def); FREEMEM(full_offset_sym); FREEMEM(imp_func); FREEMEM(full_override_sym); }
char* CFCBindMeth_novel_spec_def(CFCMethod *method) { const char *macro_sym = CFCMethod_get_macro_sym(method); const char *imp_func = CFCMethod_imp_func(method); const char *full_override_sym = "NULL"; if (!CFCMethod_final(method)) { full_override_sym = CFCMethod_full_override_sym(method); } char *full_offset_sym = CFCMethod_full_offset_sym(method, NULL); char pattern[] = " {\n" " &%s, /* offset */\n" " \"%s\", /* name */\n" " (cfish_method_t)%s, /* func */\n" " (cfish_method_t)%s /* callback_func */\n" " }"; char *def = CFCUtil_sprintf(pattern, full_offset_sym, macro_sym, imp_func, full_override_sym); FREEMEM(full_offset_sym); return def; }
static char* S_primitive_callback_def(CFCMethod *method, const char *callback_start, const char *refcount_mods) { const char *override_sym = CFCMethod_full_override_sym(method); const char *params = CFCParamList_to_c(CFCMethod_get_param_list(method)); CFCType *return_type = CFCMethod_get_return_type(method); const char *ret_type_str = CFCType_to_c(return_type); const char *micro_sym = CFCMethod_micro_sym(method); char callback_func[50]; if (CFCType_is_integer(return_type)) { strcpy(callback_func, "S_finish_callback_i64"); } else if (CFCType_is_floating(return_type)) { strcpy(callback_func, "S_finish_callback_f64"); } else { CFCUtil_die("Unexpected type: %s", ret_type_str); } char pattern[] = "%s\n" "%s(%s) {\n" "%s" " %s retval = (%s)%s(\"%s\");%s\n" " return retval;\n" "}\n"; char *callback_def = CFCUtil_sprintf(pattern, ret_type_str, override_sym, params, callback_start, ret_type_str, ret_type_str, callback_func, micro_sym, refcount_mods); return callback_def; }
static char* S_invalid_callback_def(CFCMethod *method) { char *full_method_sym = CFCMethod_full_method_sym(method, NULL); const char *override_sym = CFCMethod_full_override_sym(method); CFCParamList *param_list = CFCMethod_get_param_list(method); const char *params = CFCParamList_to_c(param_list); CFCVariable **param_vars = CFCParamList_get_variables(param_list); // Thwart compiler warnings. CFCType *return_type = CFCMethod_get_return_type(method); const char *ret_type_str = CFCType_to_c(return_type); char *unused = S_build_unused_vars(param_vars); char *unreachable = S_maybe_unreachable(return_type); char pattern[] = "%s\n" "%s(%s) {%s\n" " CFISH_THROW(CFISH_ERR, \"Can't override %s via binding\");%s\n" "}\n"; char *callback_def = CFCUtil_sprintf(pattern, ret_type_str, override_sym, params, unused, full_method_sym, unreachable); FREEMEM(full_method_sym); FREEMEM(unreachable); FREEMEM(unused); return callback_def; }
char* CFCPyMethod_callback_def(CFCMethod *method, CFCClass *invoker) { CFCParamList *param_list = CFCMethod_get_param_list(method); CFCVariable **vars = CFCParamList_get_variables(param_list); CFCType *return_type = CFCMethod_get_return_type(method); const char *ret_type_str = CFCType_to_c(return_type); const char *params = CFCParamList_to_c(param_list); char *override_sym = CFCMethod_full_override_sym(method, invoker); char *content; if (CFCMethod_can_be_bound(method)) { char *py_args = S_build_py_args(param_list); char *invocation = S_build_pymeth_invocation(method); char *refcount_mods = S_callback_refcount_mods(param_list); const char *maybe_return = CFCType_is_void(return_type) ? "" : " return cfcb_RESULT;\n"; const char pattern[] = "%s\n" "%s(%s) {\n" "%s\n" "%s\n" "%s" "%s" "}\n"; content = CFCUtil_sprintf(pattern, ret_type_str, override_sym, params, py_args, invocation, refcount_mods, maybe_return); } else { char *unused = S_build_unused_vars(vars); char *unreachable = S_maybe_unreachable(return_type); char *meth_sym = CFCMethod_full_method_sym(method, invoker); const char pattern[] = "%s\n" "%s(%s) {%s\n" " CFISH_THROW(CFISH_ERR, \"Can't override %s via binding\");%s\n" "}\n"; content = CFCUtil_sprintf(pattern, ret_type_str, override_sym, params, unused, meth_sym, unreachable); FREEMEM(meth_sym); FREEMEM(unused); FREEMEM(unreachable); } FREEMEM(override_sym); return content; }
char* CFCBindMeth_callback_dec(CFCMethod *method) { CFCType *return_type = CFCMethod_get_return_type(method); const char *ret_type_str = CFCType_to_c(return_type); const char *override_sym = CFCMethod_full_override_sym(method); const char *params = CFCParamList_to_c(CFCMethod_get_param_list(method)); char pattern[] = "%s\n" "%s(%s);\n"; char *callback_dec = CFCUtil_sprintf(pattern, ret_type_str, override_sym, params); return callback_dec; }
static char* S_obj_callback_def(CFCMethod *method, const char *callback_params, const char *refcount_mods) { const char *override_sym = CFCMethod_full_override_sym(method); const char *params = CFCParamList_to_c(CFCMethod_get_param_list(method)); CFCType *return_type = CFCMethod_get_return_type(method); const char *ret_type_str = CFCType_to_c(return_type); const char *cb_func_name = CFCType_is_string_type(return_type) ? "cfish_Host_callback_str" : "cfish_Host_callback_obj"; char *nullable_check = CFCUtil_strdup(""); if (!CFCType_nullable(return_type)) { const char *macro_sym = CFCMethod_get_macro_sym(method); char pattern[] = "\n if (!retval) { CFISH_THROW(CFISH_ERR, " "\"%s() for class '%%o' cannot return NULL\", " "Cfish_Obj_Get_Class_Name((cfish_Obj*)self)); }"; size_t size = sizeof(pattern) + strlen(macro_sym) + 30; nullable_check = (char*)REALLOCATE(nullable_check, size); sprintf(nullable_check, pattern, macro_sym); } char pattern[] = "%s\n" "%s(%s) {\n" " %s retval = (%s)%s(%s);%s%s\n" " return retval;\n" "}\n"; size_t size = sizeof(pattern) + strlen(ret_type_str) + strlen(override_sym) + strlen(params) + strlen(ret_type_str) + strlen(ret_type_str) + strlen(cb_func_name) + strlen(callback_params) + strlen(nullable_check) + strlen(refcount_mods) + 30; char *callback_def = (char*)MALLOCATE(size); sprintf(callback_def, pattern, ret_type_str, override_sym, params, ret_type_str, ret_type_str, cb_func_name, callback_params, nullable_check, refcount_mods); FREEMEM(nullable_check); return callback_def; }
static char* S_void_callback_def(CFCMethod *method, const char *callback_start, const char *refcount_mods) { const char *override_sym = CFCMethod_full_override_sym(method); const char *params = CFCParamList_to_c(CFCMethod_get_param_list(method)); const char *micro_sym = CFCMethod_micro_sym(method); const char pattern[] = "void\n" "%s(%s) {\n" "%s" " S_finish_callback_void(\"%s\");%s\n" "}\n"; char *callback_def = CFCUtil_sprintf(pattern, override_sym, params, callback_start, micro_sym, refcount_mods); return callback_def; }
static char* S_callback_decs(CFCClass *klass) { CFCMethod **fresh_methods = CFCClass_fresh_methods(klass); char *cb_decs = CFCUtil_strdup(""); for (int meth_num = 0; fresh_methods[meth_num] != NULL; meth_num++) { CFCMethod *method = fresh_methods[meth_num]; // Define callback to NULL. if (CFCMethod_novel(method) && !CFCMethod_final(method)) { const char *override_sym = CFCMethod_full_override_sym(method); cb_decs = CFCUtil_cat(cb_decs, "#define ", override_sym, " NULL\n", NULL); } } return cb_decs; }
static char* S_primitive_callback_def(CFCMethod *method, const char *callback_params, const char *refcount_mods) { const char *override_sym = CFCMethod_full_override_sym(method); const char *params = CFCParamList_to_c(CFCMethod_get_param_list(method)); CFCType *return_type = CFCMethod_get_return_type(method); const char *ret_type_str = CFCType_to_c(return_type); char cb_func_name[40]; if (CFCType_is_floating(return_type)) { strcpy(cb_func_name, "cfish_Host_callback_f64"); } else if (CFCType_is_integer(return_type)) { strcpy(cb_func_name, "cfish_Host_callback_i64"); } else if (strcmp(ret_type_str, "void*") == 0) { strcpy(cb_func_name, "cfish_Host_callback_host"); } else { CFCUtil_die("unrecognized type: %s", ret_type_str); } char pattern[] = "%s\n" "%s(%s) {\n" " return (%s)%s(%s);%s\n" "}\n"; size_t size = sizeof(pattern) + strlen(ret_type_str) + strlen(override_sym) + strlen(params) + strlen(ret_type_str) + strlen(cb_func_name) + strlen(callback_params) + strlen(refcount_mods) + 20; char *callback_def = (char*)MALLOCATE(size); sprintf(callback_def, pattern, ret_type_str, override_sym, params, ret_type_str, cb_func_name, callback_params, refcount_mods); return callback_def; }
static char* S_void_callback_def(CFCMethod *method, const char *callback_params, const char *refcount_mods) { const char *override_sym = CFCMethod_full_override_sym(method); const char *params = CFCParamList_to_c(CFCMethod_get_param_list(method)); const char pattern[] = "void\n" "%s(%s) {\n" " cfish_Host_callback(%s);%s\n" "}\n"; size_t size = sizeof(pattern) + strlen(override_sym) + strlen(params) + strlen(callback_params) + strlen(refcount_mods) + 200; char *callback_def = (char*)MALLOCATE(size); sprintf(callback_def, pattern, override_sym, params, callback_params, refcount_mods); return callback_def; }
char* CFCBindMeth_spec_def(CFCMethod *method) { const char *macro_sym = CFCMethod_get_macro_sym(method); const char *impl_sym = CFCMethod_implementing_func_sym(method); int is_novel = CFCMethod_novel(method); const char *full_override_sym = "NULL"; if ((CFCMethod_public(method) || CFCMethod_abstract(method)) && is_novel) { full_override_sym = CFCMethod_full_override_sym(method); } size_t offset_sym_size = CFCMethod_full_offset_sym(method, NULL, NULL, 0); char *full_offset_sym = (char*)MALLOCATE(offset_sym_size); CFCMethod_full_offset_sym(method, NULL, full_offset_sym, offset_sym_size); char pattern[] = " {\n" " %d, /* is_novel */\n" " \"%s\", /* name */\n" " (cfish_method_t)%s, /* func */\n" " (cfish_method_t)%s, /* callback_func */\n" " &%s /* offset */\n" " }"; size_t size = sizeof(pattern) + 10 /* for is_novel */ + strlen(macro_sym) + strlen(impl_sym) + strlen(full_override_sym) + strlen(full_offset_sym) + 30; char *def = (char*)MALLOCATE(size); sprintf(def, pattern, is_novel, macro_sym, impl_sym, full_override_sym, full_offset_sym); FREEMEM(full_offset_sym); return def; }
static char* S_obj_callback_def(CFCMethod *method, const char *callback_start, const char *refcount_mods) { const char *override_sym = CFCMethod_full_override_sym(method); const char *params = CFCParamList_to_c(CFCMethod_get_param_list(method)); CFCType *return_type = CFCMethod_get_return_type(method); const char *ret_type_str = CFCType_to_c(return_type); const char *micro_sym = CFCMethod_micro_sym(method); const char *nullable = CFCType_nullable(return_type) ? "true" : "false"; char pattern[] = "%s\n" "%s(%s) {\n" "%s" " %s retval = (%s)S_finish_callback_obj(self, \"%s\", %s);%s\n" " return retval;\n" "}\n"; char *callback_def = CFCUtil_sprintf(pattern, ret_type_str, override_sym, params, callback_start, ret_type_str, ret_type_str, micro_sym, nullable, refcount_mods); return callback_def; }