static PyObject* Preprocessor_tokenize(Preprocessor* self, PyObject *args) { const char *s = NULL; Py_ssize_t len; if (!PyArg_ParseTuple(args, "s#:tokenize", &s, &len)) return NULL; try { std::vector<cmonster::core::Token> result = self->preprocessor->tokenize(s, len); ScopedPyObject tuple(PyTuple_New(result.size())); if (!tuple) return NULL; for (Py_ssize_t i = 0; i < (Py_ssize_t)result.size(); ++i) { Token *token = create_token(self, result[i]); if (!token) return NULL; PyTuple_SetItem(tuple, i, (PyObject*)token); } return tuple.release(); } catch (...) { set_python_exception(); return NULL; } Py_INCREF(Py_None); return Py_None; }
PyObject* Preprocessor_set_include_locator(Preprocessor *self, PyObject *args) { PyObject *locator_; if (!PyArg_ParseTuple(args, "O:set_include_locator", &locator_)) return NULL; if (!PyCallable_Check(locator_)) { PyErr_SetString(PyExc_TypeError, "Expected a callable"); return NULL; } try { boost::shared_ptr<cmonster::core::IncludeLocator> locator( new cmonster::python::IncludeLocator(locator_)); self->preprocessor->set_include_locator(locator); Py_INCREF(Py_None); return Py_None; } catch (...) { set_python_exception(); return NULL; } }
static PyObject* Preprocessor_next(Preprocessor* self, PyObject *args) { PyObject *expand = Py_True; if (!PyArg_ParseTuple(args, "|O:next", &expand)) return NULL; try { std::auto_ptr<cmonster::core::Token> token( self->preprocessor->next(PyObject_IsTrue(expand))); if (token.get()) { return (PyObject*)create_token(self, *token); } else { PyErr_SetString(PyExc_RuntimeError, "Internal error: Preprocessor returned NULL"); return NULL; } } catch (...) { set_python_exception(); return NULL; } }
static PyObject* Preprocessor_add_pragma(Preprocessor* self, PyObject *args) { const char *name = NULL; PyObject *handler = NULL; if (!PyArg_ParseTuple(args, "sO:add_pragma", &name, &handler)) return NULL; try { if (PyCallable_Check(handler)) { boost::shared_ptr<cmonster::core::FunctionMacro> function(new cmonster::python::FunctionMacro(self, handler)); self->preprocessor->add_pragma(name, function); } else { PyErr_SetString(PyExc_TypeError, "expected callable for handler"); return NULL; } } catch (...) { set_python_exception(); return NULL; } Py_INCREF(Py_None); return Py_None; }
void handle_constructor_error(PyObject* self,const std::exception& error) { // Deallocate self without calling the destructor, since the constructor didn't finish. // We don't need to call Py_DECREF since we know that no one else owns self yet. free(self); // report the error set_python_exception(error); }
static PyObject* Preprocessor_iter(Preprocessor *pp) { try { return (PyObject*)create_iterator(pp); } catch (...) { set_python_exception(); return NULL; } }
PyObject* Preprocessor_format_tokens(Preprocessor *self, PyObject *args) { PyObject *tokens; if (!PyArg_ParseTuple(args, "O:format_tokens", &tokens)) return NULL; ScopedPyObject iter(PyObject_GetIter(tokens)); if (!iter) return NULL; try { // Iterate through the tokens, accumulating in a vector. std::vector<cmonster::core::Token> token_vector; for (;;) { ScopedPyObject item(PyIter_Next(iter)); if (!item) { if (PyErr_Occurred()) return NULL; else break; } if (!PyObject_TypeCheck(item, get_token_type())) { PyErr_SetString(PyExc_TypeError, "Expected sequence of tokens"); return NULL; } token_vector.push_back(get_token((Token*)(PyObject*)item)); } // Format the sequence of tokens. std::ostringstream ss; if (!token_vector.empty()) self->preprocessor->format(ss, token_vector); std::string formatted = ss.str(); return PyUnicode_FromStringAndSize(formatted.data(), formatted.size()); } catch (...) { set_python_exception(); return NULL; } }
static PyObject* Preprocessor_preprocess(Preprocessor* self, PyObject *args) { PyObject *f = NULL; if (!PyArg_ParseTuple(args, "|O:preprocess", &f)) return NULL; try { boost::shared_ptr<FILE> file; long fd; if (!f || f == Py_None) { fd = fileno(stdout); } else if (PyUnicode_Check(f)) { ScopedPyObject utf8_filename(PyUnicode_AsUTF8String(f)); const char *filename; if (utf8_filename && (filename = PyBytes_AsString(utf8_filename))) { file.reset(fopen(filename, "w"), &fclose); fd = fileno(file.get()); } else { return NULL; } } else { // Assume it's a file-like object with a fileno() method. PyObject *pylong = PyObject_CallMethod(f, (char*)"fileno", NULL); if (!pylong || (fd = PyLong_AsLong(pylong)) == -1) return NULL; } self->preprocessor->preprocess(fd); } catch (...) { set_python_exception(); return NULL; } Py_INCREF(Py_None); return Py_None; }
static PyObject* Preprocessor_add_include_dir(Preprocessor* self, PyObject *args) { char *path; PyObject *sysinclude = Py_True; if (!PyArg_ParseTuple(args, "s|O:add_include_dir", &path, &sysinclude)) return NULL; try { self->preprocessor->add_include_dir( path, PyObject_IsTrue(sysinclude)); Py_INCREF(Py_None); return Py_None; } catch (...) { set_python_exception(); } return NULL; }
static PyObject* Preprocessor_define(Preprocessor* self, PyObject *args) { PyObject *macro; PyObject *value = NULL; if (!PyArg_ParseTuple(args, "O|O:define", ¯o, &value)) return NULL; try { // First check if it's a string. If so, convert it to UTF-8 and define // an object-like macro. if (PyUnicode_Check(macro)) { ScopedPyObject utf8_name(PyUnicode_AsUTF8String(macro)); const char *macro_name; if (utf8_name && (macro_name = PyBytes_AsString(utf8_name))) { if (value) { if (PyUnicode_Check(value)) // define(name, value) { ScopedPyObject utf8_value( PyUnicode_AsUTF8String(value)); const char *macro_value; if (utf8_value && (macro_value = PyBytes_AsString(utf8_value))) { // Value specified: // "#define macro_name macro_value". self->preprocessor->define( macro_name, macro_value); } else { return NULL; } } else if (PyCallable_Check(value)) // define(name, callable) { boost::shared_ptr<cmonster::core::FunctionMacro> function(new cmonster::python::FunctionMacro( self, value)); self->preprocessor->define(macro_name, function); } else { PyErr_SetString(PyExc_TypeError, "expected string or callable for value argument"); return NULL; } } else { // No value specified: "#define macro_name". self->preprocessor->define(macro_name); } } else { return NULL; } } else if (PyCallable_Check(macro)) // define(callable) { // TODO ensure "value" was not specified. const char *name = PyEval_GetFuncName(macro); boost::shared_ptr<cmonster::core::FunctionMacro> function(new cmonster::python::FunctionMacro(self, macro)); self->preprocessor->define(name, function); } else { PyErr_SetString(PyExc_TypeError, "expected string or callable"); return NULL; } } catch (...) { set_python_exception(); return NULL; } Py_INCREF(Py_None); return Py_None; }