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/4ccff248
Tree: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/tree/4ccff248
Diff: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/diff/4ccff248

Branch: refs/heads/master
Commit: 4ccff248e08e3610e74f0a477c08d59305cad14f
Parents: c3ef338
Author: Nick Wellnhofer <[email protected]>
Authored: Tue Dec 2 02:04:13 2014 +0100
Committer: Nick Wellnhofer <[email protected]>
Committed: Wed Dec 24 16:02:03 2014 +0100

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


http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/4ccff248/compiler/src/CFCUri.c
----------------------------------------------------------------------
diff --git a/compiler/src/CFCUri.c b/compiler/src/CFCUri.c
new file mode 100644
index 0000000..88f74b5
--- /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 <ctype.h>
+#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 void
+S_parse_uri(CFCUri *self, const char *str, CFCClass *klass);
+
+static char**
+S_split(const char *str, char c, size_t *num_parts_ptr);
+
+int
+CFCUri_is_clownfish_uri(const char *uri) {
+    return strncmp(uri, "cfish:", 6) == 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, "cfish:", 6) != 0) {
+        CFCUtil_die("Invalid clownfish URI: %s", uri);
+    }
+
+    if (strcmp(uri + 6, "@null") == 0) {
+        self->type = CFC_URI_NULL;
+    }
+    else {
+        S_parse_uri(self, uri, klass);
+    }
+
+    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);
+                }
+            }
+        }
+    }
+
+    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 void
+S_parse_uri(CFCUri *self, const char *uri, CFCClass *klass) {
+    size_t num_components = 0;
+    char **components = S_split(uri + 6, '.', &num_components);
+    size_t i = 0;
+
+    self->type = CFC_URI_PARCEL;
+
+    if (islower(components[i][0])) {
+        // Parcel
+        self->prefix = CFCUtil_sprintf("%s_", components[i]);
+        ++i;
+    }
+    else {
+        if (!klass) {
+            CFCUtil_die("Class needed to complete URI: %s", uri);
+        }
+        self->prefix = CFCUtil_strdup(CFCClass_get_prefix(klass));
+    }
+
+    if (i < num_components) {
+        self->type = CFC_URI_CLASS;
+
+        if (isupper(components[i][0])) {
+            // Class
+            self->struct_sym = components[i];
+            components[i] = NULL;
+        }
+        else if (i == 0 && components[i][0] == '\0') {
+            if (!klass) {
+                CFCUtil_die("Class needed to complete URI: %s", uri);
+            }
+            self->struct_sym = CFCUtil_strdup(CFCClass_get_struct_sym(klass));
+        }
+        else {
+            CFCUtil_die("Invalid clownfish URI: %s", uri);
+        }
+
+        ++i;
+    }
+
+    if (i < num_components) {
+        if (isupper(components[i][0])) {
+            self->type = CFC_URI_METHOD;
+        }
+        else if (islower(components[i][0])) {
+            self->type = CFC_URI_FUNCTION;
+        }
+        else {
+            CFCUtil_die("Invalid clownfish URI: %s", uri);
+        }
+
+        self->func_sym = components[i];
+        components[i] = NULL;
+        ++i;
+    }
+
+    if (i != num_components) {
+        CFCUtil_die("Invalid clownfish URI: %s", uri);
+    }
+
+    for (i = 0; i < num_components; ++i) {
+        FREEMEM(components[i]);
+    }
+    FREEMEM(components);
+}
+
+static char**
+S_split(const char *str, char c, size_t *num_parts_ptr) {
+    const char *ptr;
+    int num_parts = 1;
+
+    for (ptr = str; *ptr != '\0'; ++ptr) {
+        if (*ptr == c) { ++num_parts; }
+    }
+
+    char **parts = (char**)MALLOCATE((num_parts + 1) * sizeof(char*));
+    const char *start = str;
+    size_t i = 0;
+
+    for (ptr = str; *ptr != '\0'; ++ptr) {
+        if (*ptr == c) {
+            parts[i++] = CFCUtil_strndup(start, ptr - start);
+            start = ptr + 1;
+        }
+    }
+    parts[i++] = CFCUtil_strndup(start, ptr - start);
+    parts[i]   = NULL;
+
+    *num_parts_ptr = num_parts;
+
+    return parts;
+}
+
+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/4ccff248/compiler/src/CFCUri.h
----------------------------------------------------------------------
diff --git a/compiler/src/CFCUri.h b/compiler/src/CFCUri.h
new file mode 100644
index 0000000..004fc3c
--- /dev/null
+++ b/compiler/src/CFCUri.h
@@ -0,0 +1,65 @@
+/* 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_PARCEL      1
+#define CFC_URI_CLASS       2
+#define CFC_URI_FUNCTION    3
+#define CFC_URI_METHOD      4
+#define CFC_URI_NULL        5
+
+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