CFCUri class

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

Branch: refs/heads/markdown_v2
Commit: 0a0c74391de3a3bc46588709ef2082db85779695
Parents: 65ddb13
Author: Nick Wellnhofer <[email protected]>
Authored: Tue Dec 2 02:04:13 2014 +0100
Committer: Nick Wellnhofer <[email protected]>
Committed: Tue Dec 2 18:31:14 2014 +0100

----------------------------------------------------------------------
 compiler/src/CFCUri.c | 232 +++++++++++++++++++++++++++++++++++++++++++++
 compiler/src/CFCUri.h |  64 +++++++++++++
 2 files changed, 296 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/0a0c7439/compiler/src/CFCUri.c
----------------------------------------------------------------------
diff --git a/compiler/src/CFCUri.c b/compiler/src/CFCUri.c
new file mode 100644
index 0000000..0f466a6
--- /dev/null
+++ b/compiler/src/CFCUri.c
@@ -0,0 +1,232 @@
+/* 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.
+ */
+
+#include <stdlib.h>
+#include <string.h>
+
+#define CFC_NEED_BASE_STRUCT_DEF
+#include "CFCBase.h"
+#include "CFCUri.h"
+#include "CFCClass.h"
+#include "CFCUtil.h"
+
+struct CFCUri {
+    CFCBase base;
+    int   type;
+    char *prefix;
+    char *struct_sym;
+    char *full_struct_sym;
+    char *func_sym;
+};
+
+static const CFCMeta CFCURI_META = {
+    "Clownfish::CFC::Uri",
+    sizeof(CFCUri),
+    (CFCBase_destroy_t)CFCUri_destroy
+};
+
+static char*
+S_next_component(const char *uri, const char **comp_ptr, int *num_comps);
+
+int
+CFCUri_is_clownfish_uri(const char *uri) {
+    return strncmp(uri, "clownfish:", 10) == 0;
+}
+
+CFCUri*
+CFCUri_new(const char *uri, CFCClass *klass) {
+    CFCUri *self = (CFCUri*)CFCBase_allocate(&CFCURI_META);
+    return CFCUri_init(self, uri, klass);
+}
+
+CFCUri*
+CFCUri_init(CFCUri *self, const char *uri, CFCClass *klass) {
+    CFCUTIL_NULL_CHECK(uri);
+
+    if (strncmp(uri, "clownfish:", 10) != 0) {
+        CFCUtil_die("Invalid clownfish URI: %s", uri);
+    }
+    const char *comp = uri + 10;
+
+    int num_components = 0;
+
+    char *type_str = S_next_component(uri, &comp, &num_components);
+    char *comp2    = S_next_component(uri, &comp, &num_components);
+    char *comp3    = S_next_component(uri, &comp, &num_components);
+    char *comp4    = S_next_component(uri, &comp, &num_components);
+
+    if (num_components == 0 || comp[0] != '\0') {
+        CFCUtil_die("Invalid clownfish URI: %s", uri);
+    }
+
+    if (strcmp(type_str, "null") == 0) {
+        self->type = CFC_URI_NULL;
+
+        if (num_components != 1) {
+            CFCUtil_die("Invalid clownfish URI: %s", uri);
+        }
+    }
+    else if (strcmp(type_str, "class") == 0) {
+        self->type = CFC_URI_CLASS;
+
+        if (num_components == 2) {
+            if (!klass) {
+                CFCUtil_die("Class needed to complete URI: %s", uri);
+            }
+            self->prefix     = CFCUtil_strdup(CFCClass_get_prefix(klass));
+            self->struct_sym = comp2;
+        }
+        else if (num_components == 3) {
+            self->prefix     = CFCUtil_sprintf("%s_", comp2);
+            self->struct_sym = comp3;
+            FREEMEM(comp2);
+        }
+        else {
+            CFCUtil_die("Invalid clownfish URI: %s", uri);
+        }
+    }
+    else if (strcmp(type_str, "function") == 0
+             || strcmp(type_str, "method") == 0
+    ) {
+        self->type = strcmp(type_str, "function") == 0
+                     ? CFC_URI_FUNCTION : CFC_URI_METHOD;
+
+        if (num_components == 2) {
+            if (!klass) {
+                CFCUtil_die("Class needed to complete URI: %s", uri);
+            }
+            self->prefix     = CFCUtil_strdup(CFCClass_get_prefix(klass));
+            self->struct_sym = CFCUtil_strdup(CFCClass_get_struct_sym(klass));
+            self->func_sym   = comp2;
+        }
+        else if (num_components == 3) {
+            if (!klass) {
+                CFCUtil_die("Class needed to complete URI: %s", uri);
+            }
+            self->prefix     = CFCUtil_strdup(CFCClass_get_prefix(klass));
+            self->struct_sym = comp2;
+            self->func_sym   = comp3;
+        }
+        else if (num_components == 4) {
+            self->prefix     = CFCUtil_sprintf("%s_", comp2);
+            self->struct_sym = comp3;
+            self->func_sym   = comp4;
+            FREEMEM(comp2);
+        }
+        else {
+            CFCUtil_die("Invalid clownfish URI: %s", uri);
+        }
+    }
+    else {
+        CFCUtil_die("Invalid clownfish URI: %s", uri);
+    }
+
+    if (self->prefix && self->struct_sym) {
+        self->full_struct_sym
+            = CFCUtil_sprintf("%s%s", self->prefix, self->struct_sym);
+
+        if (getenv("CFC_CHECK_LINKS")) {
+            CFCClass *klass
+                = CFCClass_fetch_by_struct_sym(self->full_struct_sym);
+
+            if (!klass) {
+                CFCUtil_warn("No class found for URI: %s", uri);
+            }
+            else if (self->type == CFC_URI_FUNCTION) {
+                if (!CFCClass_function(klass, self->func_sym)) {
+                    const char *class_name = CFCClass_get_class_name(klass);
+                    CFCUtil_warn("No function found for URI %s in %s", uri,
+                                 class_name);
+                }
+            }
+            else if (self->type == CFC_URI_METHOD) {
+                if (!CFCClass_method(klass, self->func_sym)) {
+                    const char *class_name = CFCClass_get_class_name(klass);
+                    CFCUtil_warn("No method found for URI %s in %s", uri,
+                                 class_name);
+                }
+            }
+        }
+    }
+
+    FREEMEM(type_str);
+
+    return self;
+}
+
+void
+CFCUri_destroy(CFCUri *self) {
+    FREEMEM(self->prefix);
+    FREEMEM(self->struct_sym);
+    FREEMEM(self->full_struct_sym);
+    FREEMEM(self->func_sym);
+    CFCBase_destroy((CFCBase*)self);
+}
+
+static char*
+S_next_component(const char *uri, const char **comp_ptr, int *num_comps) {
+    const char *comp = *comp_ptr;
+
+    if (comp[0] == '\0') {
+        return NULL;
+    }
+
+    const char *colon = strchr(comp, ':');
+    char *component;
+
+    if (colon) {
+        size_t len = colon - comp;
+        if (len == 0) {
+            CFCUtil_die("Invalid clownfish URI: %s", uri);
+        }
+        component = CFCUtil_strndup(comp, len);
+        *comp_ptr += len + 1;
+    }
+    else {
+        component = CFCUtil_strdup(comp);
+        *comp_ptr += strlen(comp);
+    }
+
+    ++*num_comps;
+
+    return component;
+}
+
+int
+CFCUri_get_type(CFCUri *self) {
+    return self->type;
+}
+
+const char*
+CFCUri_get_prefix(CFCUri *self) {
+    return self->prefix;
+}
+
+const char*
+CFCUri_get_struct_sym(CFCUri *self) {
+    return self->struct_sym;
+}
+
+const char*
+CFCUri_full_struct_sym(CFCUri *self) {
+    return self->full_struct_sym;
+}
+
+const char*
+CFCUri_get_func_sym(CFCUri *self) {
+    return self->func_sym;
+}
+

