Add CFCGoClass: Go bindings for a Clownfish 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/6ab33786
Tree: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/tree/6ab33786
Diff: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/diff/6ab33786

Branch: refs/heads/master
Commit: 6ab33786535a0f9dea704f74f06b4cb8db37197c
Parents: 7a801bb
Author: Marvin Humphrey <[email protected]>
Authored: Mon Mar 23 17:52:09 2015 -0700
Committer: Marvin Humphrey <[email protected]>
Committed: Wed May 6 14:25:26 2015 -0700

----------------------------------------------------------------------
 compiler/src/CFCGoClass.c | 133 +++++++++++++++++++++++++++++++++++++++++
 compiler/src/CFCGoClass.h |  65 ++++++++++++++++++++
 2 files changed, 198 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/6ab33786/compiler/src/CFCGoClass.c
----------------------------------------------------------------------
diff --git a/compiler/src/CFCGoClass.c b/compiler/src/CFCGoClass.c
new file mode 100644
index 0000000..e766f3f
--- /dev/null
+++ b/compiler/src/CFCGoClass.c
@@ -0,0 +1,133 @@
+/* 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 <string.h>
+#include <stdlib.h>
+
+#define CFC_NEED_BASE_STRUCT_DEF
+#include "CFCBase.h"
+#include "CFCGoClass.h"
+#include "CFCUtil.h"
+#include "CFCClass.h"
+#include "CFCMethod.h"
+#include "CFCParcel.h"
+#include "CFCParamList.h"
+#include "CFCFunction.h"
+#include "CFCSymbol.h"
+#include "CFCVariable.h"
+#include "CFCType.h"
+#include "CFCGoTypeMap.h"
+
+struct CFCGoClass {
+    CFCBase base;
+    CFCParcel *parcel;
+    char *class_name;
+    CFCClass *client;
+};
+
+static CFCGoClass **registry = NULL;
+static size_t registry_size = 0;
+static size_t registry_cap  = 0;
+
+static void
+S_CFCGoClass_destroy(CFCGoClass *self);
+
+static const CFCMeta CFCGOCLASS_META = {
+    "Clownfish::CFC::Binding::Go::Class",
+    sizeof(CFCGoClass),
+    (CFCBase_destroy_t)S_CFCGoClass_destroy
+};
+
+CFCGoClass*
+CFCGoClass_new(CFCParcel *parcel, const char *class_name) {
+    CFCUTIL_NULL_CHECK(parcel);
+    CFCUTIL_NULL_CHECK(class_name);
+    CFCGoClass *self = (CFCGoClass*)CFCBase_allocate(&CFCGOCLASS_META);
+    self->parcel = (CFCParcel*)CFCBase_incref((CFCBase*)parcel);
+    self->class_name = CFCUtil_strdup(class_name);
+    // Client may be NULL, since fetch_singleton() does not always succeed.
+    CFCClass *client = CFCClass_fetch_singleton(parcel, class_name);
+    self->client = (CFCClass*)CFCBase_incref((CFCBase*)client);
+    return self;
+}
+
+static void
+S_CFCGoClass_destroy(CFCGoClass *self) {
+    CFCBase_decref((CFCBase*)self->parcel);
+    CFCBase_decref((CFCBase*)self->client);
+    FREEMEM(self->class_name);
+    CFCBase_destroy((CFCBase*)self);
+}
+
+static int
+S_compare_cfcgoclass(const void *va, const void *vb) {
+    CFCGoClass *a = *(CFCGoClass**)va;
+    CFCGoClass *b = *(CFCGoClass**)vb;
+    return strcmp(a->class_name, b->class_name);
+}
+
+void
+CFCGoClass_register(CFCGoClass *self) {
+    if (registry_size == registry_cap) {
+        size_t new_cap = registry_cap + 10;
+        size_t amount = (new_cap + 1) * sizeof(CFCGoClass*);
+        registry = (CFCGoClass**)REALLOCATE(registry, amount);
+        for (size_t i = registry_cap; i <= new_cap; i++) {
+            registry[i] = NULL;
+        }
+        registry_cap = new_cap;
+    }
+    CFCGoClass *existing = CFCGoClass_singleton(self->class_name);
+    if (existing) {
+        CFCUtil_die("Class '%s' already registered", self->class_name);
+    }
+    registry[registry_size] = (CFCGoClass*)CFCBase_incref((CFCBase*)self);
+    registry_size++;
+    qsort(registry, registry_size, sizeof(CFCGoClass*),
+          S_compare_cfcgoclass);
+}
+
+CFCGoClass*
+CFCGoClass_singleton(const char *class_name) {
+    CFCUTIL_NULL_CHECK(class_name);
+    for (size_t i = 0; i < registry_size; i++) {
+        CFCGoClass *existing = registry[i];
+        if (strcmp(class_name, existing->class_name) == 0) {
+            return existing;
+        }
+    }
+    return NULL;
+}
+
+CFCGoClass**
+CFCGoClass_registry() {
+    if (!registry) {
+        registry = (CFCGoClass**)CALLOCATE(1, sizeof(CFCGoClass*));
+    }
+    return registry;
+}
+
+void
+CFCGoClass_clear_registry(void) {
+    for (size_t i = 0; i < registry_size; i++) {
+        CFCBase_decref((CFCBase*)registry[i]);
+    }
+    FREEMEM(registry);
+    registry_size = 0;
+    registry_cap  = 0;
+    registry      = NULL;
+}
+

http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/6ab33786/compiler/src/CFCGoClass.h
----------------------------------------------------------------------
diff --git a/compiler/src/CFCGoClass.h b/compiler/src/CFCGoClass.h
new file mode 100644
index 0000000..d381b62
--- /dev/null
+++ b/compiler/src/CFCGoClass.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_CFCGOCLASS
+#define H_CFCGOCLASS
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct CFCGoClass CFCGoClass;
+struct CFCParcel;
+struct CFCClass;
+
+/** Clownfish::CFC::Binding::Go::Class - Generate Go binding code for a
+ * Clownfish::CFC::Model::Class.
+ */
+
+/**
+ * @param parcel A CFCParcel.
+ * @param class_name The name of the class to be registered.
+ */
+CFCGoClass*
+CFCGoClass_new(struct CFCParcel *parcel, const char *class_name);
+
+/** Add a new class binding to the registry.  Each unique parcel/class-name
+ * combination may only be registered once.
+ */
+void
+CFCGoClass_register(CFCGoClass *self);
+
+/** Given a class name, return a class binding if one exists.
+ */
+CFCGoClass*
+CFCGoClass_singleton(const char *class_name);
+
+/** All registered class bindings.
+ */
+CFCGoClass**
+CFCGoClass_registry();
+
+/** Release all memory and references held by the registry.
+ */
+void
+CFCGoClass_clear_registry(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* H_CFCGOCLASS */
+

Reply via email to