rpm 5.3.7

rpmio/rpmsquirrel.c

Go to the documentation of this file.
00001 #include "system.h"
00002 #include <stdarg.h>
00003 
00004 #include <argv.h>
00005 
00006 #ifdef  WITH_SQUIRREL
00007 #include <squirrel.h>
00008 #endif
00009 #define _RPMSQUIRREL_INTERNAL
00010 #include "rpmsquirrel.h"
00011 
00012 #include "debug.h"
00013 
00014 /*@unchecked@*/
00015 int _rpmsquirrel_debug = 0;
00016 
00017 /*@unchecked@*/ /*@relnull@*/
00018 rpmsquirrel _rpmsquirrelI = NULL;
00019 
00020 static void rpmsquirrelFini(void * _squirrel)
00021         /*@globals fileSystem @*/
00022         /*@modifies *_squirrel, fileSystem @*/
00023 {
00024     rpmsquirrel squirrel = _squirrel;
00025 
00026 #if defined(WITH_SQUIRREL)
00027     sq_close((HSQUIRRELVM)squirrel->I);
00028 #endif
00029     squirrel->I = NULL;
00030     (void)rpmiobFree(squirrel->iob);
00031     squirrel->iob = NULL;
00032 }
00033 
00034 /*@unchecked@*/ /*@only@*/ /*@null@*/
00035 rpmioPool _rpmsquirrelPool;
00036 
00037 static rpmsquirrel rpmsquirrelGetPool(/*@null@*/ rpmioPool pool)
00038         /*@globals _rpmsquirrelPool, fileSystem @*/
00039         /*@modifies pool, _rpmsquirrelPool, fileSystem @*/
00040 {
00041     rpmsquirrel squirrel;
00042 
00043     if (_rpmsquirrelPool == NULL) {
00044         _rpmsquirrelPool = rpmioNewPool("squirrel", sizeof(*squirrel), -1, _rpmsquirrel_debug,
00045                         NULL, NULL, rpmsquirrelFini);
00046         pool = _rpmsquirrelPool;
00047     }
00048     return (rpmsquirrel) rpmioGetPool(pool, sizeof(*squirrel));
00049 }
00050 
00051 #if defined(WITH_SQUIRREL)
00052 static void rpmsquirrelPrint(HSQUIRRELVM v, const SQChar *s, ...)
00053 {
00054     rpmsquirrel squirrel = sq_getforeignptr(v);
00055     size_t nb = 1024;
00056     char * b = xmalloc(nb);
00057     va_list va;
00058 
00059     va_start(va, s);
00060     while(1) {
00061         int nw = vsnprintf(b, nb, s, va);
00062         if (nw > -1 && (size_t)nw < nb)
00063             break;
00064         if (nw > -1)            /* glibc 2.1 (and later) */
00065             nb = nw+1;
00066         else                    /* glibc 2.0 */
00067             nb *= 2;
00068         b = xrealloc(b, nb);
00069     }
00070     va_end(va);
00071 
00072     (void) rpmiobAppend(squirrel->iob, b, 0);
00073     b = _free(b);
00074 }
00075 #endif
00076 
00077 /* XXX FIXME: honor 0x8000000 in flags to use global interpreter */
00078 static rpmsquirrel rpmsquirrelI(void)
00079         /*@globals _rpmsquirrelI @*/
00080         /*@modifies _rpmsquirrelI @*/
00081 {
00082     if (_rpmsquirrelI == NULL)
00083         _rpmsquirrelI = rpmsquirrelNew(NULL, 0);
00084     return _rpmsquirrelI;
00085 }
00086 
00087 rpmsquirrel rpmsquirrelNew(char ** av, uint32_t flags)
00088 {
00089     rpmsquirrel squirrel =
00090 #ifdef  NOTYET
00091         (flags & 0x80000000) ? rpmsquirrelI() :
00092 #endif
00093         rpmsquirrelGetPool(_rpmsquirrelPool);
00094 
00095 #if defined(WITH_SQUIRREL)
00096     static const char * _av[] = { "rpmsquirrel", NULL };
00097     SQInteger stacksize = 1024;
00098     HSQUIRRELVM v = sq_open(stacksize);
00099     int ac;
00100 
00101     if (av == NULL) av = _av;
00102     ac = argvCount(av);
00103 
00104     squirrel->I = v;
00105     sq_setforeignptr(v, squirrel);
00106     sq_setprintfunc(v, rpmsquirrelPrint);
00107 
00108 #ifdef  NOTYET
00109     {   int i;
00110         sq_pushroottable(v);
00111         sc_pushstring(v, "ARGS", -1);
00112         sq_newarray(v, 0);
00113         for (i = 0, i < ac; i++) {
00114             sq_pushstring(v, av[i], -1);
00115             sq_arrayappend(v, -2);
00116         }
00117         sq_createslot(v, -3);
00118         sq_pop(v, 1);
00119     }
00120 #endif
00121 #endif
00122     squirrel->iob = rpmiobNew(0);
00123 
00124     return rpmsquirrelLink(squirrel);
00125 }
00126 
00127 rpmRC rpmsquirrelRunFile(rpmsquirrel squirrel, const char * fn, const char ** resultp)
00128 {
00129     rpmRC rc = RPMRC_FAIL;
00130 
00131 if (_rpmsquirrel_debug)
00132 fprintf(stderr, "==> %s(%p,%s)\n", __FUNCTION__, squirrel, fn);
00133 
00134     if (squirrel == NULL) squirrel = rpmsquirrelI();
00135 
00136 #if defined(NOTYET)
00137     if (fn != NULL && Tcl_EvalFile((Tcl_Interp *)squirrel->I, fn) == SQUIRREL_OK) {
00138         rc = RPMRC_OK;
00139         if (resultp)
00140             *resultp = rpmiobStr(squirrel->iob);
00141     }
00142 #endif
00143     return rc;
00144 }
00145 
00146 rpmRC rpmsquirrelRun(rpmsquirrel squirrel, const char * str, const char ** resultp)
00147 {
00148     rpmRC rc = RPMRC_FAIL;
00149 
00150 if (_rpmsquirrel_debug)
00151 fprintf(stderr, "==> %s(%p,%s)\n", __FUNCTION__, squirrel, str);
00152 
00153     if (squirrel == NULL) squirrel = rpmsquirrelI();
00154 
00155 #if defined(WITH_SQUIRREL)
00156     if (str != NULL) {
00157         size_t ns = strlen(str);
00158         if (ns > 0) {
00159             HSQUIRRELVM v = squirrel->I;
00160             SQBool raise = SQFalse;
00161             SQInteger oldtop = sq_gettop(v);
00162             SQRESULT res = sq_compilebuffer(v, str, ns, __FUNCTION__, raise);
00163 
00164             if (SQ_SUCCEEDED(res)) {
00165                 SQInteger retval = 0;
00166                 sq_pushroottable(v);
00167                 res = sq_call(v, 1, retval, raise);
00168             }
00169 
00170             sq_settop(v, oldtop);
00171         }
00172         rc = RPMRC_OK;
00173         if (resultp)
00174             *resultp = rpmiobStr(squirrel->iob);
00175     }
00176 #endif
00177     return rc;
00178 }