New directory layout for installed Clownfish headers
The .cfh files of a parcel are installed to a separate directory:
$prefix/$parcel/$version
The installed .cfp file is renamed to "parcel.json".
This makes it possible to parse only those .cfh files that are really
required. Also, .cfh files for different versions of a parcel can be
installed. A couple of checks for clashes between files and classes
from source and include directories become unnecessary.
For the C bindings, write headers for installed parcels to the autogen
directory first.
Enable major version checks for parcels from include directories.
Project: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/repo
Commit: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/commit/719095c8
Tree: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/tree/719095c8
Diff: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/diff/719095c8
Branch: refs/heads/master
Commit: 719095c8e27be1c235a91113732efa7c57953905
Parents: 6ab4fc6
Author: Nick Wellnhofer <[email protected]>
Authored: Fri Jul 15 20:20:54 2016 +0200
Committer: Nick Wellnhofer <[email protected]>
Committed: Fri Jul 22 14:17:26 2016 +0200
----------------------------------------------------------------------
compiler/c/cfc.c | 2 +
compiler/common/test/cfclash/bar/Bar.cfp | 5 +-
.../test/cfclash/class/AnimalExtension.cfp | 5 +-
compiler/common/test/cfclash/foo/Foo.cfh | 25 ---
compiler/common/test/cfclash/foo/Foo.cfp | 4 -
.../common/test/cfinc/Animal/v0.1.0/Animal.cfh | 21 ++
.../test/cfinc/Animal/v0.1.0/Animal/Dog.cfh | 28 +++
.../test/cfinc/Animal/v0.1.0/Animal/Util.cfh | 23 +++
.../common/test/cfinc/Animal/v0.1.0/parcel.json | 4 +
compiler/common/test/cfinc/Foo/v1.0.0/Foo.cfh | 25 +++
.../common/test/cfinc/Foo/v1.0.0/parcel.json | 4 +
compiler/perl/lib/Clownfish/CFC.xs | 17 +-
compiler/perl/lib/Clownfish/CFC/Perl/Build.pm | 22 +-
compiler/perl/t/403-parcel.t | 7 +-
compiler/src/CFCBindCore.c | 74 ++++++-
compiler/src/CFCBindCore.h | 9 +
compiler/src/CFCClass.c | 32 +--
compiler/src/CFCHierarchy.c | 203 ++++++++++++++-----
compiler/src/CFCParcel.c | 44 ----
compiler/src/CFCParcel.h | 12 --
compiler/src/CFCTestHierarchy.c | 66 +-----
compiler/src/CFCTestParcel.c | 7 +-
compiler/src/CFCVersion.c | 13 ++
compiler/src/CFCVersion.h | 3 +
devel/bin/setup_env.bat | 2 +-
devel/bin/setup_env.sh | 2 +-
runtime/c/install.bat | 5 +-
runtime/c/install.sh | 19 +-
runtime/core/Clownfish.cfp | 3 +-
runtime/test/TestClownfish.cfp | 1 +
30 files changed, 408 insertions(+), 279 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/719095c8/compiler/c/cfc.c
----------------------------------------------------------------------
diff --git a/compiler/c/cfc.c b/compiler/c/cfc.c
index 369a0b1..d329708 100644
--- a/compiler/c/cfc.c
+++ b/compiler/c/cfc.c
@@ -248,6 +248,8 @@ main(int argc, char **argv) {
CFCC_write_man_pages(c_binding);
}
+ CFCBindCore_copy_headers(core_binding, NULL);
+
CFCHierarchy_write_log(hierarchy);
CFCBase_decref((CFCBase*)c_binding);
http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/719095c8/compiler/common/test/cfclash/bar/Bar.cfp
----------------------------------------------------------------------
diff --git a/compiler/common/test/cfclash/bar/Bar.cfp
b/compiler/common/test/cfclash/bar/Bar.cfp
index e5868f6..e5d281e 100644
--- a/compiler/common/test/cfclash/bar/Bar.cfp
+++ b/compiler/common/test/cfclash/bar/Bar.cfp
@@ -1,4 +1,7 @@
{
"name": "Bar",
- "version": "v1.0.0"
+ "version": "v1.0.0",
+ "prerequisites": {
+ "Foo": "v1.0.0"
+ }
}
http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/719095c8/compiler/common/test/cfclash/class/AnimalExtension.cfp
----------------------------------------------------------------------
diff --git a/compiler/common/test/cfclash/class/AnimalExtension.cfp
b/compiler/common/test/cfclash/class/AnimalExtension.cfp
index 76f31d3..8b8e75b 100644
--- a/compiler/common/test/cfclash/class/AnimalExtension.cfp
+++ b/compiler/common/test/cfclash/class/AnimalExtension.cfp
@@ -1,5 +1,8 @@
{
"name": "AnimalExtension",
"nickname": "AniExt",
- "version": "v0.1.0"
+ "version": "v0.1.0",
+ "prerequisites": {
+ "Animal": null
+ }
}
http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/719095c8/compiler/common/test/cfclash/foo/Foo.cfh
----------------------------------------------------------------------
diff --git a/compiler/common/test/cfclash/foo/Foo.cfh
b/compiler/common/test/cfclash/foo/Foo.cfh
deleted file mode 100644
index b770d8a..0000000
--- a/compiler/common/test/cfclash/foo/Foo.cfh
+++ /dev/null
@@ -1,25 +0,0 @@
-/* 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.
- */
-
-parcel Foo;
-
-public class Foo inherits Clownfish::Obj {
- int var;
-
- public void
- Method(Foo *self);
-}
-
http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/719095c8/compiler/common/test/cfclash/foo/Foo.cfp
----------------------------------------------------------------------
diff --git a/compiler/common/test/cfclash/foo/Foo.cfp
b/compiler/common/test/cfclash/foo/Foo.cfp
deleted file mode 100644
index 2995169..0000000
--- a/compiler/common/test/cfclash/foo/Foo.cfp
+++ /dev/null
@@ -1,4 +0,0 @@
-{
- "name": "Foo",
- "version": "v1.0.0"
-}
http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/719095c8/compiler/common/test/cfinc/Animal/v0.1.0/Animal.cfh
----------------------------------------------------------------------
diff --git a/compiler/common/test/cfinc/Animal/v0.1.0/Animal.cfh
b/compiler/common/test/cfinc/Animal/v0.1.0/Animal.cfh
new file mode 100644
index 0000000..46130b7
--- /dev/null
+++ b/compiler/common/test/cfinc/Animal/v0.1.0/Animal.cfh
@@ -0,0 +1,21 @@
+/* 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.
+ */
+
+parcel Animal;
+
+class Clownfish::Obj { }
+
+abstract class Animal { }
http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/719095c8/compiler/common/test/cfinc/Animal/v0.1.0/Animal/Dog.cfh
----------------------------------------------------------------------
diff --git a/compiler/common/test/cfinc/Animal/v0.1.0/Animal/Dog.cfh
b/compiler/common/test/cfinc/Animal/v0.1.0/Animal/Dog.cfh
new file mode 100644
index 0000000..6d54baa
--- /dev/null
+++ b/compiler/common/test/cfinc/Animal/v0.1.0/Animal/Dog.cfh
@@ -0,0 +1,28 @@
+/* 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.
+ */
+
+parcel Animal;
+
+class Animal::Dog inherits Animal {
+ public inert incremented Dog*
+ new();
+
+ public inert Dog*
+ init(Dog *self);
+
+ public void
+ Bark(Dog *self);
+}
http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/719095c8/compiler/common/test/cfinc/Animal/v0.1.0/Animal/Util.cfh
----------------------------------------------------------------------
diff --git a/compiler/common/test/cfinc/Animal/v0.1.0/Animal/Util.cfh
b/compiler/common/test/cfinc/Animal/v0.1.0/Animal/Util.cfh
new file mode 100644
index 0000000..f5688a5
--- /dev/null
+++ b/compiler/common/test/cfinc/Animal/v0.1.0/Animal/Util.cfh
@@ -0,0 +1,23 @@
+/* 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.
+ */
+
+parcel Animal;
+
+inert class Animal::Util {
+ inert void
+ groom(Animal *animal);
+}
+
http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/719095c8/compiler/common/test/cfinc/Animal/v0.1.0/parcel.json
----------------------------------------------------------------------
diff --git a/compiler/common/test/cfinc/Animal/v0.1.0/parcel.json
b/compiler/common/test/cfinc/Animal/v0.1.0/parcel.json
new file mode 100644
index 0000000..e2b5ab5
--- /dev/null
+++ b/compiler/common/test/cfinc/Animal/v0.1.0/parcel.json
@@ -0,0 +1,4 @@
+{
+ "name": "Animal",
+ "version": "v0.1.0"
+}
http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/719095c8/compiler/common/test/cfinc/Foo/v1.0.0/Foo.cfh
----------------------------------------------------------------------
diff --git a/compiler/common/test/cfinc/Foo/v1.0.0/Foo.cfh
b/compiler/common/test/cfinc/Foo/v1.0.0/Foo.cfh
new file mode 100644
index 0000000..b770d8a
--- /dev/null
+++ b/compiler/common/test/cfinc/Foo/v1.0.0/Foo.cfh
@@ -0,0 +1,25 @@
+/* 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.
+ */
+
+parcel Foo;
+
+public class Foo inherits Clownfish::Obj {
+ int var;
+
+ public void
+ Method(Foo *self);
+}
+
http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/719095c8/compiler/common/test/cfinc/Foo/v1.0.0/parcel.json
----------------------------------------------------------------------
diff --git a/compiler/common/test/cfinc/Foo/v1.0.0/parcel.json
b/compiler/common/test/cfinc/Foo/v1.0.0/parcel.json
new file mode 100644
index 0000000..2995169
--- /dev/null
+++ b/compiler/common/test/cfinc/Foo/v1.0.0/parcel.json
@@ -0,0 +1,4 @@
+{
+ "name": "Foo",
+ "version": "v1.0.0"
+}
http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/719095c8/compiler/perl/lib/Clownfish/CFC.xs
----------------------------------------------------------------------
diff --git a/compiler/perl/lib/Clownfish/CFC.xs
b/compiler/perl/lib/Clownfish/CFC.xs
index 08930e1..74bce9d 100644
--- a/compiler/perl/lib/Clownfish/CFC.xs
+++ b/compiler/perl/lib/Clownfish/CFC.xs
@@ -1142,12 +1142,6 @@ add_inherited_parcel(self, inherited)
PPCODE:
CFCParcel_add_inherited_parcel(self, inherited);
-void
-check_prereqs(self)
- CFCParcel *self;
-PPCODE:
- CFCParcel_check_prereqs(self);
-
int
has_prereq(self, parcel)
CFCParcel *self;
@@ -1190,7 +1184,6 @@ ALIAS:
get_version = 12
get_prereqs = 14
included = 16
- required = 18
prereq_parcels = 20
inherited_parcels = 22
PPCODE:
@@ -1234,9 +1227,6 @@ PPCODE:
case 16:
retval = newSViv(CFCParcel_included(self));
break;
- case 18:
- retval = newSViv(CFCParcel_required(self));
- break;
case 20: {
CFCParcel **parcels = CFCParcel_prereq_parcels(self);
retval = S_array_of_cfcbase_to_av((CFCBase**)parcels);
@@ -1887,6 +1877,13 @@ CODE:
}
OUTPUT: RETVAL
+void
+copy_headers(self, dest_dir)
+ CFCBindCore *self;
+ const char *dest_dir;
+PPCODE:
+ CFCBindCore_copy_headers(self, dest_dir);
+
MODULE = Clownfish::CFC PACKAGE = Clownfish::CFC::Binding::Core::Function
http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/719095c8/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 dfb9417..f1c351f 100644
--- a/compiler/perl/lib/Clownfish/CFC/Perl/Build.pm
+++ b/compiler/perl/lib/Clownfish/CFC/Perl/Build.pm
@@ -199,24 +199,6 @@ sub cf_copy_include_file {
die( "Clownfish include file " . catfile(@path) . " not found" );
}
-sub ACTION_copy_clownfish_includes {
- my $self = shift;
-
- # Copy .cfh files to blib/arch/Clownfish/_include
- my $inc_dir = catdir( $self->blib, 'arch', 'Clownfish', '_include' );
- my $source_dirs = $self->clownfish_params('source');
-
- for my $source_dir (@$source_dirs) {
- my $cfh_filepaths = $self->rscan_dir( $source_dir, qr/\.cf[hp]$/ );
-
- for my $file (@$cfh_filepaths) {
- my $rel = abs2rel( $file, $source_dir );
- my $dest = catfile( $inc_dir, $rel );
- $self->copy_if_modified( from => $file, to => $dest );
- }
- }
-}
-
my %hierarchy_cache;
sub _compile_clownfish {
@@ -312,6 +294,9 @@ sub ACTION_clownfish {
print "Writing typemap...\n";
$self->add_to_cleanup('typemap');
$perl_binding->write_xs_typemap;
+
+ my $inc_dir = catdir( $self->blib, 'arch', 'Clownfish', '_include' );
+ $core_binding->copy_headers($inc_dir);
}
# Rewrite XS if either any .cfh files or relevant .pm files were modified.
@@ -531,7 +516,6 @@ sub ACTION_code {
$self->depends_on(qw(
clownfish
compile_custom_xs
- copy_clownfish_includes
));
$self->SUPER::ACTION_code;
http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/719095c8/compiler/perl/t/403-parcel.t
----------------------------------------------------------------------
diff --git a/compiler/perl/t/403-parcel.t b/compiler/perl/t/403-parcel.t
index ada6c31..c984af8 100644
--- a/compiler/perl/t/403-parcel.t
+++ b/compiler/perl/t/403-parcel.t
@@ -17,7 +17,7 @@ use strict;
use warnings;
use Clownfish::CFC::Test::TestUtils qw( test_files_dir );
-use Test::More tests => 35;
+use Test::More tests => 32;
use File::Spec::Functions qw( catdir );
BEGIN { use_ok('Clownfish::CFC::Model::Prereq') }
@@ -182,11 +182,6 @@ Clownfish::CFC::Model::Parcel->reap_singletons();
my $crust = Clownfish::CFC::Model::Parcel->new_from_json( json => $json );
$crust->register;
- $crust->check_prereqs;
- ok( !$foo->required, 'parcel not required' );
- ok( $cfish->required, 'prereq required' );
- ok( $crust->required, 'self required' );
-
my $prereq_parcels = $crust->prereq_parcels;
isa_ok( $prereq_parcels, 'ARRAY', 'prereq_parcels' );
is( scalar(@$prereq_parcels), 1, 'number of prereq_parcels' );
http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/719095c8/compiler/src/CFCBindCore.c
----------------------------------------------------------------------
diff --git a/compiler/src/CFCBindCore.c b/compiler/src/CFCBindCore.c
index 7d43415..138297a 100644
--- a/compiler/src/CFCBindCore.c
+++ b/compiler/src/CFCBindCore.c
@@ -30,6 +30,7 @@
#include "CFCHierarchy.h"
#include "CFCParcel.h"
#include "CFCUtil.h"
+#include "CFCVersion.h"
#define STRING(s) #s
#define XSTRING(s) STRING(s)
@@ -133,11 +134,9 @@ CFCBindCore_write_all_modified(CFCBindCore *self, int
modified) {
CFCParcel **parcels = CFCParcel_all_parcels();
for (size_t i = 0; parcels[i]; ++i) {
CFCParcel *parcel = parcels[i];
- if (CFCParcel_required(parcel)) {
- S_write_parcel_h(self, parcel);
- if (!CFCParcel_included(parcel)) {
- S_write_parcel_c(self, parcel);
- }
+ S_write_parcel_h(self, parcel);
+ if (!CFCParcel_included(parcel)) {
+ S_write_parcel_c(self, parcel);
}
}
}
@@ -695,4 +694,69 @@ S_charmony_alloca_defines() {
return defines;
}
+void
+CFCBindCore_copy_headers(CFCBindCore *self, const char *dest_dir) {
+ char *default_dest = NULL;
+
+ if (dest_dir == NULL) {
+ default_dest = CFCUtil_sprintf("%s" CHY_DIR_SEP "share" CHY_DIR_SEP
+ "clownfish" CHY_DIR_SEP "include",
+ CFCHierarchy_get_dest(self->hierarchy));
+ dest_dir = default_dest;
+ }
+
+ /* Copy .cfp files. */
+ CFCParcel **parcels = CFCParcel_all_parcels();
+ for (size_t i = 0; parcels[i] != NULL; i++) {
+ CFCParcel *parcel = parcels[i];
+ if (CFCParcel_included(parcel) || !CFCParcel_is_installed(parcel)) {
+ continue;
+ }
+
+ const char *source_path = CFCParcel_get_cfp_path(parcel);
+ const char *parcel_name = CFCParcel_get_name(parcel);
+ CFCVersion *version = CFCParcel_get_version(parcel);
+ const char *vstring = CFCVersion_get_vstring(version);
+
+ char *dest_path = CFCUtil_sprintf("%s" CHY_DIR_SEP "%s" CHY_DIR_SEP
+ "%s" CHY_DIR_SEP "parcel.json",
+ dest_dir, parcel_name, vstring);
+
+ size_t len = 0;
+ char *content = CFCUtil_slurp_text(source_path, &len);
+ CFCUtil_write_file(dest_path, content, len);
+
+ FREEMEM(content);
+ FREEMEM(dest_path);
+ }
+
+ /* Copy .cfh files. */
+ CFCFile **files = CFCHierarchy_files(self->hierarchy);
+ for (size_t i = 0; files[i] != NULL; i++) {
+ CFCFile *file = files[i];
+ if (CFCFile_included(file)) { continue; }
+ CFCParcel *parcel = CFCFile_get_parcel(file);
+ if (!CFCParcel_is_installed(parcel)) { continue; }
+
+ const char *source_path = CFCFile_get_path(file);
+ const char *parcel_name = CFCParcel_get_name(parcel);
+ CFCVersion *version = CFCParcel_get_version(parcel);
+ const char *vstring = CFCVersion_get_vstring(version);
+ const char *path_part = CFCFile_get_path_part(file);
+
+ char *dest_path = CFCUtil_sprintf("%s" CHY_DIR_SEP "%s" CHY_DIR_SEP
+ "%s" CHY_DIR_SEP "%s.cfh", dest_dir,
+ parcel_name, vstring, path_part);
+
+ size_t len = 0;
+ char *content = CFCUtil_slurp_text(source_path, &len);
+ CFCUtil_write_file(dest_path, content, len);
+
+ FREEMEM(content);
+ FREEMEM(dest_path);
+ }
+
+ FREEMEM(default_dest);
+}
+
http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/719095c8/compiler/src/CFCBindCore.h
----------------------------------------------------------------------
diff --git a/compiler/src/CFCBindCore.h b/compiler/src/CFCBindCore.h
index 04392ef..eff3efe 100644
--- a/compiler/src/CFCBindCore.h
+++ b/compiler/src/CFCBindCore.h
@@ -57,6 +57,15 @@ CFCBindCore_destroy(CFCBindCore *self);
int
CFCBindCore_write_all_modified(CFCBindCore *self, int modified);
+/** Copy .cfh and .cfp files for installed source parcels to the autogen
+ * directory.
+ *
+ * @param dest_dir Destination directory. Defaults to
+ * `autogen/share/clownfish/include` if NULL.
+ */
+void
+CFCBindCore_copy_headers(CFCBindCore *self, const char *dest_dir);
+
#ifdef __cplusplus
}
#endif
http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/719095c8/compiler/src/CFCClass.c
----------------------------------------------------------------------
diff --git a/compiler/src/CFCClass.c b/compiler/src/CFCClass.c
index 1bcc433..7fa7ff0 100644
--- a/compiler/src/CFCClass.c
+++ b/compiler/src/CFCClass.c
@@ -295,31 +295,21 @@ CFCClass_do_create(CFCClass *self, struct CFCParcel
*parcel,
name, CFCParcel_get_name(parcel));
}
- // Skip class if it's from an include dir and the parcel was already
- // processed in another source or include dir.
- const char *class_source_dir = CFCClass_get_source_dir(self);
- const char *parcel_source_dir = CFCParcel_get_source_dir(parcel);
- if (!CFCClass_included(self)
- || !class_source_dir
- || !parcel_source_dir
- || strcmp(class_source_dir, parcel_source_dir) == 0
- ) {
- char *error;
-
- CFCUTIL_TRY {
- // Store in registry.
- S_register(self);
- }
- CFCUTIL_CATCH(error);
+ char *error;
- if (error) {
- CFCBase_decref((CFCBase*)self);
- CFCUtil_rethrow(error);
- }
+ CFCUTIL_TRY {
+ // Store in registry.
+ S_register(self);
+ }
+ CFCUTIL_CATCH(error);
- CFCParcel_add_struct_sym(parcel, self->struct_sym);
+ if (error) {
+ CFCBase_decref((CFCBase*)self);
+ CFCUtil_rethrow(error);
}
+ CFCParcel_add_struct_sym(parcel, self->struct_sym);
+
return self;
}
http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/719095c8/compiler/src/CFCHierarchy.c
----------------------------------------------------------------------
diff --git a/compiler/src/CFCHierarchy.c b/compiler/src/CFCHierarchy.c
index 6e0d787..c33c4f8 100644
--- a/compiler/src/CFCHierarchy.c
+++ b/compiler/src/CFCHierarchy.c
@@ -38,6 +38,7 @@
#include "CFCUtil.h"
#include "CFCParser.h"
#include "CFCDocument.h"
+#include "CFCVersion.h"
struct CFCHierarchy {
CFCBase base;
@@ -67,10 +68,17 @@ typedef struct CFCFindFilesContext {
} CFCFindFilesContext;
static void
-S_parse_parcel_files(const char *source_dir, int is_included);
+S_parse_source_cfp_files(const char *source_dir);
static void
-S_check_prereqs(CFCHierarchy *self);
+S_find_prereqs(CFCHierarchy *self, CFCParcel *parcel);
+
+static void
+S_find_prereq(CFCHierarchy *self, CFCParcel *parent, CFCPrereq *prereq);
+
+static CFCParcel*
+S_audition_parcel(const char *version_dir, const char *vstring,
+ CFCVersion *min_version, CFCParcel *best);
static void
S_parse_cf_files(CFCHierarchy *self, const char *source_dir, int is_included);
@@ -208,21 +216,36 @@ void
CFCHierarchy_build(CFCHierarchy *self) {
// Read .cfp files.
for (size_t i = 0; self->sources[i] != NULL; i++) {
- S_parse_parcel_files(self->sources[i], false);
- }
- for (size_t i = 0; self->includes[i] != NULL; i++) {
- S_parse_parcel_files(self->includes[i], true);
+ S_parse_source_cfp_files(self->sources[i]);
}
- S_check_prereqs(self);
+ // Copy array of source parcels.
+ CFCParcel **parcels = CFCParcel_all_parcels();
+ size_t num_source_parcels = 0;
+ while (parcels[num_source_parcels] != NULL) { num_source_parcels++; }
+ size_t alloc_size = num_source_parcels * sizeof(CFCParcel*);
+ CFCParcel **source_parcels = (CFCParcel**)MALLOCATE(alloc_size);
+ memcpy(source_parcels, parcels, alloc_size);
+
+ // Find prerequisite parcels.
+ for (size_t i = 0; i < num_source_parcels; i++) {
+ S_find_prereqs(self, source_parcels[i]);
+ }
// Read .cfh and .md files.
for (size_t i = 0; self->sources[i] != NULL; i++) {
S_parse_cf_files(self, self->sources[i], false);
S_find_doc_files(self->sources[i]);
}
- for (size_t i = 0; self->includes[i] != NULL; i++) {
- S_parse_cf_files(self, self->includes[i], true);
+
+ // Read .cfh files of included parcels.
+ parcels = CFCParcel_all_parcels();
+ for (size_t i = 0; parcels[i] != NULL; i++) {
+ CFCParcel *parcel = parcels[i];
+ if (CFCParcel_included(parcel)) {
+ const char *source_dir = CFCParcel_get_source_dir(parcel);
+ S_parse_cf_files(self, source_dir, true);
+ }
}
for (int i = 0; self->classes[i] != NULL; i++) {
@@ -233,10 +256,12 @@ CFCHierarchy_build(CFCHierarchy *self) {
for (size_t i = 0; self->trees[i] != NULL; i++) {
CFCClass_grow_tree(self->trees[i]);
}
+
+ FREEMEM(source_parcels);
}
static void
-S_parse_parcel_files(const char *source_dir, int is_included) {
+S_parse_source_cfp_files(const char *source_dir) {
CFCFindFilesContext context;
context.ext = ".cfp";
context.paths = (char**)CALLOCATE(1, sizeof(char*));
@@ -248,21 +273,14 @@ S_parse_parcel_files(const char *source_dir, int
is_included) {
const char *path = context.paths[i];
char *path_part = S_extract_path_part(path, source_dir, ".cfp");
CFCFileSpec *file_spec
- = CFCFileSpec_new(source_dir, path_part, ".cfp", is_included);
+ = CFCFileSpec_new(source_dir, path_part, ".cfp", false);
CFCParcel *parcel = CFCParcel_new_from_file(file_spec);
const char *name = CFCParcel_get_name(parcel);
CFCParcel *existing = CFCParcel_fetch(name);
if (existing) {
- const char *existing_source_dir
- = CFCParcel_get_source_dir(existing);
- CFCUTIL_NULL_CHECK(existing_source_dir);
- // Skip parcel if it's from an include dir and was already
- // processed in another source or include dir.
- if (!is_included || strcmp(source_dir, existing_source_dir) == 0) {
- CFCUtil_die("Parcel '%s' defined twice in %s and %s",
- CFCParcel_get_name(parcel),
- CFCParcel_get_cfp_path(existing), path);
- }
+ CFCUtil_die("Parcel '%s' defined twice in %s and %s",
+ CFCParcel_get_name(parcel),
+ CFCParcel_get_cfp_path(existing), path);
}
else {
CFCParcel_register(parcel);
@@ -276,26 +294,122 @@ S_parse_parcel_files(const char *source_dir, int
is_included) {
}
static void
-S_check_prereqs(CFCHierarchy *self) {
- CFCParcel **parcels = CFCParcel_all_parcels();
+S_find_prereqs(CFCHierarchy *self, CFCParcel *parcel) {
+ CFCPrereq **prereqs = CFCParcel_get_prereqs(parcel);
+
+ for (size_t i = 0; prereqs[i] != NULL; i++) {
+ S_find_prereq(self, parcel, prereqs[i]);
+ }
+}
+static void
+S_find_prereq(CFCHierarchy *self, CFCParcel *parent, CFCPrereq *prereq) {
+ const char *name = CFCPrereq_get_name(prereq);
+ CFCVersion *min_version = CFCPrereq_get_version(prereq);
+
+ // Check whether prereq was processed already.
+ CFCParcel **parcels = CFCParcel_all_parcels();
for (int i = 0; parcels[i]; ++i) {
CFCParcel *parcel = parcels[i];
- if (!CFCParcel_included(parcel)) {
- CFCParcel_check_prereqs(parcel);
+ const char *other_name = CFCParcel_get_name(parcel);
+
+ if (strcmp(other_name, name) == 0) {
+ CFCVersion *other_version = CFCParcel_get_version(parcel);
+ CFCVersion *major_version = CFCParcel_get_major_version(parcel);
+
+ if (CFCVersion_compare_to(major_version, min_version) <= 0
+ && CFCVersion_compare_to(min_version, other_version) <= 0
+ ) {
+ // Compatible version found.
+ return;
+ }
+ else {
+ CFCUtil_die("Parcel %s %s required by %s not compatible with"
+ " version %s required by %s",
+ name, other_version, "[TODO]",
+ CFCVersion_get_vstring(min_version),
+ CFCParcel_get_name(parent));
+ }
}
}
- for (int i = 0; self->prereqs[i]; ++i) {
- const char *prereq = self->prereqs[i];
- CFCParcel *parcel = CFCParcel_fetch(prereq);
- if (parcel == NULL) {
- CFCUtil_die("Prerequisite parcel '%s' not found", prereq);
+ CFCParcel *parcel = NULL;
+
+ // TODO: Decide whether to prefer higher versions from directories
+ // that come later in the list of include dirs or stop processing once
+ // a suitable version was found in a dir.
+ for (size_t i = 0; self->includes[i] != NULL; i++) {
+ char *name_dir = CFCUtil_sprintf("%s" CHY_DIR_SEP "%s",
+ self->includes[i], name);
+
+ if (CFCUtil_is_dir(name_dir)) {
+ void *dirhandle = CFCUtil_opendir(name_dir);
+ const char *entry = NULL;
+
+ while (NULL != (entry = CFCUtil_dirnext(dirhandle))) {
+ if (!CFCVersion_is_vstring(entry)) { continue; }
+
+ char *version_dir = CFCUtil_sprintf("%s" CHY_DIR_SEP "%s",
+ name_dir, entry);
+
+ if (CFCUtil_is_dir(version_dir)) {
+ parcel = S_audition_parcel(version_dir, entry, min_version,
+ parcel);
+ }
+
+ FREEMEM(version_dir);
+ }
+
+ CFCUtil_closedir(dirhandle, name_dir);
+ }
+
+ FREEMEM(name_dir);
+ }
+
+ if (parcel == NULL) {
+ CFCUtil_die("Parcel %s %s required by %s not found",
+ name, CFCVersion_get_vstring(min_version),
+ CFCParcel_get_name(parent));
+ }
+
+ CFCParcel_register(parcel);
+
+ S_find_prereqs(self, parcel);
+
+ CFCBase_decref((CFCBase*)parcel);
+}
+
+static CFCParcel*
+S_audition_parcel(const char *version_dir, const char *vstring,
+ CFCVersion *min_version, CFCParcel *best) {
+ CFCVersion *version = CFCVersion_new(vstring);
+ CFCVersion *best_version = best ? CFCParcel_get_version(best) : NULL;
+
+ // Version must match min_version and be greater than the previous best.
+ if (CFCVersion_compare_to(version, min_version) >= 0
+ && (best_version == NULL
+ || CFCVersion_compare_to(version, best_version) > 0)
+ ) {
+ // Parse parcel JSON for major version check.
+ CFCFileSpec *file_spec = CFCFileSpec_new(version_dir, "parcel",
+ ".json", true);
+ CFCParcel *parcel = CFCParcel_new_from_file(file_spec);
+ CFCVersion *major_version = CFCParcel_get_major_version(parcel);
+
+ if (CFCVersion_compare_to(major_version, min_version) <= 0) {
+ CFCBase_decref((CFCBase*)best);
+ best = parcel;
}
else {
- CFCParcel_check_prereqs(parcel);
+ CFCBase_decref((CFCBase*)parcel);
}
+
+ CFCBase_decref((CFCBase*)file_spec);
}
+
+ CFCBase_decref((CFCBase*)version);
+
+ return best;
}
static void
@@ -331,26 +445,17 @@ S_parse_cf_files(CFCHierarchy *self, const char
*source_dir, int is_included) {
CFCUtil_die("%s:%d: parser error", source_path, lineno);
}
- // Add parsed file to pool if it's from a required parcel. Skip
- // file if it's from an include dir and the parcel was already
- // processed in another source or include dir.
- CFCParcel *parcel = CFCFile_get_parcel(file);
- const char *parcel_source_dir = CFCParcel_get_source_dir(parcel);
- CFCUTIL_NULL_CHECK(parcel_source_dir);
- if (CFCParcel_required(parcel)
- && (!is_included || strcmp(source_dir, parcel_source_dir) == 0)) {
- // Make sure path_part is unique because the name of the generated
- // C header is derived from it.
- CFCFile *existing = S_fetch_file(self, path_part);
- if (existing) {
- CFCUtil_die("File %s.cfh found twice in %s and %s",
- path_part, CFCFile_get_source_dir(existing),
- source_dir);
- }
-
- S_add_file(self, file);
+ // Make sure path_part is unique because the name of the generated
+ // C header is derived from it.
+ CFCFile *existing = S_fetch_file(self, path_part);
+ if (existing) {
+ CFCUtil_die("File %s.cfh found twice in %s and %s",
+ path_part, CFCFile_get_source_dir(existing),
+ source_dir);
}
+ S_add_file(self, file);
+
CFCBase_decref((CFCBase*)file);
CFCBase_decref((CFCBase*)file_spec);
FREEMEM(path_part);
http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/719095c8/compiler/src/CFCParcel.c
----------------------------------------------------------------------
diff --git a/compiler/src/CFCParcel.c b/compiler/src/CFCParcel.c
index b7f93d5..3b79d71 100644
--- a/compiler/src/CFCParcel.c
+++ b/compiler/src/CFCParcel.c
@@ -42,7 +42,6 @@ struct CFCParcel {
char *PREFIX;
char *privacy_sym;
int is_installed;
- int is_required;
char **inherited_parcels;
size_t num_inherited_parcels;
char **struct_syms;
@@ -209,7 +208,6 @@ CFCParcel_init(CFCParcel *self, const char *name, const
char *nickname,
// Initialize flags.
self->is_installed = false;
- self->is_required = false;
// Initialize arrays.
self->inherited_parcels = (char**)CALLOCATE(1, sizeof(char*));
@@ -451,11 +449,6 @@ CFCParcel_included(CFCParcel *self) {
return self->file_spec ? CFCFileSpec_included(self->file_spec) : false;
}
-int
-CFCParcel_required(CFCParcel *self) {
- return self->is_required;
-}
-
void
CFCParcel_add_inherited_parcel(CFCParcel *self, CFCParcel *inherited) {
const char *name = CFCParcel_get_name(self);
@@ -508,43 +501,6 @@ CFCParcel_prereq_parcels(CFCParcel *self) {
return parcels;
}
-void
-CFCParcel_check_prereqs(CFCParcel *self) {
- // This is essentially a depth-first search of the dependency graph.
- // It might be possible to skip indirect dependencies, at least if
- // they're not part of the inheritance chain. But for now, all
- // dependencies are marked recursively.
-
- if (self->is_required) { return; }
- self->is_required = true;
-
- const char *name = CFCParcel_get_name(self);
-
- for (int i = 0; self->prereqs[i]; ++i) {
- CFCPrereq *prereq = self->prereqs[i];
-
- const char *req_name = CFCPrereq_get_name(prereq);
- CFCParcel *req_parcel = CFCParcel_fetch(req_name);
- if (!req_parcel) {
- // TODO: Add include path to error message.
- CFCUtil_die("Parcel '%s' required by '%s' not found", req_name,
- name);
- }
-
- CFCVersion *version = req_parcel->version;
- CFCVersion *req_version = CFCPrereq_get_version(prereq);
- if (CFCVersion_compare_to(version, req_version) < 0) {
- const char *vstring = CFCVersion_get_vstring(version);
- const char *req_vstring = CFCVersion_get_vstring(req_version);
- CFCUtil_die("Version %s of parcel '%s' required by '%s' is lower"
- " than required version %s",
- vstring, req_name, name, req_vstring);
- }
-
- CFCParcel_check_prereqs(req_parcel);
- }
-}
-
int
CFCParcel_has_prereq(CFCParcel *self, CFCParcel *parcel) {
const char *name = CFCParcel_get_name(parcel);
http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/719095c8/compiler/src/CFCParcel.h
----------------------------------------------------------------------
diff --git a/compiler/src/CFCParcel.h b/compiler/src/CFCParcel.h
index 47dc445..ddcc2bd 100644
--- a/compiler/src/CFCParcel.h
+++ b/compiler/src/CFCParcel.h
@@ -136,12 +136,6 @@ CFCParcel_get_source_dir(CFCParcel *self);
int
CFCParcel_included(CFCParcel *self);
-/** Return true if the parcel is required. This is only valid after all
- * prerequisites were checked.
- */
-int
-CFCParcel_required(CFCParcel *self);
-
/** Add another Parcel containing superclasses that subclasses in the Parcel
* extend.
*/
@@ -165,12 +159,6 @@ CFCParcel_get_prereqs(CFCParcel *self);
CFCParcel**
CFCParcel_prereq_parcels(CFCParcel *self);
-/** Recursively verify that all prerequisite parcels are present in the
- * required version. Mark all needed parcels including 'self' as required.
- */
-void
-CFCParcel_check_prereqs(CFCParcel *self);
-
/** Return true if parcel equals self or is a direct prerequisite of self.
*/
int
http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/719095c8/compiler/src/CFCTestHierarchy.c
----------------------------------------------------------------------
diff --git a/compiler/src/CFCTestHierarchy.c b/compiler/src/CFCTestHierarchy.c
index 03d0df8..6fa1aae 100644
--- a/compiler/src/CFCTestHierarchy.c
+++ b/compiler/src/CFCTestHierarchy.c
@@ -55,7 +55,7 @@ S_run_clash_tests(CFCTest *test);
const CFCTestBatch CFCTEST_BATCH_HIERARCHY = {
"Clownfish::CFC::Model::Hierarchy",
- 47,
+ 41,
S_run_tests
};
@@ -168,13 +168,14 @@ static void
S_run_include_tests(CFCTest *test) {
char *cfbase_path = CFCTest_path("cfbase");
char *cfext_path = CFCTest_path("cfext");
+ char *cfinc_path = CFCTest_path("cfinc");
{
CFCHierarchy *hierarchy = CFCHierarchy_new(AUTOGEN);
CFCHierarchy_add_source_dir(hierarchy, cfext_path);
- CFCHierarchy_add_include_dir(hierarchy, cfbase_path);
+ CFCHierarchy_add_include_dir(hierarchy, cfinc_path);
const char **include_dirs = CFCHierarchy_get_include_dirs(hierarchy);
- STR_EQ(test, include_dirs[0], cfbase_path, "include_dirs[0]");
+ STR_EQ(test, include_dirs[0], cfinc_path, "include_dirs[0]");
OK(test, include_dirs[1] == NULL, "include_dirs[1]");
CFCHierarchy_build(hierarchy);
@@ -235,49 +236,21 @@ S_run_include_tests(CFCTest *test) {
CFCParcel_reap_singletons();
}
- {
- CFCHierarchy *hierarchy = CFCHierarchy_new(AUTOGEN);
- CFCHierarchy_add_include_dir(hierarchy, cfbase_path);
- CFCHierarchy_add_include_dir(hierarchy, cfext_path);
- CFCHierarchy_add_prereq(hierarchy, "AnimalExtension");
-
- CFCHierarchy_build(hierarchy);
-
- CFCParcel *animal = CFCParcel_fetch("Animal");
- OK(test, animal != NULL, "parcel Animal registered");
- OK(test, CFCParcel_required(animal), "parcel Animal required");
- CFCParcel *animal_ext = CFCParcel_fetch("AnimalExtension");
- OK(test, animal_ext != NULL, "parcel AnimalExtension registered");
- OK(test, CFCParcel_required(animal_ext),
- "parcel AnimalExtension required");
-
- CFCClass **classes = CFCHierarchy_ordered_classes(hierarchy);
- int num_classes = 0;
- while (classes[num_classes]) {
- ++num_classes;
- }
- INT_EQ(test, num_classes, 5, "class count");
-
- FREEMEM(classes);
- CFCBase_decref((CFCBase*)hierarchy);
- CFCClass_clear_registry();
- CFCParcel_reap_singletons();
- }
-
rmdir(AUTOGEN_INCLUDE);
rmdir(AUTOGEN_SOURCE);
rmdir(AUTOGEN);
FREEMEM(cfbase_path);
FREEMEM(cfext_path);
+ FREEMEM(cfinc_path);
}
static void
S_run_clash_tests(CFCTest *test) {
char *cfbase_path = CFCTest_path("cfbase");
+ char *cfinc_path = CFCTest_path("cfinc");
char *cfclash_file_path = CFCTest_path("cfclash" CHY_DIR_SEP "file");
char *cfclash_class_path = CFCTest_path("cfclash" CHY_DIR_SEP "class");
- char *cfclash_foo_path = CFCTest_path("cfclash" CHY_DIR_SEP "foo");
char *cfclash_bar_path = CFCTest_path("cfclash" CHY_DIR_SEP "bar");
if (getenv("CLOWNFISH_VALGRIND")) {
@@ -307,7 +280,7 @@ S_run_clash_tests(CFCTest *test) {
else {
CFCHierarchy *hierarchy = CFCHierarchy_new(AUTOGEN);
CFCHierarchy_add_source_dir(hierarchy, cfclash_class_path);
- CFCHierarchy_add_include_dir(hierarchy, cfbase_path);
+ CFCHierarchy_add_include_dir(hierarchy, cfinc_path);
char *error;
CFCUTIL_TRY {
@@ -322,38 +295,22 @@ S_run_clash_tests(CFCTest *test) {
CFCParcel_reap_singletons();
}
- {
- CFCHierarchy *hierarchy = CFCHierarchy_new(AUTOGEN);
- CFCHierarchy_add_source_dir(hierarchy, cfbase_path);
- CFCHierarchy_add_include_dir(hierarchy, cfclash_file_path);
-
- CFCHierarchy_build(hierarchy);
- CFCClass **ordered = CFCHierarchy_ordered_classes(hierarchy);
- int count = 0;
- while (ordered[count]) { count++; }
- INT_EQ(test, count, 4, "source/include filename clash");
-
- FREEMEM(ordered);
- CFCBase_decref((CFCBase*)hierarchy);
- CFCClass_clear_registry();
- CFCParcel_reap_singletons();
- }
-
if (getenv("CLOWNFISH_VALGRIND")) {
SKIP(test, 1, "Exceptions leak");
}
else {
CFCHierarchy *hierarchy = CFCHierarchy_new(AUTOGEN);
CFCHierarchy_add_source_dir(hierarchy, cfclash_bar_path);
- CFCHierarchy_add_include_dir(hierarchy, cfclash_foo_path);
- CFCHierarchy_add_include_dir(hierarchy, cfbase_path);
+ CFCHierarchy_add_include_dir(hierarchy, cfinc_path);
char *error;
CFCUTIL_TRY {
CFCHierarchy_build(hierarchy);
}
CFCUTIL_CATCH(error);
- OK(test, error && strstr(error, "from source dir found"),
+ const char *message =
+ "Class Baz from source dir found in parcel Foo from include dir";
+ OK(test, error && strstr(error, message),
"source class with included parcel");
CFCBase_decref((CFCBase*)hierarchy);
@@ -368,7 +325,6 @@ S_run_clash_tests(CFCTest *test) {
FREEMEM(cfbase_path);
FREEMEM(cfclash_file_path);
FREEMEM(cfclash_class_path);
- FREEMEM(cfclash_foo_path);
FREEMEM(cfclash_bar_path);
}
http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/719095c8/compiler/src/CFCTestParcel.c
----------------------------------------------------------------------
diff --git a/compiler/src/CFCTestParcel.c b/compiler/src/CFCTestParcel.c
index 8103351..878ab02 100644
--- a/compiler/src/CFCTestParcel.c
+++ b/compiler/src/CFCTestParcel.c
@@ -46,7 +46,7 @@ S_run_extended_tests(CFCTest *test);
const CFCTestBatch CFCTEST_BATCH_PARCEL = {
"Clownfish::CFC::Model::Parcel",
- 44,
+ 41,
S_run_tests
};
@@ -266,11 +266,6 @@ S_run_extended_tests(CFCTest *test) {
CFCParcel *crust = CFCParcel_new_from_json(crust_json, NULL);
CFCParcel_register(crust);
- CFCParcel_check_prereqs(crust);
- INT_EQ(test, CFCParcel_required(foo), false, "parcel not required");
- INT_EQ(test, CFCParcel_required(cfish), true, "prereq required");
- INT_EQ(test, CFCParcel_required(crust), true, "self required");
-
CFCParcel **prereq_parcels = CFCParcel_prereq_parcels(crust);
OK(test, prereq_parcels[0] != NULL, "prereq_parcels[0]");
const char *name = CFCParcel_get_name(prereq_parcels[0]);
http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/719095c8/compiler/src/CFCVersion.c
----------------------------------------------------------------------
diff --git a/compiler/src/CFCVersion.c b/compiler/src/CFCVersion.c
index 74d3c39..e68c5a6 100644
--- a/compiler/src/CFCVersion.c
+++ b/compiler/src/CFCVersion.c
@@ -39,6 +39,19 @@ static const CFCMeta CFCVERSION_META = {
(CFCBase_destroy_t)CFCVersion_destroy
};
+int
+CFCVersion_is_vstring(const char *vstring) {
+ if (*vstring++ != 'v') { return false; }
+
+ do {
+ if (!CFCUtil_isdigit(*vstring++)) { return false; }
+ while (CFCUtil_isdigit(*vstring)) { vstring++; }
+ if (*vstring == '\0') { return true; }
+ } while (*vstring++ == '.');
+
+ return false;
+}
+
CFCVersion*
CFCVersion_new(const char *vstring) {
CFCVersion *self = (CFCVersion*)CFCBase_allocate(&CFCVERSION_META);
http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/719095c8/compiler/src/CFCVersion.h
----------------------------------------------------------------------
diff --git a/compiler/src/CFCVersion.h b/compiler/src/CFCVersion.h
index e81a012..4b669fc 100644
--- a/compiler/src/CFCVersion.h
+++ b/compiler/src/CFCVersion.h
@@ -32,6 +32,9 @@ extern "C" {
typedef struct CFCVersion CFCVersion;
+int
+CFCVersion_is_vstring(const char *vstring);
+
/**
* @param vstring - A version string consisting of a lower-case 'v' followed
* by one or more unsigned integers separated by dots.
http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/719095c8/devel/bin/setup_env.bat
----------------------------------------------------------------------
diff --git a/devel/bin/setup_env.bat b/devel/bin/setup_env.bat
index 25e76ec..10e109b 100644
--- a/devel/bin/setup_env.bat
+++ b/devel/bin/setup_env.bat
@@ -35,7 +35,7 @@ call :add_to_path "%LIB%" "%runtime_dir%\c"
set LIB=%retval%
call :add_to_path "%LIBRARY_PATH%" "%runtime_dir%\c"
set LIBRARY_PATH=%retval%
-call :add_to_path "%CLOWNFISH_INCLUDE%" "%runtime_dir%\core"
+call :add_to_path "%CLOWNFISH_INCLUDE%"
"%runtime_dir%\c\autogen\share\clownfish\include"
set CLOWNFISH_INCLUDE=%retval%
call :add_to_path "%PERL5LIB%" "%compiler_dir%\perl\blib\arch"
set PERL5LIB=%retval%
http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/719095c8/devel/bin/setup_env.sh
----------------------------------------------------------------------
diff --git a/devel/bin/setup_env.sh b/devel/bin/setup_env.sh
index f943772..367d589 100644
--- a/devel/bin/setup_env.sh
+++ b/devel/bin/setup_env.sh
@@ -68,7 +68,7 @@ runtime_dir=$base_dir/runtime
export PATH=`add_to_path "$PATH" "$compiler_dir/c"`
export CPATH=`add_to_path "$CPATH" "$runtime_dir/perl/xs"`
export LIBRARY_PATH=`add_to_path "$LIBRARY_PATH" "$runtime_dir/c"`
-export CLOWNFISH_INCLUDE=`add_to_path "$CLOWNFISH_INCLUDE" "$runtime_dir/core"`
+export CLOWNFISH_INCLUDE=`add_to_path "$CLOWNFISH_INCLUDE"
"$runtime_dir/c/autogen/share/clownfish/include"`
export PERL5LIB=`add_to_path "$PERL5LIB" "$compiler_dir/perl/blib/arch"`
export PERL5LIB=`add_to_path "$PERL5LIB" "$compiler_dir/perl/blib/lib"`
export PERL5LIB=`add_to_path "$PERL5LIB" "$runtime_dir/perl/blib/arch"`
http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/719095c8/runtime/c/install.bat
----------------------------------------------------------------------
diff --git a/runtime/c/install.bat b/runtime/c/install.bat
index 98aa582..592a7aa 100644
--- a/runtime/c/install.bat
+++ b/runtime/c/install.bat
@@ -41,9 +41,8 @@ copy libcfish-%major_version%.dll.a "%prefix%\lib" >nul
rem Install executables.
copy ..\..\compiler\c\cfc.exe "%prefix%\bin" >nul
-rem Install Clownfish header files.
-xcopy /siy ..\core\*.cfh "%prefix%\share\clownfish\include" >nul
-xcopy /siy ..\core\*.cfp "%prefix%\share\clownfish\include" >nul
+rem Install Clownfish header files and HTML documentation.
+xcopy /siy autogen\share "%prefix%" >nul
rem Install man pages.
xcopy /siy autogen\man "%prefix%" >nul
http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/719095c8/runtime/c/install.sh
----------------------------------------------------------------------
diff --git a/runtime/c/install.sh b/runtime/c/install.sh
index 16953eb..237e0dd 100755
--- a/runtime/c/install.sh
+++ b/runtime/c/install.sh
@@ -115,24 +115,13 @@ esac
mkdir -p "$prefix/bin"
cp ../../compiler/c/cfc "$prefix/bin/cfc"
-# Install Clownfish header files.
-for src in `find ../core -name '*.cf[hp]'`; do
- file=${src#../core/}
- dest=$prefix/share/clownfish/include/$file
- dir=`dirname "$dest"`
- mkdir -p "$dir"
- cp $src "$dest"
-done
+# Install Clownfish header files and HTML documentation.
+mkdir -p "$prefix/share"
+cp -R autogen/share/* "$prefix/share"
# Install man pages.
mkdir -p "$prefix/man"
-# Resolve symbolic links.
-man_dir=$(cd "$prefix/man" && pwd -P)
-if [ -n "$man_dir" ]; then
- cp -R autogen/man "$man_dir"
-else
- echo "Warning: Invalid directory $prefix/man"
-fi
+cp -R autogen/man/* "$prefix/man"
# Create pkg-config file.
mkdir -p "$prefix/lib/pkgconfig"
http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/719095c8/runtime/core/Clownfish.cfp
----------------------------------------------------------------------
diff --git a/runtime/core/Clownfish.cfp b/runtime/core/Clownfish.cfp
index 23da323..edb708f 100644
--- a/runtime/core/Clownfish.cfp
+++ b/runtime/core/Clownfish.cfp
@@ -1,5 +1,6 @@
{
"name": "Clownfish",
"nickname": "Cfish",
- "version": "v0.5.0"
+ "version": "v0.5.0",
+ "major_version": "v0.5.0"
}
http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/719095c8/runtime/test/TestClownfish.cfp
----------------------------------------------------------------------
diff --git a/runtime/test/TestClownfish.cfp b/runtime/test/TestClownfish.cfp
index 6db4b4a..abae9c0 100644
--- a/runtime/test/TestClownfish.cfp
+++ b/runtime/test/TestClownfish.cfp
@@ -1,6 +1,7 @@
{
"name": "TestClownfish",
"nickname": "TestCfish",
+ "installed": false,
"version": "v0.5.0",
"prerequisites": {
"Clownfish": "v0.5.0"