You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@lucy.apache.org by nw...@apache.org on 2014/11/11 16:23:27 UTC

[1/4] lucy-clownfish git commit: Update Clownfish documentation

Repository: lucy-clownfish
Updated Branches:
  refs/heads/master 76b9206dc -> 92efcd663


Update Clownfish documentation

* Parcel prerequisites.
* Single parcel specifier per header file.
* ivars struct.
* Parcel prefix of methods.
* Details of class, function and variable exposure are yet to be
  decided.
* Misc clarifications.


Project: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/repo
Commit: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/commit/ebef22bd
Tree: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/tree/ebef22bd
Diff: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/diff/ebef22bd

Branch: refs/heads/master
Commit: ebef22bd4bcfbd9209a00e0f0074074aff646276
Parents: 76b9206
Author: Nick Wellnhofer <we...@aevum.de>
Authored: Fri Aug 22 20:19:13 2014 +0200
Committer: Nick Wellnhofer <we...@aevum.de>
Committed: Tue Nov 11 16:08:23 2014 +0100

----------------------------------------------------------------------
 runtime/perl/lib/Clownfish.pod | 114 +++++++++++++++++++++++-------------
 1 file changed, 72 insertions(+), 42 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/ebef22bd/runtime/perl/lib/Clownfish.pod
----------------------------------------------------------------------
diff --git a/runtime/perl/lib/Clownfish.pod b/runtime/perl/lib/Clownfish.pod
index a4dcbb5..e177adc 100644
--- a/runtime/perl/lib/Clownfish.pod
+++ b/runtime/perl/lib/Clownfish.pod
@@ -15,7 +15,7 @@
 
 =head1 NAME
 
-Clownfish - Symbiotic object system.
+Clownfish - Apache Clownfish symbiotic object system.
 
 =head1 VERSION
 
@@ -23,8 +23,8 @@ Clownfish - Symbiotic object system.
 
 =head1 DESCRIPTION
 
-Clownfish is a "symbiotic" object system for C which is designed to pair
-with a "host" dynamic language environment, facilitating the development
+Apache Clownfish is a "symbiotic" object system for C which is designed to
+pair with a "host" dynamic language environment, facilitating the development
 of high performance host language extensions.  Clownfish classes are
 declared in header files with a C<.cfh> extension.  The Clownfish headers
 are used by the Clownfish compiler to generate C header files and host
@@ -63,6 +63,11 @@ arrays and hash tables.
 
 =item *
 
+Guaranteed ABI stability when adding or reordering methods or instance
+variables.
+
+=item *
+
 Modularity.
 
 =item *
@@ -83,11 +88,6 @@ Documentation generator.
 
 Support for more host languages.
 
-=item *
-
-Guaranteed ABI stability when adding or reordering methods or instance
-variables.
-
 =back
 
 =head1 USING CLOWNFISH CLASSES
@@ -121,6 +121,11 @@ A version specifier of the following form (without whitespace):
     version-specifier = "v" version-number
     version-number = digit | digit "." version-number
 
+=item prerequisites
+
+A hash containing the prerequisite parcels. The hash keys are the parcel
+names. The values contain the minimum required version.
+
 =back
 
 An example C<.cfp> file might look like:
@@ -128,7 +133,10 @@ An example C<.cfp> file might look like:
     {
         "name": "Pathfinder",
         "nickname": "Pfind",
-        "version": "v2.3.8"
+        "version": "v2.3.8",
+        "prerequisites": {
+            "Clownfish": "v0.4.0"
+        }
     }
 
 A parcel specifier of the following form is used in Clownfish header files:
@@ -140,7 +148,8 @@ For example:
 
     parcel Pathfinder;
 
-All classes following a parcel specifier will be associated with that parcel.
+Every C<.cfh> file starts with a parcel specifier containing the name of
+the parcel for all classes in the header file.
 
 =head3 Initialization
 
@@ -152,6 +161,9 @@ Example call:
 
     pfind_bootstrap_parcel();
 
+The generated host language bindings call the bootstrap function
+automatically. C projects must call the function manually.
+
 =head3 Short names
 
 If a macro with the uppercase name C<{PARCEL_NICK}_USE_SHORT_NAMES> is
@@ -168,7 +180,7 @@ Example:
     Path *path = Graph_Find_Shortest_Path(graph);
 
     /* Without PFIND_USE_SHORT_NAMES, one would have to write: */
-    pfind_Path *path = Pfind_Graph_Find_Shortest_Path(graph);
+    pfind_Path *path = PFIND_Graph_Find_Shortest_Path(graph);
 
 For object types in Clownfish header files, prefixes of class structs can
 also be omitted unless multiple parcels declare classes with the same last
@@ -201,16 +213,16 @@ Class name components must start with an uppercase letter and must not contain
 underscores. The last component must contain at least one lowercase letter and
 must be unique for every class in a parcel.
 
-For every class, a struct with the name C<{parcel_nick}_{Class_Last_Comp}>
-and a corresponding typedef are declared in the generated C header. The struct
-members are only visible if the uppercase macro
-C<C_{PARCEL_NICK}_{CLASS_LAST_COMP}> is defined before including the header
-file.
+For every class, a type with the name C<{parcel_nick}_{Class_Last_Comp}>
+is defined in the generated C header. This is an opaque typedef used to
+ensure type safety.
 
 For every class, a global variable with the uppercase name
 C<{PARCEL_NICK}_{CLASS_LAST_COMP}> is defined. This variable is a pointer to
 a Clownfish::Class object which is initialized when bootstrapping the parcel.
 
+Non-inert classes inherit from Clownfish::Obj by default.
+
 Example of a class declaration:
 
     parcel Pathfinder;
@@ -222,23 +234,19 @@ Example of a class declaration:
 
 This will generate:
 
-    struct pfind_VisibilityGraph {
-        /* Instance variables */
-    };
     typedef struct pfind_VisibilityGraph pfind_VisibilityGraph;
     extern cfish_Class *PFIND_VISIBILITYGRAPH;
 
 =head3 Class exposure
 
-Classes without public exposure have parcel exposure. They are not visible
-outside of the parcel and must not contain public variables or functions.
+TODO
 
 =head3 Inert classes
 
