"Fossies" - the Fresh Open Source Software Archive

Member "cheetah3-3.2.6.post2/Cheetah/c/_namemapper.c" (20 Apr 2021, 14522 Bytes) of package /linux/www/cheetah3-3.2.6.post2.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "_namemapper.c" see the Fossies "Dox" file reference documentation and the last Fossies "Diffs" side-by-side code changes report: 3-3.2.5_vs_3-3.2.6.

    1 /* ***************************************************************************
    2 This is the C language version of NameMapper.py.  See the comments and
    3 DocStrings in NameMapper for details on the purpose and interface of this
    4 module.
    5 
    6 ===============================================================================
    7 Authors: Tavis Rudd <tavis@damnsimple.com>
    8 Version: 1.34
    9 Start Date: 2001/08/07
   10 Last Revision Date: 2007/12/10 18:25:20
   11 */
   12 
   13 /* *************************************************************************** */
   14 #include <Python.h>
   15 #include <string.h>
   16 #include <stdlib.h>
   17 
   18 #include "_namemapper.h"
   19 
   20 #ifdef __cplusplus
   21 extern "C" {
   22 #endif
   23 
   24 
   25 static PyObject *NotFound;   /* locally-raised exception */
   26 static PyObject *TooManyPeriods;   /* locally-raised exception */
   27 static PyObject* pprintMod_pformat; /* used for exception formatting */
   28 
   29 
   30 /* *************************************************************************** */
   31 /* First the c versions of the functions */
   32 /* *************************************************************************** */
   33 
   34 static void setNotFoundException(char *key, PyObject *namespace)
   35 {
   36     PyObject *exceptionStr = NULL;
   37     exceptionStr = PyUnicode_FromFormat("cannot find \'%s\'", key);
   38     PyErr_SetObject(NotFound, exceptionStr);
   39     Py_XDECREF(exceptionStr);
   40 }
   41 
   42 static int wrapInternalNotFoundException(char *fullName, PyObject *namespace)
   43 {
   44     PyObject *excType, *excValue, *excTraceback, *isAlreadyWrapped = NULL;
   45     PyObject *newExcValue = NULL;
   46     if (!ALLOW_WRAPPING_OF_NOTFOUND_EXCEPTIONS) {
   47         return 0;
   48     }
   49 
   50     if (!PyErr_Occurred()) {
   51         return 0;
   52     }
   53 
   54     if (PyErr_GivenExceptionMatches(PyErr_Occurred(), NotFound)) {
   55         PyErr_Fetch(&excType, &excValue, &excTraceback);
   56         isAlreadyWrapped = PyObject_CallMethod(excValue, "find", "s", "while searching");
   57 
   58         if (isAlreadyWrapped != NULL) {
   59             if (PyLong_AsLong(isAlreadyWrapped) == -1) {
   60                 newExcValue = PyUnicode_FromFormat("%U while searching for \'%s\'",
   61                         excValue, fullName);
   62             }
   63             Py_DECREF(isAlreadyWrapped);
   64         }
   65         else {
   66            newExcValue = excValue;
   67         }
   68         PyErr_Restore(excType, newExcValue, excTraceback);
   69         return -1;
   70     }
   71     return 0;
   72 }
   73 
   74 
   75 static int isInstanceOrClass(PyObject *nextVal) {
   76 #ifndef IS_PYTHON3
   77     /* old style classes or instances */
   78     if((PyInstance_Check(nextVal)) || (PyClass_Check(nextVal))) {
   79         return 1;
   80     }
   81 #endif
   82 
   83     if (!PyObject_HasAttrString(nextVal, "__class__")) {
   84         return 0;
   85     }
   86 
   87     /* new style classes or instances */
   88     if (PyType_Check(nextVal) || PyObject_HasAttrString(nextVal, "mro")) {
   89         return 1;
   90     }
   91 
   92     if (strncmp(nextVal->ob_type->tp_name, "function", 9) == 0)
   93         return 0;
   94 
   95     /* method, func, or builtin func */
   96     if (PyObject_HasAttrString(nextVal, "__func__")
   97         || PyObject_HasAttrString(nextVal, "__code__")
   98         || PyObject_HasAttrString(nextVal, "__self__")) {
   99         return 0;
  100     }
  101 
  102     /* instance */
  103     if ((!PyObject_HasAttrString(nextVal, "mro")) &&
  104             PyObject_HasAttrString(nextVal, "__init__")) {
  105         return 1;
  106     }
  107 
  108     return 0;
  109 }
  110 
  111 
  112 static int getNameChunks(char *nameChunks[], char *name, char *nameCopy)
  113 {
  114     char c;
  115     char *currChunk;
  116     int currChunkNum = 0;
  117 
  118     currChunk = nameCopy;
  119     while ('\0' != (c = *nameCopy)){
  120         if ('.' == c) {
  121             if (currChunkNum >= (MAXCHUNKS-2)) { /* avoid overflowing nameChunks[] */
  122                 PyErr_SetString(TooManyPeriods, name);
  123                 return 0;
  124             }
  125 
  126             *nameCopy ='\0';
  127             nameChunks[currChunkNum++] = currChunk;
  128             nameCopy++;
  129             currChunk = nameCopy;
  130         } else
  131             nameCopy++;
  132     }
  133     if (nameCopy > currChunk) {
  134         nameChunks[currChunkNum++] = currChunk;
  135     }
  136     return currChunkNum;
  137 }
  138 
  139 
  140 static int PyNamemapper_hasKey(PyObject *obj, char *key)
  141 {
  142     if (PyMapping_Check(obj) && PyMapping_HasKeyString(obj, key)) {
  143         return TRUE;
  144     } else if (PyObject_HasAttrString(obj, key)) {
  145         return TRUE;
  146     }
  147     return FALSE;
  148 }
  149 
  150 
  151 static PyObject *PyNamemapper_valueForKey(PyObject *obj, char *key)
  152 {
  153     PyObject *theValue = NULL;
  154 
  155     if (PyMapping_Check(obj) && PyMapping_HasKeyString(obj, key)) {
  156         theValue = PyMapping_GetItemString(obj, key);
  157     } else if (PyObject_HasAttrString(obj, key)) {
  158         theValue = PyObject_GetAttrString(obj, key);
  159     } else {
  160         setNotFoundException(key, obj);
  161     }
  162     return theValue;
  163 }
  164 
  165 static PyObject *PyNamemapper_valueForName(PyObject *obj, char *nameChunks[], int numChunks, int executeCallables)
  166 {
  167     int i;
  168     char *currentKey;
  169     PyObject *currentVal = NULL;
  170     PyObject *nextVal = NULL;
  171 
  172     currentVal = obj;
  173     for (i=0; i < numChunks;i++) {
  174         currentKey = nameChunks[i];
  175         if (PyErr_CheckSignals()) {     /* not sure if I really need to do this here, but what the hell */
  176             if (i>0) {
  177                 Py_DECREF(currentVal);
  178             }
  179             return NULL;
  180         }
  181 
  182         if (PyMapping_Check(currentVal) && PyMapping_HasKeyString(currentVal, currentKey)) {
  183             nextVal = PyMapping_GetItemString(currentVal, currentKey);
  184         }
  185 
  186         else {
  187             PyObject *exc;
  188             nextVal = PyObject_GetAttrString(currentVal, currentKey);
  189             exc = PyErr_Occurred();
  190 
  191             if (exc != NULL) {
  192                 // if exception == AttributeError, report our own exception
  193                 if (PyErr_ExceptionMatches(PyExc_AttributeError)) {
  194                     setNotFoundException(currentKey, currentVal);
  195                 }
  196                 // any exceptions results in failure
  197                 if (i > 0) {
  198                     Py_DECREF(currentVal);
  199                 }
  200                 return NULL;
  201             }
  202 
  203             if (nextVal == NULL) {
  204                 setNotFoundException(currentKey, currentVal);
  205                 // any exceptions results in failure
  206                 if (i > 0) {
  207                     Py_DECREF(currentVal);
  208                 }
  209                 return NULL;
  210             }
  211         }
  212         if (i > 0) {
  213             Py_DECREF(currentVal);
  214         }
  215 
  216         if (executeCallables && PyCallable_Check(nextVal) &&
  217                 (isInstanceOrClass(nextVal) == 0) ) {
  218             if (!(currentVal = PyObject_CallObject(nextVal, NULL))) {
  219                 Py_DECREF(nextVal);
  220                 return NULL;
  221             }
  222             Py_DECREF(nextVal);
  223         } else {
  224             currentVal = nextVal;
  225         }
  226     }
  227 
  228     return currentVal;
  229 }
  230 
  231 
  232 /* *************************************************************************** */
  233 /* Now the wrapper functions to export into the Python module */
  234 /* *************************************************************************** */
  235 
  236 
  237 static PyObject *namemapper_valueForKey(PyObject *self, PyObject *args)
  238 {
  239     PyObject *obj;
  240     char *key;
  241 
  242     if (!PyArg_ParseTuple(args, "Os", &obj, &key)) {
  243         return NULL;
  244     }
  245 
  246     return PyNamemapper_valueForKey(obj, key);
  247 }
  248 
  249 static PyObject *namemapper_valueForName(PYARGS)
  250 {
  251     PyObject *obj;
  252     char *name;
  253     int executeCallables = 0;
  254 
  255     char *nameCopy = NULL;
  256     char *tmpPntr1 = NULL;
  257     char *tmpPntr2 = NULL;
  258     char *nameChunks[MAXCHUNKS];
  259     int numChunks;
  260 
  261     PyObject *theValue;
  262 
  263     static char *kwlist[] = {"obj", "name", "executeCallables", NULL};
  264 
  265     if (!PyArg_ParseTupleAndKeywords(args, kwargs, "Os|i", kwlist,  &obj, &name, &executeCallables)) {
  266         return NULL;
  267     }
  268 
  269     createNameCopyAndChunks();
  270 
  271     if (numChunks <= 0) {
  272         PyErr_SetString(PyExc_ValueError, "Invalid lookup of empty name");
  273         theValue = NULL;
  274     } else {
  275         theValue = PyNamemapper_valueForName(obj, nameChunks, numChunks, executeCallables);
  276         if (wrapInternalNotFoundException(name, obj)) {
  277             theValue = NULL;
  278         }
  279     }
  280     free(nameCopy);
  281     return theValue;
  282 }
  283 
  284 static PyObject *namemapper_valueFromSearchList(PYARGS)
  285 {
  286     PyObject *searchList;
  287     char *name;
  288     int executeCallables = 0;
  289 
  290     char *nameCopy = NULL;
  291     char *tmpPntr1 = NULL;
  292     char *tmpPntr2 = NULL;
  293     char *nameChunks[MAXCHUNKS];
  294     int numChunks;
  295 
  296     PyObject *nameSpace = NULL;
  297     PyObject *theValue = NULL;
  298     PyObject *iterator = NULL;
  299 
  300     static char *kwlist[] = {"searchList", "name", "executeCallables", NULL};
  301 
  302     if (!PyArg_ParseTupleAndKeywords(args, kwargs, "Os|i", kwlist, &searchList, &name, &executeCallables)) {
  303         return NULL;
  304     }
  305 
  306     createNameCopyAndChunks();
  307 
  308     if (numChunks <= 0) {
  309         PyErr_SetString(PyExc_ValueError, "Invalid lookup of empty name");
  310         goto done;
  311     }
  312 
  313     iterator = PyObject_GetIter(searchList);
  314     if (iterator == NULL) {
  315         PyErr_SetString(PyExc_TypeError,"This searchList is not iterable!");
  316         goto done;
  317     }
  318 
  319     while ((nameSpace = PyIter_Next(iterator))) {
  320         checkForNameInNameSpaceAndReturnIfFound(TRUE);
  321         Py_DECREF(nameSpace);
  322         if(PyErr_CheckSignals()) {
  323         theValue = NULL;
  324         goto done;
  325         }
  326     }
  327     if (PyErr_Occurred()) {
  328         theValue = NULL;
  329         goto done;
  330     }
  331 
  332     setNotFoundException(nameChunks[0], searchList);
  333 
  334 done:
  335     Py_XDECREF(iterator);
  336     free(nameCopy);
  337     return theValue;
  338 }
  339 
  340 static PyObject *namemapper_valueFromFrameOrSearchList(PyObject *self, PyObject *args, PyObject *keywds)
  341 {
  342     /* python function args */
  343     char *name;
  344     int executeCallables = 0;
  345     PyObject *searchList = NULL;
  346 
  347     /* locals */
  348     char *nameCopy = NULL;
  349     char *tmpPntr1 = NULL;
  350     char *tmpPntr2 = NULL;
  351     char *nameChunks[MAXCHUNKS];
  352     int numChunks;
  353 
  354     PyObject *nameSpace = NULL;
  355     PyObject *theValue = NULL;
  356     PyObject *excString = NULL;
  357     PyObject *iterator = NULL;
  358 
  359     static char *kwlist[] = {"searchList", "name", "executeCallables", NULL};
  360 
  361     if (!PyArg_ParseTupleAndKeywords(args, keywds, "Os|i", kwlist,  &searchList, &name,
  362                     &executeCallables)) {
  363         return NULL;
  364     }
  365 
  366     createNameCopyAndChunks();
  367 
  368     if (numChunks <= 0) {
  369         PyErr_SetString(PyExc_ValueError, "Invalid lookup of empty name");
  370         goto done;
  371     }
  372 
  373     nameSpace = PyEval_GetLocals();
  374     checkForNameInNameSpaceAndReturnIfFound(FALSE);
  375 
  376     iterator = PyObject_GetIter(searchList);
  377     if (iterator == NULL) {
  378         PyErr_SetString(PyExc_TypeError,"This searchList is not iterable!");
  379         goto done;
  380     }
  381     while ( (nameSpace = PyIter_Next(iterator)) ) {
  382         checkForNameInNameSpaceAndReturnIfFound(TRUE);
  383         Py_DECREF(nameSpace);
  384         if(PyErr_CheckSignals()) {
  385             theValue = NULL;
  386             goto done;
  387         }
  388     }
  389     if (PyErr_Occurred()) {
  390         theValue = NULL;
  391         goto done;
  392     }
  393 
  394     nameSpace = PyEval_GetGlobals();
  395     checkForNameInNameSpaceAndReturnIfFound(FALSE);
  396 
  397     nameSpace = PyEval_GetBuiltins();
  398     checkForNameInNameSpaceAndReturnIfFound(FALSE);
  399 
  400     excString = Py_BuildValue("s", "[locals()]+searchList+[globals(), __builtins__]");
  401     setNotFoundException(nameChunks[0], excString);
  402     Py_DECREF(excString);
  403 
  404 done:
  405     Py_XDECREF(iterator);
  406     free(nameCopy);
  407     return theValue;
  408 }
  409 
  410 static PyObject *namemapper_valueFromFrame(PyObject *self, PyObject *args, PyObject *keywds)
  411 {
  412     /* python function args */
  413     char *name;
  414     int executeCallables = 0;
  415 
  416     /* locals */
  417     char *tmpPntr1 = NULL;
  418     char *tmpPntr2 = NULL;
  419 
  420     char *nameCopy = NULL;
  421     char *nameChunks[MAXCHUNKS];
  422     int numChunks;
  423 
  424     PyObject *nameSpace = NULL;
  425     PyObject *theValue = NULL;
  426     PyObject *excString = NULL;
  427 
  428     static char *kwlist[] = {"name", "executeCallables", NULL};
  429 
  430     if (!PyArg_ParseTupleAndKeywords(args, keywds, "s|i", kwlist, &name, &executeCallables)) {
  431         return NULL;
  432     }
  433 
  434     createNameCopyAndChunks();
  435 
  436     if (numChunks <= 0) {
  437         PyErr_SetString(PyExc_ValueError, "Invalid lookup of empty name");
  438         goto done;
  439     }
  440 
  441     nameSpace = PyEval_GetLocals();
  442     checkForNameInNameSpaceAndReturnIfFound(FALSE);
  443 
  444     nameSpace = PyEval_GetGlobals();
  445     checkForNameInNameSpaceAndReturnIfFound(FALSE);
  446 
  447     nameSpace = PyEval_GetBuiltins();
  448     checkForNameInNameSpaceAndReturnIfFound(FALSE);
  449 
  450     excString = Py_BuildValue("s", "[locals(), globals(), __builtins__]");
  451     setNotFoundException(nameChunks[0], excString);
  452     Py_DECREF(excString);
  453 done:
  454     free(nameCopy);
  455     return theValue;
  456 }
  457 
  458 /* *************************************************************************** */
  459 /* Method registration table: name-string -> function-pointer */
  460 
  461 static struct PyMethodDef namemapper_methods[] = {
  462   {"valueForKey", namemapper_valueForKey,  1},
  463   {"valueForName", (PyCFunction)namemapper_valueForName,  METH_VARARGS|METH_KEYWORDS},
  464   {"valueFromSearchList", (PyCFunction)namemapper_valueFromSearchList,  METH_VARARGS|METH_KEYWORDS},
  465   {"valueFromFrame", (PyCFunction)namemapper_valueFromFrame,  METH_VARARGS|METH_KEYWORDS},
  466   {"valueFromFrameOrSearchList", (PyCFunction)namemapper_valueFromFrameOrSearchList,  METH_VARARGS|METH_KEYWORDS},
  467   {NULL,         NULL}
  468 };
  469 
  470 
  471 /* *************************************************************************** */
  472 /* Initialization function (import-time) */
  473 
  474 #ifdef IS_PYTHON3
  475 static struct PyModuleDef namemappermodule = {
  476     PyModuleDef_HEAD_INIT,
  477     "_namemapper",
  478     NULL, /* docstring */
  479     -1,
  480     namemapper_methods,
  481     NULL,
  482     NULL,
  483     NULL,
  484     NULL};
  485 
  486 PyMODINIT_FUNC PyInit__namemapper(void)
  487 {
  488     PyObject *m = PyModule_Create(&namemappermodule);
  489 #else
  490 DL_EXPORT(void) init_namemapper(void)
  491 {
  492     PyObject *m = Py_InitModule3("_namemapper", namemapper_methods, NULL);
  493 #endif
  494 
  495     PyObject *d, *pprintMod;
  496 
  497     /* add symbolic constants to the module */
  498     d = PyModule_GetDict(m);
  499     NotFound = PyErr_NewException("NameMapper.NotFound",PyExc_LookupError,NULL);
  500     TooManyPeriods = PyErr_NewException("NameMapper.TooManyPeriodsInName",NULL,NULL);
  501     PyDict_SetItemString(d, "NotFound", NotFound);
  502     PyDict_SetItemString(d, "TooManyPeriodsInName", TooManyPeriods);
  503     pprintMod = PyImport_ImportModule("pprint");
  504     if (!pprintMod) {
  505 #ifdef IS_PYTHON3
  506         return NULL;
  507 #else
  508         return;
  509 #endif
  510     }
  511     pprintMod_pformat = PyObject_GetAttrString(pprintMod, "pformat");
  512     Py_DECREF(pprintMod);
  513     /* check for errors */
  514     if (PyErr_Occurred()) {
  515         Py_FatalError("Can't initialize module _namemapper");
  516     }
  517 #ifdef IS_PYTHON3
  518     return m;
  519 #endif
  520 }
  521 
  522 #ifdef __cplusplus
  523 }
  524 #endif