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 2013/07/20 18:06:00 UTC

[lucy-commits] [1/4] git commit: refs/heads/cfc-pod - Extract CFC DocuComments from C headers

Updated Branches:
  refs/heads/cfc-pod [created] 5d8677be6


Extract CFC DocuComments from C headers

Write a quick and dirty parser that builds CFC classes with DocuComments
from C headers. Then the .pod files for Clownfish::CFC can be generated
using CFC itself.


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

Branch: refs/heads/cfc-pod
Commit: 5d8677be6b0a1a04908b2eb3e363de2dc2328990
Parents: d9d1ec1
Author: Nick Wellnhofer <we...@aevum.de>
Authored: Sat Jul 20 17:47:57 2013 +0200
Committer: Nick Wellnhofer <we...@aevum.de>
Committed: Sat Jul 20 18:05:22 2013 +0200

----------------------------------------------------------------------
 clownfish/compiler/perl/.gitignore              |   1 +
 .../perl/buildlib/Clownfish/CFC/Build.pm        |  65 +++++++
 .../buildlib/Clownfish/CFC/Build/Binding.pm     | 170 +++++++++++++++++++
 3 files changed, 236 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/lucy/blob/5d8677be/clownfish/compiler/perl/.gitignore
----------------------------------------------------------------------
diff --git a/clownfish/compiler/perl/.gitignore b/clownfish/compiler/perl/.gitignore
index 5517019..36bb0e4 100644
--- a/clownfish/compiler/perl/.gitignore
+++ b/clownfish/compiler/perl/.gitignore
@@ -1,3 +1,4 @@
+*.pod
 /Build
 /Charmony.pm
 /MYMETA.json

http://git-wip-us.apache.org/repos/asf/lucy/blob/5d8677be/clownfish/compiler/perl/buildlib/Clownfish/CFC/Build.pm
----------------------------------------------------------------------
diff --git a/clownfish/compiler/perl/buildlib/Clownfish/CFC/Build.pm b/clownfish/compiler/perl/buildlib/Clownfish/CFC/Build.pm
index 4ba1a6b..2f4cc2a 100644
--- a/clownfish/compiler/perl/buildlib/Clownfish/CFC/Build.pm
+++ b/clownfish/compiler/perl/buildlib/Clownfish/CFC/Build.pm
@@ -146,5 +146,70 @@ sub ACTION_code {
     $self->SUPER::ACTION_code;
 }
 
+sub ACTION_pod {
+    my $self = shift;
+
+    local @INC = ( @INC, qw( blib/lib blib/arch ) );
+    require Clownfish::CFC;
+
+    # Create a dummy hierarchy.
+    my $hierarchy = Clownfish::CFC::Model::Hierarchy->new(
+        dest => 'autogen',
+    );
+
+    # Process all Binding classes in buildlib.
+    my $pm_filepaths = $self->rscan_dir( 'buildlib', qr/\.pm$/ );
+    for my $pm_filepath (@$pm_filepaths) {
+        next unless $pm_filepath =~ /Binding/;
+        require $pm_filepath;
+        my $package_name = $pm_filepath;
+        $package_name =~ s/buildlib\/(.*)\.pm$/$1/;
+        $package_name =~ s/\//::/g;
+        $package_name->bind_all($hierarchy);
+    }
+
+    my $binding = Clownfish::CFC::Binding::Perl->new(
+        hierarchy  => $hierarchy,
+        lib_dir    => 'lib',
+        boot_class => 'Clownfish::CFC',
+        header     => $self->autogen_header,
+        footer     => '',
+    );
+
+    print "Writing POD...\n";
+    my $pod_files = $binding->write_pod;
+    $self->add_to_cleanup($_) for @$pod_files;
+}
+
+sub autogen_header {
+    my $self = shift;
+    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.
+ */
+
+END_AUTOGEN
+}
+
 1;
 

