rpm 5.3.12
|
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 }