rpm  5.4.15
rpmsquirrel.c
Go to the documentation of this file.
1 #include "system.h"
2 #include <stdarg.h>
3 
4 #define _RPMIOB_INTERNAL /* XXX necessary? */
5 #include <rpmiotypes.h>
6 #include <argv.h>
7 
8 #ifdef WITH_SQUIRREL
9 #include <squirrel.h>
10 #include <sqstdaux.h>
11 #include <sqstdblob.h>
12 #include <sqstdio.h>
13 #include <sqstdmath.h>
14 #include <sqstdstring.h>
15 #include <sqstdsystem.h>
16 #endif
17 
18 #define _RPMSQUIRREL_INTERNAL
19 #include "rpmsquirrel.h"
20 
21 #include "debug.h"
22 
23 /*@unchecked@*/
25 
26 /*@unchecked@*/ /*@relnull@*/
28 
29 static void rpmsquirrelFini(void * _squirrel)
30  /*@globals fileSystem @*/
31  /*@modifies *_squirrel, fileSystem @*/
32 {
33  rpmsquirrel squirrel = (rpmsquirrel) _squirrel;
34 
35 #if defined(WITH_SQUIRREL)
36  sq_close((HSQUIRRELVM)squirrel->I);
37 #endif
38  squirrel->I = NULL;
39  (void)rpmiobFree(squirrel->iob);
40  squirrel->iob = NULL;
41 }
42 
43 /*@unchecked@*/ /*@only@*/ /*@null@*/
45 
47  /*@globals _rpmsquirrelPool, fileSystem @*/
48  /*@modifies pool, _rpmsquirrelPool, fileSystem @*/
49 {
50  rpmsquirrel squirrel;
51 
52  if (_rpmsquirrelPool == NULL) {
53  _rpmsquirrelPool = rpmioNewPool("squirrel", sizeof(*squirrel), -1, _rpmsquirrel_debug,
54  NULL, NULL, rpmsquirrelFini);
55  pool = _rpmsquirrelPool;
56  }
57  return (rpmsquirrel) rpmioGetPool(pool, sizeof(*squirrel));
58 }
59 
60 #if defined(WITH_SQUIRREL)
61 static void rpmsquirrelPrint(HSQUIRRELVM v, const SQChar *s, ...)
62 {
63  rpmsquirrel squirrel = sq_getforeignptr(v);
64  size_t nb = 1024;
65  char * b = xmalloc(nb);
66  va_list va;
67 
68  va_start(va, s);
69  while(1) {
70  int nw = vsnprintf(b, nb, s, va);
71  if (nw > -1 && (size_t)nw < nb)
72  break;
73  if (nw > -1) /* glibc 2.1 (and later) */
74  nb = nw+1;
75  else /* glibc 2.0 */
76  nb *= 2;
77  b = xrealloc(b, nb);
78  }
79  va_end(va);
80 
81  (void) rpmiobAppend(squirrel->iob, b, 0);
82  b = _free(b);
83 }
84 
85 #if defined(SQUIRREL_VERSION_NUMBER) && SQUIRREL_VERSION_NUMBER >= 300
86 static void rpmsquirrelStderr(HSQUIRRELVM v, const SQChar *s,...)
87 {
88  va_list vl;
89  va_start(vl, s);
90  vfprintf(stderr, s, vl);
91  va_end(vl);
92 }
93 #endif
94 #endif
95 
96 /* XXX FIXME: honor 0x8000000 in flags to use global interpreter */
98  /*@globals _rpmsquirrelI @*/
99  /*@modifies _rpmsquirrelI @*/
100 {
101  if (_rpmsquirrelI == NULL)
102  _rpmsquirrelI = rpmsquirrelNew(NULL, 0);
103  return _rpmsquirrelI;
104 }
105 
106 rpmsquirrel rpmsquirrelNew(char ** av, uint32_t flags)
107 {
108  rpmsquirrel squirrel =
109 #ifdef NOTYET
110  (flags & 0x80000000) ? rpmsquirrelI() :
111 #endif
112  rpmsquirrelGetPool(_rpmsquirrelPool);
113 
114 #if defined(WITH_SQUIRREL)
115  static char * _av[] = { "rpmsquirrel", NULL };
116  SQInteger stacksize = 1024;
117  HSQUIRRELVM v = sq_open(stacksize);
118  int ac;
119  int i;
120 
121  if (av == NULL) av = _av;
122  ac = argvCount((ARGV_t)av);
123 
124 assert(v);
125  squirrel->I = v;
126  sq_setforeignptr(v, squirrel);
127 
128 #if defined(SQUIRREL_VERSION_NUMBER) && SQUIRREL_VERSION_NUMBER >= 300
129  sq_setprintfunc(v, rpmsquirrelPrint, rpmsquirrelStderr);
130 #else
131  sq_setprintfunc(v, rpmsquirrelPrint);
132 #endif
133 
134  sqstd_seterrorhandlers(v);
135 
136  /* Initialize libraries. */
137  sqstd_register_bloblib(v);
138  sqstd_register_iolib(v);
139  sqstd_register_mathlib(v);
140  sqstd_register_stringlib(v);
141  sqstd_register_systemlib(v);
142 
143  /* Register globals (using squirrelsh conventions). */
144 #ifdef NOTYET
145  SetSqString(v, "SHELL_VERSION", SHELL_VERSION_STR, SQTrue);
146  SetSqString(v, "SQUIRREL_VERSION", SQUIRREL_VERSION_SHORT, SQTrue);
147  SetSqString(v, "PLATFORM", SHELL_PLATFORM, SQTrue);
148  SetSqString(v, "CPU_ARCH", SHELL_CPUARCH, SQTrue);
149 #else
150  sq_pushconsttable(v);
151  sq_pushstring(v, "SQUIRREL_VERSION", -1);
152  sq_pushstring(v, SQUIRREL_VERSION, -1);
153 assert(!SQ_FAILED(sq_newslot(v, -3, SQFalse)));
154  sq_pop(v, 1);
155 #endif
156 
157  /* Pass argv[argc] (using squirrelsh conventions). */
158  sq_pushroottable(v);
159  sq_pushstring(v, "__argc", -1);
160  sq_pushinteger(v, (SQInteger)ac);
161 assert(!SQ_FAILED(sq_newslot(v, -3, SQFalse)));
162  sq_pushstring(v, "__argv", -1);
163  sq_newarray(v, 0);
164  for (i = 0; av[i]; ++i) {
165  sq_pushstring(v, av[i], -1);
166  sq_arrayappend(v, -2);
167  }
168 assert(!SQ_FAILED(sq_newslot(v, -3, SQFalse)));
169  sq_pop(v, 1);
170 #endif /* defined(WITH_SQUIRREL) */
171 
172  squirrel->iob = rpmiobNew(0);
173 
174  return rpmsquirrelLink(squirrel);
175 }
176 
177 rpmRC rpmsquirrelRunFile(rpmsquirrel squirrel, const char * fn, const char ** resultp)
178 {
179  rpmRC rc = RPMRC_FAIL;
180  rpmiob iob = NULL;
181  char * b = NULL;
182 
184 fprintf(stderr, "==> %s(%p,%s)\n", __FUNCTION__, squirrel, fn);
185 
186  if (squirrel == NULL) squirrel = rpmsquirrelI();
187 
188  if (fn == NULL)
189  goto exit;
190 
191  /* Read the file */
192  rc = rpmiobSlurp(fn, &iob);
193  if (rc)
194  goto exit;
195 
196  /* XXX Change #! into a comment. */
197  for (b = rpmiobStr(iob); *b; b++) {
198  if (xisspace(*b))
199  continue;
200  if (b[0] == '#' && b[1] == '!')
201  b[0] = b[1] = '/';
202  break;
203  }
204  rc = rpmsquirrelRun(squirrel, b, resultp);
205 
206 exit:
207  iob = rpmiobFree(iob);
208  return rc;
209 }
210 
211 rpmRC rpmsquirrelRun(rpmsquirrel squirrel, const char * str, const char ** resultp)
212 {
213  rpmRC rc = RPMRC_FAIL;
214 
216 fprintf(stderr, "==> %s(%p,%s)\n", __FUNCTION__, squirrel, str);
217 
218  if (squirrel == NULL) squirrel = rpmsquirrelI();
219 
220 #if defined(WITH_SQUIRREL)
221  if (str != NULL) {
222  size_t ns = strlen(str);
223  if (ns > 0) {
224  HSQUIRRELVM v = squirrel->I;
225  SQBool raise = SQFalse;
226  SQInteger oldtop = sq_gettop(v);
227  SQRESULT res = sq_compilebuffer(v, str, ns, __FUNCTION__, raise);
228 
229  if (SQ_SUCCEEDED(res)) {
230  SQInteger retval = 0;
231  sq_pushroottable(v);
232  res = sq_call(v, 1, retval, raise);
233  }
234 
235  sq_settop(v, oldtop);
236  }
237  rc = RPMRC_OK;
238  if (resultp)
239  *resultp = rpmiobStr(squirrel->iob);
240  }
241 #endif
242  return rc;
243 }
const bson * b
Definition: bson.h:280
rpmsquirrel rpmsquirrelLink(rpmsquirrel squirrel)
Reference a squirrel interpreter instance.
rpmsquirrel _rpmsquirrelI
Definition: rpmsquirrel.c:27
rpmiob rpmiobFree(rpmiob iob)
Destroy a I/O buffer instance.
static rpmsquirrel rpmsquirrelGetPool(rpmioPool pool)
Definition: rpmsquirrel.c:46
rpmiob rpmiobAppend(rpmiob iob, const char *s, size_t nl)
Append string to I/O buffer.
Definition: rpmiob.c:77
int _rpmsquirrel_debug
Definition: rpmsquirrel.c:24
int rpmiobSlurp(const char *fn, rpmiob *iobp)
Definition: rpmiob.c:129
const char * str
Definition: bson.h:593
const char const bson_bool_t v
Definition: bson.h:919
rpmioItem rpmioGetPool(rpmioPool pool, size_t size)
Get unused item from pool, or alloc a new item.
Definition: rpmmalloc.c:220
int argvCount(const ARGV_t argv)
Return no.
Definition: argv.c:71
static int xisspace(int c)
Definition: rpmiotypes.h:555
rpmRC rpmsquirrelRunFile(rpmsquirrel squirrel, const char *fn, const char **resultp)
Execute squirrel from a file.
Definition: rpmsquirrel.c:177
static void rpmsquirrelFini(void *_squirrel)
Definition: rpmsquirrel.c:29
rpmRC rpmsquirrelRun(rpmsquirrel squirrel, const char *str, const char **resultp)
Execute squirrel string.
Definition: rpmsquirrel.c:211
static rpmsquirrel rpmsquirrelI(void)
Definition: rpmsquirrel.c:97
rpmiob rpmiobNew(size_t len)
Create an I/O buffer.
Definition: rpmiob.c:44
const char const bson int mongo_write_concern int flags
Definition: mongo.h:485
struct rpmsquirrel_s * rpmsquirrel
Definition: rpmsquirrel.h:11
enum rpmRC_e rpmRC
RPM return codes.
char * rpmiobStr(rpmiob iob)
Return I/O buffer (as string).
Definition: rpmiob.c:112
const char const int i
Definition: bson.h:778
rpmioPool _rpmsquirrelPool
Definition: rpmsquirrel.c:44
static int vsnprintf(char *buf, int nb, const char *fmt, va_list ap)
Definition: rpmps.c:212
rpmioPool rpmioNewPool(const char *name, size_t size, int limit, int flags, char *(*dbg)(void *item), void(*init)(void *item), void(*fini)(void *item))
Create a memory pool.
Definition: rpmmalloc.c:109
static void * _free(const void *p)
Wrapper to free(3), hides const compilation noise, permit NULL, return NULL.
Definition: rpmiotypes.h:756
struct rpmiob_s * rpmiob
Definition: rpmiotypes.h:60
#define xmalloc
Definition: system.h:32
ARGstr_t * ARGV_t
Definition: argv.h:12
rpmsquirrel rpmsquirrelNew(char **av, uint32_t flags)
Definition: rpmsquirrel.c:106
#define xrealloc
Definition: system.h:35
const char * ns
Definition: mongo.h:326