diff options
| author | Miodrag Milanovic <mmicko@gmail.com> | 2018-06-28 17:56:44 +0200 | 
|---|---|---|
| committer | Miodrag Milanovic <mmicko@gmail.com> | 2018-06-28 17:57:26 +0200 | 
| commit | 1676b285ae726eb858d4d7ed089496133ce3de4b (patch) | |
| tree | b7c2a9a59c2a9a0377d266567e545f5a1c23ae58 /3rdparty/python-console | |
| parent | 2037fff7426e252a8692b971f88689c1dd8c03e8 (diff) | |
| download | nextpnr-1676b285ae726eb858d4d7ed089496133ce3de4b.tar.gz nextpnr-1676b285ae726eb858d4d7ed089496133ce3de4b.tar.bz2 nextpnr-1676b285ae726eb858d4d7ed089496133ce3de4b.zip  | |
adapted python-console  for easier use
Diffstat (limited to '3rdparty/python-console')
| -rw-r--r-- | 3rdparty/python-console/Utils.h | 2 | ||||
| -rw-r--r-- | 3rdparty/python-console/modified/pyconsole.cc | 294 | ||||
| -rw-r--r-- | 3rdparty/python-console/modified/pyconsole.h | 77 | ||||
| -rw-r--r-- | 3rdparty/python-console/modified/pyinterpreter.cc | 155 | ||||
| -rw-r--r-- | 3rdparty/python-console/modified/pyinterpreter.h | 36 | ||||
| -rw-r--r-- | 3rdparty/python-console/modified/pyredirector.cc | 112 | ||||
| -rw-r--r-- | 3rdparty/python-console/modified/pyredirector.h | 32 | 
7 files changed, 707 insertions, 1 deletions
diff --git a/3rdparty/python-console/Utils.h b/3rdparty/python-console/Utils.h index ebd4234f..bbd11a1a 100644 --- a/3rdparty/python-console/Utils.h +++ b/3rdparty/python-console/Utils.h @@ -23,7 +23,7 @@ std::string LongestCommonPrefix( InputIterator begin, InputIterator end )          const std::string& str = *it;          for (int j = 0; j <= endIndex; ++j)          { -            if (j >= str.size() || str[j] != str0[j]) +            if (j >= (int)str.size() || str[j] != str0[j])                  endIndex = j - 1;          }      } diff --git a/3rdparty/python-console/modified/pyconsole.cc b/3rdparty/python-console/modified/pyconsole.cc new file mode 100644 index 00000000..35f3e930 --- /dev/null +++ b/3rdparty/python-console/modified/pyconsole.cc @@ -0,0 +1,294 @@ +#include "pyconsole.h" +#include "pyinterpreter.h" +#include "ColumnFormatter.h" + +#include <iostream> +#include <QKeyEvent> +#include <QFont> + +#include "Utils.h" + +const QString PythonConsole::PROMPT = ">>> "; +const QString PythonConsole::MULTILINE_PROMPT = "... "; +const QColor PythonConsole::NORMAL_COLOR = QColor::fromRgbF( 0, 0, 0 ); +const QColor PythonConsole::ERROR_COLOR = QColor::fromRgbF( 1.0, 0, 0 ); +const QColor PythonConsole::OUTPUT_COLOR = QColor::fromRgbF( 0, 0, 1.0 ); + +PythonConsole::PythonConsole( QWidget* parent ): +    QTextEdit( parent ) +{ +    QFont font("unexistent"); +    font.setStyleHint(QFont::Monospace); +    setFont(font); +    m_parseHelper.subscribe( this );     +} + +void PythonConsole::keyPressEvent( QKeyEvent* e ) +{ +    switch ( e->key() ) +    { +        case Qt::Key_Return: +            handleReturnKeyPress( ); +            return; + +        case Qt::Key_Tab: +            autocomplete( ); +            return; + +        case Qt::Key_Backspace: +            if ( ! canBackspace( ) ) +                return; +            break; + +        case Qt::Key_Up: +            previousHistory( ); +            return; + +        case Qt::Key_Down: +            nextHistory( ); +            return; + +        case Qt::Key_Left: +            if ( ! canGoLeft( ) ) +                return; +    } + +    QTextEdit::keyPressEvent( e ); +} + +void PythonConsole::handleReturnKeyPress( ) +{ +    if ( ! cursorIsOnInputLine( ) ) +    { +        return; +    } + +    QString line = getLine( ); + +    m_parseHelper.process( line.toStdString( ) ); +    if ( m_parseHelper.buffered( ) ) +    { +        append(""); +        displayPrompt( ); +    } +    if ( line.size( ) ) +    { +        m_historyBuffer.push_back( line.toStdString( ) ); +        m_historyIt = m_historyBuffer.end(); +    } +    moveCursorToEnd( ); +} + +void PythonConsole::parseEvent( const ParseMessage& message ) +{ +    // handle invalid user input +    if ( message.errorCode ) +    { +        setTextColor( ERROR_COLOR ); +        append(message.message.c_str()); + +        setTextColor( NORMAL_COLOR ); +        append(""); +        displayPrompt( ); +        return; +    } + +    // interpret valid user input +    int errorCode; +    std::string res; +    if ( message.message.size() ) +        res = pyinterpreter_execute( message.message, &errorCode ); +    if ( errorCode ) +    { +        setTextColor( ERROR_COLOR ); +    } +    else +    { +        setTextColor( OUTPUT_COLOR ); +    } + +    if ( res.size( ) ) +    { +        append(res.c_str()); +    } + +    setTextColor( NORMAL_COLOR ); + +    // set up the next line on the console +    append(""); +    displayPrompt( ); +} + +QString PythonConsole::getLine( ) +{ +    QTextCursor cursor = textCursor(); +    cursor.movePosition( QTextCursor::StartOfLine ); +    cursor.movePosition( QTextCursor::Right, QTextCursor::MoveAnchor, PythonConsole::PROMPT.size( ) ); +    cursor.movePosition( QTextCursor::EndOfLine, QTextCursor::KeepAnchor ); +    QString line = cursor.selectedText( ); +    cursor.clearSelection( ); +    return line; +} + +bool PythonConsole::cursorIsOnInputLine( ) +{ +    int cursorBlock = textCursor( ).blockNumber( ); +    QTextCursor bottomCursor = textCursor( ); +    bottomCursor.movePosition( QTextCursor::End ); +    int bottomBlock = bottomCursor.blockNumber( ); +    return ( cursorBlock == bottomBlock ); +} + +bool PythonConsole::inputLineIsEmpty( ) +{ +    QTextCursor bottomCursor = textCursor( ); +    bottomCursor.movePosition( QTextCursor::End ); +    int col = bottomCursor.columnNumber( ); +    return ( col == PythonConsole::PROMPT.size( ) ); +} + +bool PythonConsole::canBackspace( ) +{ +    if ( ! cursorIsOnInputLine( ) ) +    { +        return false; +    } + +    if ( inputLineIsEmpty( ) ) +    { +        return false; +    } + +    return true; +} + +bool PythonConsole::canGoLeft( ) +{ +    if ( cursorIsOnInputLine( ) ) +    { +        QTextCursor bottomCursor = textCursor( ); +        int col = bottomCursor.columnNumber( ); +        return (col > PythonConsole::PROMPT.size( )); +    } +    return true; +} + +void PythonConsole::displayPrompt( ) +{ +    QTextCursor cursor = textCursor(); +    cursor.movePosition( QTextCursor::End ); +    if ( m_parseHelper.buffered( ) ) +    { +        cursor.insertText( PythonConsole::MULTILINE_PROMPT ); +    } +    else +    { +        cursor.insertText( PythonConsole::PROMPT ); +    } +    cursor.movePosition( QTextCursor::EndOfLine ); +} + +void PythonConsole::displayString(QString text) +{ +    QTextCursor cursor = textCursor(); +    cursor.movePosition( QTextCursor::End ); +    cursor.insertText( text ); +    cursor.movePosition( QTextCursor::EndOfLine ); +} + +void PythonConsole::autocomplete( ) +{ +    if ( ! cursorIsOnInputLine( ) ) +        return; + +    QString line = getLine( ); +    const std::list<std::string>& suggestions = +        pyinterpreter_suggest( line.toStdString( ) ); +    if (suggestions.size() == 1) +    { +        line = suggestions.back().c_str(); +    } +    else +    { +        // try to complete to longest common prefix +        std::string prefix = +            LongestCommonPrefix(suggestions.begin(), suggestions.end()); +        if (prefix.size() > (size_t)line.size()) +        { +            line = prefix.c_str(); +        } +        else +        { +            ColumnFormatter fmt; +            fmt.setItems(suggestions.begin(), suggestions.end()); +            fmt.format(width() / 10); +            setTextColor( OUTPUT_COLOR ); +            const std::list<std::string>& formatted = fmt.formattedOutput(); +            for (std::list<std::string>::const_iterator it = formatted.begin(); +                it != formatted.end(); ++it) +            { +                append(it->c_str()); +            } +            setTextColor( NORMAL_COLOR ); +        } +    } + +    // set up the next line on the console +    append(""); +    displayPrompt( ); +    moveCursorToEnd( ); +    QTextCursor cursor = textCursor(); +    cursor.insertText( line ); +    moveCursorToEnd( ); +} + +void PythonConsole::previousHistory( ) +{ +    if ( ! cursorIsOnInputLine( ) ) +        return; + +    if ( ! m_historyBuffer.size( ) ) +        return; + +    QTextCursor cursor = textCursor(); +    cursor.movePosition( QTextCursor::StartOfLine ); +    cursor.movePosition( QTextCursor::Right, QTextCursor::MoveAnchor, PythonConsole::PROMPT.size( ) ); +    cursor.movePosition( QTextCursor::EndOfLine, QTextCursor::KeepAnchor ); +    cursor.removeSelectedText( ); +    if ( m_historyIt != m_historyBuffer.begin( ) ) +    { +        --m_historyIt; +    } +    cursor.insertText( m_historyIt->c_str() ); +} + +void PythonConsole::nextHistory( ) +{ +    if ( ! cursorIsOnInputLine( ) ) +        return; + +    if ( ! m_historyBuffer.size( ) ) +        return; +    if ( m_historyIt == m_historyBuffer.end( ) ) +    { +        return; +    } +    QTextCursor cursor = textCursor(); +    cursor.movePosition( QTextCursor::StartOfLine ); +    cursor.movePosition( QTextCursor::Right, QTextCursor::MoveAnchor, PythonConsole::PROMPT.size( ) ); +    cursor.movePosition( QTextCursor::EndOfLine, QTextCursor::KeepAnchor ); +    cursor.removeSelectedText( ); +    ++m_historyIt; +    if ( m_historyIt == m_historyBuffer.end( ) ) +    { +        return; +    } +    cursor.insertText( m_historyIt->c_str() ); +} + +void PythonConsole::moveCursorToEnd( ) +{ +    QTextCursor cursor = textCursor(); +    cursor.movePosition( QTextCursor::End ); +    setTextCursor( cursor ); +} diff --git a/3rdparty/python-console/modified/pyconsole.h b/3rdparty/python-console/modified/pyconsole.h new file mode 100644 index 00000000..eb2c98a4 --- /dev/null +++ b/3rdparty/python-console/modified/pyconsole.h @@ -0,0 +1,77 @@ +/** +python-console +Copyright (C) 2018  Alex Tsui + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies +of the Software, and to permit persons to whom the Software is furnished to do +so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +*/ + +#ifndef PYCONSOLE_H +#define PYCONSOLE_H +#include <QColor> +#include <QTextEdit> +#include "ParseHelper.h" +#include "ParseListener.h" + +class QWidget; +class QKeyEvent; + +class PythonConsole : public QTextEdit, ParseListener +{ +    Q_OBJECT + +  public: +    PythonConsole(QWidget *parent = 0); + +    void displayPrompt(); +    void displayString(QString text); + +  protected: +    // override QTextEdit +    virtual void keyPressEvent(QKeyEvent *e); + +    virtual void handleReturnKeyPress(); + +    /** +    Handle a compilable chunk of Python user input. +    */ +    virtual void parseEvent(const ParseMessage &message); + +    QString getLine(); +    bool cursorIsOnInputLine(); +    bool inputLineIsEmpty(); +    bool canBackspace(); +    bool canGoLeft(); +    void autocomplete(); +    void previousHistory(); +    void nextHistory(); +    void moveCursorToEnd(); + +    static const QString PROMPT; +    static const QString MULTILINE_PROMPT; + +    static const QColor NORMAL_COLOR; +    static const QColor ERROR_COLOR; +    static const QColor OUTPUT_COLOR; + +    ParseHelper m_parseHelper; +    std::list<std::string> m_historyBuffer; +    std::list<std::string>::const_iterator m_historyIt; +}; + +#endif // PYCONSOLE_H diff --git a/3rdparty/python-console/modified/pyinterpreter.cc b/3rdparty/python-console/modified/pyinterpreter.cc new file mode 100644 index 00000000..ee8c4aa8 --- /dev/null +++ b/3rdparty/python-console/modified/pyinterpreter.cc @@ -0,0 +1,155 @@ +/** +python-console +Copyright (C) 2014  Alex Tsui + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies +of the Software, and to permit persons to whom the Software is furnished to do +so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +*/ + +#include "pyinterpreter.h" +#include <Python.h> +#include <iostream> +#include <map> +#include <memory> +#include "pyredirector.h" + +static PyThreadState *MainThreadState = NULL; + +static PyThreadState *m_threadState = NULL; +static PyObject *glb = NULL; +static PyObject *loc = NULL; + +static std::list<std::string> m_suggestions; + +template <typename... Args> std::string string_format(const std::string &format, Args... args) +{ +    size_t size = std::snprintf(nullptr, 0, format.c_str(), args...) + 1; // Extra space for '\0' +    std::unique_ptr<char[]> buf(new char[size]); +    std::snprintf(buf.get(), size, format.c_str(), args...); +    return std::string(buf.get(), buf.get() + size - 1); // We don't want the '\0' inside +} + +std::string pyinterpreter_execute(const std::string &command, int *errorCode) +{ +    PyEval_AcquireThread(m_threadState); +    *errorCode = 0; + +    PyObject *py_result; +    PyObject *dum; +    std::string res; +    py_result = Py_CompileString(command.c_str(), "<stdin>", Py_single_input); +    if (py_result == 0) { +        if (PyErr_Occurred()) { +            *errorCode = 1; +            PyErr_Print(); +            res = redirector_take_output(m_threadState); +        } + +        PyEval_ReleaseThread(m_threadState); +        return res; +    } +    dum = PyEval_EvalCode(py_result, glb, loc); +    Py_XDECREF(dum); +    Py_XDECREF(py_result); +    if (PyErr_Occurred()) { +        *errorCode = 1; +        PyErr_Print(); +    } + +    res = redirector_take_output(m_threadState); + +    PyEval_ReleaseThread(m_threadState); +    return res; +} + +const std::list<std::string> &pyinterpreter_suggest(const std::string &hint) +{ +    PyEval_AcquireThread(m_threadState); +    m_suggestions.clear(); +    int i = 0; +    std::string command = string_format("sys.completer.complete('%s', %d)\n", hint.c_str(), i); +    std::string res; +    do { +        PyObject *py_result; +        PyObject *dum; +        py_result = Py_CompileString(command.c_str(), "<stdin>", Py_single_input); +        dum = PyEval_EvalCode(py_result, glb, loc); +        Py_XDECREF(dum); +        Py_XDECREF(py_result); +        res = redirector_take_output(m_threadState); + +        ++i; +        command = string_format("sys.completer.complete('%s', %d)\n", hint.c_str(), i); +        if (res.size()) { +            // throw away the newline +            res = res.substr(1, res.size() - 3); +            m_suggestions.push_back(res); +        } +    } while (res.size()); + +    PyEval_ReleaseThread(m_threadState); +    return m_suggestions; +} + +void pyinterpreter_preinit() +{ +    m_suggestions.clear(); +    inittab_redirector(); +} + +void pyinterpreter_initialize() +{ +    PyEval_InitThreads(); +    MainThreadState = PyEval_SaveThread(); +    PyEval_AcquireThread(MainThreadState); +    m_threadState = Py_NewInterpreter(); + +    PyObject *module = PyImport_ImportModule("__main__"); +    loc = glb = PyModule_GetDict(module); + +    PyRun_SimpleString("import sys\n" +                       "import redirector\n" +                       "sys.path.insert(0, \".\")\n" // add current path +                       "sys.stdout = redirector.redirector()\n" +                       "sys.stderr = sys.stdout\n" +                       "import rlcompleter\n" +                       "sys.completer = rlcompleter.Completer()\n"); + +    PyEval_ReleaseThread(m_threadState); +} + +void pyinterpreter_finalize() +{ +    m_suggestions.clear(); + +    PyEval_AcquireThread(m_threadState); +    Py_EndInterpreter(m_threadState); +    PyEval_ReleaseLock(); + +    PyEval_RestoreThread(MainThreadState); +} + +void pyinterpreter_aquire() +{ +    PyEval_AcquireThread(m_threadState); +} + +void pyinterpreter_release() +{ +    PyEval_ReleaseThread(m_threadState); +} diff --git a/3rdparty/python-console/modified/pyinterpreter.h b/3rdparty/python-console/modified/pyinterpreter.h new file mode 100644 index 00000000..1a85c1fb --- /dev/null +++ b/3rdparty/python-console/modified/pyinterpreter.h @@ -0,0 +1,36 @@ +/** +python-console +Copyright (C) 2014  Alex Tsui + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies +of the Software, and to permit persons to whom the Software is furnished to do +so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +*/ + +#ifndef PYINTERPRETER_H +#define PYINTERPRETER_H +#include <list> +#include <string> + +std::string pyinterpreter_execute(const std::string &command, int *errorCode); +const std::list<std::string> &pyinterpreter_suggest(const std::string &hint); +void pyinterpreter_preinit(); +void pyinterpreter_initialize(); +void pyinterpreter_finalize(); +void pyinterpreter_aquire(); +void pyinterpreter_release(); +#endif // PYINTERPRETER_H diff --git a/3rdparty/python-console/modified/pyredirector.cc b/3rdparty/python-console/modified/pyredirector.cc new file mode 100644 index 00000000..5f6c43a1 --- /dev/null +++ b/3rdparty/python-console/modified/pyredirector.cc @@ -0,0 +1,112 @@ +/** +python-console +Copyright (C) 2014  Alex Tsui + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies +of the Software, and to permit persons to whom the Software is furnished to do +so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +*/ + +#include "pyredirector.h" +#include <map> + +static std::map<PyThreadState *, std::string> thread_strings; + +static std::string &redirector_string(PyThreadState *threadState) +{ +    if (!thread_strings.count(threadState)) { +        thread_strings[threadState] = ""; +    } +    return thread_strings[threadState]; +} + +std::string redirector_take_output(PyThreadState *threadState) +{ +    std::string res = redirector_string(threadState); +    redirector_string(threadState) = ""; +    return res; +} + +static PyObject *redirector_init(PyObject *, PyObject *) +{ +    Py_INCREF(Py_None); +    return Py_None; +} + +static PyObject *redirector_write(PyObject *, PyObject *args) +{ +    char *output; +    PyObject *selfi; + +    if (!PyArg_ParseTuple(args, "Os", &selfi, &output)) { +        return NULL; +    } + +    std::string outputString(output); +    PyThreadState *currentThread = PyThreadState_Get(); +    std::string &resultString = redirector_string(currentThread); +    resultString = resultString + outputString; +    Py_INCREF(Py_None); +    return Py_None; +} + +static PyMethodDef redirector_methods[] = { +        {"__init__", redirector_init, METH_VARARGS, "initialize the stdout/err redirector"}, +        {"write", redirector_write, METH_VARARGS, "implement the write method to redirect stdout/err"}, +        {NULL, NULL, 0, NULL}, +}; + +static PyObject *createClassObject(const char *name, PyMethodDef methods[]) +{ +    PyObject *pClassName = PyUnicode_FromString(name); +    PyObject *pClassBases = PyTuple_New(0); // An empty tuple for bases is equivalent to `(object,)` +    PyObject *pClassDic = PyDict_New(); + +    PyMethodDef *def; +    // add methods to class +    for (def = methods; def->ml_name != NULL; def++) { +        PyObject *func = PyCFunction_New(def, NULL); +        PyObject *method = PyInstanceMethod_New(func); +        PyDict_SetItemString(pClassDic, def->ml_name, method); +        Py_DECREF(func); +        Py_DECREF(method); +    } + +    // pClass = type(pClassName, pClassBases, pClassDic) +    PyObject *pClass = PyObject_CallFunctionObjArgs((PyObject *)&PyType_Type, pClassName, pClassBases, pClassDic, NULL); + +    Py_DECREF(pClassName); +    Py_DECREF(pClassBases); +    Py_DECREF(pClassDic); + +    return pClass; +} + +static struct PyModuleDef moduledef = {PyModuleDef_HEAD_INIT, "redirector", 0, -1, 0}; + +PyMODINIT_FUNC PyInit_redirector(void) +{ +    PyObject *m = PyModule_Create(&moduledef); +    if (m) { +        PyObject *fooClass = createClassObject("redirector", redirector_methods); +        PyModule_AddObject(m, "redirector", fooClass); +        Py_DECREF(fooClass); +    } +    return m; +} + +void inittab_redirector() { PyImport_AppendInittab("redirector", PyInit_redirector); }
\ No newline at end of file diff --git a/3rdparty/python-console/modified/pyredirector.h b/3rdparty/python-console/modified/pyredirector.h new file mode 100644 index 00000000..21e20a62 --- /dev/null +++ b/3rdparty/python-console/modified/pyredirector.h @@ -0,0 +1,32 @@ +/** +python-console +Copyright (C) 2014  Alex Tsui + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies +of the Software, and to permit persons to whom the Software is furnished to do +so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +*/ + +#ifndef PYREDIRECTOR_H +#define PYREDIRECTOR_H +#include <Python.h> +#include <string> + +std::string redirector_take_output(PyThreadState *threadState); +void inittab_redirector(); + +#endif // PYREDIRECTOR_H  | 
