summaryrefslogtreecommitdiffstats
path: root/src/python/python.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/python/python.cpp')
-rw-r--r--src/python/python.cpp186
1 files changed, 186 insertions, 0 deletions
diff --git a/src/python/python.cpp b/src/python/python.cpp
new file mode 100644
index 0000000..53fb867
--- /dev/null
+++ b/src/python/python.cpp
@@ -0,0 +1,186 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#include "orcus/env.hpp"
+#include "orcus/info.hpp"
+
+#include "root.hpp"
+#include "xlsx.hpp"
+#include "ods.hpp"
+#include "csv.hpp"
+#include "xls_xml.hpp"
+#include "gnumeric.hpp"
+
+#ifdef __ORCUS_SPREADSHEET_MODEL
+#include "document.hpp"
+#include "sheet.hpp"
+#include "sheet_rows.hpp"
+#include "cell.hpp"
+#include "named_expression.hpp"
+#include "named_expressions.hpp"
+#include "formula_token.hpp"
+#include "formula_tokens.hpp"
+#endif
+
+#include <iostream>
+#include <sstream>
+#include <string>
+
+#include <Python.h>
+
+#define ORCUS_DEBUG_PYTHON 0
+#define GETSTATE(m) ((struct module_state*)PyModule_GetState(m))
+
+using namespace std;
+
+namespace orcus { namespace python {
+
+namespace {
+
+#if ORCUS_DEBUG_PYTHON
+void print_args(PyObject* args)
+{
+ string args_str;
+ PyObject* repr = PyObject_Repr(args);
+ if (repr)
+ {
+ Py_INCREF(repr);
+ args_str = PyBytes_AsString(repr);
+ Py_DECREF(repr);
+ }
+ cout << args_str << "\n";
+}
+#endif
+
+PyMethodDef orcus_methods[] =
+{
+ { "detect_format", (PyCFunction)detect_format, METH_VARARGS | METH_KEYWORDS,
+ "Detect the format type of a spreadsheet file." },
+
+ { "_csv_read", (PyCFunction)csv_read, METH_VARARGS | METH_KEYWORDS,
+ "Load specified csv file into a document model." },
+
+ { "_ods_read", (PyCFunction)ods_read, METH_VARARGS | METH_KEYWORDS,
+ "Load specified ods file into a document model." },
+
+ { "_xlsx_read", (PyCFunction)xlsx_read, METH_VARARGS | METH_KEYWORDS,
+ "Load specified xlsx file into a document model." },
+
+ { "_xls_xml_read", (PyCFunction)xls_xml_read, METH_VARARGS | METH_KEYWORDS,
+ "Load specified xls-xml file into a document model." },
+
+ { "_gnumeric_read", (PyCFunction)gnumeric_read, METH_VARARGS | METH_KEYWORDS,
+ "Load specified gnumeric file into a document model." },
+
+ { nullptr, nullptr, 0, nullptr }
+};
+
+struct module_state
+{
+ PyObject* error;
+};
+
+int orcus_traverse(PyObject* m, visitproc visit, void* arg)
+{
+ Py_VISIT(GETSTATE(m)->error);
+ return 0;
+}
+
+int orcus_clear(PyObject* m)
+{
+ Py_CLEAR(GETSTATE(m)->error);
+ return 0;
+}
+
+[[maybe_unused]]
+bool add_type_to_module(PyObject* m, PyTypeObject* typeobj, const char* type_name)
+{
+ if (PyType_Ready(typeobj))
+ return false;
+
+ Py_INCREF(typeobj);
+ if (PyModule_AddObject(m, type_name, reinterpret_cast<PyObject*>(typeobj)) < 0)
+ {
+ Py_DECREF(m);
+ Py_DECREF(typeobj);
+ return false;
+ }
+
+ return true;
+}
+
+bool populate_module_attributes(PyObject* m)
+{
+ std::ostringstream os;
+ os << orcus::get_version_major() << '.'
+ << orcus::get_version_minor() << '.'
+ << orcus::get_version_micro();
+
+ PyObject* version = PyUnicode_FromString(os.str().data());
+ if (PyModule_AddObject(m, "__version__", version) < 0)
+ return false;
+
+ return true;
+}
+
+}
+
+struct PyModuleDef moduledef =
+{
+ PyModuleDef_HEAD_INIT,
+ "_orcus",
+ nullptr,
+ sizeof(struct module_state),
+ orcus_methods,
+ nullptr,
+ orcus_traverse,
+ orcus_clear,
+ nullptr
+};
+
+}}
+
+extern "C" {
+
+ORCUS_DLLPUBLIC PyObject* PyInit__orcus()
+{
+ PyObject* m = PyModule_Create(&orcus::python::moduledef);
+ if (!orcus::python::populate_module_attributes(m))
+ return nullptr;
+
+#ifdef __ORCUS_SPREADSHEET_MODEL
+ if (!orcus::python::add_type_to_module(m, orcus::python::get_document_type(), "Document"))
+ return nullptr;
+
+ if (!orcus::python::add_type_to_module(m, orcus::python::get_sheet_type(), "Sheet"))
+ return nullptr;
+
+ if (!orcus::python::add_type_to_module(m, orcus::python::get_sheet_rows_type(), "SheetRows"))
+ return nullptr;
+
+ if (!orcus::python::add_type_to_module(m, orcus::python::get_cell_type(), "Cell"))
+ return nullptr;
+
+ if (!orcus::python::add_type_to_module(m, orcus::python::get_named_exp_type(), "NamedExpression"))
+ return nullptr;
+
+ if (!orcus::python::add_type_to_module(m, orcus::python::get_named_exps_type(), "NamedExpressions"))
+ return nullptr;
+
+ if (!orcus::python::add_type_to_module(m, orcus::python::get_formula_token_type(), "FormulaToken"))
+ return nullptr;
+
+ if (!orcus::python::add_type_to_module(m, orcus::python::get_formula_tokens_type(), "FormulaTokens"))
+ return nullptr;
+#endif
+
+ return m;
+}
+
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */