Annotation of gpl/axl/py-axl/py_axl.c, revision 1.1.1.1

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>
                     39: 
                     40: #define LOG_DOMAIN "py-axl"
                     41: 
                     42: 
                     43: static PyObject * py_axl_doc_parse (PyObject * self, PyObject * args)
                     44: {
                     45:        const char * document  = NULL;
                     46:        int          size      = -1;
                     47:        PyObject   * doc;
                     48:        axlDoc     * _doc;
                     49:        axlError   * _error     = NULL;
                     50:        PyObject   * result;
                     51:        PyObject   * error;
                     52: 
                     53:        /* parse and check result */
                     54:        if (! PyArg_ParseTuple (args, "s|i", &document, &size))
                     55:                return NULL;
                     56:        
                     57:        /* parse document */
                     58:        _doc   = axl_doc_parse (document, size, &_error);
                     59:        result = PyTuple_New (2);
                     60:        if (_doc == NULL) {
                     61:                /* set none document */
                     62:                Py_INCREF (Py_None);
                     63:                PyTuple_SetItem (result, 0, Py_None);
                     64: 
                     65:                /* create error */
                     66:                error = py_axl_error_create (_error);
                     67:                
                     68:                /* set error */
                     69:                PyTuple_SetItem (result, 1, error);
                     70: 
                     71:                /* return result tuple */
                     72:                return result;
                     73:        } /* end if */
                     74:        
                     75:        /* document parsed ok */
                     76:        doc = py_axl_doc_create (_doc, axl_true);
                     77:        PyTuple_SetItem (result, 0, doc);
                     78:        PyTuple_SetItem (result, 1, Py_None);
                     79:        Py_INCREF (Py_None);
                     80: 
                     81:        return result;
                     82: }
                     83: 
                     84: static PyObject * py_axl_doc_parse_from_file (PyObject * self, PyObject * args)
                     85: {
                     86:        const char * path  = NULL;
                     87:        PyObject   * doc;
                     88:        axlDoc     * _doc;
                     89:        axlError   * _error     = NULL;
                     90:        PyObject   * result;
                     91:        PyObject   * error;
                     92: 
                     93:        /* parse and check result */
                     94:        if (! PyArg_ParseTuple (args, "s", &path))
                     95:                return NULL;
                     96:        
                     97:        /* parse document */
                     98:        _doc   = axl_doc_parse_from_file (path, &_error);
                     99:        result = PyTuple_New (2);
                    100:        if (_doc == NULL) {
                    101:                /* set none document */
                    102:                Py_INCREF (Py_None);
                    103:                PyTuple_SetItem (result, 0, Py_None);
                    104: 
                    105:                /* create error */
                    106:                error = py_axl_error_create (_error);
                    107:                
                    108:                /* set error */
                    109:                PyTuple_SetItem (result, 1, error);
                    110: 
                    111:                /* return result tuple */
                    112:                return result;
                    113:        } /* end if */
                    114:        
                    115:        /* document parsed ok */
                    116:        doc = py_axl_doc_create (_doc, axl_true);
                    117:        PyTuple_SetItem (result, 0, doc);
                    118:        PyTuple_SetItem (result, 1, Py_None);
                    119:        Py_INCREF (Py_None);
                    120: 
                    121:        return result;
                    122: }
                    123: 
                    124: static PyObject * py_axl_dtd_parse_from_file (PyObject * self, PyObject * args)
                    125: {
                    126:        const char * path  = NULL;
                    127:        PyObject   * dtd;
                    128:        axlDtd     * _dtd;
                    129:        axlError   * _error     = NULL;
                    130:        PyObject   * result;
                    131:        PyObject   * error;
                    132: 
                    133:        /* parse and check result */
                    134:        if (! PyArg_ParseTuple (args, "s", &path))
                    135:                return NULL;
                    136:        
                    137:        /* parse document */
                    138:        _dtd   = axl_dtd_parse_from_file (path, &_error);
                    139:        result = PyTuple_New (2);
                    140:        if (_dtd == NULL) {
                    141:                /* set none document */
                    142:                Py_INCREF (Py_None);
                    143:                PyTuple_SetItem (result, 0, Py_None);
                    144: 
                    145:                /* create error */
                    146:                error = py_axl_error_create (_error);
                    147:                
                    148:                /* set error */
                    149:                PyTuple_SetItem (result, 1, error);
                    150: 
                    151:                /* return result tuple */
                    152:                return result;
                    153:        } /* end if */
                    154:        
                    155:        /* document parsed ok */
                    156:        dtd = py_axl_dtd_create (_dtd);
                    157:        PyTuple_SetItem (result, 0, dtd);
                    158:        PyTuple_SetItem (result, 1, Py_None);
                    159:        Py_INCREF (Py_None);
                    160: 
                    161:        return result;
                    162: }
                    163: 
                    164: static PyObject * py_axl_version (PyObject * self)
                    165: {
                    166:        return Py_BuildValue ("s", VERSION);
                    167: }
                    168: 
                    169: static PyMethodDef py_axl_methods[] = { 
                    170:        /* parse */
                    171:        {"parse", (PyCFunction) py_axl_doc_parse, METH_VARARGS,
                    172:         "Parse an string provided returning a new reference to (axl.Doc, axl.Error)"},
                    173:        /* file_parse */
                    174:        {"file_parse", (PyCFunction) py_axl_doc_parse_from_file, METH_VARARGS,
                    175:         "Parse the document found in the file path provided returning a new reference to (axl.Doc, axl.Error)"},
                    176:        /* dtd_file_parse */
                    177:        {"dtd_file_parse", (PyCFunction) py_axl_dtd_parse_from_file, METH_VARARGS,
                    178:         "Parse the DTD document found in the file path provided returning a new reference to (axl.Dtd, axl.Error)"},
                    179:        /* version */
                    180:        {"version", (PyCFunction) py_axl_version, METH_NOARGS,
                    181:         "Returns current py-axl version (with is the same as Axl Library)"},
                    182:        {NULL, NULL, 0, NULL}   /* sentinel */
                    183: }; 
                    184: 
                    185: /** 
                    186:  * @internal Function that inits all axl modules and classes.
                    187:  */ 
                    188: PyMODINIT_FUNC  initlibpy_axl (void)
                    189: {
                    190:        PyObject * module;
                    191: 
                    192:        /* call to initilize threading API and to acquire the lock */
                    193:        PyEval_InitThreads();
                    194: 
                    195:        /* register axl module */
                    196:        module = Py_InitModule3 ("libpy_axl", py_axl_methods, 
                    197:                                 "Base module that implements wrapper functions for base Axl Library");
                    198:        if (module == NULL) 
                    199:                return;
                    200: 
                    201:        /* call to register all axl modules and types */
                    202:        init_axl_doc           (module);
                    203:        init_axl_error         (module);
                    204:        init_axl_node          (module);
                    205:        init_axl_attr_cursor   (module);
                    206:        init_axl_dtd           (module);
                    207:        init_axl_list          (module);
                    208:        init_axl_hash          (module);
                    209:        init_axl_stack         (module);
                    210:        init_axl_stream        (module);
                    211:        return;
                    212: }
                    213: 
                    214: /** 
                    215:  * @internal Handler used to notify exception catched and handled by
                    216:  * py_axl_handle_and_clear_exception.
                    217:  */
                    218: PyAxlExceptionHandler py_axl_exception_handler = NULL;
                    219: 
                    220: /** 
                    221:  * @brief Allows to check, handle and clear exception state.
                    222:  */ 
                    223: void py_axl_handle_and_clear_exception (void)
                    224: {
                    225:        PyObject * ptype      = NULL;
                    226:        PyObject * pvalue     = NULL;
                    227:        PyObject * ptraceback = NULL;
                    228:        PyObject * list;
                    229:        PyObject * string;
                    230:        PyObject * mod;
                    231:        int        iterator;
                    232:        char     * str;
                    233:        char     * str_aux;
                    234: 
                    235: 
                    236:        /* check exception */
                    237:        if (PyErr_Occurred()) {
                    238:                __axl_log (LOG_DOMAIN, AXL_LEVEL_CRITICAL, "found exception...handling..");
                    239: 
                    240:                /* fetch exception state */
                    241:                PyErr_Fetch(&ptype, &pvalue, &ptraceback);
                    242: 
                    243:                /* import traceback module */
                    244:                mod = PyImport_ImportModule("traceback");
                    245:                if (! mod) {
                    246:                        __axl_log (LOG_DOMAIN, AXL_LEVEL_CRITICAL, "failed to import traceback module, printing error to console");
                    247:                        /* print exception */
                    248:                        PyErr_Print ();
                    249:                        goto clean_up;
                    250:                } /* end if */
                    251: 
                    252:                /* list of backtrace items */
                    253:                __axl_log (LOG_DOMAIN, AXL_LEVEL_CRITICAL, "formating exception: ptype:%p  pvalue:%p  ptraceback:%p",
                    254:                               ptype, pvalue, ptraceback);
                    255: 
                    256:                /* check ptraceback */
                    257:                if (ptraceback == NULL) {
                    258:                        ptraceback = Py_None;
                    259:                        Py_INCREF (Py_None);
                    260:                } /* end if */
                    261: 
                    262:                list     = PyObject_CallMethod (mod, "format_exception", "OOO", ptype,  pvalue, ptraceback);
                    263:                iterator = 0;
                    264:                if (py_axl_exception_handler)
                    265:                        str      = axl_strdup ("");
                    266:                else
                    267:                        str      = axl_strdup ("PyAxl found exception inside: \n");
                    268:                while (iterator < PyList_Size (list)) {
                    269:                        /* get the string */
                    270:                        string  = PyList_GetItem (list, iterator);
                    271: 
                    272:                        str_aux = str;
                    273:                        str     = axl_strdup_printf ("%s%s", str_aux, PyString_AsString (string));
                    274:                        axl_free (str_aux);
                    275: 
                    276:                        /* next iterator */
                    277:                        iterator++;
                    278:                }
                    279: 
                    280:                /* drop a log */
                    281:                __axl_log (LOG_DOMAIN, AXL_LEVEL_CRITICAL, str);
                    282:                if (py_axl_exception_handler) {
                    283:                        /* remove trailing \n */
                    284:                        str[strlen (str) - 1] = 0;
                    285:                        py_axl_exception_handler (str);
                    286:                }
                    287:                /* free message */
                    288:                axl_free (str);
                    289: 
                    290:                /* create an empty string \n */
                    291:                Py_XDECREF (list);
                    292:                Py_DECREF (mod);
                    293: 
                    294: 
                    295:        clean_up:
                    296:                /* call to finish retrieved vars .. */
                    297:                Py_XDECREF (ptype);
                    298:                Py_XDECREF (pvalue);
                    299:                Py_XDECREF (ptraceback);
                    300: 
                    301:        } /* end if */
                    302: 
                    303:        /* clear exception */
                    304:        PyErr_Clear ();
                    305:        return;
                    306: }
                    307: 
                    308: /** 
                    309:  * @brief Allows to configure a handler that will receive the
                    310:  * exception message created. 
                    311:  *
                    312:  * @param handler The handler to configure to receive all exception
                    313:  * handling.
                    314:  */
                    315: void     py_axl_set_exception_handler (PyAxlExceptionHandler handler)
                    316: {
                    317:        /* configure the handler */
                    318:        py_axl_exception_handler = handler;
                    319: 
                    320:        return;
                    321: }

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>