/* * $Id$ * * ***** BEGIN GPL LICENSE BLOCK ***** * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * * ***** END GPL LICENSE BLOCK ***** */ #include #include #include "py_capi_utils.h" /* for debugging */ void PyC_ObSpit(const char *name, PyObject *var) { fprintf(stderr, "<%s> : ", name); if (var==NULL) { fprintf(stderr, ""); } else { PyObject_Print(var, stderr, 0); fprintf(stderr, " ref:%d ", (int)var->ob_refcnt); fprintf(stderr, " ptr:%p", (void *)var); fprintf(stderr, " type:"); if(Py_TYPE(var)) fprintf(stderr, "%s", Py_TYPE(var)->tp_name); else fprintf(stderr, ""); } fprintf(stderr, "\n"); } void PyC_LineSpit(void) { const char *filename; int lineno; PyErr_Clear(); PyC_FileAndNum(&filename, &lineno); fprintf(stderr, "%s:%d\n", filename, lineno); } /* python 3.2 only, copied from frameobjec.c */ #if PY_VERSION_HEX < 0x03020000 int PyFrame_GetLineNumber(PyFrameObject *f) { if (f->f_trace) return f->f_lineno; else return PyCode_Addr2Line(f->f_code, f->f_lasti); } #endif void PyC_FileAndNum(const char **filename, int *lineno) { PyFrameObject *frame; if (filename) *filename= NULL; if (lineno) *lineno = -1; if (!(frame= PyThreadState_GET()->frame)) { return; } /* when executing a script */ if (filename) { *filename = _PyUnicode_AsString(frame->f_code->co_filename); } /* when executing a module */ if(filename && *filename == NULL) { /* try an alternative method to get the filename - module based * references below are all borrowed (double checked) */ PyObject *mod_name= PyDict_GetItemString(PyEval_GetGlobals(), "__name__"); if(mod_name) { PyObject *mod= PyDict_GetItem(PyImport_GetModuleDict(), mod_name); if(mod) { *filename= PyModule_GetFilename(mod); } /* unlikely, fallback */ if(*filename == NULL) { *filename= _PyUnicode_AsString(mod_name); } } } if (lineno) { *lineno = PyFrame_GetLineNumber(frame); } } /* Would be nice if python had this built in */ PyObject *PyC_Object_GetAttrStringArgs(PyObject *o, Py_ssize_t n, ...) { Py_ssize_t i; PyObject *item= o; char *attr; va_list vargs; va_start(vargs, n); for (i=0; i> foo = 10 >> print(__import__("__main__").foo) * * note: this overwrites __main__ which gives problems with nested calles. * be sure to run PyC_MainModule_Backup & PyC_MainModule_Restore if there is * any chance that python is in the call stack. *****************************************************************************/ PyObject *PyC_DefaultNameSpace(const char *filename) { PyInterpreterState *interp= PyThreadState_GET()->interp; PyObject *mod_main= PyModule_New("__main__"); PyDict_SetItemString(interp->modules, "__main__", mod_main); Py_DECREF(mod_main); /* sys.modules owns now */ PyModule_AddStringConstant(mod_main, "__name__", "__main__"); if(filename) PyModule_AddStringConstant(mod_main, "__file__", filename); /* __file__ only for nice UI'ness */ PyModule_AddObject(mod_main, "__builtins__", interp->builtins); Py_INCREF(interp->builtins); /* AddObject steals a reference */ return PyModule_GetDict(mod_main); } /* restore MUST be called after this */ void PyC_MainModule_Backup(PyObject **main_mod) { PyInterpreterState *interp= PyThreadState_GET()->interp; *main_mod= PyDict_GetItemString(interp->modules, "__main__"); Py_XINCREF(*main_mod); /* dont free */ } void PyC_MainModule_Restore(PyObject *main_mod) { PyInterpreterState *interp= PyThreadState_GET()->interp; PyDict_SetItemString(interp->modules, "__main__", main_mod); Py_XDECREF(main_mod); } /* Would be nice if python had this built in */ void PyC_RunQuicky(const char *filepath, int n, ...) { FILE *fp= fopen(filepath, "r"); if(fp) { PyGILState_STATE gilstate= PyGILState_Ensure(); va_list vargs; int *sizes= PyMem_MALLOC(sizeof(int) * (n / 2)); int i; PyObject *py_dict = PyC_DefaultNameSpace(filepath); PyObject *values= PyList_New(n / 2); /* namespace owns this, dont free */ PyObject *py_result, *ret; PyObject *struct_mod= PyImport_ImportModule("struct"); PyObject *calcsize= PyObject_GetAttrString(struct_mod, "calcsize"); /* struct.calcsize */ PyObject *pack= PyObject_GetAttrString(struct_mod, "pack"); /* struct.pack */ PyObject *unpack= PyObject_GetAttrString(struct_mod, "unpack"); /* struct.unpack */ Py_DECREF(struct_mod); va_start(vargs, n); for (i=0; i * 2