summaryrefslogtreecommitdiffstats
path: root/src/python/python.cpp
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/python/python.cpp174
1 files changed, 174 insertions, 0 deletions
diff --git a/src/python/python.cpp b/src/python/python.cpp
new file mode 100644
index 0000000..1c8b5bf
--- /dev/null
+++ b/src/python/python.cpp
@@ -0,0 +1,174 @@
+/* -*- 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 "document.hpp"
+#include "sheet.hpp"
+#include "global.hpp"
+
+#include "ixion/env.hpp"
+#include "ixion/info.hpp"
+
+#include <iostream>
+#include <string>
+
+#define IXION_DEBUG_PYTHON 0
+#define GETSTATE(m) ((struct module_state*)PyModule_GetState(m))
+
+using namespace std;
+
+namespace ixion { namespace python {
+
+namespace {
+
+#if IXION_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
+
+PyObject* info(PyObject*, PyObject*)
+{
+ cout << "ixion version: "
+ << ixion::get_version_major() << '.'
+ << ixion::get_version_minor() << '.'
+ << ixion::get_version_micro() << endl;
+
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+PyObject* column_label(PyObject* /*module*/, PyObject* args, PyObject* kwargs)
+{
+ int start;
+ int stop;
+ int resolver_index = 1; // Excel A1 by default
+ static const char* kwlist[] = { "start", "stop", "resolver", nullptr };
+ if (!PyArg_ParseTupleAndKeywords(args, kwargs, "ii|i", const_cast<char**>(kwlist), &start, &stop, &resolver_index))
+ return nullptr;
+
+ if (start >= stop)
+ {
+ PyErr_SetString(
+ PyExc_IndexError,
+ "Start position is larger or equal to the stop position.");
+ return nullptr;
+ }
+
+ if (start < 0)
+ {
+ PyErr_SetString(
+ PyExc_IndexError,
+ "Start position should be larger than or equal to 0.");
+ return nullptr;
+ }
+
+ auto resolver = formula_name_resolver::get(
+ static_cast<formula_name_resolver_t>(resolver_index), nullptr);
+ if (!resolver)
+ {
+ PyErr_SetString(
+ get_python_formula_error(), "Specified resolver type is invalid.");
+ return nullptr;
+ }
+
+ int size = stop - start;
+ PyObject* t = PyTuple_New(size);
+
+ for (int i = start; i < stop; ++i)
+ {
+ string s = resolver->get_column_name(i);
+ PyObject* o = PyUnicode_FromString(s.c_str());
+ PyTuple_SetItem(t, i-start, o);
+ }
+
+ return t;
+}
+
+PyMethodDef ixion_methods[] =
+{
+ { "info", (PyCFunction)info, METH_NOARGS, "Print ixion module information." },
+ { "column_label", (PyCFunction)column_label, METH_VARARGS | METH_KEYWORDS,
+ "Return a list of column label strings based on specified column range values." },
+ { nullptr, nullptr, 0, nullptr }
+};
+
+struct module_state
+{
+ PyObject* error;
+};
+
+int ixion_traverse(PyObject* m, visitproc visit, void* arg)
+{
+ Py_VISIT(GETSTATE(m)->error);
+ return 0;
+}
+
+int ixion_clear(PyObject* m)
+{
+ Py_CLEAR(GETSTATE(m)->error);
+ return 0;
+}
+
+}
+
+struct PyModuleDef moduledef =
+{
+ PyModuleDef_HEAD_INIT,
+ "ixion",
+ nullptr,
+ sizeof(struct module_state),
+ ixion_methods,
+ nullptr,
+ ixion_traverse,
+ ixion_clear,
+ nullptr
+};
+
+}}
+
+extern "C" {
+
+IXION_DLLPUBLIC PyObject* PyInit_ixion()
+{
+ PyTypeObject* doc_type = ixion::python::get_document_type();
+ if (PyType_Ready(doc_type) < 0)
+ return nullptr;
+
+ PyTypeObject* sheet_type = ixion::python::get_sheet_type();
+ if (PyType_Ready(sheet_type) < 0)
+ return nullptr;
+
+ PyObject* m = PyModule_Create(&ixion::python::moduledef);
+
+ Py_INCREF(doc_type);
+ PyModule_AddObject(m, "Document", reinterpret_cast<PyObject*>(doc_type));
+
+ Py_INCREF(sheet_type);
+ PyModule_AddObject(m, "Sheet", reinterpret_cast<PyObject*>(sheet_type));
+
+ PyModule_AddObject(
+ m, "DocumentError", ixion::python::get_python_document_error());
+ PyModule_AddObject(
+ m, "SheetError", ixion::python::get_python_sheet_error());
+ PyModule_AddObject(
+ m, "FormulaError", ixion::python::get_python_formula_error());
+
+ return m;
+}
+
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */