rpm 5.3.12
rpmio/rpmpython.c
Go to the documentation of this file.
00001 #include "system.h"
00002 
00003 #define _RPMIOB_INTERNAL        /* XXX necessary? */
00004 #include <rpmiotypes.h>
00005 #include <argv.h>
00006 
00007 #define _RPMPYTHON_INTERNAL
00008 #include "rpmpython.h"
00009 
00010 #if defined(WITH_PYTHONEMBED)
00011 #include <Python.h>
00012 #include <cStringIO.h>
00013 #endif
00014 
00015 #include "debug.h"
00016 
00017 /*@unchecked@*/
00018 int _rpmpython_debug = 0;
00019 
00020 /*@unchecked@*/ /*@relnull@*/
00021 rpmpython _rpmpythonI = NULL;
00022 
00023 static void rpmpythonFini(void * _python)
00024         /*@globals fileSystem @*/
00025         /*@modifies *_python, fileSystem @*/
00026 {
00027     rpmpython python = _python;
00028 
00029 #if defined(WITH_PYTHONEMBED)
00030     Py_Finalize();
00031 #endif
00032     python->I = NULL;
00033 }
00034 
00035 /*@unchecked@*/ /*@only@*/ /*@null@*/
00036 rpmioPool _rpmpythonPool;
00037 
00038 static rpmpython rpmpythonGetPool(/*@null@*/ rpmioPool pool)
00039         /*@globals _rpmpythonPool, fileSystem @*/
00040         /*@modifies pool, _rpmpythonPool, fileSystem @*/
00041 {
00042     rpmpython python;
00043 
00044     if (_rpmpythonPool == NULL) {
00045         _rpmpythonPool = rpmioNewPool("python", sizeof(*python), -1, _rpmpython_debug,
00046                         NULL, NULL, rpmpythonFini);
00047         pool = _rpmpythonPool;
00048     }
00049     return (rpmpython) rpmioGetPool(pool, sizeof(*python));
00050 }
00051 
00052 /*@unchecked@*/
00053 #if defined(WITH_PYTHONEMBED)
00054 static const char * rpmpythonInitStringIO = "\
00055 import sys\n\
00056 from cStringIO import StringIO\n\
00057 sys.stdout = StringIO()\n\
00058 import rpm\n\
00059 ";
00060 #endif
00061 
00062 static rpmpython rpmpythonI(void)
00063         /*@globals _rpmpythonI @*/
00064         /*@modifies _rpmpythonI @*/
00065 {
00066     if (_rpmpythonI == NULL)
00067         _rpmpythonI = rpmpythonNew(NULL, 0);
00068     return _rpmpythonI;
00069 }
00070 
00071 rpmpython rpmpythonNew(char ** av, uint32_t flags)
00072 {
00073     static char * _av[] = { "rpmpython", NULL };
00074 #if defined(WITH_PYTHONEMBED)
00075     int initialize = (!(flags & 0x80000000) || _rpmpythonI == NULL);
00076 #endif
00077     rpmpython python = (flags & 0x80000000)
00078         ? rpmpythonI() : rpmpythonGetPool(_rpmpythonPool);
00079 
00080 if (_rpmpython_debug)
00081 fprintf(stderr, "==> %s(%p, %d) python %p\n", __FUNCTION__, av, flags, python);
00082 
00083     if (av == NULL) av = _av;
00084 
00085 #if defined(WITH_PYTHONEMBED)
00086     if (!Py_IsInitialized()) {
00087         Py_SetProgramName((char *)_av[0]);
00088         Py_Initialize();
00089     }
00090     if (PycStringIO == NULL)
00091         PycStringIO = PyCObject_Import("cStringIO", "cStringIO_CAPI");
00092 
00093     if (initialize) {
00094         int ac = argvCount((ARGV_t)av);
00095         (void) PySys_SetArgv(ac, (char **)av);
00096         (void) rpmpythonRun(python, rpmpythonInitStringIO, NULL);
00097     }
00098 #endif
00099 
00100     return rpmpythonLink(python);
00101 }
00102 
00103 rpmRC rpmpythonRunFile(rpmpython python, const char * fn, const char ** resultp)
00104 {
00105     rpmRC rc = RPMRC_FAIL;
00106 
00107 
00108 if (_rpmpython_debug)
00109 fprintf(stderr, "==> %s(%p,%s)\n", __FUNCTION__, python, fn);
00110 
00111     if (python == NULL) python = rpmpythonI();
00112 
00113     if (fn != NULL) {
00114 #if defined(WITH_PYTHONEMBED)
00115         const char * pyfn = ((fn == NULL || !strcmp(fn, "-")) ? "<stdin>" : fn);
00116         FILE * pyfp = (!strcmp(pyfn, "<stdin>") ? stdin : fopen(fn, "rb"));
00117         int closeit = (pyfp != stdin);
00118         PyCompilerFlags cf = { .cf_flags = 0 };
00119         
00120         if (pyfp != NULL) {
00121             PyRun_AnyFileExFlags(pyfp, pyfn, closeit, &cf);
00122             rc = RPMRC_OK;
00123         }
00124 #endif
00125     }
00126     return rc;
00127 }
00128 
00129 static const char * rpmpythonSlurp(const char * arg)
00130         /*@*/
00131 {
00132     rpmiob iob = NULL;
00133     const char * val = NULL;
00134     struct stat sb;
00135     int xx;
00136 
00137     if (!strcmp(arg, "-")) {    /* Macros from stdin arg. */
00138         xx = rpmiobSlurp(arg, &iob);
00139     } else
00140     if ((arg[0] == '/' || strchr(arg, ' ') == NULL)
00141      && !Stat(arg, &sb)
00142      && S_ISREG(sb.st_mode)) {  /* Macros from a file arg. */
00143         xx = rpmiobSlurp(arg, &iob);
00144     } else {                    /* Macros from string arg. */
00145         iob = rpmiobAppend(rpmiobNew(strlen(arg)+1), arg, 0);
00146     }
00147 
00148     val = xstrdup(rpmiobStr(iob));
00149     iob = rpmiobFree(iob);
00150     return val;
00151 }
00152 
00153 rpmRC rpmpythonRun(rpmpython python, const char * str, const char ** resultp)
00154 {
00155     rpmRC rc = RPMRC_FAIL;
00156 
00157 if (_rpmpython_debug)
00158 fprintf(stderr, "==> %s(%p,%s,%p)\n", __FUNCTION__, python, str, resultp);
00159 
00160     if (python == NULL) python = rpmpythonI();
00161 
00162     if (str != NULL) {
00163         const char * val = rpmpythonSlurp(str);
00164 #if defined(WITH_PYTHONEMBED)
00165         PyCompilerFlags cf = { .cf_flags = 0 };
00166         PyObject * m = PyImport_AddModule("__main__");
00167         PyObject * d = (m ? PyModule_GetDict(m) : NULL);
00168         PyObject * v = (m ? PyRun_StringFlags(val, Py_file_input, d, d, &cf) : NULL);
00169 
00170         if (v == NULL) {
00171             PyErr_Print();
00172         } else {
00173             if (resultp != NULL) {
00174                 PyObject * sys_stdout = PySys_GetObject("stdout");
00175                 if (sys_stdout != NULL && PycStringIO_OutputCheck(sys_stdout)) {
00176                     PyObject * o = (*PycStringIO->cgetvalue)(sys_stdout);
00177                     *resultp = (PyString_Check(o) ? PyString_AsString(o) : "");
00178                 } else
00179                     *resultp = "";
00180             }
00181             Py_DECREF(v);
00182             if (Py_FlushLine())
00183                 PyErr_Clear();
00184             rc = RPMRC_OK;
00185         }
00186 #endif
00187         val = _free(val);
00188     }
00189     return rc;
00190 }