Add function to write custom POD
Project: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/repo Commit: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/commit/9a4a2147 Tree: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/tree/9a4a2147 Diff: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/diff/9a4a2147 Branch: refs/heads/documentation Commit: 9a4a2147f98b6d7634aefafa65cb19d1544c019e Parents: 1a19ac4 Author: Nick Wellnhofer <[email protected]> Authored: Sun Aug 31 14:37:26 2014 +0200 Committer: Nick Wellnhofer <[email protected]> Committed: Sun Aug 31 15:32:07 2014 +0200 ---------------------------------------------------------------------- compiler/perl/lib/Clownfish/CFC.xs | 8 +++ compiler/src/CFCPerl.c | 87 ++++++++++++++++++++++++++++----- compiler/src/CFCPerl.h | 5 ++ 3 files changed, 87 insertions(+), 13 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/9a4a2147/compiler/perl/lib/Clownfish/CFC.xs ---------------------------------------------------------------------- diff --git a/compiler/perl/lib/Clownfish/CFC.xs b/compiler/perl/lib/Clownfish/CFC.xs index 38aa3fc..a306b68 100644 --- a/compiler/perl/lib/Clownfish/CFC.xs +++ b/compiler/perl/lib/Clownfish/CFC.xs @@ -2046,6 +2046,14 @@ CODE: CFCBase_decref((CFCBase*)self); OUTPUT: RETVAL +void +add_custom_pod(self, pod_name, pod) + CFCPerl *self; + const char *pod_name; + const char *pod; +PPCODE: + CFCPerl_add_custom_pod(self, pod_name, pod); + SV* write_pod(self) CFCPerl *self; http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/9a4a2147/compiler/src/CFCPerl.c ---------------------------------------------------------------------- diff --git a/compiler/src/CFCPerl.c b/compiler/src/CFCPerl.c index a04bb61..7e05fd8 100644 --- a/compiler/src/CFCPerl.c +++ b/compiler/src/CFCPerl.c @@ -37,16 +37,20 @@ struct CFCPerl { CFCBase base; CFCHierarchy *hierarchy; - char *lib_dir; - char *boot_class; - char *header; - char *footer; - char *c_header; - char *c_footer; - char *pod_header; - char *pod_footer; - char *xs_path; - char *boot_func; + char *lib_dir; + char *boot_class; + char *header; + char *footer; + char *c_header; + char *c_footer; + char *pod_header; + char *pod_footer; + char *xs_path; + char *boot_func; + char **custom_pod_names; + char **custom_pods; + size_t num_custom_pods; + }; // Modify a string in place, swapping out "::" for the supplied character. @@ -100,6 +104,11 @@ CFCPerl_init(CFCPerl *self, CFCHierarchy *hierarchy, const char *lib_dir, } } + // Initialize custom PODs. + self->custom_pod_names = (char**)CALLOCATE(1, sizeof(char*)); + self->custom_pods = (char**)CALLOCATE(1, sizeof(char*)); + self->num_custom_pods = 0; + return self; } @@ -116,6 +125,14 @@ CFCPerl_destroy(CFCPerl *self) { FREEMEM(self->pod_footer); FREEMEM(self->xs_path); FREEMEM(self->boot_func); + for (size_t i = 0; self->custom_pod_names[i]; ++i) { + FREEMEM(self->custom_pod_names[i]); + } + FREEMEM(self->custom_pod_names); + for (size_t i = 0; self->custom_pods[i]; ++i) { + FREEMEM(self->custom_pods[i]); + } + FREEMEM(self->custom_pods); CFCBase_destroy((CFCBase*)self); } @@ -134,14 +151,33 @@ S_replace_double_colons(char *text, char replacement) { text[pos] = '\0'; } +void +CFCPerl_add_custom_pod(CFCPerl *self, const char *pod_name, const char *pod) { + size_t num_custom_pods = self->num_custom_pods; + + size_t new_size = (num_custom_pods + 2) * sizeof(char*); + self->custom_pod_names = (char**)REALLOCATE(self->custom_pod_names, + new_size); + self->custom_pods = (char**)REALLOCATE(self->custom_pods, new_size); + + self->custom_pod_names[num_custom_pods] = CFCUtil_strdup(pod_name); + self->custom_pods[num_custom_pods] = CFCUtil_strdup(pod); + self->custom_pod_names[num_custom_pods+1] = NULL; + self->custom_pods[num_custom_pods+1] = NULL; + + self->num_custom_pods = num_custom_pods + 1; +} + char** CFCPerl_write_pod(CFCPerl *self) { CFCPerlClass **registry = CFCPerlClass_registry(); size_t num_registered = 0; while (registry[num_registered] != NULL) { num_registered++; } - char **pod_paths = (char**)CALLOCATE(num_registered + 1, sizeof(char*)); - char **pods = (char**)CALLOCATE(num_registered + 1, sizeof(char*)); - size_t count = 0; + + size_t max_pods = num_registered + self->num_custom_pods; + char **pod_paths = (char**)CALLOCATE(max_pods + 1, sizeof(char*)); + char **pods = (char**)CALLOCATE(max_pods + 1, sizeof(char*)); + size_t count = 0; // Generate POD, but don't write. That way, if there's an error while // generating pod, we leak memory but don't clutter up the file system. @@ -162,11 +198,36 @@ CFCPerl_write_pod(CFCPerl *self) { FREEMEM(raw_pod); } + for (size_t i = 0; i < self->num_custom_pods; i++) { + char *pod = CFCUtil_sprintf("%s\n%s%s", self->pod_header, + self->custom_pods[i], self->pod_footer); + char *pod_path = CFCUtil_sprintf("%s" CHY_DIR_SEP "%s.pod", + self->lib_dir, + self->custom_pod_names[i]); + S_replace_double_colons(pod_path, CHY_DIR_SEP_CHAR); + + pods[count] = pod; + pod_paths[count] = pod_path; + count++; + } + // Write out any POD files that have changed. size_t num_written = 0; for (size_t i = 0; i < count; i++) { char *pod = pods[i]; char *pod_path = pod_paths[i]; + + // Create directory if it doesn't exist. + char *dir = CFCUtil_strdup(pod_path); + char *last_sep = strrchr(dir, CHY_DIR_SEP_CHAR); + if (last_sep) { + *last_sep = '\0'; + if (!CFCUtil_is_dir(dir)) { + CFCUtil_make_path(dir); + } + } + FREEMEM(dir); + if (CFCUtil_write_if_changed(pod_path, pod, strlen(pod))) { pod_paths[num_written] = pod_path; num_written++; http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/9a4a2147/compiler/src/CFCPerl.h ---------------------------------------------------------------------- diff --git a/compiler/src/CFCPerl.h b/compiler/src/CFCPerl.h index eef10ac..9ed6b9f 100644 --- a/compiler/src/CFCPerl.h +++ b/compiler/src/CFCPerl.h @@ -78,6 +78,11 @@ CFCPerl_init(CFCPerl *self, struct CFCHierarchy *hierarchy, void CFCPerl_destroy(CFCPerl *self); +/** Add a custom POD file. + */ +void +CFCPerl_add_custom_pod(CFCPerl *self, const char *pod_name, const char *pod); + /** Auto-generate POD for all class bindings where pod specs were created. * See whether a .pod file exists and is up-to-date; if not, write it out. *
