You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@lucy.apache.org by ma...@apache.org on 2016/02/25 23:40:20 UTC
[05/17] lucy-clownfish git commit: Add registry for CFCPyClass.
Add registry for CFCPyClass.
Register CFCPyClass singletons in a crude map. Also prepare to generate
per-class glue code.
Project: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/repo
Commit: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/commit/f0048b30
Tree: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/tree/f0048b30
Diff: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/diff/f0048b30
Branch: refs/heads/master
Commit: f0048b30e37a52cc7257e6500306b2c00970ec57
Parents: 72102ab
Author: Marvin Humphrey <ma...@rectangular.com>
Authored: Thu Jan 28 18:10:01 2016 -0800
Committer: Marvin Humphrey <ma...@rectangular.com>
Committed: Wed Feb 24 15:20:37 2016 -0800
----------------------------------------------------------------------
compiler/src/CFCPyClass.c | 70 ++++++++++++++++++++++++++++++++++++++++++
compiler/src/CFCPyClass.h | 24 +++++++++++++++
compiler/src/CFCPython.c | 32 ++++++++++++++++++-
3 files changed, 125 insertions(+), 1 deletion(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/f0048b30/compiler/src/CFCPyClass.c
----------------------------------------------------------------------
diff --git a/compiler/src/CFCPyClass.c b/compiler/src/CFCPyClass.c
index 8eaa702..e79c2d4 100644
--- a/compiler/src/CFCPyClass.c
+++ b/compiler/src/CFCPyClass.c
@@ -14,6 +14,9 @@
* limitations under the License.
*/
+#include <string.h>
+#include <stdlib.h>
+
#define CFC_NEED_BASE_STRUCT_DEF 1
#include "CFCBase.h"
@@ -34,6 +37,10 @@ struct CFCPyClass {
char *meth_defs;
};
+static CFCPyClass **registry = NULL;
+static size_t registry_size = 0;
+static size_t registry_cap = 0;
+
static void
S_CFCPyClass_destroy(CFCPyClass *self);
@@ -66,3 +73,66 @@ S_CFCPyClass_destroy(CFCPyClass *self) {
CFCBase_destroy((CFCBase*)self);
}
+static int
+S_compare_cfcperlclass(const void *va, const void *vb) {
+ CFCPyClass *a = *(CFCPyClass**)va;
+ CFCPyClass *b = *(CFCPyClass**)vb;
+ return strcmp(a->class_name, b->class_name);
+}
+
+void
+CFCPyClass_add_to_registry(CFCPyClass *self) {
+ if (registry_size == registry_cap) {
+ size_t new_cap = registry_cap + 10;
+ registry = (CFCPyClass**)REALLOCATE(registry,
+ (new_cap + 1) * sizeof(CFCPyClass*));
+ for (size_t i = registry_cap; i <= new_cap; i++) {
+ registry[i] = NULL;
+ }
+ registry_cap = new_cap;
+ }
+ CFCPyClass *existing = CFCPyClass_singleton(self->class_name);
+ if (existing) {
+ CFCUtil_die("Class '%s' already registered", self->class_name);
+ }
+ registry[registry_size] = (CFCPyClass*)CFCBase_incref((CFCBase*)self);
+ registry_size++;
+ qsort(registry, registry_size, sizeof(CFCPyClass*),
+ S_compare_cfcperlclass);
+}
+
+CFCPyClass*
+CFCPyClass_singleton(const char *class_name) {
+ CFCUTIL_NULL_CHECK(class_name);
+ for (size_t i = 0; i < registry_size; i++) {
+ CFCPyClass *existing = registry[i];
+ if (strcmp(class_name, existing->class_name) == 0) {
+ return existing;
+ }
+ }
+ return NULL;
+}
+
+CFCPyClass**
+CFCPyClass_registry() {
+ if (!registry) {
+ registry = (CFCPyClass**)CALLOCATE(1, sizeof(CFCPyClass*));
+ }
+ return registry;
+}
+
+void
+CFCPyClass_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;
+}
+
+char*
+CFCPyClass_gen_binding_code(CFCPyClass *self) {
+ return CFCUtil_strdup("");
+}
http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/f0048b30/compiler/src/CFCPyClass.h
----------------------------------------------------------------------
diff --git a/compiler/src/CFCPyClass.h b/compiler/src/CFCPyClass.h
index 4803833..b905502 100644
--- a/compiler/src/CFCPyClass.h
+++ b/compiler/src/CFCPyClass.h
@@ -32,6 +32,30 @@ struct CFCClass;
CFCPyClass*
CFCPyClass_new(struct CFCClass *client);
+/** Add a new class binding to the registry. Each unique parcel/class-name
+ * combination may only be registered once.
+ */
+void
+CFCPyClass_add_to_registry(CFCPyClass *self);
+
+/** Given a class name, return a class binding if one exists.
+ */
+CFCPyClass*
+CFCPyClass_singleton(const char *class_name);
+
+/** All registered class bindings.
+ */
+CFCPyClass**
+CFCPyClass_registry();
+
+/** Release all memory and references held by the registry.
+ */
+void
+CFCPyClass_clear_registry(void);
+
+char*
+CFCPyClass_gen_binding_code(CFCPyClass *self);
+
#ifdef __cplusplus
}
#endif
http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/f0048b30/compiler/src/CFCPython.c
----------------------------------------------------------------------
diff --git a/compiler/src/CFCPython.c b/compiler/src/CFCPython.c
index e17feeb..c7ae4c2 100644
--- a/compiler/src/CFCPython.c
+++ b/compiler/src/CFCPython.c
@@ -24,6 +24,7 @@
#define CFC_NEED_BASE_STRUCT_DEF
#include "CFCBase.h"
#include "CFCPython.h"
+#include "CFCPyClass.h"
#include "CFCPyMethod.h"
#include "CFCParcel.h"
#include "CFCClass.h"
@@ -361,6 +362,30 @@ S_gen_callbacks(CFCPython *self, CFCParcel *parcel, CFCClass **ordered) {
return content;
}
+static char*
+S_gen_class_bindings(CFCPython *self, CFCParcel *parcel,
+ const char *pymod_name, CFCClass **ordered) {
+ char *bindings = CFCUtil_strdup("");
+ for (size_t i = 0; ordered[i] != NULL; i++) {
+ CFCClass *klass = ordered[i];
+ if (CFCClass_included(klass)) {
+ continue;
+ }
+ const char *class_name = CFCClass_get_name(klass);
+ CFCPyClass *class_binding = CFCPyClass_singleton(class_name);
+ if (!class_binding) {
+ // No binding spec'd out, so create one using defaults.
+ class_binding = CFCPyClass_new(klass);
+ CFCPyClass_add_to_registry(class_binding);
+ }
+
+ char *code = CFCPyClass_gen_binding_code(class_binding);
+ bindings = CFCUtil_cat(bindings, code, NULL);
+ FREEMEM(code);
+ }
+ return bindings;
+}
+
static void
S_write_module_file(CFCPython *self, CFCParcel *parcel, const char *dest) {
const char *parcel_name = CFCParcel_get_name(parcel);
@@ -382,6 +407,7 @@ S_write_module_file(CFCPython *self, CFCParcel *parcel, const char *dest) {
CFCParcel **parcels = CFCParcel_all_parcels();
char *callbacks = S_gen_callbacks(self, parcel, ordered);
char *pound_includes = CFCUtil_strdup("");
+ char *class_bindings = S_gen_class_bindings(self, parcel, pymod_name, ordered);
for (size_t i = 0; ordered[i] != NULL; i++) {
CFCClass *klass = ordered[i];
@@ -410,6 +436,8 @@ S_write_module_file(CFCPython *self, CFCParcel *parcel, const char *dest) {
" NULL, NULL, NULL, NULL, NULL\n"
"};\n"
"\n"
+ "%s" // class bindings
+ "\n"
"PyMODINIT_FUNC\n"
"PyInit__%s(void) {\n"
" PyObject *module = PyModule_Create(&module_def);\n"
@@ -421,7 +449,8 @@ S_write_module_file(CFCPython *self, CFCParcel *parcel, const char *dest) {
char *content
= CFCUtil_sprintf(pattern, self->header, pound_includes, callbacks,
- helper_mod_name, last_component, self->footer);
+ helper_mod_name, class_bindings, last_component,
+ self->footer);
char *filepath = CFCUtil_sprintf("%s" CHY_DIR_SEP "_%s.c", dest,
last_component);
@@ -429,6 +458,7 @@ S_write_module_file(CFCPython *self, CFCParcel *parcel, const char *dest) {
FREEMEM(filepath);
FREEMEM(content);
+ FREEMEM(class_bindings);
FREEMEM(helper_mod_name);
FREEMEM(pymod_name);
FREEMEM(pound_includes);