http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/0a0c7439/compiler/src/CFCUri.h
----------------------------------------------------------------------
diff --git a/compiler/src/CFCUri.h b/compiler/src/CFCUri.h
new file mode 100644
index 0000000..51784e2
--- /dev/null
+++ b/compiler/src/CFCUri.h
@@ -0,0 +1,64 @@
+/* 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.
+ */
+
+#ifndef H_CFCURI
+#define H_CFCURI
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define CFC_URI_NULL        1
+#define CFC_URI_CLASS       2
+#define CFC_URI_FUNCTION    3
+#define CFC_URI_METHOD      4
+
+typedef struct CFCUri CFCUri;
+struct CFCClass;
+
+int
+CFCUri_is_clownfish_uri(const char *uri);
+
+CFCUri*
+CFCUri_new(const char *uri, struct CFCClass *klass);
+
+CFCUri*
+CFCUri_init(CFCUri *self, const char *uri, struct CFCClass *klass);
+
+void
+CFCUri_destroy(CFCUri *self);
+
+int
+CFCUri_get_type(CFCUri *self);
+
+const char*
+CFCUri_get_prefix(CFCUri *self);
+
+const char*
+CFCUri_get_struct_sym(CFCUri *self);
+
+const char*
+CFCUri_full_struct_sym(CFCUri *self);
+
+const char*
+CFCUri_get_func_sym(CFCUri *self);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* H_CFCURI */
+

Reply via email to