-Inert classes must contain only inert variables or inert methods, that is,
+Inert classes must contain only inert variables or inert functions, that is,
 neither instance variables nor methods. They must not inherit from another
-class or be inherited from. Non-inert classes inherit from Clownfish::Obj by
-default.
+class or be inherited from. They're essentially nothing more than a
+namespace for functions and global variables.
 
 =head3 Final classes
 
@@ -258,8 +266,8 @@ Variables are declared with a declaration of the following form:
 
 =head3 Inert variables
 
-Inert variables are class variables of which only a single copy exists.
-They are declared in the generated C header with the name
+Inert variables are global class variables of which only a single copy
+exists. They are declared in the generated C header with the name
 C<{parcel_nick}_{Class_Nick}_{Variable_Name}> and must be defined in a C
 source file.
 
@@ -280,13 +288,12 @@ definition will look like:
 
 =head3 Inert variable exposure
 
-Inert variables without public exposure have parcel exposure. They are not
-visible outside of the parcel.
+TODO
 
 =head3 Instance variables
 
-Non-inert variables are instance variables and added to the class struct. They
-must not have an exposure specifier.
+Non-inert variables are instance variables and added to the class's ivars
+struct. They must not have an exposure specifier.
 
 Example:
 
@@ -297,9 +304,26 @@ Example:
         Get_Num_Nodes(Path *self);
     }
 
-This will add a C<num_nodes> member to struct C<pfind_Path>. To access the
-member, the macro C<C_PFIND_PATH> must be defined before including the
-generated header file:
+This will add a C<num_nodes> member to the ivars struct of C<Path>.
+
+=head3 The ivars struct
+
+To access instance variables, the macro C<C_{PARCEL_NICK}_{CLASS_LAST_COMP}>
+must be defined before including the generated header file. This will make
+a struct named C<{parcel_nick}_{Class_Name}IVARS> with a corresponding
+typedef and short name available that contains all instance variables
+of the class and all superclasses from the same parcel. Instance
+variables defined in other parcels are not accessible. This is by
+design to guarantee ABI stability if the instance variable layout
+of a superclass from another parcel changes in a different version.
+If you need to access an instance variable from another parcel,
+add accessor methods.
+
+A pointer to the ivars struct can be obtained by calling an inline
+function named C<{parcel_nick}_{Class_Name}_IVARS>. This function
+takes the object of the class (typically C<self>) as argument.
+
+Example using short names:
 
     #define C_PFIND_PATH
     #define PFIND_USE_SHORT_NAMES
@@ -307,7 +331,8 @@ generated header file:
 
     int
     Path_get_num_nodes(Path *self) {
-        return self->num_nodes;
+        PathIVARS *ivars = Path_IVARS(self);
+        return ivars->num_nodes;
     }
 
 =head2 Functions
@@ -328,8 +353,7 @@ generated header file:
 
 =head3 Function exposure
 
-Functions without public exposure have parcel exposure. They are not
-visible outside of the parcel.
+TODO
 
 =head3 Inert functions
 
@@ -381,11 +405,11 @@ this parameter is named C<self>.
 
 For every method, an inline wrapper for dynamic dispatch is defined in
 the generated C header with the name
-C<{Parcel_Nick}_{Class_Nick}_{Method_Name}>. Additionally, an
+C<{PARCEL_NICK}_{Class_Nick}_{Method_Name}>. Additionally, an
 implementing function is declared with the name
-C<{Parcel_Nick}_{Class_Nick}_{Method_Name}_IMP>. The Clownfish compiler also
+C<{PARCEL_NICK}_{Class_Nick}_{Method_Name}_IMP>. The Clownfish compiler also
 generates a typedef for the method's function pointer type named
-C<{Parcel_Nick}_{Class_Nick}_{Method_Name}_t>. Wrappers and typedefs are
+C<{PARCEL_NICK}_{Class_Nick}_{Method_Name}_t>. Wrappers and typedefs are
 created for all subclasses whether they override a method or not.
 
 Example:
@@ -401,18 +425,18 @@ This will generate:
 
     /* Wrapper for dynamic dispatch */
     static inline void
