/* -*- 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 "formula_tokens.hpp" #include "formula_token.hpp" #include "orcus/spreadsheet/document.hpp" #include #include namespace ss = orcus::spreadsheet; namespace orcus { namespace python { namespace { /** non-python part. */ struct formula_tokens_data { const ss::document* doc; ixion::abs_address_t origin; const ixion::formula_tokens_t* tokens = nullptr; ixion::formula_tokens_t::const_iterator pos; ixion::formula_tokens_t::const_iterator end; }; /** python object */ struct pyobj_formula_tokens { PyObject_HEAD formula_tokens_data* data = nullptr; }; inline pyobj_formula_tokens* t(PyObject* self) { return reinterpret_cast(self); } void init_members( pyobj_formula_tokens* self, const ss::document& doc, const ixion::abs_address_t& origin, const ixion::formula_tokens_t& tokens) { assert(self->data); self->data->doc = &doc; self->data->origin = origin; self->data->tokens = &tokens; } void tp_dealloc(pyobj_formula_tokens* self) { delete self->data; Py_TYPE(self)->tp_free(reinterpret_cast(self)); } int tp_init(pyobj_formula_tokens* /*self*/, PyObject* /*args*/, PyObject* /*kwargs*/) { return 0; } PyObject* tp_new(PyTypeObject* type, PyObject* /*args*/, PyObject* /*kwargs*/) { pyobj_formula_tokens* self = t(type->tp_alloc(type, 0)); self->data = new formula_tokens_data; return reinterpret_cast(self); } PyObject* tp_iter(PyObject* self) { formula_tokens_data& data = *t(self)->data; data.pos = data.tokens->cbegin(); data.end = data.tokens->cend(); Py_INCREF(self); return self; } PyObject* tp_iternext(PyObject* self) { formula_tokens_data& data = *t(self)->data; if (data.pos == data.end) { // No more elements. Stop the iteration. PyErr_SetNone(PyExc_StopIteration); return nullptr; } PyObject* ft_obj = create_formula_token_object(*data.doc, data.origin, *data.pos); ++data.pos; return ft_obj; } Py_ssize_t sq_length(PyObject* self) { formula_tokens_data& data = *t(self)->data; return data.tokens->size(); } PySequenceMethods tp_as_sequence = { sq_length, // lenfunc sq_length 0, // binaryfunc sq_concat 0, // ssizeargfunc sq_repeat 0, // ssizeargfunc sq_item 0, // void *was_sq_slice 0, // ssizeobjargproc sq_ass_item 0, // void *was_sq_ass_slice 0, // objobjproc sq_contains 0, // binaryfunc sq_inplace_concat 0, // ssizeargfunc sq_inplace_repeat }; PyMethodDef tp_methods[] = { { nullptr } }; PyMemberDef tp_members[] = { { nullptr } }; PyTypeObject formula_tokens_type = { PyVarObject_HEAD_INIT(nullptr, 0) "orcus.FormulaTokens", // tp_name sizeof(pyobj_formula_tokens), // tp_basicsize 0, // tp_itemsize (destructor)tp_dealloc, // tp_dealloc 0, // tp_print 0, // tp_getattr 0, // tp_setattr 0, // tp_compare 0, // tp_repr 0, // tp_as_number &tp_as_sequence, // 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 | Py_TPFLAGS_BASETYPE, // tp_flags "orcus spreadsheet formula tokens", // tp_doc 0, // tp_traverse 0, // tp_clear 0, // tp_richcompare 0, // tp_weaklistoffset tp_iter, // tp_iter tp_iternext, // tp_iternext tp_methods, // tp_methods tp_members, // tp_members 0, // tp_getset 0, // tp_base 0, // tp_dict 0, // tp_descr_get 0, // tp_descr_set 0, // tp_dictoffset (initproc)tp_init, // tp_init 0, // tp_alloc tp_new, // tp_new }; } // anonymous namespace PyObject* create_formula_tokens_iterator_object( const ss::document& doc, const ixion::abs_address_t& origin, const ixion::formula_tokens_t& tokens) { PyTypeObject* ft_type = get_formula_tokens_type(); if (!ft_type) { PyErr_SetString(PyExc_RuntimeError, "Failed to get the formula tokens type object."); return nullptr; } PyObject* obj = ft_type->tp_new(ft_type, nullptr, nullptr); if (!obj) { PyErr_SetString(PyExc_RuntimeError, "Failed to instantiate a formula tokens object."); return nullptr; } init_members(t(obj), doc, origin, tokens); return obj; } PyTypeObject* get_formula_tokens_type() { return &formula_tokens_type; } }} /* vim:set shiftwidth=4 softtabstop=4 expandtab: */