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/08/01 15:55:55 UTC

[1/8] git commit: Find .cfp files using S_find_files

Repository: lucy-clownfish
Updated Branches:
  refs/heads/include_dir_fixes [created] 14f990fc5


Find .cfp files using S_find_files


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

Branch: refs/heads/include_dir_fixes
Commit: 79f8473f75693e40e2c58bb046ef17fb2f76594e
Parents: 149b939
Author: Nick Wellnhofer <we...@aevum.de>
Authored: Fri Aug 1 13:47:46 2014 +0200
Committer: Nick Wellnhofer <we...@aevum.de>
Committed: Fri Aug 1 14:36:03 2014 +0200

----------------------------------------------------------------------
 compiler/src/CFCHierarchy.c | 116 +++++++++++++++++++--------------------
 1 file changed, 57 insertions(+), 59 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/79f8473f/compiler/src/CFCHierarchy.c
----------------------------------------------------------------------
diff --git a/compiler/src/CFCHierarchy.c b/compiler/src/CFCHierarchy.c
index 190c01d..672b7c1 100644
--- a/compiler/src/CFCHierarchy.c
+++ b/compiler/src/CFCHierarchy.c
@@ -66,22 +66,23 @@ typedef struct CFCFindFilesContext {
     size_t       num_paths;
 } CFCFindFilesContext;
 
-typedef struct CFCParseParcelFilesContext {
-    int is_included;
-} CFCParseParcelFilesContext;
+static void
+S_do_make_path(const char *path);
 
-// CFCUtil_walk() callback which parses .cfp files.
 static void
-S_parse_parcel_files(const char *path, void *context);
+S_parse_parcel_files(const char *source_dir, int is_included);
 
 static void
 S_check_prereqs(CFCHierarchy *self);
 
 static void
-S_do_make_path(const char *path);
+S_parse_cf_files(CFCHierarchy *self, const char *source_dir, int is_included);
 
 static void
-S_parse_cf_files(CFCHierarchy *self, const char *source_dir, int is_included);
+S_find_files(const char *path, void *arg);
+
+static void
+S_free_find_files_context(CFCFindFilesContext *context);
 
 static void
 S_connect_classes(CFCHierarchy *self);
@@ -217,24 +218,21 @@ CFCHierarchy_add_prereq(CFCHierarchy *self, const char *parcel) {
 void
 CFCHierarchy_build(CFCHierarchy *self) {
     // Read .cfp files.
-    CFCParseParcelFilesContext context;
-    context.is_included = false;
     for (size_t i = 0; self->sources[i] != NULL; i++) {
-        CFCUtil_walk(self->sources[i], S_parse_parcel_files, &context);
+        S_parse_parcel_files(self->sources[i], false);
     }
-    context.is_included = true;
     for (size_t i = 0; self->includes[i] != NULL; i++) {
-        CFCUtil_walk(self->includes[i], S_parse_parcel_files, &context);
+        S_parse_parcel_files(self->includes[i], true);
     }
 
     S_check_prereqs(self);
 
     // Read .cfh files.
     for (size_t i = 0; self->sources[i] != NULL; i++) {
-        S_parse_cf_files(self, self->sources[i], 0);
+        S_parse_cf_files(self, self->sources[i], false);
     }
     for (size_t i = 0; self->includes[i] != NULL; i++) {
-        S_parse_cf_files(self, self->includes[i], 1);
+        S_parse_cf_files(self, self->includes[i], true);
     }
 
     for (int i = 0; self->classes[i] != NULL; i++) {
@@ -248,24 +246,22 @@ CFCHierarchy_build(CFCHierarchy *self) {
 }
 
 static void
-S_parse_parcel_files(const char *path, void *arg) {
-    CFCParseParcelFilesContext *context = (CFCParseParcelFilesContext*)arg;
-
-    // Ignore hidden files.
-    if (strstr(path, CHY_DIR_SEP ".") != NULL) {
-        return;
-    }
+S_parse_parcel_files(const char *source_dir, int is_included) {
+    CFCFindFilesContext context;
+    context.ext       = ".cfp";
+    context.paths     = (char**)CALLOCATE(1, sizeof(char*));
+    context.num_paths = 0;
+    CFCUtil_walk(source_dir, S_find_files, &context);
 
     // Parse .cfp files and register the parcels they define.
-    size_t path_len = strlen(path);
-    if (path_len > 4 && (strcmp((path + path_len - 4), ".cfp") == 0)) {
-        CFCParcel *parcel = CFCParcel_new_from_file(path,
-                                                    context->is_included);
+    for (int i = 0; context.paths[i] != NULL; i++) {
+        const char *path = context.paths[i];
+        CFCParcel *parcel = CFCParcel_new_from_file(path, is_included);
         const char *name = CFCParcel_get_name(parcel);
         CFCParcel *existing = CFCParcel_fetch(name);
         if (existing) {
             if (!CFCParcel_equals(parcel, existing)) {
-                if (context->is_included && !CFCParcel_included(existing)) {
+                if (is_included && !CFCParcel_included(existing)) {
                     // Allow clash between source and include dirs.
                     CFCUtil_warn("Warning: Parcel %s from source dir takes "
                                  "precedence over parcel from include dir",
@@ -282,6 +278,8 @@ S_parse_parcel_files(const char *path, void *arg) {
         }
         CFCBase_decref((CFCBase*)parcel);
     }
+
+    S_free_find_files_context(&context);
 }
 
 static void
@@ -308,39 +306,6 @@ S_check_prereqs(CFCHierarchy *self) {
 }
 
 static void
-S_find_files(const char *path, void *arg) {
-    // Ignore updirs and hidden files.
-    if (strstr(path, CHY_DIR_SEP ".") != NULL) {
-        return;
-    }
-
-    CFCFindFilesContext *context = (CFCFindFilesContext*)arg;
-    const char  *ext       = context->ext;
-    size_t       path_len  = strlen(path);
-    size_t       ext_len   = strlen(ext);
-
-    if (path_len > ext_len && (strcmp(path + path_len - ext_len, ext) == 0)) {
-        size_t   num_paths = context->num_paths;
-        size_t   size      = (num_paths + 2) * sizeof(char*);
-        char   **paths     = (char**)REALLOCATE(context->paths, size);
-
-        paths[num_paths]     = CFCUtil_strdup(path);
-        paths[num_paths + 1] = NULL;
-
-        context->num_paths++;
-        context->paths = paths;
-    }
-}
-
-static void
-S_free_find_files_context(CFCFindFilesContext *context) {
-    for (int i = 0; context->paths[i] != NULL; i++) {
-        FREEMEM(context->paths[i]);
-    }
-    FREEMEM(context->paths);
-}
-
-static void
 S_parse_cf_files(CFCHierarchy *self, const char *source_dir, int is_included) {
     CFCFindFilesContext context;
     context.ext       = ".cfh";
@@ -420,6 +385,39 @@ S_parse_cf_files(CFCHierarchy *self, const char *source_dir, int is_included) {
 }
 
 static void
+S_find_files(const char *path, void *arg) {
+    // Ignore updirs and hidden files.
+    if (strstr(path, CHY_DIR_SEP ".") != NULL) {
+        return;
+    }
+
+    CFCFindFilesContext *context = (CFCFindFilesContext*)arg;
+    const char  *ext       = context->ext;
+    size_t       path_len  = strlen(path);
+    size_t       ext_len   = strlen(ext);
+
+    if (path_len > ext_len && (strcmp(path + path_len - ext_len, ext) == 0)) {
+        size_t   num_paths = context->num_paths;
+        size_t   size      = (num_paths + 2) * sizeof(char*);
+        char   **paths     = (char**)REALLOCATE(context->paths, size);
+
+        paths[num_paths]     = CFCUtil_strdup(path);
+        paths[num_paths + 1] = NULL;
+
+        context->num_paths++;
+        context->paths = paths;
+    }
+}
+
+static void
+S_free_find_files_context(CFCFindFilesContext *context) {
+    for (int i = 0; context->paths[i] != NULL; i++) {
+        FREEMEM(context->paths[i]);
+    }
+    FREEMEM(context->paths);
+}
+
+static void
 S_connect_classes(CFCHierarchy *self) {
     // Wrangle the classes into hierarchies and figure out inheritance.
     for (int i = 0; self->classes[i] != NULL; i++) {


[6/8] git commit: Skip file from include dir if parcel was already processed

Posted by nw...@apache.org.
Skip file from include dir if parcel was already processed

The parcel from the first source or include dir takes precedence.


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

Branch: refs/heads/include_dir_fixes
Commit: bec8dc327b54e9d5111ff35b7662f2a114c21c11
Parents: 76f81ce
Author: Nick Wellnhofer <we...@aevum.de>
Authored: Fri Aug 1 13:47:46 2014 +0200
Committer: Nick Wellnhofer <we...@aevum.de>
Committed: Fri Aug 1 15:48:17 2014 +0200

----------------------------------------------------------------------
 compiler/perl/t/502-clash.t |  2 +-
 compiler/src/CFCHierarchy.c | 34 ++++++++++++++++------------------
 2 files changed, 17 insertions(+), 19 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/bec8dc32/compiler/perl/t/502-clash.t
----------------------------------------------------------------------
diff --git a/compiler/perl/t/502-clash.t b/compiler/perl/t/502-clash.t
index cd875f0..4bb5a63 100644
--- a/compiler/perl/t/502-clash.t
+++ b/compiler/perl/t/502-clash.t
@@ -40,7 +40,7 @@ SKIP: {
     eval { $hierarchy->build; };
 
     my $filename = catfile(qw( Animal Dog.cfh ));
-    like( $@, qr/File \Q$filename\E already registered/,
+    like( $@, qr|\Q$filename\E .* \Q$base_dir\E .* \Q$file_clash_dir\E|,
           "source/source filename clash" );
 
     Clownfish::CFC::Model::Class->_clear_registry();

http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/bec8dc32/compiler/src/CFCHierarchy.c
----------------------------------------------------------------------
diff --git a/compiler/src/CFCHierarchy.c b/compiler/src/CFCHierarchy.c
index e336b29..9698e61 100644
--- a/compiler/src/CFCHierarchy.c
+++ b/compiler/src/CFCHierarchy.c
@@ -352,22 +352,6 @@ S_parse_cf_files(CFCHierarchy *self, const char *source_dir, int is_included) {
         memcpy(path_part, src, path_part_len);
         path_part[path_part_len] = '\0';
 
-        // Make sure path_part is unique
-        CFCFile *existing = S_fetch_file(self, path_part);
-        if (existing) {
-            if (is_included && !CFCFile_included(existing)) {
-                // Allow filename clash between source and include dirs
-                CFCUtil_warn("Warning: File %s.cfh from source dir takes "
-                             "precedence over file from include dir",
-                             path_part);
-                // Ignore file
-                continue;
-            }
-            else {
-                CFCUtil_die("File %s.cfh already registered", path_part);
-            }
-        }
-
         CFCFileSpec *file_spec = CFCFileSpec_new(source_dir, path_part,
                                                  is_included);
 
@@ -381,9 +365,23 @@ 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.
+        // 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);
-        if (CFCParcel_required(parcel)) {
+        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);
         }
 


[5/8] git commit: Skip parcel from include dir if already processed

Posted by nw...@apache.org.
Skip parcel from include dir if already processed

The parcel from the first source or include dir takes precedence.


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

Branch: refs/heads/include_dir_fixes
Commit: 76f81ce74450272be3be49ae3afdbdb470b2aacd
Parents: c4b7580
Author: Nick Wellnhofer <we...@aevum.de>
Authored: Fri Aug 1 13:47:46 2014 +0200
Committer: Nick Wellnhofer <we...@aevum.de>
Committed: Fri Aug 1 15:46:58 2014 +0200

----------------------------------------------------------------------
 compiler/src/CFCHierarchy.c | 20 +++++++++-----------
 1 file changed, 9 insertions(+), 11 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/76f81ce7/compiler/src/CFCHierarchy.c
----------------------------------------------------------------------
diff --git a/compiler/src/CFCHierarchy.c b/compiler/src/CFCHierarchy.c
index 9cc1999..e336b29 100644
--- a/compiler/src/CFCHierarchy.c
+++ b/compiler/src/CFCHierarchy.c
@@ -273,17 +273,15 @@ S_parse_parcel_files(const char *source_dir, int is_included) {
         const char *name = CFCParcel_get_name(parcel);
         CFCParcel *existing = CFCParcel_fetch(name);
         if (existing) {
-            if (!CFCParcel_equals(parcel, existing)) {
-                if (is_included && !CFCParcel_included(existing)) {
-                    // Allow clash between source and include dirs.
-                    CFCUtil_warn("Warning: Parcel %s from source dir takes "
-                                 "precedence over parcel from include dir",
-                                 name);
-                }
-                else {
-                    CFCUtil_die("Incompatible parcel '%s' already registered",
-                                CFCParcel_get_name(parcel));
-                }
+            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);
             }
         }
         else {


[2/8] git commit: Find files with arbitrary extensions

Posted by nw...@apache.org.
Find files with arbitrary extensions


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

Branch: refs/heads/include_dir_fixes
Commit: 149b939cc06a618f0072ca6a74dbe57b11916c2f
Parents: 648541a
Author: Nick Wellnhofer <we...@aevum.de>
Authored: Fri Aug 1 13:47:46 2014 +0200
Committer: Nick Wellnhofer <we...@aevum.de>
Committed: Fri Aug 1 14:36:03 2014 +0200

----------------------------------------------------------------------
 compiler/src/CFCHierarchy.c | 58 ++++++++++++++++++++++++++--------------
 1 file changed, 38 insertions(+), 20 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/149b939c/compiler/src/CFCHierarchy.c
----------------------------------------------------------------------
diff --git a/compiler/src/CFCHierarchy.c b/compiler/src/CFCHierarchy.c
index dddb121..190c01d 100644
--- a/compiler/src/CFCHierarchy.c
+++ b/compiler/src/CFCHierarchy.c
@@ -60,6 +60,12 @@ struct CFCHierarchy {
     size_t num_classes;
 };
 
+typedef struct CFCFindFilesContext {
+    const char  *ext;
+    char       **paths;
+    size_t       num_paths;
+} CFCFindFilesContext;
+
 typedef struct CFCParseParcelFilesContext {
     int is_included;
 } CFCParseParcelFilesContext;
@@ -302,38 +308,53 @@ S_check_prereqs(CFCHierarchy *self) {
 }
 
 static void
-S_find_cfh(const char *path, void *context) {
-    char ***cfh_ptr = (char***)context;
-    char **cfh_list = *cfh_ptr;
+S_find_files(const char *path, void *arg) {
     // Ignore updirs and hidden files.
     if (strstr(path, CHY_DIR_SEP ".") != NULL) {
         return;
     }
-    size_t path_len = strlen(path);
-    if (path_len > 4 && (strcmp((path + path_len - 4), ".cfh") == 0)) {
-        size_t num_cfh = 0;
-        while (cfh_list[num_cfh] != NULL) { num_cfh++; }
-        size_t size = (num_cfh + 2) * sizeof(char*);
-        cfh_list = (char**)REALLOCATE(cfh_list, size);
-        cfh_list[num_cfh] = CFCUtil_strdup(path);
-        cfh_list[num_cfh + 1] = NULL;
+
+    CFCFindFilesContext *context = (CFCFindFilesContext*)arg;
+    const char  *ext       = context->ext;
+    size_t       path_len  = strlen(path);
+    size_t       ext_len   = strlen(ext);
+
+    if (path_len > ext_len && (strcmp(path + path_len - ext_len, ext) == 0)) {
+        size_t   num_paths = context->num_paths;
+        size_t   size      = (num_paths + 2) * sizeof(char*);
+        char   **paths     = (char**)REALLOCATE(context->paths, size);
+
+        paths[num_paths]     = CFCUtil_strdup(path);
+        paths[num_paths + 1] = NULL;
+
+        context->num_paths++;
+        context->paths = paths;
     }
+}
 
-    *cfh_ptr = cfh_list;
+static void
+S_free_find_files_context(CFCFindFilesContext *context) {
+    for (int i = 0; context->paths[i] != NULL; i++) {
+        FREEMEM(context->paths[i]);
+    }
+    FREEMEM(context->paths);
 }
 
 static void
 S_parse_cf_files(CFCHierarchy *self, const char *source_dir, int is_included) {
-    char **all_source_paths = (char**)CALLOCATE(1, sizeof(char*));
-    CFCUtil_walk(source_dir, S_find_cfh, &all_source_paths);
+    CFCFindFilesContext context;
+    context.ext       = ".cfh";
+    context.paths     = (char**)CALLOCATE(1, sizeof(char*));
+    context.num_paths = 0;
+    CFCUtil_walk(source_dir, S_find_files, &context);
     size_t source_dir_len  = strlen(source_dir);
     char *path_part = NULL;
     size_t path_part_max = 0;
 
     // Process any file that has at least one class declaration.
-    for (int i = 0; all_source_paths[i] != NULL; i++) {
+    for (int i = 0; context.paths[i] != NULL; i++) {
         // Derive the name of the class that owns the module file.
-        char *source_path = all_source_paths[i];
+        char *source_path = context.paths[i];
         size_t source_path_len = strlen(source_path);
         if (strncmp(source_path, source_dir, source_dir_len) != 0) {
             CFCUtil_die("'%s' doesn't start with '%s'", source_path,
@@ -394,10 +415,7 @@ S_parse_cf_files(CFCHierarchy *self, const char *source_dir, int is_included) {
     }
     self->classes[self->num_classes] = NULL;
 
-    for (int i = 0; all_source_paths[i] != NULL; i++) {
-        FREEMEM(all_source_paths[i]);
-    }
-    FREEMEM(all_source_paths);
+    S_free_find_files_context(&context);
     FREEMEM(path_part);
 }
 


[3/8] git commit: Cache full_path in FileSpec

Posted by nw...@apache.org.
Cache full_path in FileSpec


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

Branch: refs/heads/include_dir_fixes
Commit: 648541a5f3ac10e461e10ab20de30e398da3bbd5
Parents: c25e329
Author: Nick Wellnhofer <we...@aevum.de>
Authored: Fri Aug 1 14:31:16 2014 +0200
Committer: Nick Wellnhofer <we...@aevum.de>
Committed: Fri Aug 1 14:36:03 2014 +0200

----------------------------------------------------------------------
 compiler/src/CFCFileSpec.c | 11 +++++++++++
 compiler/src/CFCFileSpec.h |  3 +++
 2 files changed, 14 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/648541a5/compiler/src/CFCFileSpec.c
----------------------------------------------------------------------
diff --git a/compiler/src/CFCFileSpec.c b/compiler/src/CFCFileSpec.c
index 41e3ba4..90e3b76 100644
--- a/compiler/src/CFCFileSpec.c
+++ b/compiler/src/CFCFileSpec.c
@@ -14,6 +14,8 @@
  * limitations under the License.
  */
 
+#include "charmony.h"
+
 #include <string.h>
 #include <stdio.h>
 #include <ctype.h>
@@ -33,6 +35,7 @@ struct CFCFileSpec {
     CFCBase base;
     char *source_dir;
     char *path_part;
+    char *path;
     int is_included;
 };
 
@@ -57,6 +60,8 @@ CFCFileSpec_init(CFCFileSpec *self, const char *source_dir,
 
     self->source_dir  = CFCUtil_strdup(source_dir);
     self->path_part   = CFCUtil_strdup(path_part);
+    self->path        = CFCUtil_sprintf("%s" CHY_DIR_SEP "%s", source_dir,
+                                        path_part);
     self->is_included = !!is_included;
 
     return self;
@@ -66,10 +71,16 @@ void
 CFCFileSpec_destroy(CFCFileSpec *self) {
     FREEMEM(self->source_dir);
     FREEMEM(self->path_part);
+    FREEMEM(self->path);
     CFCBase_destroy((CFCBase*)self);
 }
 
 const char*
+CFCFileSpec_get_path(CFCFileSpec *self) {
+    return self->path;
+}
+
+const char*
 CFCFileSpec_get_source_dir(CFCFileSpec *self) {
     return self->source_dir;
 }

http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/648541a5/compiler/src/CFCFileSpec.h
----------------------------------------------------------------------
diff --git a/compiler/src/CFCFileSpec.h b/compiler/src/CFCFileSpec.h
index 830a618..971bdd5 100644
--- a/compiler/src/CFCFileSpec.h
+++ b/compiler/src/CFCFileSpec.h
@@ -53,6 +53,9 @@ void
 CFCFileSpec_destroy(CFCFileSpec *self);
 
 const char*
+CFCFileSpec_get_path(CFCFileSpec *self);
+
+const char*
 CFCFileSpec_get_source_dir(CFCFileSpec *self);
 
 const char*


[4/8] git commit: Add information about .cfp file to CFCParcel

Posted by nw...@apache.org.
Add information about .cfp file to CFCParcel

Pass a CFCFileSpec to CFCParcel so it knows about the source or include
dir and full path of the .cfp file.


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

Branch: refs/heads/include_dir_fixes
Commit: c4b758036a8f0d2675ec9b39815126b4a6872dd6
Parents: 79f8473
Author: Nick Wellnhofer <we...@aevum.de>
Authored: Fri Aug 1 13:47:46 2014 +0200
Committer: Nick Wellnhofer <we...@aevum.de>
Committed: Fri Aug 1 15:35:29 2014 +0200

----------------------------------------------------------------------
 compiler/perl/lib/Clownfish/CFC.pm | 22 ++++++++--------
 compiler/perl/lib/Clownfish/CFC.xs | 18 ++++++-------
 compiler/perl/t/403-parcel.t       | 29 ++++++++++++++++-----
 compiler/src/CFCHierarchy.c        | 16 +++++++++++-
 compiler/src/CFCParcel.c           | 46 +++++++++++++++++++++++----------
 compiler/src/CFCParcel.h           | 21 ++++++++++++---
 compiler/src/CFCParseHeader.y      | 13 ++++------
 compiler/src/CFCTestParcel.c       | 26 ++++++++++++-------
 compiler/src/CFCTestParser.c       |  2 +-
 compiler/src/CFCTestSymbol.c       |  8 +++---
 compiler/src/CFCTestType.c         | 12 ++++-----
 11 files changed, 140 insertions(+), 73 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/c4b75803/compiler/perl/lib/Clownfish/CFC.pm
----------------------------------------------------------------------
diff --git a/compiler/perl/lib/Clownfish/CFC.pm b/compiler/perl/lib/Clownfish/CFC.pm
index 8b80ea5..7dd8171 100644
--- a/compiler/perl/lib/Clownfish/CFC.pm
+++ b/compiler/perl/lib/Clownfish/CFC.pm
@@ -351,41 +351,41 @@ BEGIN { XSLoader::load( 'Clownfish::CFC', '0.01' ) }
     use Carp;
 
     our %new_PARAMS = (
-        name        => undef,
-        nickname    => undef,
-        version     => undef,
-        is_included => undef,
+        name      => undef,
+        nickname  => undef,
+        version   => undef,
+        file_spec => undef,
     );
 
     sub new {
         my ( $either, %args ) = @_;
         verify_args( \%new_PARAMS, %args ) or confess $@;
         confess "no subclassing allowed" unless $either eq __PACKAGE__;
-        return _new( @args{qw( name nickname version is_included )} );
+        return _new( @args{qw( name nickname version file_spec )} );
     }
 
     our %new_from_json_PARAMS = (
-        json        => undef,
-        is_included => undef,
+        json      => undef,
+        file_spec => undef,
     );
 
     sub new_from_json {
         my ( $either, %args ) = @_;
         verify_args( \%new_from_json_PARAMS, %args ) or confess $@;
         confess "no subclassing allowed" unless $either eq __PACKAGE__;
-        return _new_from_json( @args{qw( json is_included )} );
+        return _new_from_json( @args{qw( json file_spec )} );
     }
 
     our %new_from_file_PARAMS = (
-        path        => undef,
-        is_included => undef,
+        path      => undef,
+        file_spec => undef,
     );
 
     sub new_from_file {
         my ( $either, %args ) = @_;
         verify_args( \%new_from_file_PARAMS, %args ) or confess $@;
         confess "no subclassing allowed" unless $either eq __PACKAGE__;
-        return _new_from_file( @args{qw( path is_included )} );
+        return _new_from_file( @args{qw( path file_spec )} );
     }
 
 #    $parcel = Clownfish::CFC::Model::Parcel->acquire($parcel_name_or_parcel_object);

http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/c4b75803/compiler/perl/lib/Clownfish/CFC.xs
----------------------------------------------------------------------
diff --git a/compiler/perl/lib/Clownfish/CFC.xs b/compiler/perl/lib/Clownfish/CFC.xs
index c1983b7..a6ea249 100644
--- a/compiler/perl/lib/Clownfish/CFC.xs
+++ b/compiler/perl/lib/Clownfish/CFC.xs
@@ -1061,35 +1061,35 @@ PPCODE:
 MODULE = Clownfish::CFC   PACKAGE = Clownfish::CFC::Model::Parcel
 
 SV*
-_new(name_sv, nickname_sv, version, is_included)
+_new(name_sv, nickname_sv, version, file_spec)
     SV *name_sv;
     SV *nickname_sv;
     CFCVersion *version;
-    bool is_included;
+    CFCFileSpec *file_spec;
 CODE:
     const char *name     = SvOK(name_sv)  ? SvPV_nolen(name_sv)  : NULL;
     const char *nickname = SvOK(nickname_sv) ? SvPV_nolen(nickname_sv) : NULL;
-    CFCParcel *self = CFCParcel_new(name, nickname, version, is_included);
+    CFCParcel *self = CFCParcel_new(name, nickname, version, file_spec);
     RETVAL = S_cfcbase_to_perlref(self);
     CFCBase_decref((CFCBase*)self);
 OUTPUT: RETVAL
 
 SV*
-_new_from_file(path, is_included)
+_new_from_file(path, file_spec)
     const char *path;
-    bool is_included;
+    CFCFileSpec *file_spec;
 CODE:
-    CFCParcel *self = CFCParcel_new_from_file(path, is_included);
+    CFCParcel *self = CFCParcel_new_from_file(path, file_spec);
     RETVAL = S_cfcbase_to_perlref(self);
     CFCBase_decref((CFCBase*)self);
 OUTPUT: RETVAL
 
 SV*
-_new_from_json(json, is_included)
+_new_from_json(json, file_spec)
     const char *json;
-    bool is_included;
+    CFCFileSpec *file_spec;
 CODE:
-    CFCParcel *self = CFCParcel_new_from_json(json, is_included);
+    CFCParcel *self = CFCParcel_new_from_json(json, file_spec);
     RETVAL = S_cfcbase_to_perlref(self);
     CFCBase_decref((CFCBase*)self);
 OUTPUT: RETVAL

http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/c4b75803/compiler/perl/t/403-parcel.t
----------------------------------------------------------------------
diff --git a/compiler/perl/t/403-parcel.t b/compiler/perl/t/403-parcel.t
index 2121322..25ac79b 100644
--- a/compiler/perl/t/403-parcel.t
+++ b/compiler/perl/t/403-parcel.t
@@ -52,10 +52,15 @@ eval { $same_nick->register; };
 like( $@, qr/parcel with nickname .* already registered/i,
       "can't register two parcels with the same nickname" );
 
-my $included_foo = Clownfish::CFC::Model::Parcel->new(
-    name        => "IncludedFoo",
+my $foo_file_spec = Clownfish::CFC::Model::FileSpec->new(
+    source_dir  => '.',
+    path_part   => 'Foo.cfp',
     is_included => 1,
 );
+my $included_foo = Clownfish::CFC::Model::Parcel->new(
+    name      => "IncludedFoo",
+    file_spec => $foo_file_spec,
+);
 ok( $included_foo->included, "included" );
 $included_foo->register;
 
@@ -140,20 +145,30 @@ Clownfish::CFC::Model::Parcel->reap_singletons();
 }
 
 {
-    my $foo = Clownfish::CFC::Model::Parcel->new(
-        name        => 'Foo',
+    my $foo_file_spec = Clownfish::CFC::Model::FileSpec->new(
+        source_dir  => '.',
+        path_part   => 'Foo.cfp',
         is_included => 1,
     );
+    my $foo = Clownfish::CFC::Model::Parcel->new(
+        name      => 'Foo',
+        file_spec => $foo_file_spec,
+    );
     $foo->register;
 
     my $cfish_version = Clownfish::CFC::Model::Version->new(
         vstring => 'v0.8.7',
     );
-    my $cfish = Clownfish::CFC::Model::Parcel->new(
-        name        => 'Clownfish',
-        version     => $cfish_version,
+    my $cfish_file_spec = Clownfish::CFC::Model::FileSpec->new(
+        source_dir  => '.',
+        path_part   => 'Clownfish.cfp',
         is_included => 1,
     );
+    my $cfish = Clownfish::CFC::Model::Parcel->new(
+        name      => 'Clownfish',
+        version   => $cfish_version,
+        file_spec => $cfish_file_spec,
+    );
     $cfish->register;
 
     my $json = qq|

http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/c4b75803/compiler/src/CFCHierarchy.c
----------------------------------------------------------------------
diff --git a/compiler/src/CFCHierarchy.c b/compiler/src/CFCHierarchy.c
index 672b7c1..9cc1999 100644
--- a/compiler/src/CFCHierarchy.c
+++ b/compiler/src/CFCHierarchy.c
@@ -253,10 +253,23 @@ S_parse_parcel_files(const char *source_dir, int is_included) {
     context.num_paths = 0;
     CFCUtil_walk(source_dir, S_find_files, &context);
 
+    size_t source_dir_len = strlen(source_dir);
+
     // Parse .cfp files and register the parcels they define.
     for (int i = 0; context.paths[i] != NULL; i++) {
         const char *path = context.paths[i];
-        CFCParcel *parcel = CFCParcel_new_from_file(path, is_included);
+
+        if (strncmp(path, source_dir, source_dir_len) != 0) {
+            CFCUtil_die("'%s' doesn't start with '%s'", path, source_dir);
+        }
+        const char *path_part = path + source_dir_len;
+        while (*path_part == CHY_DIR_SEP_CHAR) {
+            ++path_part;
+        }
+
+        CFCFileSpec *file_spec
+            = CFCFileSpec_new(source_dir, path_part, is_included);
+        CFCParcel *parcel = CFCParcel_new_from_file(path, file_spec);
         const char *name = CFCParcel_get_name(parcel);
         CFCParcel *existing = CFCParcel_fetch(name);
         if (existing) {
@@ -277,6 +290,7 @@ S_parse_parcel_files(const char *source_dir, int is_included) {
             CFCParcel_register(parcel);
         }
         CFCBase_decref((CFCBase*)parcel);
+        CFCBase_decref((CFCBase*)file_spec);
     }
 
     S_free_find_files_context(&context);

http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/c4b75803/compiler/src/CFCParcel.c
----------------------------------------------------------------------
diff --git a/compiler/src/CFCParcel.c b/compiler/src/CFCParcel.c
index 15811e8..f54c81c 100644
--- a/compiler/src/CFCParcel.c
+++ b/compiler/src/CFCParcel.c
@@ -26,6 +26,7 @@
 #define CFC_NEED_BASE_STRUCT_DEF
 #include "CFCBase.h"
 #include "CFCParcel.h"
+#include "CFCFileSpec.h"
 #include "CFCVersion.h"
 #include "CFCUtil.h"
 
@@ -34,11 +35,11 @@ struct CFCParcel {
     char *name;
     char *nickname;
     CFCVersion *version;
+    CFCFileSpec *file_spec;
     char *prefix;
     char *Prefix;
     char *PREFIX;
     char *privacy_sym;
-    int is_included;
     int is_required;
     char **inherited_parcels;
     size_t num_inherited_parcels;
@@ -155,14 +156,14 @@ static const CFCMeta CFCPARCEL_META = {
 
 CFCParcel*
 CFCParcel_new(const char *name, const char *nickname, CFCVersion *version,
-              int is_included) {
+              CFCFileSpec *file_spec) {
     CFCParcel *self = (CFCParcel*)CFCBase_allocate(&CFCPARCEL_META);
-    return CFCParcel_init(self, name, nickname, version, is_included);
+    return CFCParcel_init(self, name, nickname, version, file_spec);
 }
 
 CFCParcel*
 CFCParcel_init(CFCParcel *self, const char *name, const char *nickname,
-               CFCVersion *version, int is_included) {
+               CFCVersion *version, CFCFileSpec *file_spec) {
     // Validate name.
     if (!name || !S_validate_name_or_nickname(name)) {
         CFCUtil_die("Invalid name: '%s'", name ? name : "[NULL]");
@@ -189,6 +190,9 @@ CFCParcel_init(CFCParcel *self, const char *name, const char *nickname,
         self->version = CFCVersion_new("v0");
     }
 
+    // Set file_spec.
+    self->file_spec = (CFCFileSpec*)CFCBase_incref((CFCBase*)file_spec);
+
     // Derive prefix, Prefix, PREFIX.
     size_t nickname_len  = strlen(self->nickname);
     size_t prefix_len = nickname_len ? nickname_len + 1 : 0;
@@ -222,7 +226,6 @@ CFCParcel_init(CFCParcel *self, const char *name, const char *nickname,
     self->privacy_sym[privacy_sym_len] = '\0';
 
     // Initialize flags.
-    self->is_included = is_included;
     self->is_required = false;
 
     // Initialize arrays.
@@ -237,7 +240,7 @@ CFCParcel_init(CFCParcel *self, const char *name, const char *nickname,
 }
 
 static CFCParcel*
-S_new_from_json(const char *json, const char *path, int is_included) {
+S_new_from_json(const char *json, const char *path, CFCFileSpec *file_spec) {
     JSONNode *parsed = S_parse_json_for_parcel(json);
     if (!parsed) {
         CFCUtil_die("Invalid JSON parcel definition in '%s'", path);
@@ -293,7 +296,7 @@ S_new_from_json(const char *json, const char *path, int is_included) {
     if (!version) {
         CFCUtil_die("Missing required key 'version' (filepath '%s')", path);
     }
-    CFCParcel *self = CFCParcel_new(name, nickname, version, is_included);
+    CFCParcel *self = CFCParcel_new(name, nickname, version, file_spec);
     if (prereqs) {
         S_set_prereqs(self, prereqs, path);
     }
@@ -338,15 +341,15 @@ S_set_prereqs(CFCParcel *self, JSONNode *node, const char *path) {
 }
 
 CFCParcel*
-CFCParcel_new_from_json(const char *json, int is_included) {
-    return S_new_from_json(json, "[NULL]", is_included);
+CFCParcel_new_from_json(const char *json, CFCFileSpec *file_spec) {
+    return S_new_from_json(json, "[NULL]", file_spec);
 }
 
 CFCParcel*
-CFCParcel_new_from_file(const char *path, int is_included) {
+CFCParcel_new_from_file(const char *path, CFCFileSpec *file_spec) {
     size_t len;
     char *json = CFCUtil_slurp_text(path, &len);
-    CFCParcel *self = S_new_from_json(json, path, is_included);
+    CFCParcel *self = S_new_from_json(json, path, file_spec);
     FREEMEM(json);
     return self;
 }
@@ -356,6 +359,7 @@ CFCParcel_destroy(CFCParcel *self) {
     FREEMEM(self->name);
     FREEMEM(self->nickname);
     CFCBase_decref((CFCBase*)self->version);
+    CFCBase_decref((CFCBase*)self->file_spec);
     FREEMEM(self->prefix);
     FREEMEM(self->Prefix);
     FREEMEM(self->PREFIX);
@@ -382,7 +386,9 @@ CFCParcel_equals(CFCParcel *self, CFCParcel *other) {
     if (CFCVersion_compare_to(self->version, other->version) != 0) {
         return false;
     }
-    if (self->is_included != other->is_included) { return false; }
+    if (CFCParcel_included(self) != CFCParcel_included(other)) {
+        return false;
+    }
     return true;
 }
 
@@ -421,9 +427,23 @@ CFCParcel_get_privacy_sym(CFCParcel *self) {
     return self->privacy_sym;
 }
 
+const char*
+CFCParcel_get_cfp_path(CFCParcel *self) {
+    return self->file_spec
+           ? CFCFileSpec_get_path(self->file_spec)
+           : NULL;
+}
+
+const char*
+CFCParcel_get_source_dir(CFCParcel *self) {
+    return self->file_spec
+           ? CFCFileSpec_get_source_dir(self->file_spec)
+           : NULL;
+}
+
 int
 CFCParcel_included(CFCParcel *self) {
-    return self->is_included;
+    return self->file_spec ? CFCFileSpec_included(self->file_spec) : false;
 }
 
 int

http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/c4b75803/compiler/src/CFCParcel.h
----------------------------------------------------------------------
diff --git a/compiler/src/CFCParcel.h b/compiler/src/CFCParcel.h
index ec3d99a..9bd37be 100644
--- a/compiler/src/CFCParcel.h
+++ b/compiler/src/CFCParcel.h
@@ -38,6 +38,7 @@ extern "C" {
 
 typedef struct CFCParcel CFCParcel;
 typedef struct CFCPrereq CFCPrereq;
+struct CFCFileSpec;
 struct CFCVersion;
 
 /** Return the parcel which has been registered for <code>name</code>.
@@ -63,17 +64,17 @@ CFCParcel_reap_singletons(void);
 
 CFCParcel*
 CFCParcel_new(const char *name, const char *nickname,
-              struct CFCVersion *version, int is_included);
+              struct CFCVersion *version, struct CFCFileSpec *file_spec);
 
 CFCParcel*
-CFCParcel_new_from_file(const char *path, int is_included);
+CFCParcel_new_from_file(const char *path, struct CFCFileSpec *file_spec);
 
 CFCParcel*
-CFCParcel_new_from_json(const char *json, int is_included);
+CFCParcel_new_from_json(const char *json, struct CFCFileSpec *file_spec);
 
 CFCParcel*
 CFCParcel_init(CFCParcel *self, const char *name, const char *nickname,
-               struct CFCVersion *version, int is_included);
+               struct CFCVersion *version, struct CFCFileSpec *file_spec);
 
 void
 CFCParcel_destroy(CFCParcel *self);
@@ -110,6 +111,18 @@ CFCParcel_get_PREFIX(CFCParcel *self);
 const char*
 CFCParcel_get_privacy_sym(CFCParcel *self);
 
+/* Return the path to the Parcel's .cfp file. May return NULL if the parcel
+ * wasn't created from a file.
+ */
+const char*
+CFCParcel_get_cfp_path(CFCParcel *self);
+
+/* Return the Parcel's source or include dir. May return NULL if the parcel
+ * wasn't created from a file.
+ */
+const char*
+CFCParcel_get_source_dir(CFCParcel *self);
+
 /** Return true if the parcel is from an include directory.
  */
 int

http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/c4b75803/compiler/src/CFCParseHeader.y
----------------------------------------------------------------------
diff --git a/compiler/src/CFCParseHeader.y b/compiler/src/CFCParseHeader.y
index 13912d9..5e609df 100644
--- a/compiler/src/CFCParseHeader.y
+++ b/compiler/src/CFCParseHeader.y
@@ -330,16 +330,13 @@ parcel_definition(A) ::= PARCEL qualified_id(B) SEMICOLON.
 {
     A = CFCParcel_fetch(B);
     if (!A) {
-        CFCFileSpec *file_spec = CFCParser_get_file_spec(state);
-        int is_included = false;
-        if (file_spec) {
-            is_included = CFCFileSpec_included(file_spec);
-        }
-        A = CFCParcel_new(B, NULL, NULL, is_included);
+        /* Allow unregistered parcels to simplify tests. */
+        A = CFCParcel_new(B, NULL, NULL, NULL);
         CFCParcel_register(A);
-        CFCBase_decref((CFCBase*)A);
     }
-    CFCBase_incref((CFCBase*)A);
+    else {
+        CFCBase_incref((CFCBase*)A);
+    }
     CFCParser_set_parcel(state, A);
 }
 

http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/c4b75803/compiler/src/CFCTestParcel.c
----------------------------------------------------------------------
diff --git a/compiler/src/CFCTestParcel.c b/compiler/src/CFCTestParcel.c
index 46d8f1c..0c171e2 100644
--- a/compiler/src/CFCTestParcel.c
+++ b/compiler/src/CFCTestParcel.c
@@ -18,6 +18,7 @@
 
 #define CFC_USE_TEST_MACROS
 #include "CFCBase.h"
+#include "CFCFileSpec.h"
 #include "CFCParcel.h"
 #include "CFCSymbol.h"
 #include "CFCUtil.h"
@@ -78,16 +79,18 @@ S_run_prereq_tests(CFCTest *test) {
 static void
 S_run_parcel_tests(CFCTest *test) {
     {
-        CFCParcel *parcel = CFCParcel_new("Foo", NULL, NULL, false);
+        CFCParcel *parcel = CFCParcel_new("Foo", NULL, NULL, NULL);
         OK(test, parcel != NULL, "new");
         OK(test, !CFCParcel_included(parcel), "not included");
         CFCBase_decref((CFCBase*)parcel);
     }
 
     {
-        CFCParcel *parcel = CFCParcel_new("Foo", NULL, NULL, true);
+        CFCFileSpec *file_spec = CFCFileSpec_new(".", "Parcel.cfp", true);
+        CFCParcel *parcel = CFCParcel_new("Foo", NULL, NULL, file_spec);
         OK(test, CFCParcel_included(parcel), "included");
         CFCBase_decref((CFCBase*)parcel);
+        CFCBase_decref((CFCBase*)file_spec);
     }
 
     {
@@ -97,20 +100,20 @@ S_run_parcel_tests(CFCTest *test) {
             "            \"nickname\": \"Crust\",\n"
             "            \"version\": \"v0.1.0\"\n"
             "        }\n";
-        CFCParcel *parcel = CFCParcel_new_from_json(json, false);
+        CFCParcel *parcel = CFCParcel_new_from_json(json, NULL);
         OK(test, parcel != NULL, "new_from_json");
         CFCBase_decref((CFCBase*)parcel);
     }
 
     {
         const char *path = "t" CHY_DIR_SEP "cfbase" CHY_DIR_SEP "Animal.cfp";
-        CFCParcel *parcel = CFCParcel_new_from_file(path, false);
+        CFCParcel *parcel = CFCParcel_new_from_file(path, NULL);
         OK(test, parcel != NULL, "new_from_file");
         CFCBase_decref((CFCBase*)parcel);
     }
 
     {
-        CFCParcel *parcel = CFCParcel_new("Crustacean", "Crust", NULL, false);
+        CFCParcel *parcel = CFCParcel_new("Crustacean", "Crust", NULL, NULL);
         CFCParcel_register(parcel);
         STR_EQ(test, CFCVersion_get_vstring(CFCParcel_get_version(parcel)),
                "v0", "get_version");
@@ -138,7 +141,7 @@ S_run_parcel_tests(CFCTest *test) {
             "                \"Arthropod\": \"v30.104.5\"\n"
             "            }\n"
             "        }\n";
-        CFCParcel *parcel = CFCParcel_new_from_json(json, false);
+        CFCParcel *parcel = CFCParcel_new_from_json(json, NULL);
 
         CFCPrereq **prereqs = CFCParcel_get_prereqs(parcel);
         OK(test, prereqs != NULL, "prereqs");
@@ -169,12 +172,15 @@ S_run_parcel_tests(CFCTest *test) {
     }
 
     {
-        CFCParcel *foo = CFCParcel_new("Foo", NULL, NULL, true);
+        CFCFileSpec *foo_file_spec = CFCFileSpec_new(".", "Foo.cfp", true);
+        CFCParcel *foo = CFCParcel_new("Foo", NULL, NULL, foo_file_spec);
         CFCParcel_register(foo);
 
         CFCVersion *cfish_version = CFCVersion_new("v0.8.7");
+        CFCFileSpec *cfish_file_spec
+            = CFCFileSpec_new(".", "Clownfish.cfp", true);
         CFCParcel *cfish
-            = CFCParcel_new("Clownfish", NULL, cfish_version, true);
+            = CFCParcel_new("Clownfish", NULL, cfish_version, cfish_file_spec);
         CFCParcel_register(cfish);
 
         const char *crust_json =
@@ -185,7 +191,7 @@ S_run_parcel_tests(CFCTest *test) {
             "                \"Clownfish\": \"v0.8.5\",\n"
             "            }\n"
             "        }\n";
-        CFCParcel *crust = CFCParcel_new_from_json(crust_json, false);
+        CFCParcel *crust = CFCParcel_new_from_json(crust_json, NULL);
         CFCParcel_register(crust);
 
         CFCParcel_check_prereqs(crust);
@@ -217,7 +223,9 @@ S_run_parcel_tests(CFCTest *test) {
         FREEMEM(prereq_parcels);
         CFCBase_decref((CFCBase*)crust);
         CFCBase_decref((CFCBase*)cfish_version);
+        CFCBase_decref((CFCBase*)cfish_file_spec);
         CFCBase_decref((CFCBase*)cfish);
+        CFCBase_decref((CFCBase*)foo_file_spec);
         CFCBase_decref((CFCBase*)foo);
         CFCParcel_reap_singletons();
     }

http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/c4b75803/compiler/src/CFCTestParser.c
----------------------------------------------------------------------
diff --git a/compiler/src/CFCTestParser.c b/compiler/src/CFCTestParser.c
index 9a0ccae..622dfff 100644
--- a/compiler/src/CFCTestParser.c
+++ b/compiler/src/CFCTestParser.c
@@ -55,7 +55,7 @@ S_run_tests(CFCTest *test) {
         CFCParcel *fish = CFCTest_parse_parcel(test, parser, "parcel Fish;");
 
         CFCParcel *registered
-            = CFCParcel_new("Crustacean", "Crust", NULL, false);
+            = CFCParcel_new("Crustacean", "Crust", NULL, NULL);
         CFCParcel_register(registered);
         CFCParcel *parcel
             = CFCTest_parse_parcel(test, parser, "parcel Crustacean;");

http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/c4b75803/compiler/src/CFCTestSymbol.c
----------------------------------------------------------------------
diff --git a/compiler/src/CFCTestSymbol.c b/compiler/src/CFCTestSymbol.c
index 2fff530..fe1fbc3 100644
--- a/compiler/src/CFCTestSymbol.c
+++ b/compiler/src/CFCTestSymbol.c
@@ -36,7 +36,7 @@ const CFCTestBatch CFCTEST_BATCH_SYMBOL = {
 
 static void
 S_run_tests(CFCTest *test) {
-    CFCParcel *parcel = CFCParcel_new("Parcel", NULL, NULL, false);
+    CFCParcel *parcel = CFCParcel_new("Parcel", NULL, NULL, NULL);
 
     {
         static const char *exposures[4] = {
@@ -95,7 +95,7 @@ S_run_tests(CFCTest *test) {
 
     {
         CFCParcel *lucifer_parcel
-            = CFCParcel_new("Lucifer", NULL, NULL, false);
+            = CFCParcel_new("Lucifer", NULL, NULL, NULL);
         CFCParcel_register(lucifer_parcel);
         CFCSymbol *lucifer
             = CFCSymbol_new(lucifer_parcel, "parcel", NULL, NULL, "sym");
@@ -109,7 +109,7 @@ S_run_tests(CFCTest *test) {
         const char *PREFIX = CFCSymbol_get_PREFIX(lucifer);
         STR_EQ(test, PREFIX, "LUCIFER_", "get_PREFIX");
 
-        CFCParcel *luser_parcel = CFCParcel_new("Luser", NULL, NULL, false);
+        CFCParcel *luser_parcel = CFCParcel_new("Luser", NULL, NULL, NULL);
         CFCParcel_register(luser_parcel);
         CFCSymbol *luser
             = CFCSymbol_new(luser_parcel, "parcel", NULL, NULL, "sym");
@@ -133,7 +133,7 @@ S_run_tests(CFCTest *test) {
     }
 
     {
-        CFCParcel *eep_parcel = CFCParcel_new("Eep", NULL, NULL, false);
+        CFCParcel *eep_parcel = CFCParcel_new("Eep", NULL, NULL, NULL);
         CFCParcel_register(eep_parcel);
         CFCSymbol *eep
             = CFCSymbol_new(eep_parcel, "parcel", "Op::Ork", NULL, "ah_ah");

http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/c4b75803/compiler/src/CFCTestType.c
----------------------------------------------------------------------
diff --git a/compiler/src/CFCTestType.c b/compiler/src/CFCTestType.c
index 167a497..fcbd444 100644
--- a/compiler/src/CFCTestType.c
+++ b/compiler/src/CFCTestType.c
@@ -79,7 +79,7 @@ S_run_tests(CFCTest *test) {
 
 static void
 S_run_basic_tests(CFCTest *test) {
-    CFCParcel *neato_parcel = CFCParcel_new("Neato", NULL, NULL, false);
+    CFCParcel *neato_parcel = CFCParcel_new("Neato", NULL, NULL, NULL);
     CFCParcel_register(neato_parcel);
     CFCType *type = CFCType_new(0, neato_parcel, "mytype_t", 0);
 
@@ -112,7 +112,7 @@ S_run_basic_tests(CFCTest *test) {
 
 static void
 S_run_primitive_tests(CFCTest *test) {
-    CFCParcel *parcel = CFCParcel_new("Parcel", NULL, NULL, false);
+    CFCParcel *parcel = CFCParcel_new("Parcel", NULL, NULL, NULL);
     CFCType *type = CFCType_new(CFCTYPE_PRIMITIVE, parcel, "hump_t", 0);
     OK(test, CFCType_is_primitive(type), "is_primitive");
 
@@ -328,7 +328,7 @@ S_run_object_tests(CFCTest *test) {
         CFCBase_decref((CFCBase*)parser);
     }
 
-    CFCParcel *neato_parcel = CFCParcel_new("Neato", NULL, NULL, false);
+    CFCParcel *neato_parcel = CFCParcel_new("Neato", NULL, NULL, NULL);
     CFCClass *foo_class
         = CFCClass_create(neato_parcel, NULL, "Foo", NULL, NULL, NULL, NULL,
                           NULL, false, false);
@@ -356,7 +356,7 @@ S_run_object_tests(CFCTest *test) {
 
     {
         CFCParcel *foreign_parcel
-            = CFCParcel_new("Foreign", NULL, NULL, false);
+            = CFCParcel_new("Foreign", NULL, NULL, NULL);
         CFCClass *foreign_foo_class
             = CFCClass_create(foreign_parcel, NULL, "Foreign::Foo", NULL, NULL,
                               NULL, NULL, NULL, false, false);
@@ -424,7 +424,7 @@ S_run_va_list_tests(CFCTest *test) {
 static void
 S_run_arbitrary_tests(CFCTest *test) {
     {
-        CFCParcel *neato_parcel = CFCParcel_new("Neato", NULL, NULL, false);
+        CFCParcel *neato_parcel = CFCParcel_new("Neato", NULL, NULL, NULL);
         CFCParcel_register(neato_parcel);
 
         CFCType *foo = CFCType_new_arbitrary(neato_parcel, "foo_t");
@@ -464,7 +464,7 @@ S_run_arbitrary_tests(CFCTest *test) {
 static void
 S_run_composite_tests(CFCTest *test) {
     CFCParser *parser = CFCParser_new();
-    CFCParcel *neato_parcel = CFCParcel_new("Neato", NULL, NULL, false);
+    CFCParcel *neato_parcel = CFCParcel_new("Neato", NULL, NULL, NULL);
     CFCParser_set_parcel(parser, neato_parcel);
 
     {


[7/8] git commit: Skip class from include dir if parcel was already processed

Posted by nw...@apache.org.
Skip class from include dir if parcel was already processed

The parcel from the first source or include dir takes precedence.


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

Branch: refs/heads/include_dir_fixes
Commit: 79246685bc3635b443053bdea1adf4d893786b4b
Parents: bec8dc3
Author: Nick Wellnhofer <we...@aevum.de>
Authored: Fri Aug 1 13:47:46 2014 +0200
Committer: Nick Wellnhofer <we...@aevum.de>
Committed: Fri Aug 1 15:49:09 2014 +0200

----------------------------------------------------------------------
 compiler/perl/t/502-clash.t | 21 +--------------------
 compiler/src/CFCClass.c     | 40 ++++++++++++++++++++++++----------------
 compiler/src/CFCClass.h     |  3 +++
 3 files changed, 28 insertions(+), 36 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/79246685/compiler/perl/t/502-clash.t
----------------------------------------------------------------------
diff --git a/compiler/perl/t/502-clash.t b/compiler/perl/t/502-clash.t
index 4bb5a63..4cf870b 100644
--- a/compiler/perl/t/502-clash.t
+++ b/compiler/perl/t/502-clash.t
@@ -16,7 +16,7 @@
 use strict;
 use warnings;
 
-use Test::More tests => 5;
+use Test::More tests => 4;
 
 use Clownfish::CFC::Model::Hierarchy;
 use File::Spec::Functions qw( catdir catfile splitpath );
@@ -90,25 +90,6 @@ SKIP: {
 
     my $hierarchy = Clownfish::CFC::Model::Hierarchy->new(dest => $dest_dir);
 
-    $hierarchy->add_source_dir($foo_dir);
-    $hierarchy->add_include_dir($bar_dir);
-    $hierarchy->add_include_dir($base_dir);
-
-    eval { $hierarchy->build; };
-
-    like( $@, qr/Class .* from include dir .* parcel .* from source dir/,
-          "included class with source parcel" );
-
-    Clownfish::CFC::Model::Class->_clear_registry();
-    Clownfish::CFC::Model::Parcel->reap_singletons();
-}
-
-SKIP: {
-    skip( 'Exceptions leak', 1 )
-        if $ENV{LUCY_VALGRIND};
-
-    my $hierarchy = Clownfish::CFC::Model::Hierarchy->new(dest => $dest_dir);
-
     $hierarchy->add_source_dir($bar_dir);
     $hierarchy->add_include_dir($foo_dir);
     $hierarchy->add_include_dir($base_dir);

http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/79246685/compiler/src/CFCClass.c
----------------------------------------------------------------------
diff --git a/compiler/src/CFCClass.c b/compiler/src/CFCClass.c
index 7322e22..59ec8c3 100644
--- a/compiler/src/CFCClass.c
+++ b/compiler/src/CFCClass.c
@@ -184,25 +184,26 @@ CFCClass_do_create(CFCClass *self, struct CFCParcel *parcel,
     self->is_final    = !!is_final;
     self->is_inert    = !!is_inert;
 
-    if (file_spec && CFCFileSpec_included(file_spec)) {
-        if (!CFCParcel_included(parcel)) {
-            CFCUtil_die("Class %s from include dir found in parcel %s from"
-                        " source dir",
-                        class_name, CFCParcel_get_name(parcel));
-        }
-    }
-    else {
-        if (CFCParcel_included(parcel)) {
-            CFCUtil_die("Class %s from source dir found in parcel %s from"
-                        " include dir",
-                        class_name, CFCParcel_get_name(parcel));
-        }
+    if (!CFCClass_included(self) && CFCParcel_included(parcel)) {
+        CFCUtil_die("Class %s from source dir found in parcel %s from"
+                    " include dir",
+                    class_name, CFCParcel_get_name(parcel));
     }
 
-    // Store in registry.
-    S_register(self);
+    // 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
+    ) {
+        // Store in registry.
+        S_register(self);
 
-    CFCParcel_add_struct_sym(parcel, self->struct_sym);
+        CFCParcel_add_struct_sym(parcel, self->struct_sym);
+    }
 
     return self;
 }
@@ -717,6 +718,13 @@ CFCClass_get_parent(CFCClass *self) {
 }
 
 const char*
+CFCClass_get_source_dir(CFCClass *self) {
+    return self->file_spec
+           ? CFCFileSpec_get_source_dir(self->file_spec)
+           : NULL;
+}
+
+const char*
 CFCClass_get_path_part(CFCClass *self) {
     return self->file_spec ? CFCFileSpec_get_path_part(self->file_spec) : NULL;
 }

http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/79246685/compiler/src/CFCClass.h
----------------------------------------------------------------------
diff --git a/compiler/src/CFCClass.h b/compiler/src/CFCClass.h
index 78eefd0..877a84a 100644
--- a/compiler/src/CFCClass.h
+++ b/compiler/src/CFCClass.h
@@ -202,6 +202,9 @@ CFCClass*
 CFCClass_get_parent(CFCClass *self);
 
 const char*
+CFCClass_get_source_dir(CFCClass *self);
+
+const char*
 CFCClass_get_path_part(CFCClass *self);
 
 int


[8/8] git commit: Search all dirs in @INC for Clownfish headers

Posted by nw...@apache.org.
Search all dirs in @INC for Clownfish 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/14f990fc
Tree: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/tree/14f990fc
Diff: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/diff/14f990fc

Branch: refs/heads/include_dir_fixes
Commit: 14f990fc5f4b95b7a6d0b08edbfc479b7756e32c
Parents: 7924668
Author: Nick Wellnhofer <we...@aevum.de>
Authored: Fri Aug 1 13:47:46 2014 +0200
Committer: Nick Wellnhofer <we...@aevum.de>
Committed: Fri Aug 1 15:49:31 2014 +0200

----------------------------------------------------------------------
 compiler/perl/lib/Clownfish/CFC/Perl/Build.pm | 42 +++++-----------------
 1 file changed, 8 insertions(+), 34 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/14f990fc/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 cd3f3a7..eaa9dd7 100644
--- a/compiler/perl/lib/Clownfish/CFC/Perl/Build.pm
+++ b/compiler/perl/lib/Clownfish/CFC/Perl/Build.pm
@@ -73,17 +73,15 @@ sub new {
     push( @$cf_source, catdir( $AUTOGEN_DIR, 'source' ) );
     $self->clownfish_params( source => $cf_source );
 
-    my $cf_include = $self->clownfish_params('include');
-    if ( !defined($cf_include) ) {
-        if ($ENV{CLOWNFISH_INCLUDE}) {
-            $cf_include = [ split( /:/, $ENV{CLOWNFISH_INCLUDE} ) ];
-        }
-        else {
-            $cf_include = [ $self->cf_system_include_dirs ];
-        }
+    my $cf_include = $self->clownfish_params('include') || [];
+    # Add include dirs from CLOWNFISH_INCLUDE environment variable.
+    if ($ENV{CLOWNFISH_INCLUDE}) {
+        push( @$cf_include, split( /:/, $ENV{CLOWNFISH_INCLUDE} ) );
     }
-    elsif ( !ref($cf_include) ) {
-        $cf_include = [ $cf_include ];
+    # Add include dirs from @INC.
+    for my $dir (@INC) {
+        my $cf_incdir = catdir( $dir, 'Clownfish', '_include' );
+        push( @$cf_include, $cf_incdir ) if -d $cf_incdir;
     }
     $self->clownfish_params( include => $cf_include );
 
@@ -117,20 +115,6 @@ sub cf_base_path {
     return @BASE_PATH;
 }
 
-sub cf_system_include_dirs {
-    my $self_or_class = shift;
-
-    my @include_dirs;
-    for my $location ( qw( site vendor ) ) {
-        my $install_dir = $Config{"install${location}arch"};
-        my $include_dir = catdir( $install_dir, 'Clownfish', '_include' );
-        next unless -d $include_dir;
-        push(@include_dirs, $include_dir);
-    }
-
-    return @include_dirs;
-}
-
 sub cf_linker_flags {
     my $self_or_class = shift;
 
@@ -582,7 +566,6 @@ the Perl bindings for Clownfish modules.
     use File::Spec::Functions qw( catdir );
 
     my @cf_base_path    = Clownfish::CFC::Perl::Build->cf_base_path;
-    my @cf_sys_includes = Clownfish::CFC::Perl::Build->cf_system_include_dirs;
     my @cf_linker_flags = Clownfish::CFC::Perl::Build->cf_linker_flags(
         'Other::Module',
     );
@@ -592,11 +575,9 @@ the Perl bindings for Clownfish modules.
         dist_abstract      => 'Do something with this and that',
         dist_author        => 'The Author <au...@example.com>',
         dist_version       => '0.1.0',
-        include_dirs       => [ @cf_sys_includes ],
         extra_linker_flags => [ @cf_linker_flags ],
         clownfish_params => {
             source  => [ catdir( @cf_base_path, 'core' ) ],
-            include => [ @cf_sys_includes ],
         },
         requires => {
             'Other::Module' => '0.3.0',
@@ -692,13 +673,6 @@ Clownfish .c files.
 Returns the base path components of the source tree where C<core> was found.
 Currently either C<()> or C<('..')>.
 
-=head2 cf_system_include_dirs()
-
-    my @dirs = Clownfish::CFC::Perl::Build->cf_system_include_dirs();
-
-Returns a list of Clownfish include directories of system-wide installations
-of Clownfish modules.
-
 =head2 cf_linker_flags( I<[module_names]> )
 
     my @flags = Clownfish::CFC::Perl::Build->cf_linker_flags(@module_names);