Annotation of gpl/axl/py-axl/py_axl.c, revision 1.1.1.2
1.1 misho 1: /**
2: * PyAxl: Axl Library python bindings
3: * Copyright (C) 2009 Advanced Software Production Line, S.L.
4: *
5: * This program is free software; you can redistribute it and/or
6: * modify it under the terms of the GNU Lesser General Public License
7: * as published by the Free Software Foundation; either version 2.1
8: * of the License, or (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 GNU
13: * Lesser General Public License for more details.
14: *
15: * You should have received a copy of the GNU Lesser General Public
16: * License along with this program; if not, write to the Free
17: * Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
18: * 02111-1307 USA
19: *
20: * You may find a copy of the license under this software is released
21: * at COPYING file. This is LGPL software: you are welcome to develop
22: * proprietary applications using this library without any royalty or
23: * fee but returning back any change, improvement or addition in the
24: * form of source code, project image, documentation patches, etc.
25: *
26: * For commercial support for XML enabled solutions contact us:
27: *
28: * Postal address:
29: * Advanced Software Production Line, S.L.
30: * C/ Antonio Suarez Nº 10,
31: * Edificio Alius A, Despacho 102
32: * Alcalá de Henares 28802 (Madrid)
33: * Spain
34: *
35: * Email address:
36: * info@aspl.es - http://www.aspl.es/axl
37: */
38: #include <py_axl.h>
1.1.1.2 ! misho 39: #include <locale.h>
1.1 misho 40:
41: #define LOG_DOMAIN "py-axl"
42:
43:
44: static PyObject * py_axl_doc_parse (PyObject * self, PyObject * args)
45: {
46: const char * document = NULL;
47: int size = -1;
48: PyObject * doc;
49: axlDoc * _doc;
50: axlError * _error = NULL;
51: PyObject * result;
52: PyObject * error;
53:
54: /* parse and check result */
55: if (! PyArg_ParseTuple (args, "s|i", &document, &size))
56: return NULL;
57:
58: /* parse document */
59: _doc = axl_doc_parse (document, size, &_error);
60: result = PyTuple_New (2);
61: if (_doc == NULL) {
62: /* set none document */
63: Py_INCREF (Py_None);
64: PyTuple_SetItem (result, 0, Py_None);
65:
66: /* create error */
67: error = py_axl_error_create (_error);
68:
69: /* set error */
70: PyTuple_SetItem (result, 1, error);
71:
72: /* return result tuple */
73: return result;
74: } /* end if */
75:
76: /* document parsed ok */
77: doc = py_axl_doc_create (_doc, axl_true);
78: PyTuple_SetItem (result, 0, doc);
79: PyTuple_SetItem (result, 1, Py_None);
80: Py_INCREF (Py_None);
81:
82: return result;
83: }
84:
85: static PyObject * py_axl_doc_parse_from_file (PyObject * self, PyObject * args)
86: {
87: const char * path = NULL;
88: PyObject * doc;
89: axlDoc * _doc;
90: axlError * _error = NULL;
91: PyObject * result;
92: PyObject * error;
93:
94: /* parse and check result */
95: if (! PyArg_ParseTuple (args, "s", &path))
96: return NULL;
97:
98: /* parse document */
99: _doc = axl_doc_parse_from_file (path, &_error);
100: result = PyTuple_New (2);
101: if (_doc == NULL) {
102: /* set none document */
103: Py_INCREF (Py_None);
104: PyTuple_SetItem (result, 0, Py_None);
105:
106: /* create error */
107: error = py_axl_error_create (_error);
108:
109: /* set error */
110: PyTuple_SetItem (result, 1, error);
111:
112: /* return result tuple */
113: return result;
114: } /* end if */
115:
116: /* document parsed ok */
117: doc = py_axl_doc_create (_doc, axl_true);
118: PyTuple_SetItem (result, 0, doc);
119: PyTuple_SetItem (result, 1, Py_None);
120: Py_INCREF (Py_None);
121:
122: return result;
123: }
124:
125: static PyObject * py_axl_dtd_parse_from_file (PyObject * self, PyObject * args)
126: {
127: const char * path = NULL;
128: PyObject * dtd;
129: axlDtd * _dtd;
130: axlError * _error = NULL;
131: PyObject * result;
132: PyObject * error;
133:
134: /* parse and check result */
135: if (! PyArg_ParseTuple (args, "s", &path))
136: return NULL;
137:
138: /* parse document */
139: _dtd = axl_dtd_parse_from_file (path, &_error);
140: result = PyTuple_New (2);
141: if (_dtd == NULL) {
142: /* set none document */
143: Py_INCREF (Py_None);
144: PyTuple_SetItem (result, 0, Py_None);
145:
146: /* create error */
147: error = py_axl_error_create (_error);
148:
149: /* set error */
150: PyTuple_SetItem (result, 1, error);
151:
152: /* return result tuple */
153: return result;
154: } /* end if */
155:
156: /* document parsed ok */
157: dtd = py_axl_dtd_create (_dtd);
158: PyTuple_SetItem (result, 0, dtd);
159: PyTuple_SetItem (result, 1, Py_None);
160: Py_INCREF (Py_None);
161:
162: return result;
163: }
164:
165: static PyObject * py_axl_version (PyObject * self)
166: {
167: return Py_BuildValue ("s", VERSION);
168: }
169:
170: static PyMethodDef py_axl_methods[] = {
171: /* parse */
172: {"parse", (PyCFunction) py_axl_doc_parse, METH_VARARGS,
173: "Parse an string provided returning a new reference to (axl.Doc, axl.Error)"},
174: /* file_parse */
175: {"file_parse", (PyCFunction) py_axl_doc_parse_from_file, METH_VARARGS,
176: "Parse the document found in the file path provided returning a new reference to (axl.Doc, axl.Error)"},
177: /* dtd_file_parse */
178: {"dtd_file_parse", (PyCFunction) py_axl_dtd_parse_from_file, METH_VARARGS,
179: "Parse the DTD document found in the file path provided returning a new reference to (axl.Dtd, axl.Error)"},
180: /* version */
181: {"version", (PyCFunction) py_axl_version, METH_NOARGS,
182: "Returns current py-axl version (with is the same as Axl Library)"},
183: {NULL, NULL, 0, NULL} /* sentinel */
184: };
185:
186: /**
187: * @internal Function that inits all axl modules and classes.
188: */
189: PyMODINIT_FUNC initlibpy_axl (void)
190: {
191: PyObject * module;
192:
1.1.1.2 ! misho 193: /**
! 194: * NOTE: it seems the previous call is not the appropriate way
! 195: * but there are relevant people that do not think so:
! 196: *
! 197: * http://fedoraproject.org/wiki/Features/PythonEncodingUsesSystemLocale
! 198: *
! 199: * Our appreciation is that python should take care of the
! 200: * current system locale to translate unicode content into
! 201: * const char strings, for those Py_ParseTuple and Py_BuildArg
! 202: * using s and z, rather forcing people to get into these
! 203: * hacks which are problematic.
! 204: */
! 205: PyUnicode_SetDefaultEncoding ("UTF-8");
! 206:
! 207:
1.1 misho 208: /* call to initilize threading API and to acquire the lock */
209: PyEval_InitThreads();
210:
211: /* register axl module */
212: module = Py_InitModule3 ("libpy_axl", py_axl_methods,
213: "Base module that implements wrapper functions for base Axl Library");
214: if (module == NULL)
215: return;
216:
217: /* call to register all axl modules and types */
218: init_axl_doc (module);
219: init_axl_error (module);
220: init_axl_node (module);
221: init_axl_attr_cursor (module);
222: init_axl_dtd (module);
223: init_axl_list (module);
224: init_axl_hash (module);
225: init_axl_stack (module);
226: init_axl_stream (module);
227: return;
228: }
229:
230: /**
231: * @internal Handler used to notify exception catched and handled by
232: * py_axl_handle_and_clear_exception.
233: */
234: PyAxlExceptionHandler py_axl_exception_handler = NULL;
235:
236: /**
237: * @brief Allows to check, handle and clear exception state.
238: */
239: void py_axl_handle_and_clear_exception (void)
240: {
241: PyObject * ptype = NULL;
242: PyObject * pvalue = NULL;
243: PyObject * ptraceback = NULL;
244: PyObject * list;
245: PyObject * string;
246: PyObject * mod;
247: int iterator;
248: char * str;
249: char * str_aux;
250:
251:
252: /* check exception */
253: if (PyErr_Occurred()) {
254: __axl_log (LOG_DOMAIN, AXL_LEVEL_CRITICAL, "found exception...handling..");
255:
256: /* fetch exception state */
257: PyErr_Fetch(&ptype, &pvalue, &ptraceback);
258:
259: /* import traceback module */
260: mod = PyImport_ImportModule("traceback");
261: if (! mod) {
262: __axl_log (LOG_DOMAIN, AXL_LEVEL_CRITICAL, "failed to import traceback module, printing error to console");
263: /* print exception */
264: PyErr_Print ();
265: goto clean_up;
266: } /* end if */
267:
268: /* list of backtrace items */
269: __axl_log (LOG_DOMAIN, AXL_LEVEL_CRITICAL, "formating exception: ptype:%p pvalue:%p ptraceback:%p",
270: ptype, pvalue, ptraceback);
271:
272: /* check ptraceback */
273: if (ptraceback == NULL) {
274: ptraceback = Py_None;
275: Py_INCREF (Py_None);
276: } /* end if */
277:
278: list = PyObject_CallMethod (mod, "format_exception", "OOO", ptype, pvalue, ptraceback);
279: iterator = 0;
280: if (py_axl_exception_handler)
281: str = axl_strdup ("");
282: else
283: str = axl_strdup ("PyAxl found exception inside: \n");
284: while (iterator < PyList_Size (list)) {
285: /* get the string */
286: string = PyList_GetItem (list, iterator);
287:
288: str_aux = str;
289: str = axl_strdup_printf ("%s%s", str_aux, PyString_AsString (string));
290: axl_free (str_aux);
291:
292: /* next iterator */
293: iterator++;
294: }
295:
296: /* drop a log */
297: __axl_log (LOG_DOMAIN, AXL_LEVEL_CRITICAL, str);
298: if (py_axl_exception_handler) {
299: /* remove trailing \n */
300: str[strlen (str) - 1] = 0;
301: py_axl_exception_handler (str);
302: }
303: /* free message */
304: axl_free (str);
305:
306: /* create an empty string \n */
307: Py_XDECREF (list);
308: Py_DECREF (mod);
309:
310:
311: clean_up:
312: /* call to finish retrieved vars .. */
313: Py_XDECREF (ptype);
314: Py_XDECREF (pvalue);
315: Py_XDECREF (ptraceback);
316:
317: } /* end if */
318:
319: /* clear exception */
320: PyErr_Clear ();
321: return;
322: }
323:
324: /**
325: * @brief Allows to configure a handler that will receive the
326: * exception message created.
327: *
328: * @param handler The handler to configure to receive all exception
329: * handling.
330: */
331: void py_axl_set_exception_handler (PyAxlExceptionHandler handler)
332: {
333: /* configure the handler */
334: py_axl_exception_handler = handler;
335:
336: return;
337: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>