File:  [ELWIX - Embedded LightWeight unIX -] / gpl / axl / py-axl / py_axl.c
Revision 1.1.1.2 (vendor branch): download - view: text, annotated - select for diffs - revision graph
Fri Feb 17 12:50:03 2012 UTC (12 years, 4 months ago) by misho
Branches: axl, MAIN
CVS tags: HEAD, AXL0_6_7
version 0.6.7

    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>
   39: #include <locale.h>
   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: 
  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: 
  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>