1 /* Python plug-in for dia
2  * Copyright (C) 1999  James Henstridge
3  * Copyright (C) 2000  Hans Breuer
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation; either version 2 of the License, or
8  * (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program; if not, write to the Free Software
17  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
18  */
19 
20 #include <config.h>
21 
22 #include "pydia-object.h"
23 #include "pydia-error.h"
24 #include "message.h"
25 
26 /*
27  * A little helper to dump pythons last error info either to file only or
28  * additional popup a message_error
29  */
30 void
_pyerror_report_last(gboolean popup,const char * fn,const char * file,int line)31 _pyerror_report_last (gboolean popup, const char* fn, const char* file, int line)
32 {
33   PyObject *exc, *v, *tb, *ef;
34   char* sLoc;
35 
36   if (strlen(fn) > 0)
37     sLoc = g_strdup_printf ("PyDia Error (%s):\n", fn); /* GNU_PRETTY_FUNCTION is enough */
38   else
39     sLoc = g_strdup_printf ("PyDia Error (%s:%d):\n", file, line);
40 
41   PyErr_Fetch (&exc, &v, &tb);
42   PyErr_NormalizeException(&exc, &v, &tb);
43 
44   ef = PyDiaError_New(sLoc, popup ? FALSE : TRUE);
45   PyFile_WriteObject (exc, ef, 0);
46   PyFile_WriteObject (v, ef, 0);
47   PyTraceBack_Print(tb, ef);
48   if (((PyDiaError*)ef)->str && popup)
49     message_error ("%s", ((PyDiaError*)ef)->str->str);
50   g_free (sLoc);
51   Py_DECREF (ef);
52   Py_XDECREF(exc);
53   Py_XDECREF(v);
54   Py_XDECREF(tb);
55 }
56 
57 /*
58  * New
59  */
PyDiaError_New(const char * s,gboolean unbuffered)60 PyObject* PyDiaError_New (const char* s, gboolean unbuffered)
61 {
62   PyDiaError *self;
63 
64   self = PyObject_NEW(PyDiaError, &PyDiaError_Type);
65   if (!self) return NULL;
66   if (unbuffered) {
67     self->str = NULL;
68   }
69   else {
70     if (s)
71       self->str = g_string_new (s);
72     else
73       self->str = g_string_new ("");
74   }
75 
76   return (PyObject *)self;
77 }
78 
79 /*
80  * Dealloc
81  */
82 static void
PyDiaError_Dealloc(PyDiaError * self)83 PyDiaError_Dealloc(PyDiaError *self)
84 {
85   if (self->str)
86     g_string_free (self->str, TRUE);
87   PyObject_DEL(self);
88 }
89 
90 /*
91  * Compare
92  */
93 static int
PyDiaError_Compare(PyDiaError * self,PyDiaError * other)94 PyDiaError_Compare(PyDiaError *self,
95                   PyDiaError *other)
96 {
97   int len = 0;
98 
99   if (self->str == other->str) return 0;
100   if (NULL == self->str) return -1;
101   if (NULL == other->str) return -1;
102 
103   len = (self->str->len > other->str->len ? other->str->len : self->str->len);
104   return memcmp(self->str->str, other->str->str, len);
105 }
106 
107 /*
108  * Hash
109  */
110 static long
PyDiaError_Hash(PyObject * self)111 PyDiaError_Hash(PyObject *self)
112 {
113   return (long)self;
114 }
115 
116 static PyObject *
PyDiaError_Write(PyDiaError * self,PyObject * args)117 PyDiaError_Write(PyDiaError *self, PyObject *args)
118 {
119   PyObject* obj;
120   gchar* s;
121 
122   if (!PyArg_ParseTuple(args, "O", &obj))
123     return NULL;
124 
125   s = PyString_AsString (obj);
126 
127   if (self->str)
128     g_string_append (self->str, s);
129 
130   g_print ("%s", s);
131 
132   Py_INCREF(Py_None);
133   return Py_None;
134 }
135 
136 static PyMethodDef PyDiaError_Methods [] = {
137     { "write", (PyCFunction)PyDiaError_Write, METH_VARARGS },
138     { NULL, 0, 0, NULL }
139 };
140 
141 /*
142  * GetAttr
143  */
144 static PyObject *
PyDiaError_GetAttr(PyDiaError * self,gchar * attr)145 PyDiaError_GetAttr(PyDiaError *self, gchar *attr)
146 {
147   return Py_FindMethod(PyDiaError_Methods, (PyObject *)self, attr);
148 }
149 
150 /*
151  * Repr / _Str
152  */
153 static PyObject *
PyDiaError_Str(PyDiaError * self)154 PyDiaError_Str(PyDiaError *self)
155 {
156   return PyString_FromString(self->str->str);
157 }
158 
159 /*
160  * Python objetcs
161  */
162 PyTypeObject PyDiaError_Type = {
163     PyObject_HEAD_INIT(&PyType_Type)
164     0,
165     "DiaError",
166     sizeof(PyDiaError),
167     0,
168     (destructor)PyDiaError_Dealloc,
169     (printfunc)0,
170     (getattrfunc)PyDiaError_GetAttr,
171     (setattrfunc)0,
172     (cmpfunc)PyDiaError_Compare,
173     (reprfunc)0,
174     0,
175     0,
176     0,
177     (hashfunc)PyDiaError_Hash,
178     (ternaryfunc)0,
179     (reprfunc)PyDiaError_Str,
180     0L,0L,0L,0L,
181     NULL
182 };
183