Rework CFCPerl_write_bindings Merge S_xs_file_contents into CFCPerl_write_bindings. Use separate variables for different parts of the XS file content.
Project: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/repo Commit: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/commit/0cd7edb2 Tree: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/tree/0cd7edb2 Diff: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/diff/0cd7edb2 Branch: refs/heads/master Commit: 0cd7edb2e5497c1e29ca7b77629f5eb2a10625d5 Parents: 516ae68 Author: Nick Wellnhofer <wellnho...@aevum.de> Authored: Mon May 30 16:28:19 2016 +0200 Committer: Nick Wellnhofer <wellnho...@aevum.de> Committed: Mon May 30 16:32:04 2016 +0200 ---------------------------------------------------------------------- compiler/src/CFCPerl.c | 171 +++++++++++++++++++------------------------- 1 file changed, 74 insertions(+), 97 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/0cd7edb2/compiler/src/CFCPerl.c ---------------------------------------------------------------------- diff --git a/compiler/src/CFCPerl.c b/compiler/src/CFCPerl.c index ec8c3b8..6a15d43 100644 --- a/compiler/src/CFCPerl.c +++ b/compiler/src/CFCPerl.c @@ -526,59 +526,6 @@ CFCPerl_write_host_code(CFCPerl *self) { } static char* -S_xs_file_contents(CFCPerl *self, const char *generated_xs, - const char *class_specs, const char *xsub_specs, - const char *hand_rolled_xs) { - char *bootstrap_calls = CFCUtil_strdup(""); - CFCParcel **parcels = CFCParcel_all_parcels(); - for (size_t i = 0; parcels[i]; ++i) { - if (!CFCParcel_included(parcels[i])) { - const char *prefix = CFCParcel_get_prefix(parcels[i]); - bootstrap_calls - = CFCUtil_cat(bootstrap_calls, " ", prefix, - "bootstrap_perl();\n", NULL); - } - } - - const char pattern[] = - "%s" - "\n" - "%s\n" - "\n" - "MODULE = %s PACKAGE = %s\n" - "\n" - "BOOT:\n" - "{\n" - " static const cfish_XSBind_ClassSpec class_specs[] = {\n" - "%s\n" - " };\n" - " static const cfish_XSBind_XSubSpec xsub_specs[] = {\n" - "%s\n" - " };\n" - " size_t num_classes\n" - " = sizeof(class_specs) / sizeof(class_specs[0]);\n" - " const char* file = __FILE__;\n" - "\n" - "%s" - "\n" - " cfish_XSBind_bootstrap(aTHX_ num_classes, class_specs,\n" - " xsub_specs, file);\n" - "}\n" - "\n" - "%s\n" - "\n" - "%s"; - char *contents - = CFCUtil_sprintf(pattern, self->c_header, generated_xs, - self->boot_class, self->boot_class, class_specs, - xsub_specs, bootstrap_calls, hand_rolled_xs, - self->c_footer); - - FREEMEM(bootstrap_calls); - return contents; -} - -static char* S_add_xsub_spec(char *xsub_specs, CFCPerlSub *xsub) { const char *c_name = CFCPerlSub_c_name(xsub); const char *alias = CFCPerlSub_get_alias(xsub); @@ -593,53 +540,41 @@ CFCPerl_write_bindings(CFCPerl *self) { CFCParcel **parcels = CFCParcel_all_parcels(); CFCClass **ordered = CFCHierarchy_ordered_classes(self->hierarchy); CFCPerlClass **registry = CFCPerlClass_registry(); - char *hand_rolled_xs = CFCUtil_strdup(""); - char *generated_xs = CFCUtil_strdup(""); - char *class_specs = CFCUtil_strdup(""); - char *xsub_specs = CFCUtil_strdup(""); - - // Bake the parcel privacy defines into the XS, so it can be compiled - // without any extra compiler flags. - for (size_t i = 0; parcels[i]; ++i) { - if (!CFCParcel_included(parcels[i])) { - const char *privacy_sym = CFCParcel_get_privacy_sym(parcels[i]); - generated_xs = CFCUtil_cat(generated_xs, "#define ", privacy_sym, - "\n", NULL); - } - } - generated_xs = CFCUtil_cat(generated_xs, "\n", NULL); + char *privacy_syms = CFCUtil_strdup(""); + char *includes = CFCUtil_strdup(""); + char *generated_xs = CFCUtil_strdup(""); + char *class_specs = CFCUtil_strdup(""); + char *xsub_specs = CFCUtil_strdup(""); + char *bootstrap_calls = CFCUtil_strdup(""); + char *hand_rolled_xs = CFCUtil_strdup(""); - // Include XSBind.h and *_perl.h. - generated_xs = CFCUtil_cat(generated_xs, "#include \"XSBind.h\"\n", NULL); for (size_t i = 0; parcels[i]; ++i) { - if (!CFCParcel_included(parcels[i])) { - const char *prefix = CFCParcel_get_prefix(parcels[i]); - generated_xs = CFCUtil_cat(generated_xs, "#include \"", prefix, - "perl.h\"\n", NULL); - } + if (CFCParcel_included(parcels[i])) { continue; } + + // Bake the parcel privacy defines into the XS, so it can be compiled + // without any extra compiler flags. + const char *privacy_sym = CFCParcel_get_privacy_sym(parcels[i]); + privacy_syms = CFCUtil_cat(privacy_syms, "#define ", privacy_sym, + "\n", NULL); + + // Bootstrap calls. + const char *prefix = CFCParcel_get_prefix(parcels[i]); + includes = CFCUtil_cat(includes, "#include \"", prefix, "perl.h\"\n", + NULL); + bootstrap_calls = CFCUtil_cat(bootstrap_calls, " ", prefix, + "bootstrap_perl();\n", NULL); } - // Pound-includes for generated headers. for (size_t i = 0; ordered[i] != NULL; i++) { CFCClass *klass = ordered[i]; if (CFCClass_included(klass)) { continue; } - const char *include_h = CFCClass_include_h(klass); - generated_xs = CFCUtil_cat(generated_xs, "#include \"", include_h, - "\"\n", NULL); - } - generated_xs = CFCUtil_cat(generated_xs, "\n", NULL); - generated_xs = CFCUtil_cat(generated_xs, - "#ifndef XS_INTERNAL\n" - " #define XS_INTERNAL XS\n" - "#endif\n" - "\n", - NULL); - - for (size_t i = 0; ordered[i] != NULL; i++) { - CFCClass *klass = ordered[i]; - if (CFCClass_included(klass) || CFCClass_inert(klass)) { continue; } + // Pound-includes for generated headers. + const char *include_h = CFCClass_include_h(klass); + includes = CFCUtil_cat(includes, "#include \"", include_h, "\"\n", + NULL); + if (CFCClass_inert(klass)) { continue; } int num_xsubs = 0; // Constructors. @@ -707,18 +642,60 @@ CFCPerl_write_bindings(CFCPerl *self) { hand_rolled_xs = CFCUtil_cat(hand_rolled_xs, xs, "\n", NULL); } + const char pattern[] = + "%s" // Header. + "\n" + "%s" // Privacy syms. + "\n" + "#include \"XSBind.h\"\n" + "%s" // Includes. + "\n" + "#ifndef XS_INTERNAL\n" + " #define XS_INTERNAL XS\n" + "#endif\n" + "\n" + "%s" // Generated XS. + "\n" + "MODULE = %s PACKAGE = %s\n" // Boot class. + "\n" + "BOOT:\n" + "{\n" + " static const cfish_XSBind_ClassSpec class_specs[] = {\n" + "%s\n" // Class specs. + " };\n" + " static const cfish_XSBind_XSubSpec xsub_specs[] = {\n" + "%s\n" // XSUB specs. + " };\n" + " size_t num_classes\n" + " = sizeof(class_specs) / sizeof(class_specs[0]);\n" + " const char* file = __FILE__;\n" + "\n" + "%s" // Bootstrap calls. + "\n" + " cfish_XSBind_bootstrap(aTHX_ num_classes, class_specs,\n" + " xsub_specs, file);\n" + "}\n" + "\n" + "%s" // Hand-rolled XS. + "\n" + "%s"; // Footer + char *contents + = CFCUtil_sprintf(pattern, self->c_header, privacy_syms, includes, + generated_xs, self->boot_class, self->boot_class, + class_specs, xsub_specs, bootstrap_calls, + hand_rolled_xs, self->c_footer); + // Write out if there have been any changes. - char *xs_file_contents - = S_xs_file_contents(self, generated_xs, class_specs, xsub_specs, - hand_rolled_xs); - CFCUtil_write_if_changed(self->xs_path, xs_file_contents, - strlen(xs_file_contents)); + CFCUtil_write_if_changed(self->xs_path, contents, strlen(contents)); - FREEMEM(xs_file_contents); + FREEMEM(contents); FREEMEM(hand_rolled_xs); + FREEMEM(bootstrap_calls); FREEMEM(xsub_specs); FREEMEM(class_specs); FREEMEM(generated_xs); + FREEMEM(includes); + FREEMEM(privacy_syms); FREEMEM(ordered); }