-    Pfind_VisGraph_Add_Node(pfind_VisibilityGraph *self, pfind_Node *node) {
+    PFIND_VisGraph_Add_Node(pfind_VisibilityGraph *self, pfind_Node *node) {
         /* Inline code for wrapper */
     }
 
     /* Declaration of implementing function */
     void
-    Pfind_VisGraph_Add_Node_IMP(pfind_VisibilityGraph *self,
+    PFIND_VisGraph_Add_Node_IMP(pfind_VisibilityGraph *self,
                                 pfind_Node *node);
 
     /* Declaration of function pointer type */
     typedef void
-    (*Pfind_VisGraph_Add_Node_t)(pfind_VisibilityGraph *self,
+    (*PFIND_VisGraph_Add_Node_t)(pfind_VisibilityGraph *self,
                                  pfind_Node *node);
 
 The implementing function of non-abstract methods must be defined in a C source
@@ -483,6 +507,12 @@ before the call and decrement it when it's no longer used. If the caller does
 not make further use of the passed-in object, it must not decrement its
 reference count after the call.
 
+This is typically used in container classes like VArray:
+
+    String *string = String_newf("Hello");
+    VA_Push(array, (Obj*)string);
+    // No need to DECREF the string.
+
 =head3 Default parameter values
 
 Default parameter values can be given as integer, float, or string literals.


[3/4] lucy-clownfish git commit: Automate creation of C comments from autogen headers

Posted by nw...@apache.org.
Automate creation of C comments from autogen headers


Project: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/repo
Commit: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/commit/eaf2c94b
Tree: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/tree/eaf2c94b
Diff: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/diff/eaf2c94b

Branch: refs/heads/master
Commit: eaf2c94b9e97feac4431bda135a6498c030b7767
Parents: c8e8fe0
Author: Nick Wellnhofer <we...@aevum.de>
Authored: Sat Aug 23 17:17:36 2014 +0200
Committer: Nick Wellnhofer <we...@aevum.de>
Committed: Tue Nov 11 16:17:23 2014 +0100

----------------------------------------------------------------------
 compiler/perl/lib/Clownfish/CFC/Perl/Build.pm |  9 ++--
 compiler/src/CFCBindCore.c                    | 32 +++++++-------
 compiler/src/CFCC.c                           | 18 ++++----
 compiler/src/CFCPerl.c                        | 24 ++++++----
 compiler/src/CFCRuby.c                        | 26 +++++------
 compiler/src/CFCUtil.c                        | 51 ++++++++++++++++++++++
 compiler/src/CFCUtil.h                        | 13 ++++++
 runtime/c/cfc_header                          | 37 ++++++++--------
 runtime/perl/buildlib/Clownfish/Build.pm      | 44 +++++++++----------
 runtime/ruby/Rakefile.common                  |  8 ++--
 10 files changed, 164 insertions(+), 98 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/eaf2c94b/compiler/perl/lib/Clownfish/CFC/Perl/Build.pm
----------------------------------------------------------------------
diff --git a/compiler/perl/lib/Clownfish/CFC/Perl/Build.pm b/compiler/perl/lib/Clownfish/CFC/Perl/Build.pm
index b50c976..fc4ba86 100644
--- a/compiler/perl/lib/Clownfish/CFC/Perl/Build.pm
+++ b/compiler/perl/lib/Clownfish/CFC/Perl/Build.pm
@@ -77,14 +77,13 @@ sub new {
     my $autogen_header = $self->clownfish_params('autogen_header');
     if ( !defined($autogen_header) ) {
         $self->clownfish_params( autogen_header => <<'END_AUTOGEN' );
-/***********************************************
+***********************************************
 
- !!!! DO NOT EDIT !!!!
+!!!! DO NOT EDIT !!!!
 
- This file was auto-generated by Build.PL.
-
- ***********************************************/
+This file was auto-generated by Build.PL.
 
+***********************************************
 END_AUTOGEN
     }
 

http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/eaf2c94b/compiler/src/CFCBindCore.c
----------------------------------------------------------------------
diff --git a/compiler/src/CFCBindCore.c b/compiler/src/CFCBindCore.c
index 774b1a3..679da04 100644
--- a/compiler/src/CFCBindCore.c
+++ b/compiler/src/CFCBindCore.c
@@ -36,8 +36,8 @@
 struct CFCBindCore {
     CFCBase base;
     CFCHierarchy *hierarchy;
-    char         *header;
-    char         *footer;
+    char         *c_header;
+    char         *c_footer;
 };
 
 /* Write the "parcel.h" header file, which contains common symbols needed by
@@ -92,24 +92,24 @@ CFCBindCore_init(CFCBindCore *self, CFCHierarchy *hierarchy,
     CFCUTIL_NULL_CHECK(header);
     CFCUTIL_NULL_CHECK(footer);
     self->hierarchy = (CFCHierarchy*)CFCBase_incref((CFCBase*)hierarchy);
-    self->header    = CFCUtil_strdup(header);
-    self->footer    = CFCUtil_strdup(footer);
+    self->c_header  = CFCUtil_make_c_comment(header);
+    self->c_footer  = CFCUtil_make_c_comment(footer);
     return self;
 }
 
 void
 CFCBindCore_destroy(CFCBindCore *self) {
     CFCBase_decref((CFCBase*)self->hierarchy);
-    FREEMEM(self->header);
-    FREEMEM(self->footer);
+    FREEMEM(self->c_header);
+    FREEMEM(self->c_footer);
     CFCBase_destroy((CFCBase*)self);
 }
 
 int
 CFCBindCore_write_all_modified(CFCBindCore *self, int modified) {
     CFCHierarchy *hierarchy = self->hierarchy;
-    const char   *header    = self->header;
-    const char   *footer    = self->footer;
+    const char   *header    = self->c_header;
+    const char   *footer    = self->c_footer;
 
     // Discover whether files need to be regenerated.
     modified = CFCHierarchy_propagate_modified(hierarchy, modified);
@@ -330,10 +330,10 @@ S_write_parcel_h(CFCBindCore *self, CFCParcel *parcel) {
         "%s\n"
         "\n";
     char *file_content
-        = CFCUtil_sprintf(pattern, self->header, PREFIX, PREFIX,
+        = CFCUtil_sprintf(pattern, self->c_header, PREFIX, PREFIX,
                           extra_includes, privacy_sym, PREFIX, PREFIX,
                           typedefs, extra_defs, PREFIX, prefix, PREFIX, prefix,
-                          prefix, PREFIX, self->footer);
+                          prefix, PREFIX, self->c_footer);
 
     // Unlink then write file.
     const char *inc_dest = CFCHierarchy_get_include_dest(hierarchy);
@@ -467,10 +467,10 @@ S_write_parcel_c(CFCBindCore *self, CFCParcel *parcel) {
         "\n"
         "%s\n";
     char *file_content
-        = CFCUtil_sprintf(pattern, self->header, privacy_syms, prefix,
+        = CFCUtil_sprintf(pattern, self->c_header, privacy_syms, prefix,
                           includes, c_data, class_specs, prefix, inh_bootstrap,
                           num_specs, prefix, prefix, prereq_bootstrap, prefix,
-                          self->footer);
+                          self->c_footer);
 
     // Unlink then open file.
     const char *src_dest = CFCHierarchy_get_source_dest(hierarchy);
@@ -539,8 +539,8 @@ CFCBindCore_write_callbacks_h(CFCBindCore *self) {
         "%s\n"
         "\n";
     char *file_content
-        = CFCUtil_sprintf(pattern, self->header, includes, all_cb_decs,
-                          self->footer);
+        = CFCUtil_sprintf(pattern, self->c_header, includes, all_cb_decs,
+                          self->c_footer);
 
     // Unlink then write file.
     const char *inc_dest = CFCHierarchy_get_include_dest(hierarchy);
@@ -592,9 +592,9 @@ S_write_platform_h(CFCBindCore *self) {
         "%s"
         "\n";
     char *file_content
-        = CFCUtil_sprintf(pattern, self->header, feature_defs, string_defs,
+        = CFCUtil_sprintf(pattern, self->c_header, feature_defs, string_defs,
                           stdbool_defs, stdint_defs, alloca_defs,
-                          self->footer);
+                          self->c_footer);
 
     // Unlink then write file.
     const char *inc_dest = CFCHierarchy_get_include_dest(self->hierarchy);

http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/eaf2c94b/compiler/src/CFCC.c
----------------------------------------------------------------------
diff --git a/compiler/src/CFCC.c b/compiler/src/CFCC.c
index 3f21a0d..e0a355d 100644
--- a/compiler/src/CFCC.c
+++ b/compiler/src/CFCC.c
@@ -30,8 +30,8 @@
 struct CFCC {
     CFCBase base;
     CFCHierarchy *hierarchy;
-    char         *header;
-    char         *footer;
+    char         *c_header;
+    char         *c_footer;
 };
 
 static const CFCMeta CFCC_META = {
@@ -53,16 +53,16 @@ CFCC_init(CFCC *self, CFCHierarchy *hierarchy, const char *header,
     CFCUTIL_NULL_CHECK(header);
     CFCUTIL_NULL_CHECK(footer);
     self->hierarchy = (CFCHierarchy*)CFCBase_incref((CFCBase*)hierarchy);
-    self->header    = CFCUtil_strdup(header);
-    self->footer    = CFCUtil_strdup(footer);
+    self->c_header  = CFCUtil_make_c_comment(header);
+    self->c_footer  = CFCUtil_make_c_comment(footer);
     return self;
 }
 
 void
 CFCC_destroy(CFCC *self) {
     CFCBase_decref((CFCBase*)self->hierarchy);
-    FREEMEM(self->header);
-    FREEMEM(self->footer);
+    FREEMEM(self->c_header);
+    FREEMEM(self->c_footer);
     CFCBase_destroy((CFCBase*)self);
 }
 
@@ -99,8 +99,8 @@ CFCC_write_callbacks(CFCC *self) {
         "\n"
         "%s\n"
         "\n";
-    char *file_content = CFCUtil_sprintf(pattern, self->header, all_cb_decs,
-                                         self->footer);
+    char *file_content = CFCUtil_sprintf(pattern, self->c_header, all_cb_decs,
+                                         self->c_footer);
 
     // Unlink then write file.
     const char *inc_dest = CFCHierarchy_get_include_dest(hierarchy);
@@ -182,7 +182,7 @@ CFCC_write_hostdefs(CFCC *self) {
         "\n"
         "%s\n";
     char *content
-        = CFCUtil_sprintf(pattern, self->header, self->footer);
+        = CFCUtil_sprintf(pattern, self->c_header, self->c_footer);
 
     // Unlink then write file.
     const char *inc_dest = CFCHierarchy_get_include_dest(self->hierarchy);

http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/eaf2c94b/compiler/src/CFCPerl.c
----------------------------------------------------------------------
diff --git a/compiler/src/CFCPerl.c b/compiler/src/CFCPerl.c
index 41fce09..c78fcbf 100644
--- a/compiler/src/CFCPerl.c
+++ b/compiler/src/CFCPerl.c
@@ -41,6 +41,8 @@ struct CFCPerl {
     char *boot_class;
     char *header;
     char *footer;
+    char *c_header;
+    char *c_footer;
     char *xs_path;
     char *boot_func;
 };
@@ -78,6 +80,8 @@ CFCPerl_init(CFCPerl *self, CFCHierarchy *hierarchy, const char *lib_dir,
     self->boot_class = CFCUtil_strdup(boot_class);
     self->header     = CFCUtil_strdup(header);
     self->footer     = CFCUtil_strdup(footer);
+    self->c_header   = CFCUtil_make_c_comment(header);
+    self->c_footer   = CFCUtil_make_c_comment(footer);
 
     // Derive path to generated .xs file.
     self->xs_path = CFCUtil_sprintf("%s" CHY_DIR_SEP "%s.xs", lib_dir,
@@ -102,6 +106,8 @@ CFCPerl_destroy(CFCPerl *self) {
     FREEMEM(self->boot_class);
     FREEMEM(self->header);
     FREEMEM(self->footer);
+    FREEMEM(self->c_header);
+    FREEMEM(self->c_footer);
     FREEMEM(self->xs_path);
     FREEMEM(self->boot_func);
     CFCBase_destroy((CFCBase*)self);
@@ -196,8 +202,8 @@ S_write_boot_h(CFCPerl *self) {
         "\n"
         "%s\n";
     char *content
-        = CFCUtil_sprintf(pattern, self->header, guard, guard, self->boot_func,
-                          guard, self->footer);
+        = CFCUtil_sprintf(pattern, self->c_header, guard, guard,
+                          self->boot_func, guard, self->c_footer);
 
     const char *inc_dest = CFCHierarchy_get_include_dest(self->hierarchy);
     char *boot_h_path = CFCUtil_sprintf("%s" CHY_DIR_SEP "boot.h", inc_dest);
@@ -303,9 +309,9 @@ S_write_boot_c(CFCPerl *self) {
         "%s\n"
         "\n";
     char *content
-        = CFCUtil_sprintf(pattern, self->header, pound_includes,
+        = CFCUtil_sprintf(pattern, self->c_header, pound_includes,
                           self->boot_func, bootstrap_code, alias_adds,
-                          isa_pushes, self->footer);
+                          isa_pushes, self->c_footer);
 
     const char *src_dest = CFCHierarchy_get_source_dest(self->hierarchy);
     char *boot_c_path = CFCUtil_sprintf("%s" CHY_DIR_SEP "boot.c", src_dest);
@@ -341,7 +347,7 @@ CFCPerl_write_hostdefs(CFCPerl *self) {
         "\n"
         "%s\n";
     char *content
-        = CFCUtil_sprintf(pattern, self->header, self->footer);
+        = CFCUtil_sprintf(pattern, self->c_header, self->c_footer);
 
     // Unlink then write file.
     const char *inc_dest = CFCHierarchy_get_include_dest(self->hierarchy);
@@ -381,9 +387,9 @@ S_xs_file_contents(CFCPerl *self, const char *generated_xs,
         "\n"
         "%s";
     char *contents
-        = CFCUtil_sprintf(pattern, self->header, generated_xs,
+        = CFCUtil_sprintf(pattern, self->c_header, generated_xs,
                           self->boot_class, self->boot_class, self->boot_func,
-                          xs_init, hand_rolled_xs, self->footer);
+                          xs_init, hand_rolled_xs, self->c_footer);
 
     return contents;
 }
@@ -577,7 +583,7 @@ S_write_callbacks_c(CFCPerl *self) {
         "    return retval;\n"
         "}\n"
         "\n";
-    char *content = CFCUtil_sprintf(pattern, self->header);
+    char *content = CFCUtil_sprintf(pattern, self->c_header);
 
     for (size_t i = 0; ordered[i] != NULL; i++) {
         CFCClass *klass = ordered[i];
@@ -597,7 +603,7 @@ S_write_callbacks_c(CFCPerl *self) {
         FREEMEM(fresh_methods);
     }
 
-    content = CFCUtil_cat(content, self->footer, NULL);
+    content = CFCUtil_cat(content, self->c_footer, NULL);
 
     // Write if changed.
     const char *src_dest = CFCHierarchy_get_source_dest(self->hierarchy);

http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/eaf2c94b/compiler/src/CFCRuby.c
----------------------------------------------------------------------
diff --git a/compiler/src/CFCRuby.c b/compiler/src/CFCRuby.c
index c185218..ec3dd9a 100644
--- a/compiler/src/CFCRuby.c
+++ b/compiler/src/CFCRuby.c
@@ -33,8 +33,8 @@ struct CFCRuby {
     CFCHierarchy *hierarchy;
     char *lib_dir;
     char *boot_class;
-    char *header;
-    char *footer;
+    char *c_header;
+    char *c_footer;
     char *boot_h_file;
     char *boot_c_file;
     char *boot_h_path;
@@ -74,8 +74,8 @@ CFCRuby_init(CFCRuby *self, CFCParcel *parcel, CFCHierarchy *hierarchy,
     self->hierarchy  = (CFCHierarchy*)CFCBase_incref((CFCBase*)hierarchy);
     self->lib_dir    = CFCUtil_strdup(lib_dir);
     self->boot_class = CFCUtil_strdup(boot_class);
-    self->header     = CFCUtil_strdup(header);
-    self->footer     = CFCUtil_strdup(footer);
+    self->c_header   = CFCUtil_make_c_comment(header);
+    self->c_footer   = CFCUtil_make_c_comment(footer);
 
     const char *prefix   = CFCParcel_get_prefix(parcel);
     const char *inc_dest = CFCHierarchy_get_include_dest(hierarchy);
@@ -103,8 +103,8 @@ CFCRuby_destroy(CFCRuby *self) {
     CFCBase_decref((CFCBase*)self->hierarchy);
     FREEMEM(self->lib_dir);
     FREEMEM(self->boot_class);
-    FREEMEM(self->header);
-    FREEMEM(self->footer);
+    FREEMEM(self->c_header);
+    FREEMEM(self->c_footer);
     FREEMEM(self->boot_h_file);
     FREEMEM(self->boot_c_file);
     FREEMEM(self->boot_h_path);
@@ -153,16 +153,16 @@ S_write_boot_h(CFCRuby *self) {
         "%s\n";
 
     size_t size = sizeof(pattern)
-                  + strlen(self->header)
+                  + strlen(self->c_header)
                   + strlen(guard)
                   + strlen(guard)
                   + strlen(self->boot_func)
                   + strlen(guard)
-                  + strlen(self->footer)
+                  + strlen(self->c_footer)
                   + 20;
     char *content = (char*)MALLOCATE(size);
-    sprintf(content, pattern, self->header, guard, guard, self->boot_func,
-            guard, self->footer);
+    sprintf(content, pattern, self->c_header, guard, guard, self->boot_func,
+            guard, self->c_footer);
     CFCUtil_write_file(self->boot_h_path, content, strlen(content));
 
     FREEMEM(content);
@@ -212,9 +212,9 @@ S_write_boot_c(CFCRuby *self) {
         "\n";
 
     char *content
-        = CFCUtil_sprintf(pattern, self->header, self->boot_h_file, prefix,
+        = CFCUtil_sprintf(pattern, self->c_header, self->boot_h_file, prefix,
                           pound_includes, self->boot_func, prefix,
-                          self->footer);
+                          self->c_footer);
     CFCUtil_write_file(self->boot_c_path, content, strlen(content));
 
     FREEMEM(content);
@@ -249,7 +249,7 @@ CFCRuby_write_hostdefs(CFCRuby *self) {
         "\n"
         "%s\n";
     char *content
-        = CFCUtil_sprintf(pattern, self->header, self->footer);
+        = CFCUtil_sprintf(pattern, self->c_header, self->c_footer);
 
     // Unlink then write file.
     const char *inc_dest = CFCHierarchy_get_include_dest(self->hierarchy);

http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/eaf2c94b/compiler/src/CFCUtil.c
----------------------------------------------------------------------
diff --git a/compiler/src/CFCUtil.c b/compiler/src/CFCUtil.c
index fdcfe7a..c3b47d7 100644
--- a/compiler/src/CFCUtil.c
+++ b/compiler/src/CFCUtil.c
@@ -144,6 +144,57 @@ CFCUtil_trim_whitespace(char *text) {
     *text = '\0';
 }
 
+char*
+CFCUtil_enclose_lines(const char *text, const char *line_prefix,
+                      const char *line_postfix, const char *prefix,
+                      const char *postfix) {
+    if (!text) { return NULL; }
+
+    if (!line_prefix)  { line_prefix  = ""; }
+    if (!line_postfix) { line_postfix = ""; }
+    if (!prefix)       { prefix       = ""; }
+    if (!postfix)      { postfix      = ""; }
+
+    char *result = CFCUtil_strdup(prefix);
+
+    const char *line_start = text;
+    const char *text_end   = text + strlen(text);
+
+    while (line_start < text_end) {
+        const char *line_end = strchr(line_start, '\n');
+        const char *next_start;
+        size_t      line_len;
+
+        if (line_end == NULL) {
+            line_len   = text_end - line_start;
+            next_start = text_end;
+        }
+        else {
+            line_len   = line_end - line_start;
+            next_start = line_end + 1;
+        }
+
+        char *line = (char*)MALLOCATE(line_len + 1);
+        memcpy(line, line_start, line_len);
+        line[line_len] = '\0';
+        result = CFCUtil_cat(result, line_prefix, line, line_postfix, "\n",
+                             NULL);
+        FREEMEM(line);
+
+        line_start = next_start;
+    }
+
+    result = CFCUtil_cat(result, postfix, NULL);
+
+    return result;
+}
+
+char*
+CFCUtil_make_c_comment(const char *text) {
+    if (text && text[0] == '\0') { return CFCUtil_strdup(text); }
+    return CFCUtil_enclose_lines(text, " * ", "", "/*\n", " */\n");
+}
+
 void*
 CFCUtil_wrapped_malloc(size_t count, const char *file, int line) {
     void *pointer = malloc(count);

http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/eaf2c94b/compiler/src/CFCUtil.h
----------------------------------------------------------------------
diff --git a/compiler/src/CFCUtil.h b/compiler/src/CFCUtil.h
index 961bccf..6012b3d 100644
--- a/compiler/src/CFCUtil.h
+++ b/compiler/src/CFCUtil.h
@@ -69,6 +69,19 @@ CFCUtil_cat(char *string, ...);
 void
 CFCUtil_trim_whitespace(char *text);
 
+/** Enclose every line in text with line_prefix and line_postfix and the
+ * whole text with prefix and postfix.
+ */
+char*
+CFCUtil_enclose_lines(const char *text, const char *line_prefix,
+                      const char *line_postfix, const char *prefix,
+                      const char *postfix);
+
+/** Create a C comment.
+ */
+char*
+CFCUtil_make_c_comment(const char *text);
+
 /** Attempt to allocate memory with malloc, but print an error and exit if the
  * call fails.
  */

http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/eaf2c94b/runtime/c/cfc_header
----------------------------------------------------------------------
diff --git a/runtime/c/cfc_header b/runtime/c/cfc_header
index d982cf9..f2fff7c 100644
--- a/runtime/c/cfc_header
+++ b/runtime/c/cfc_header
@@ -1,23 +1,22 @@
-/***********************************************
+***********************************************
 
- !!!! DO NOT EDIT !!!!
+!!!! DO NOT EDIT !!!!
 
- This file was auto-generated by cfc.
+This file was auto-generated by cfc.
 
- ***********************************************/
+***********************************************
 
-/* Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
+Licensed to the Apache Software Foundation (ASF) under one or more
+contributor license agreements.  See the NOTICE file distributed with
+this work for additional information regarding copyright ownership.
+The ASF licenses this file to You under the Apache License, Version 2.0
+(the "License"); you may not use this file except in compliance with
+the License.  You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.

http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/eaf2c94b/runtime/perl/buildlib/Clownfish/Build.pm
----------------------------------------------------------------------
diff --git a/runtime/perl/buildlib/Clownfish/Build.pm b/runtime/perl/buildlib/Clownfish/Build.pm
index 0b7da01..b0743e2 100644
--- a/runtime/perl/buildlib/Clownfish/Build.pm
+++ b/runtime/perl/buildlib/Clownfish/Build.pm
@@ -246,30 +246,28 @@ sub ACTION_test_valgrind {
 
 sub _autogen_header {
     return <<"END_AUTOGEN";
-/***********************************************
-
- !!!! DO NOT EDIT !!!!
-
- This file was auto-generated by Build.PL.
-
- ***********************************************/
-
-/* Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
+***********************************************
 
+!!!! DO NOT EDIT !!!!
+
+This file was auto-generated by Build.PL.
+
+***********************************************
+
+Licensed to the Apache Software Foundation (ASF) under one or more
+contributor license agreements.  See the NOTICE file distributed with
+this work for additional information regarding copyright ownership.
+The ASF licenses this file to You under the Apache License, Version 2.0
+(the "License"); you may not use this file except in compliance with
+the License.  You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
 END_AUTOGEN
 }
 

http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/eaf2c94b/runtime/ruby/Rakefile.common
----------------------------------------------------------------------
diff --git a/runtime/ruby/Rakefile.common b/runtime/ruby/Rakefile.common
index cca6c09..3e61582 100644
--- a/runtime/ruby/Rakefile.common
+++ b/runtime/ruby/Rakefile.common
@@ -136,13 +136,13 @@ end
 
 def autogen_header
   "
-/***********************************************
+***********************************************
 
- !!!! DO NOT EDIT !!!!
+!!!! DO NOT EDIT !!!!
 
- This file was auto-generated by Rakefile.
+This file was auto-generated by Rakefile.
 
- ***********************************************/
+***********************************************
  "
 
 end


[2/4] lucy-clownfish git commit: Fix StringIterator documentation

Posted by nw...@apache.org.
Fix StringIterator documentation


Project: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/repo
Commit: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/commit/c8e8fe08
Tree: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/tree/c8e8fe08
Diff: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/diff/c8e8fe08

Branch: refs/heads/master
Commit: c8e8fe08bca11bcaf3925473dfee244c0dcfcb06
Parents: ebef22b
Author: Nick Wellnhofer <we...@aevum.de>
Authored: Sat Aug 23 19:16:57 2014 +0200
Committer: Nick Wellnhofer <we...@aevum.de>
Committed: Tue Nov 11 16:08:32 2014 +0100

----------------------------------------------------------------------
 runtime/core/Clownfish/String.cfh | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/c8e8fe08/runtime/core/Clownfish/String.cfh
----------------------------------------------------------------------
diff --git a/runtime/core/Clownfish/String.cfh b/runtime/core/Clownfish/String.cfh
index a053e99..383f6b7 100644
--- a/runtime/core/Clownfish/String.cfh
+++ b/runtime/core/Clownfish/String.cfh
@@ -319,8 +319,8 @@ class Clownfish::StringIterator nickname StrIter
     new(String *string, size_t byte_offset);
 
     /** Return the substring between the top and tail iterators.
-     * @param offset Top iterator. Use start of string if NULL.
-     * @param len Tail iterator. Use end of string if NULL.
+     * @param top Top iterator. Use start of string if NULL.
+     * @param tail Tail iterator. Use end of string if NULL.
      */
     inert incremented String*
     substring(StringIterator *top, StringIterator *tail);


[4/4] lucy-clownfish git commit: Don't hardcode POD and man page headers

Posted by nw...@apache.org.
Don't hardcode POD and man page headers

Use the supplied autogen header and footer instead.


Project: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/repo
Commit: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/commit/92efcd66
Tree: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/tree/92efcd66
Diff: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/diff/92efcd66

Branch: refs/heads/master
Commit: 92efcd6634eae3efa0edd1089558da4ee0f9b5e6
Parents: eaf2c94
Author: Nick Wellnhofer <we...@aevum.de>
Authored: Sat Aug 23 17:41:01 2014 +0200
Committer: Nick Wellnhofer <we...@aevum.de>
Committed: Tue Nov 11 16:17:23 2014 +0100

----------------------------------------------------------------------
 compiler/src/CFCC.c         | 19 ++++++++++----
 compiler/src/CFCCClass.c    | 28 +++++---------------
 compiler/src/CFCPerl.c      | 14 ++++++++--
 compiler/src/CFCPerlClass.c | 55 ++++++++++++++--------------------------
 compiler/src/CFCUtil.c      | 10 ++++++++
 compiler/src/CFCUtil.h      | 10 ++++++++
 6 files changed, 72 insertions(+), 64 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/92efcd66/compiler/src/CFCC.c
----------------------------------------------------------------------
diff --git a/compiler/src/CFCC.c b/compiler/src/CFCC.c
index e0a355d..60a949b 100644
--- a/compiler/src/CFCC.c
+++ b/compiler/src/CFCC.c
@@ -32,6 +32,8 @@ struct CFCC {
     CFCHierarchy *hierarchy;
     char         *c_header;
     char         *c_footer;
+    char         *man_header;
+    char         *man_footer;
 };
 
 static const CFCMeta CFCC_META = {
@@ -52,9 +54,11 @@ CFCC_init(CFCC *self, CFCHierarchy *hierarchy, const char *header,
     CFCUTIL_NULL_CHECK(hierarchy);
     CFCUTIL_NULL_CHECK(header);
     CFCUTIL_NULL_CHECK(footer);
-    self->hierarchy = (CFCHierarchy*)CFCBase_incref((CFCBase*)hierarchy);
-    self->c_header  = CFCUtil_make_c_comment(header);
-    self->c_footer  = CFCUtil_make_c_comment(footer);
+    self->hierarchy  = (CFCHierarchy*)CFCBase_incref((CFCBase*)hierarchy);
+    self->c_header   = CFCUtil_make_c_comment(header);
+    self->c_footer   = CFCUtil_make_c_comment(footer);
+    self->man_header = CFCUtil_make_troff_comment(header);
+    self->man_footer = CFCUtil_make_troff_comment(footer);
     return self;
 }
 
@@ -63,6 +67,8 @@ CFCC_destroy(CFCC *self) {
     CFCBase_decref((CFCBase*)self->hierarchy);
     FREEMEM(self->c_header);
     FREEMEM(self->c_footer);
+    FREEMEM(self->man_header);
+    FREEMEM(self->man_footer);
     CFCBase_destroy((CFCBase*)self);
 }
 
@@ -151,8 +157,10 @@ CFCC_write_man_pages(CFCC *self) {
         CFCClass *klass = ordered[i];
         if (CFCClass_included(klass)) { continue; }
 
-        char *man_page = man_pages[j++];
-        if (!man_page) { continue; }
+        char *raw_man_page = man_pages[j++];
+        if (!raw_man_page) { continue; }
+        char *man_page = CFCUtil_sprintf("%s%s%s", self->man_header,
+                                         raw_man_page, self->man_footer);
 
         const char *full_struct_sym = CFCClass_full_struct_sym(klass);
         char *filename = CFCUtil_sprintf("%s" CHY_DIR_SEP "%s.3", man3_path,
@@ -160,6 +168,7 @@ CFCC_write_man_pages(CFCC *self) {
         CFCUtil_write_if_changed(filename, man_page, strlen(man_page));
         FREEMEM(filename);
         FREEMEM(man_page);
+        FREEMEM(raw_man_page);
     }
 
     FREEMEM(man3_path);

http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/92efcd66/compiler/src/CFCCClass.c
----------------------------------------------------------------------
diff --git a/compiler/src/CFCCClass.c b/compiler/src/CFCCClass.c
index b6def3b..8dfe9db 100644
--- a/compiler/src/CFCCClass.c
+++ b/compiler/src/CFCCClass.c
@@ -121,27 +121,13 @@ CFCCClass_create_man_page(CFCClass *klass) {
 
     // Put it all together.
     const char pattern[] =
-    ".\\\" Licensed to the Apache Software Foundation (ASF) under one or more\n"
-    ".\\\" contributor license agreements.  See the NOTICE file distributed with\n"
-    ".\\\" this work for additional information regarding copyright ownership.\n"
-    ".\\\" The ASF licenses this file to You under the Apache License, Version 2.0\n"
-    ".\\\" (the \"License\"); you may not use this file except in compliance with\n"
-    ".\\\" the License.  You may obtain a copy of the License at\n"
-    ".\\\"\n"
-    ".\\\"     http://www.apache.org/licenses/LICENSE-2.0\n"
-    ".\\\"\n"
-    ".\\\" Unless required by applicable law or agreed to in writing, software\n"
-    ".\\\" distributed under the License is distributed on an \"AS IS\" BASIS,\n"
-    ".\\\" WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n"
-    ".\\\" See the License for the specific language governing permissions and\n"
-    ".\\\" limitations under the License.\n"
-    ".TH %s 3\n"
-    "%s"
-    "%s"
-    "%s"
-    "%s"
-    "%s"
-    "%s";
+        ".TH %s 3\n"
+        "%s"
+        "%s"
+        "%s"
+        "%s"
+        "%s"
+        "%s";
     char *man_page
         = CFCUtil_sprintf(pattern, class_name, name, synopsis, description,
                           functions_man, methods_man, inheritance);

http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/92efcd66/compiler/src/CFCPerl.c
----------------------------------------------------------------------
diff --git a/compiler/src/CFCPerl.c b/compiler/src/CFCPerl.c
index c78fcbf..a04bb61 100644
--- a/compiler/src/CFCPerl.c
+++ b/compiler/src/CFCPerl.c
@@ -43,6 +43,8 @@ struct CFCPerl {
     char *footer;
     char *c_header;
     char *c_footer;
+    char *pod_header;
+    char *pod_footer;
     char *xs_path;
     char *boot_func;
 };
@@ -82,6 +84,8 @@ CFCPerl_init(CFCPerl *self, CFCHierarchy *hierarchy, const char *lib_dir,
     self->footer     = CFCUtil_strdup(footer);
     self->c_header   = CFCUtil_make_c_comment(header);
     self->c_footer   = CFCUtil_make_c_comment(footer);
+    self->pod_header = CFCUtil_make_perl_comment(header);
+    self->pod_footer = CFCUtil_make_perl_comment(footer);
 
     // Derive path to generated .xs file.
     self->xs_path = CFCUtil_sprintf("%s" CHY_DIR_SEP "%s.xs", lib_dir,
@@ -108,6 +112,8 @@ CFCPerl_destroy(CFCPerl *self) {
     FREEMEM(self->footer);
     FREEMEM(self->c_header);
     FREEMEM(self->c_footer);
+    FREEMEM(self->pod_header);
+    FREEMEM(self->pod_footer);
     FREEMEM(self->xs_path);
     FREEMEM(self->boot_func);
     CFCBase_destroy((CFCBase*)self);
@@ -141,8 +147,10 @@ CFCPerl_write_pod(CFCPerl *self) {
     // generating pod, we leak memory but don't clutter up the file system.
     for (size_t i = 0; i < num_registered; i++) {
         const char *class_name = CFCPerlClass_get_class_name(registry[i]);
-        char *pod = CFCPerlClass_create_pod(registry[i]);
-        if (!pod) { continue; }
+        char *raw_pod = CFCPerlClass_create_pod(registry[i]);
+        if (!raw_pod) { continue; }
+        char *pod = CFCUtil_sprintf("%s\n%s%s", self->pod_header, raw_pod,
+                                    self->pod_footer);
         char *pod_path = CFCUtil_sprintf("%s" CHY_DIR_SEP "%s.pod",
                                          self->lib_dir, class_name);
         S_replace_double_colons(pod_path, CHY_DIR_SEP_CHAR);
@@ -150,6 +158,8 @@ CFCPerl_write_pod(CFCPerl *self) {
         pods[count] = pod;
         pod_paths[count] = pod_path;
         count++;
+
+        FREEMEM(raw_pod);
     }
 
     // Write out any POD files that have changed.

http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/92efcd66/compiler/src/CFCPerlClass.c
----------------------------------------------------------------------
diff --git a/compiler/src/CFCPerlClass.c b/compiler/src/CFCPerlClass.c
index 14af20a..b35b29c 100644
--- a/compiler/src/CFCPerlClass.c
+++ b/compiler/src/CFCPerlClass.c
@@ -406,42 +406,25 @@ CFCPerlClass_create_pod(CFCPerlClass *self) {
     }
 
     // Put it all together.
-    const char pattern[] = 
-    "# Auto-generated file -- DO NOT EDIT!!!!!\n"
-    "\n"
-    "# Licensed to the Apache Software Foundation (ASF) under one or more\n"
-    "# contributor license agreements.  See the NOTICE file distributed with\n"
-    "# this work for additional information regarding copyright ownership.\n"
-    "# The ASF licenses this file to You under the Apache License, Version 2.0\n"
-    "# (the \"License\"); you may not use this file except in compliance with\n"
-    "# the License.  You may obtain a copy of the License at\n"
-    "#\n"
-    "#     http://www.apache.org/licenses/LICENSE-2.0\n"
-    "#\n"
-    "# Unless required by applicable law or agreed to in writing, software\n"
-    "# distributed under the License is distributed on an \"AS IS\" BASIS,\n"
-    "# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n"
-    "# See the License for the specific language governing permissions and\n"
-    "# limitations under the License.\n"
-    "\n"
-    "=head1 NAME\n"
-    "\n"
-    "%s - %s\n"
-    "\n"
-    "%s\n"
-    "\n"
-    "=head1 DESCRIPTION\n"
-    "\n"
-    "%s\n"
-    "\n"
-    "%s\n"
-    "\n"
-    "%s\n"
-    "\n"
-    "%s\n"
-    "\n"
-    "=cut\n"
-    "\n";
+    const char pattern[] =
+        "=head1 NAME\n"
+        "\n"
+        "%s - %s\n"
+        "\n"
+        "%s\n"
+        "\n"
+        "=head1 DESCRIPTION\n"
+        "\n"
+        "%s\n"
+        "\n"
+        "%s\n"
+        "\n"
+        "%s\n"
+        "\n"
+        "%s\n"
+        "\n"
+        "=cut\n"
+        "\n";
     char *pod
         = CFCUtil_sprintf(pattern, class_name, brief, synopsis, description,
                           constructor_pod, methods_pod, inheritance);

http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/92efcd66/compiler/src/CFCUtil.c
----------------------------------------------------------------------
diff --git a/compiler/src/CFCUtil.c b/compiler/src/CFCUtil.c
index c3b47d7..e3f05d3 100644
--- a/compiler/src/CFCUtil.c
+++ b/compiler/src/CFCUtil.c
@@ -195,6 +195,16 @@ CFCUtil_make_c_comment(const char *text) {
     return CFCUtil_enclose_lines(text, " * ", "", "/*\n", " */\n");
 }
 
+char*
+CFCUtil_make_perl_comment(const char *text) {
+    return CFCUtil_enclose_lines(text, "# ", "", "", "");
+}
+
+char*
+CFCUtil_make_troff_comment(const char *text) {
+    return CFCUtil_enclose_lines(text, ".\\\" ", "", "", "");
+}
+
 void*
 CFCUtil_wrapped_malloc(size_t count, const char *file, int line) {
     void *pointer = malloc(count);

http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/92efcd66/compiler/src/CFCUtil.h
----------------------------------------------------------------------
diff --git a/compiler/src/CFCUtil.h b/compiler/src/CFCUtil.h
index 6012b3d..6540672 100644
--- a/compiler/src/CFCUtil.h
+++ b/compiler/src/CFCUtil.h
@@ -82,6 +82,16 @@ CFCUtil_enclose_lines(const char *text, const char *line_prefix,
 char*
 CFCUtil_make_c_comment(const char *text);
 
+/** Create a Perl comment.
+ */
+char*
+CFCUtil_make_perl_comment(const char *text);
+
+/** Create a troff comment.
+ */
+char*
+CFCUtil_make_troff_comment(const char *text);
+
 /** Attempt to allocate memory with malloc, but print an error and exit if the
  * call fails.
  */