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 */
+