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/09 18:11:21 UTC
[04/12] lucy-clownfish git commit: Add CFCPython.
Add CFCPython.
Start with writing cfish_hostdefs.h.
Project: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/repo
Commit: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/commit/b10130e0
Tree: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/tree/b10130e0
Diff: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/diff/b10130e0
Branch: refs/heads/master
Commit: b10130e067253b05cb57c213157d6e901805eebe
Parents: 1cf2a6d
Author: Marvin Humphrey <ma...@rectangular.com>
Authored: Thu Dec 18 18:43:29 2014 -0800
Committer: Marvin Humphrey <ma...@rectangular.com>
Committed: Sat Feb 6 09:58:13 2016 -0800
----------------------------------------------------------------------
compiler/include/CFC.h | 2 +
compiler/python/src/cfc/_cfc.c | 125 ++++++++++++++++++++++++++++++++++--
compiler/src/CFCPython.c | 115 +++++++++++++++++++++++++++++++++
compiler/src/CFCPython.h | 63 ++++++++++++++++++
4 files changed, 300 insertions(+), 5 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/b10130e0/compiler/include/CFC.h
----------------------------------------------------------------------
diff --git a/compiler/include/CFC.h b/compiler/include/CFC.h
index 9d1c222..1bdc968 100644
--- a/compiler/include/CFC.h
+++ b/compiler/include/CFC.h
@@ -57,5 +57,7 @@
#include "CFCPerlPod.h"
#include "CFCPerlTypeMap.h"
+#include "CFCPython.h"
+
#include "CFCRuby.h"
http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/b10130e0/compiler/python/src/cfc/_cfc.c
----------------------------------------------------------------------
diff --git a/compiler/python/src/cfc/_cfc.c b/compiler/python/src/cfc/_cfc.c
index d20b5fa..24e45a4 100644
--- a/compiler/python/src/cfc/_cfc.c
+++ b/compiler/python/src/cfc/_cfc.c
@@ -103,9 +103,16 @@ S_to_BindCore(PyObject *wrapper) {
"Clownfish::CFC::Binding::Core");
}
+static CFCPython*
+S_to_BindPython(PyObject *wrapper) {
+ return (CFCPython*)S_to_cfc_something(wrapper,
+ "Clownfish::CFC::Binding::Python");
+}
+
static PyTypeObject *Hierarchy_pytype;
static PyTypeObject *Parcel_pytype;
static PyTypeObject *BindCore_pytype;
+static PyTypeObject *BindPython_pytype;
/***************************** CFCHierarchy *****************************/
@@ -173,6 +180,13 @@ S_CFCHierarchy_add_source_dir(PyObject *wrapper, PyObject *dir) {
}
static PyObject*
+S_CFCHierarchy_get_dest(PyObject *wrapper, PyObject *unused) {
+ CHY_UNUSED_VAR(unused);
+ const char *dest = CFCHierarchy_get_dest(S_to_Hierarchy(wrapper));
+ return PyUnicode_DecodeASCII(dest, strlen(dest), NULL);
+}
+
+static PyObject*
S_CFCHierarchy_write_log(PyObject *wrapper, PyObject *unused) {
CHY_UNUSED_VAR(unused);
CFCHierarchy_write_log(S_to_Hierarchy(wrapper));
@@ -183,6 +197,7 @@ static PyMethodDef hierarchy_methods[] = {
{"add_include_dir", (PyCFunction)S_CFCHierarchy_add_include_dir, METH_O, NULL},
{"add_source_dir", (PyCFunction)S_CFCHierarchy_add_source_dir, METH_O, NULL},
{"build", (PyCFunction)S_CFCHierarchy_build, METH_NOARGS, NULL},
+ {"get_dest", (PyCFunction)S_CFCHierarchy_get_dest, METH_NOARGS, NULL},
{"write_log", (PyCFunction)S_CFCHierarchy_write_log, METH_NOARGS, NULL},
{NULL}
};
@@ -306,8 +321,13 @@ S_CFCBindCore_write_all_modified(PyObject *wrapper, PyObject *args) {
int modified = 0;
int result = PyArg_ParseTuple(args, "|p", &modified);
if (!result) { return NULL; }
- CFCBindCore_write_all_modified(S_to_BindCore(wrapper), modified);
- Py_RETURN_NONE;
+ modified = CFCBindCore_write_all_modified(S_to_BindCore(wrapper), modified);
+ if (modified) {
+ Py_RETURN_TRUE;
+ }
+ else {
+ Py_RETURN_FALSE;
+ }
}
static PyMethodDef bindcore_methods[] = {
@@ -356,14 +376,103 @@ static PyTypeObject BindCore_pytype_struct = {
(newfunc)S_CFCBindCore_new // tp_new
};
+/***************************** CFCPython *****************************/
+
+static PyObject*
+S_CFCPython_new(PyTypeObject *type, PyObject *args, PyObject *keyword_args) {
+ PyObject *hierarchy_wrapped;
+ char *keywords[] = {"hierarchy", NULL};
+ int result = PyArg_ParseTupleAndKeywords(args, keyword_args, "O!",
+ keywords, Hierarchy_pytype,
+ &hierarchy_wrapped);
+ if (!result) { return NULL; }
+ CFCHierarchy *hierarchy = S_to_Hierarchy(hierarchy_wrapped);
+ CFCPython *obj = CFCPython_new(hierarchy);
+ return S_wrap_cfcbase(BindPython_pytype, obj);
+}
+
+static PyObject*
+S_CFCPython_set_header(PyObject *wrapper, PyObject *header) {
+ CFCPython_set_header(S_to_BindPython(wrapper), PyUnicode_AsUTF8(header));
+ Py_RETURN_NONE;
+}
+
+static PyObject*
+S_CFCPython_set_footer(PyObject *wrapper, PyObject *footer) {
+ CFCPython_set_footer(S_to_BindPython(wrapper), PyUnicode_AsUTF8(footer));
+ Py_RETURN_NONE;
+}
+
+static PyObject*
+S_CFCPython_write_bindings(PyObject *wrapper, PyObject *args,
+ PyObject *keyword_args) {
+ char *parcel;
+ char *dest;
+ char *keywords[] = {"parcel", "dest", NULL};
+ int result = PyArg_ParseTupleAndKeywords(args, keyword_args, "ss",
+ keywords, &parcel, &dest);
+ if (!result) { return NULL; }
+ CFCPython_write_bindings(S_to_BindPython(wrapper), parcel, dest);
+ Py_RETURN_NONE;
+}
+
+static PyMethodDef bindpython_methods[] = {
+ {"set_header", (PyCFunction)S_CFCPython_set_header, METH_O, NULL},
+ {"set_footer", (PyCFunction)S_CFCPython_set_footer, METH_O, NULL},
+ {"write_bindings", (PyCFunction)S_CFCPython_write_bindings, METH_KEYWORDS|METH_VARARGS, NULL},
+ {NULL}
+};
+
+static PyTypeObject BindPython_pytype_struct = {
+ PyVarObject_HEAD_INIT(NULL, 0)
+ "cfc.binding.Python", // tp_name
+ sizeof(CFCPyWrapper), // tp_basicsize
+ 0, // tp_itemsize
+ (destructor)S_CFCBase_dealloc, // tp_dealloc
+ 0, // tp_print
+ 0, // tp_getattr
+ 0, // tp_setattr
+ 0, // tp_reserved
+ 0, // tp_repr
+ 0, // tp_as_number
+ 0, // tp_as_sequence
+ 0, // tp_as_mapping
+ 0, // tp_hash
+ 0, // tp_call
+ 0, // tp_str
+ 0, // tp_getattro
+ 0, // tp_setattro
+ 0, // tp_as_buffer
+ Py_TPFLAGS_DEFAULT, // tp_flags
+ "CFCBindPython", // tp_doc
+ 0, // tp_traverse
+ 0, // tp_clear
+ 0, // tp_richcompare
+ 0, // tp_weaklistoffset
+ 0, // tp_iter
+ 0, // tp_iternext
+ bindpython_methods, // tp_methods
+ 0, // tp_members
+ 0, // tp_getset
+ 0, // tp_base
+ 0, // tp_dict
+ 0, // tp_descr_get
+ 0, // tp_descr_set
+ 0, // tp_dictoffset
+ 0, // tp_init
+ 0, // tp_allow
+ (newfunc)S_CFCPython_new // tp_new
+};
+
/******************************* common ******************************/
PyMODINIT_FUNC
PyInit__cfc(void) {
// Initialize Python type objects.
- Hierarchy_pytype = &Hierarchy_pytype_struct;
- Parcel_pytype = &Parcel_pytype_struct;
- BindCore_pytype = &BindCore_pytype_struct;
+ Hierarchy_pytype = &Hierarchy_pytype_struct;
+ Parcel_pytype = &Parcel_pytype_struct;
+ BindCore_pytype = &BindCore_pytype_struct;
+ BindPython_pytype = &BindPython_pytype_struct;
if (PyType_Ready(Hierarchy_pytype) < 0) {
return NULL;
}
@@ -373,6 +482,9 @@ PyInit__cfc(void) {
if (PyType_Ready(BindCore_pytype) < 0) {
return NULL;
}
+ if (PyType_Ready(BindPython_pytype) < 0) {
+ return NULL;
+ }
// Initialize modules.
cfc_module = PyModule_Create(&cfc_module_def);
@@ -393,6 +505,9 @@ PyInit__cfc(void) {
Py_INCREF(BindCore_pytype);
PyModule_AddObject(cfc_binding_module, "BindCore",
(PyObject*)BindCore_pytype);
+ Py_INCREF(BindCore_pytype);
+ PyModule_AddObject(cfc_binding_module, "Python",
+ (PyObject*)BindPython_pytype);
return cfc_module;
}
http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/b10130e0/compiler/src/CFCPython.c
----------------------------------------------------------------------
diff --git a/compiler/src/CFCPython.c b/compiler/src/CFCPython.c
new file mode 100644
index 0000000..729570a
--- /dev/null
+++ b/compiler/src/CFCPython.c
@@ -0,0 +1,115 @@
+/* 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 "charmony.h"
+
+#include <string.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <ctype.h>
+
+#define CFC_NEED_BASE_STRUCT_DEF
+#include "CFCBase.h"
+#include "CFCPython.h"
+#include "CFCParcel.h"
+#include "CFCClass.h"
+#include "CFCMethod.h"
+#include "CFCHierarchy.h"
+#include "CFCUtil.h"
+#include "CFCBindCore.h"
+
+struct CFCPython {
+ CFCBase base;
+ CFCHierarchy *hierarchy;
+ char *header;
+ char *footer;
+};
+
+void
+S_destroy(CFCPython *self);
+
+static const CFCMeta CFCPYTHON_META = {
+ "Clownfish::CFC::Binding::Python",
+ sizeof(CFCPython),
+ (CFCBase_destroy_t)S_destroy
+};
+
+CFCPython*
+CFCPython_new(CFCHierarchy *hierarchy) {
+ CFCUTIL_NULL_CHECK(hierarchy);
+ CFCPython *self = (CFCPython*)CFCBase_allocate(&CFCPYTHON_META);
+ self->hierarchy = (CFCHierarchy*)CFCBase_incref((CFCBase*)hierarchy);
+ self->header = CFCUtil_strdup("");
+ self->footer = CFCUtil_strdup("");
+ return self;
+}
+
+void
+S_destroy(CFCPython *self) {
+ CFCBase_decref((CFCBase*)self->hierarchy);
+ FREEMEM(self->header);
+ FREEMEM(self->footer);
+ CFCBase_destroy((CFCBase*)self);
+}
+
+void
+CFCPython_set_header(CFCPython *self, const char *header) {
+ CFCUTIL_NULL_CHECK(header);
+ free(self->header);
+ self->header = CFCUtil_make_c_comment(header);
+}
+
+void
+CFCPython_set_footer(CFCPython *self, const char *footer) {
+ CFCUTIL_NULL_CHECK(footer);
+ free(self->footer);
+ self->footer = CFCUtil_make_c_comment(footer);
+}
+
+static void
+S_write_hostdefs(CFCPython *self) {
+ const char pattern[] =
+ "%s\n"
+ "\n"
+ "#ifndef H_CFISH_HOSTDEFS\n"
+ "#define H_CFISH_HOSTDEFS 1\n"
+ "\n"
+ "#include \"Python.h\"\n"
+ "\n"
+ "#define CFISH_OBJ_HEAD \\\n"
+ " PyObject_HEAD\n"
+ "\n"
+ "#endif /* H_CFISH_HOSTDEFS */\n"
+ "\n"
+ "%s\n";
+ char *content
+ = CFCUtil_sprintf(pattern, self->header, self->footer);
+
+ // Write if the content has changed.
+ const char *inc_dest = CFCHierarchy_get_include_dest(self->hierarchy);
+ char *filepath = CFCUtil_sprintf("%s" CHY_DIR_SEP "cfish_hostdefs.h",
+ inc_dest);
+ CFCUtil_write_if_changed(filepath, content, strlen(content));
+
+ FREEMEM(filepath);
+ FREEMEM(content);
+}
+
+void
+CFCPython_write_bindings(CFCPython *self, const char *parcel_name, const char *dest) {
+ S_write_hostdefs(self);
+}
+
http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/b10130e0/compiler/src/CFCPython.h
----------------------------------------------------------------------
diff --git a/compiler/src/CFCPython.h b/compiler/src/CFCPython.h
new file mode 100644
index 0000000..6fa846a
--- /dev/null
+++ b/compiler/src/CFCPython.h
@@ -0,0 +1,63 @@
+/* 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_CFCPYTHON
+#define H_CFCPYTHON
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct CFCPython CFCPython;
+struct CFCParcel;
+struct CFCHierarchy;
+
+/** Clownfish::CFC::Binding::Python - Python bindings for a
+ * Clownfish::CFC::Model::Hierarchy.
+ *
+ * Clownfish::CFC::Binding::Python presents an interface for auto-generating
+ * Python C API code to bind to a Clownfish class hierarchy.
+ */
+
+/**
+ * @param hierarchy A CFCHierarchy.
+ */
+
+CFCPython*
+CFCPython_new(struct CFCHierarchy *hierarchy);
+
+/** Set the text which will be prepended to generated C files -- for
+ * instance, an "autogenerated file" warning.
+ */
+void
+CFCPython_set_header(CFCPython *self, const char *header);
+
+/** Set the text which will be appended to the end of generated C files.
+ */
+void
+CFCPython_set_footer(CFCPython *self, const char *footer);
+
+/** Generate Python bindings for the specified parcel.
+ */
+void
+CFCPython_write_bindings(CFCPython *self, const char *parcel, const char *dest);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* H_CFCPYTHON */
+