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>