00001 /*************************************************************************** 00002 * Copyright (c) 2010 Werner Mayer <wmayer[at]users.sourceforge.net> * 00003 * * 00004 * This file is part of the FreeCAD CAx development system. * 00005 * * 00006 * This library is free software; you can redistribute it and/or * 00007 * modify it under the terms of the GNU Library General Public * 00008 * License as published by the Free Software Foundation; either * 00009 * version 2 of the License, or (at your option) any later version. * 00010 * * 00011 * This library is distributed in the hope that it will be useful, * 00012 * but WITHOUT ANY WARRANTY; without even the implied warranty of * 00013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 00014 * GNU Library General Public License for more details. * 00015 * * 00016 * You should have received a copy of the GNU Library General Public * 00017 * License along with this library; see the file COPYING.LIB. If not, * 00018 * write to the Free Software Foundation, Inc., 59 Temple Place, * 00019 * Suite 330, Boston, MA 02111-1307, USA * 00020 * * 00021 ***************************************************************************/ 00022 00023 00024 #ifndef GUI_PYTHONDEBUG_H 00025 #define GUI_PYTHONDEBUG_H 00026 00027 #include <CXX/Extensions.hxx> 00028 #include <frameobject.h> 00029 #include <string> 00030 #include <set> 00031 00032 namespace Gui { 00033 00034 class Breakpoint 00035 { 00036 public: 00037 Breakpoint(); 00038 Breakpoint(const Breakpoint&); 00039 Breakpoint& operator=(const Breakpoint&); 00040 00041 ~Breakpoint(); 00042 00043 const QString& filename() const; 00044 void setFilename(const QString& fn); 00045 00046 bool operator ==(const Breakpoint& bp); 00047 bool operator ==(const QString& fn); 00048 00049 void addLine(int line); 00050 void removeLine(int line); 00051 bool checkLine(int line); 00052 00053 int countLines()const; 00054 int lineIndex(int ind)const; 00055 00056 bool checkBreakpoint(const QString& fn, int line); 00057 00058 private: 00059 QString _filename; 00060 std::set<int> _linenums; 00061 }; 00062 00063 inline const QString& Breakpoint::filename()const 00064 { 00065 return _filename; 00066 } 00067 00068 inline int Breakpoint::countLines()const 00069 { 00070 return static_cast<int>(_linenums.size()); 00071 } 00072 00073 inline bool Breakpoint::checkBreakpoint(const QString& fn, int line) 00074 { 00075 assert(!_filename.isEmpty()); 00076 if (_linenums.find(line) != _linenums.end()) 00077 { 00078 return fn == _filename; 00079 } 00080 return false; 00081 } 00082 00083 inline bool Breakpoint::operator ==(const Breakpoint& bp) 00084 { 00085 return _filename == bp._filename; 00086 } 00087 00088 inline bool Breakpoint::operator ==(const QString& fn) 00089 { 00090 return _filename == fn; 00091 } 00092 00096 class GuiExport PythonDebugModule : public Py::ExtensionModule<PythonDebugModule> 00097 { 00098 public: 00099 static void init_module(void); 00100 00101 PythonDebugModule(); 00102 virtual ~PythonDebugModule(); 00103 00104 private: 00105 Py::Object getFunctionCallCount(const Py::Tuple &a); 00106 Py::Object getExceptionCount(const Py::Tuple &a); 00107 Py::Object getLineCount(const Py::Tuple &a); 00108 Py::Object getFunctionReturnCount(const Py::Tuple &a); 00109 }; 00110 00114 class GuiExport PythonDebugStdout : public Py::PythonExtension<PythonDebugStdout> 00115 { 00116 public: 00117 static void init_type(void); // announce properties and methods 00118 00119 PythonDebugStdout(); 00120 ~PythonDebugStdout(); 00121 00122 Py::Object repr(); 00123 Py::Object write(const Py::Tuple&); 00124 Py::Object flush(const Py::Tuple&); 00125 }; 00126 00130 class GuiExport PythonDebugStderr : public Py::PythonExtension<PythonDebugStderr> 00131 { 00132 public: 00133 static void init_type(void); // announce properties and methods 00134 00135 PythonDebugStderr(); 00136 ~PythonDebugStderr(); 00137 00138 Py::Object repr(); 00139 Py::Object write(const Py::Tuple&); 00140 }; 00141 00145 class GuiExport PythonDebugExcept : public Py::PythonExtension<PythonDebugExcept> 00146 { 00147 public: 00148 static void init_type(void); // announce properties and methods 00149 00150 PythonDebugExcept(); 00151 ~PythonDebugExcept(); 00152 00153 Py::Object repr(); 00154 Py::Object excepthook(const Py::Tuple&); 00155 }; 00156 00157 class GuiExport PythonDebugger : public QObject 00158 { 00159 Q_OBJECT 00160 00161 public: 00162 PythonDebugger(); 00163 ~PythonDebugger(); 00164 Breakpoint getBreakpoint(const QString&) const; 00165 bool toggleBreakpoint(int line, const QString&); 00166 void runFile(const QString& fn); 00167 bool isRunning() const; 00168 bool start(); 00169 bool stop(); 00170 void tryStop(); 00171 void stepOver(); 00172 void showDebugMarker(const QString&, int line); 00173 void hideDebugMarker(const QString&); 00174 00175 Q_SIGNALS: 00176 void signalNextStep(); 00177 00178 private: 00179 static int tracer_callback(PyObject *obj, PyFrameObject *frame, int what, PyObject *arg); 00180 00181 private: 00182 struct PythonDebuggerP* d; 00183 }; 00184 00185 } // namespace Gui 00186 00187 #endif // GUI_PYTHONDEBUG_H