Updated Branches: refs/heads/master 8ac8d6b1e -> e808115e1
Autogenerate callbacks.h Declare callbacks in their own header file. As a side effect, callbacks now have "C" linkage. Project: http://git-wip-us.apache.org/repos/asf/lucy/repo Commit: http://git-wip-us.apache.org/repos/asf/lucy/commit/e808115e Tree: http://git-wip-us.apache.org/repos/asf/lucy/tree/e808115e Diff: http://git-wip-us.apache.org/repos/asf/lucy/diff/e808115e Branch: refs/heads/master Commit: e808115e103a686c14bbdda7a685c00a1ef90961 Parents: e5c275c Author: Nick Wellnhofer <[email protected]> Authored: Sun Dec 16 17:27:43 2012 +0100 Committer: Nick Wellnhofer <[email protected]> Committed: Mon Jan 7 23:50:12 2013 +0100 ---------------------------------------------------------------------- clownfish/compiler/src/CFCBindClass.c | 45 +++++++++++------ clownfish/compiler/src/CFCBindClass.h | 5 ++ clownfish/compiler/src/CFCBindCore.c | 74 ++++++++++++++++++++++++++++ clownfish/compiler/src/CFCBindCore.h | 6 ++ clownfish/compiler/src/CFCPerl.c | 15 ++++++ 5 files changed, 130 insertions(+), 15 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/lucy/blob/e808115e/clownfish/compiler/src/CFCBindClass.c ---------------------------------------------------------------------- diff --git a/clownfish/compiler/src/CFCBindClass.c b/clownfish/compiler/src/CFCBindClass.c index 7bfcf53..f4bb499 100644 --- a/clownfish/compiler/src/CFCBindClass.c +++ b/clownfish/compiler/src/CFCBindClass.c @@ -256,9 +256,9 @@ CFCBindClass_to_c_data(CFCBindClass *self) { CFCMethod **methods = CFCClass_methods(client); CFCMethod **fresh_methods = CFCClass_fresh_methods(client); - char *offsets = CFCUtil_strdup(""); - char *cb_funcs = CFCUtil_strdup(""); - char *ms_var = CFCUtil_strdup(""); + char *offsets = CFCUtil_strdup(""); + char *method_defs = CFCUtil_strdup(""); + char *ms_var = CFCUtil_strdup(""); for (int meth_num = 0; methods[meth_num] != NULL; meth_num++) { CFCMethod *method = methods[meth_num]; @@ -288,17 +288,10 @@ CFCBindClass_to_c_data(CFCBindClass *self) { // Create a default implementation for abstract methods. if (CFCMethod_abstract(method)) { char *method_def = CFCBindMeth_abstract_method_def(method); - cb_funcs = CFCUtil_cat(cb_funcs, method_def, "\n", NULL); + method_defs = CFCUtil_cat(method_defs, method_def, "\n", NULL); FREEMEM(method_def); } - // Declare (but don't define) callback. - if (CFCMethod_novel(method) && !CFCMethod_final(method)) { - char *cb_dec = CFCBindMeth_callback_dec(method); - cb_funcs = CFCUtil_cat(cb_funcs, cb_dec, "\n", NULL); - FREEMEM(cb_dec); - } - // Define MethodSpec struct. if (meth_num != 0) { ms_var = CFCUtil_cat(ms_var, ",\n", NULL); @@ -319,8 +312,7 @@ CFCBindClass_to_c_data(CFCBindClass *self) { "\n" "%s\n" "\n" - "/* Define functions which implement host callbacks for the methods\n" - " * of this class which can be overridden via the host.\n" + "/* Define abstract methods of this class.\n" " */\n" "\n" "%s\n" @@ -341,12 +333,12 @@ CFCBindClass_to_c_data(CFCBindClass *self) { "\n" "%s\n" "\n"; - char *code = CFCUtil_sprintf(pattern, offsets, cb_funcs, ms_var, vt_var, + char *code = CFCUtil_sprintf(pattern, offsets, method_defs, ms_var, vt_var, autocode); FREEMEM(fresh_methods); FREEMEM(offsets); - FREEMEM(cb_funcs); + FREEMEM(method_defs); FREEMEM(ms_var); return code; } @@ -421,6 +413,29 @@ CFCBindClass_spec_def(CFCBindClass *self) { return code; } +// Declare host callbacks. +char* +CFCBindClass_callback_decs(CFCBindClass *self) { + CFCClass *client = self->client; + CFCMethod **fresh_methods = CFCClass_fresh_methods(client); + char *cb_decs = CFCUtil_strdup(""); + + for (int meth_num = 0; fresh_methods[meth_num] != NULL; meth_num++) { + CFCMethod *method = fresh_methods[meth_num]; + + // Declare callback. + if (CFCMethod_novel(method) && !CFCMethod_final(method)) { + char *cb_dec = CFCBindMeth_callback_dec(method); + cb_decs = CFCUtil_cat(cb_decs, cb_dec, "\n", NULL); + FREEMEM(cb_dec); + } + } + + FREEMEM(fresh_methods); + + return cb_decs; +} + // Declare typedefs for every method, to ease casting. static char* S_method_typedefs(CFCBindClass *self) { http://git-wip-us.apache.org/repos/asf/lucy/blob/e808115e/clownfish/compiler/src/CFCBindClass.h ---------------------------------------------------------------------- diff --git a/clownfish/compiler/src/CFCBindClass.h b/clownfish/compiler/src/CFCBindClass.h index c84954e..6cb9347 100644 --- a/clownfish/compiler/src/CFCBindClass.h +++ b/clownfish/compiler/src/CFCBindClass.h @@ -59,6 +59,11 @@ CFCBindClass_to_c_data(CFCBindClass *self); char* CFCBindClass_spec_def(CFCBindClass *self); +/* Return the declarations of the host callbacks of this class. + */ +char* +CFCBindClass_callback_decs(CFCBindClass *self); + #ifdef __cplusplus } #endif http://git-wip-us.apache.org/repos/asf/lucy/blob/e808115e/clownfish/compiler/src/CFCBindCore.c ---------------------------------------------------------------------- diff --git a/clownfish/compiler/src/CFCBindCore.c b/clownfish/compiler/src/CFCBindCore.c index f5d2afb..7cf461e 100644 --- a/clownfish/compiler/src/CFCBindCore.c +++ b/clownfish/compiler/src/CFCBindCore.c @@ -325,6 +325,7 @@ S_write_parcel_c(CFCBindCore *self) { "#define C_LUCY_VTABLE\n" "%s\n" "#include \"parcel.h\"\n" + "#include \"callbacks.h\"\n" "#include \"Clownfish/VTable.h\"\n" "%s\n" "\n" @@ -360,3 +361,76 @@ S_write_parcel_c(CFCBindCore *self) { FREEMEM(file_content); } +/* Write the "callbacks.h" header file, which contains declarations of host + * callbacks. + */ +void +CFCBindCore_write_callbacks_h(CFCBindCore *self) { + CFCHierarchy *hierarchy = self->hierarchy; + CFCClass **ordered = CFCHierarchy_ordered_classes(hierarchy); + char *includes = CFCUtil_strdup(""); + char *all_cb_decs = CFCUtil_strdup(""); + + for (int i = 0; ordered[i] != NULL; i++) { + CFCClass *klass = ordered[i]; + + const char *include_h = CFCClass_include_h(klass); + includes = CFCUtil_cat(includes, "#include \"", include_h, "\"\n", + NULL); + + if (!CFCClass_included(klass)) { + CFCBindClass *class_binding = CFCBindClass_new(klass); + char *cb_decs = CFCBindClass_callback_decs(class_binding); + all_cb_decs = CFCUtil_cat(all_cb_decs, cb_decs, NULL); + FREEMEM(cb_decs); + CFCBase_decref((CFCBase*)class_binding); + } + } + + FREEMEM(ordered); + + const char pattern[] = + "%s\n" + "#ifndef CFCCALLBACKS_H\n" + "#define CFCCALLBACKS_H 1\n" + "\n" + "#ifdef __cplusplus\n" + "extern \"C\" {\n" + "#endif\n" + "\n" + "#include \"parcel.h\"\n" + "%s" + "\n" + "%s" + "\n" + "#ifdef __cplusplus\n" + "}\n" + "#endif\n" + "\n" + "#endif /* CFCCALLBACKS_H */\n" + "\n" + "%s\n" + "\n"; + size_t size = sizeof(pattern) + + strlen(self->header) + + strlen(includes) + + strlen(all_cb_decs) + + strlen(self->footer) + + 50; + char *file_content = (char*)MALLOCATE(size); + sprintf(file_content, pattern, self->header, includes, all_cb_decs, + self->footer); + + // Unlink then write file. + const char *inc_dest = CFCHierarchy_get_include_dest(hierarchy); + char *filepath = CFCUtil_sprintf("%s" CHY_DIR_SEP "callbacks.h", inc_dest); + remove(filepath); + CFCUtil_write_file(filepath, file_content, strlen(file_content)); + FREEMEM(filepath); + + FREEMEM(includes); + FREEMEM(all_cb_decs); + FREEMEM(file_content); +} + + http://git-wip-us.apache.org/repos/asf/lucy/blob/e808115e/clownfish/compiler/src/CFCBindCore.h ---------------------------------------------------------------------- diff --git a/clownfish/compiler/src/CFCBindCore.h b/clownfish/compiler/src/CFCBindCore.h index 2b667f7..33fdd82 100644 --- a/clownfish/compiler/src/CFCBindCore.h +++ b/clownfish/compiler/src/CFCBindCore.h @@ -57,6 +57,12 @@ CFCBindCore_destroy(CFCBindCore *self); int CFCBindCore_write_all_modified(CFCBindCore *self, int modified); +/** Write the "callbacks.h" header file, which contains declarations of host + * callbacks. + */ +void +CFCBindCore_write_callbacks_h(CFCBindCore *self); + #ifdef __cplusplus } #endif http://git-wip-us.apache.org/repos/asf/lucy/blob/e808115e/clownfish/compiler/src/CFCPerl.c ---------------------------------------------------------------------- diff --git a/clownfish/compiler/src/CFCPerl.c b/clownfish/compiler/src/CFCPerl.c index 43cffe5..5983c3d 100644 --- a/clownfish/compiler/src/CFCPerl.c +++ b/clownfish/compiler/src/CFCPerl.c @@ -32,6 +32,7 @@ #include "CFCPerlConstructor.h" #include "CFCPerlMethod.h" #include "CFCPerlTypeMap.h" +#include "CFCBindCore.h" struct CFCPerl { CFCBase base; @@ -53,6 +54,9 @@ struct CFCPerl { static void S_replace_double_colons(char *text, char replacement); +static void +S_write_callbacks_c(CFCPerl *self); + const static CFCMeta CFCPERL_META = { "Clownfish::CFC::Binding::Perl", sizeof(CFCPerl), @@ -445,11 +449,22 @@ CFCPerl_write_bindings(CFCPerl *self) { 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); +} + +static void +S_write_callbacks_c(CFCPerl *self) { CFCClass **ordered = CFCHierarchy_ordered_classes(self->hierarchy); static const char pattern[] = "%s" "\n" "#include \"XSBind.h\"\n" + "#include \"callbacks.h\"\n" "#include \"parcel.h\"\n" "\n" "static void\n"