http://git-wip-us.apache.org/repos/asf/lucy/blob/5d8677be/clownfish/compiler/perl/buildlib/Clownfish/CFC/Build/Binding.pm
----------------------------------------------------------------------
diff --git a/clownfish/compiler/perl/buildlib/Clownfish/CFC/Build/Binding.pm b/clownfish/compiler/perl/buildlib/Clownfish/CFC/Build/Binding.pm
new file mode 100644
index 0000000..0819b4b
--- /dev/null
+++ b/clownfish/compiler/perl/buildlib/Clownfish/CFC/Build/Binding.pm
@@ -0,0 +1,170 @@
+# 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.
+
+package Clownfish::CFC::Build::Binding;
+use strict;
+
+sub bind_all {
+    my $class = shift;
+    $class->bind_perlclass;
+}
+
+sub bind_perlclass {
+    class_from_c('CFCPerlClass', 'Clownfish::CFC::Binding::Perl::Class');
+
+    my @exposed = qw(
+        Bind_Constructor
+        Bind_Method
+        Exclude_Constructor
+        Exclude_Method
+        Set_Pod_Spec
+    );
+
+    my $pod_spec = Clownfish::CFC::Binding::Perl::Pod->new;
+    $pod_spec->add_constructor( alias => 'new' );
+    $pod_spec->add_method( method => $_, alias => lc($_) ) for @exposed;
+
+    my $binding = Clownfish::CFC::Binding::Perl::Class->new(
+        class_name => 'Clownfish::CFC::Binding::Perl::Class',
+    );
+    $binding->set_pod_spec($pod_spec);
+
+    Clownfish::CFC::Binding::Perl::Class->register($binding);
+}
+
+# Quick and dirty hack to create a CFC class from a C header.
+sub class_from_c {
+    my ($cfc_class_name, $class_name) = @_;
+
+    $class_name =~ /::(\w+)$/;
+    my $last_component = $1;
+
+    my $h_filename = "../src/$cfc_class_name.h";
+    open(my $h_file, '<', $h_filename)
+        or die("$h_filename: $!");
+
+    my ($class_doc, $function_doc, @functions);
+    my $state = 'before_class_doc';
+
+    while (my $line = <$h_file>) {
+        if ($state eq 'before_class_doc') {
+            if ($line =~ m"^/\*\*") {
+                $class_doc = $line;
+                $state = 'in_class_doc';
+            }
+        }
+        elsif ($state eq 'in_class_doc') {
+            $class_doc .= $line;
+            if ($line =~ m"\*/") {
+                $state = 'before_function_doc';
+            }
+        }
+        elsif ($state eq 'before_function_doc') {
+            if ($line =~ m"^/\*\*") {
+                $function_doc = $line;
+                $state = 'in_function_doc';
+            }
+        }
+        elsif ($state eq 'in_function_doc') {
+            $function_doc .= $line;
+            if ($line =~ m"\*/") {
+                $state = 'after_function_doc';
+            }
+        }
+        elsif ($state eq 'after_function_doc') {
+            if ($line =~ m"^${cfc_class_name}_(\w+)(\(.*)") {
+                my $function_name = $1;
+                my $c_params      = $2;
+
+                while ($c_params !~ /\)/) {
+                    $c_params .= <$h_file>;
+                }
+
+                $c_params =~ s/\).*/\)/;
+
+                push(@functions, {
+                    name     => $function_name,
+                    c_params => $c_params,
+                    doc      => $function_doc,
+                });
+
+                $state = 'before_function_doc';
+            }
+        }
+    }
+
+    close($h_file);
+
+    my $class = Clownfish::CFC::Model::Class->create(
+        class_name  => $class_name,
+        docucomment => Clownfish::CFC::Model::DocuComment->parse($class_doc),
+    );
+
+    my $parser = Clownfish::CFC::Parser->new;
+    my $void_type = Clownfish::CFC::Model::Type->new_void;
+
+    for my $function (@functions) {
+        my $name     = $function->{name};
+        my $c_params = $function->{c_params};
+        my $dc = Clownfish::CFC::Model::DocuComment->parse($function->{doc});
+
+        # "struct" is not allowed in Clownfish types.
+        $c_params =~ s/\bstruct //g;
+        # Clownfish reserved words.
+        $c_params =~ s/\bparcel\b/_$&/g;
+        # Empty param list.
+        $c_params = '()' if $c_params eq '(void)';
+
+        if ($c_params =~ /\($cfc_class_name \*self/) {
+            my $macro_sym = $name;
+            $macro_sym =~ s/(^|_)([a-z])/$1 . uc($2)/ge;
+
+            $c_params =~ s/^\(\w+/($last_component/;
+            my $param_list = $parser->parse($c_params)
+                or die("Invalid param list: $c_params");
+
+            my $method = Clownfish::CFC::Model::Method->new(
+                class_name  => $class_name,
+                exposure    => 'public',
+                macro_sym   => $macro_sym,
+                docucomment => $dc,
+                return_type => $void_type,
+                param_list  => $param_list,
+            );
+            $class->add_method($method);
+        }
+        else {
+            $name = 'init' if $name eq 'new';
+
+            my $param_list = $parser->parse($c_params)
+                or die("Invalid param list: $c_params");
+
+            my $function = Clownfish::CFC::Model::Function->new(
+                class_name  => $class_name,
+                exposure    => 'public',
+                micro_sym   => $name,
+                docucomment => $dc,
+                return_type => $void_type,
+                param_list  => $param_list,
+            );
+            $class->add_function($function);
+        }
+    }
+
+    return $class;
+}
+
+1;
+


[lucy-commits] [3/4] git commit: refs/heads/cfc-pod - Fix Clownfish::CFC::Model::ParamList constructor

Posted by nw...@apache.org.
Fix Clownfish::CFC::Model::ParamList constructor


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

Branch: refs/heads/cfc-pod
Commit: d9d1ec1d265446ce2e363d2c060066cdb68af1e4
Parents: 7adad47
Author: Nick Wellnhofer <we...@aevum.de>
Authored: Sat Jul 20 17:29:06 2013 +0200
Committer: Nick Wellnhofer <we...@aevum.de>
Committed: Sat Jul 20 18:05:22 2013 +0200

----------------------------------------------------------------------
 clownfish/compiler/perl/lib/Clownfish/CFC.xs | 2 +-
 clownfish/compiler/perl/t/301-param_list.t   | 4 +++-
 2 files changed, 4 insertions(+), 2 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/lucy/blob/d9d1ec1d/clownfish/compiler/perl/lib/Clownfish/CFC.xs
----------------------------------------------------------------------
diff --git a/clownfish/compiler/perl/lib/Clownfish/CFC.xs b/clownfish/compiler/perl/lib/Clownfish/CFC.xs
index fafe3c3..93c1f97 100644
--- a/clownfish/compiler/perl/lib/Clownfish/CFC.xs
+++ b/clownfish/compiler/perl/lib/Clownfish/CFC.xs
@@ -1029,7 +1029,7 @@ PPCODE:
 MODULE = Clownfish::CFC   PACKAGE = Clownfish::CFC::Model::ParamList
 
 SV*
-_new(klass, variadic)
+_new(variadic)
     int variadic;
 CODE:
     CFCParamList *self = CFCParamList_new(variadic);

http://git-wip-us.apache.org/repos/asf/lucy/blob/d9d1ec1d/clownfish/compiler/perl/t/301-param_list.t
----------------------------------------------------------------------
diff --git a/clownfish/compiler/perl/t/301-param_list.t b/clownfish/compiler/perl/t/301-param_list.t
index fb6505b..bec8118 100644
--- a/clownfish/compiler/perl/t/301-param_list.t
+++ b/clownfish/compiler/perl/t/301-param_list.t
@@ -16,10 +16,12 @@
 use strict;
 use warnings;
 
-use Test::More tests => 13;
+use Test::More tests => 14;
 
 BEGIN { use_ok('Clownfish::CFC::Model::ParamList') }
 
+ok( Clownfish::CFC::Model::ParamList->new, 'new' );
+
 my $parser = Clownfish::CFC::Parser->new;
 $parser->parse('parcel Neato;')
     or die "failed to process parcel_definition";


[lucy-commits] [2/4] git commit: refs/heads/cfc-pod - Fix a double-free in CFCPerlClass

Posted by nw...@apache.org.
Fix a double-free in CFCPerlClass


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

Branch: refs/heads/cfc-pod
Commit: 7adad47713579ab21b94ec02a509a68f14eba568
Parents: 0d32936
Author: Nick Wellnhofer <we...@aevum.de>
Authored: Sat Jul 20 17:23:51 2013 +0200
Committer: Nick Wellnhofer <we...@aevum.de>
Committed: Sat Jul 20 18:05:22 2013 +0200

----------------------------------------------------------------------
 clownfish/compiler/src/CFCPerlClass.c | 1 -
 1 file changed, 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/lucy/blob/7adad477/clownfish/compiler/src/CFCPerlClass.c
----------------------------------------------------------------------
diff --git a/clownfish/compiler/src/CFCPerlClass.c b/clownfish/compiler/src/CFCPerlClass.c
index 05dc585..a3c8670 100644
--- a/clownfish/compiler/src/CFCPerlClass.c
+++ b/clownfish/compiler/src/CFCPerlClass.c
@@ -90,7 +90,6 @@ CFCPerlClass_init(CFCPerlClass *self, CFCParcel *parcel,
 void
 CFCPerlClass_destroy(CFCPerlClass *self) {
     CFCBase_decref((CFCBase*)self->parcel);
-    CFCBase_decref((CFCBase*)self->client);
     CFCBase_decref((CFCBase*)self->pod_spec);
     FREEMEM(self->class_name);
     FREEMEM(self->xs_code);


[lucy-commits] [4/4] git commit: refs/heads/cfc-pod - Add a check to CFCPerlPod_constructors_pod

Posted by nw...@apache.org.
Add a check to CFCPerlPod_constructors_pod


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

Branch: refs/heads/cfc-pod
Commit: 0d329362cb9a6f4ef67d59be4ad7bbe835ed9844
Parents: f089ae8
Author: Nick Wellnhofer <we...@aevum.de>
Authored: Sat Jul 20 17:21:50 2013 +0200
Committer: Nick Wellnhofer <we...@aevum.de>
Committed: Sat Jul 20 18:05:22 2013 +0200

----------------------------------------------------------------------
 clownfish/compiler/src/CFCPerlPod.c | 4 ++++
 1 file changed, 4 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/lucy/blob/0d329362/clownfish/compiler/src/CFCPerlPod.c
----------------------------------------------------------------------
diff --git a/clownfish/compiler/src/CFCPerlPod.c b/clownfish/compiler/src/CFCPerlPod.c
index 78c804f..a1040e2 100644
--- a/clownfish/compiler/src/CFCPerlPod.c
+++ b/clownfish/compiler/src/CFCPerlPod.c
@@ -210,6 +210,10 @@ CFCPerlPod_constructors_pod(CFCPerlPod *self, CFCClass *klass) {
         }
         else {
             CFCFunction *init_func = CFCClass_function(klass, slot.func);
+            if (!init_func) {
+                CFCUtil_die("Can't find function '%s' in class '%s'",
+                            slot.func, CFCClass_get_class_name(klass));
+            }
             char *sub_pod
                 = CFCPerlPod_gen_subroutine_pod(self, init_func, slot.alias, klass,
                                                 slot.sample, class_name, true);