rpm  5.4.15
rpmtcl.c
Go to the documentation of this file.
1 #include "system.h"
2 
3 #include <argv.h>
4 
5 #ifdef WITH_TCL
6 #include <tcl.h>
7 #endif
8 #define _RPMTCL_INTERNAL
9 #include "rpmtcl.h"
10 
11 #include "debug.h"
12 
13 /*@unchecked@*/
14 int _rpmtcl_debug = 0;
15 
16 /*@unchecked@*/ /*@relnull@*/
18 
19 static void rpmtclFini(void * _tcl)
20  /*@globals fileSystem @*/
21  /*@modifies *_tcl, fileSystem @*/
22 {
23  rpmtcl tcl = (rpmtcl) _tcl;
24 
25 #if defined(WITH_TCL)
26  Tcl_DeleteInterp((Tcl_Interp *)tcl->I);
27 #endif
28  tcl->I = NULL;
29  (void)rpmiobFree(tcl->iob);
30  tcl->iob = NULL;
31 }
32 
33 /*@unchecked@*/ /*@only@*/ /*@null@*/
35 
36 static rpmtcl rpmtclGetPool(/*@null@*/ rpmioPool pool)
37  /*@globals _rpmtclPool, fileSystem @*/
38  /*@modifies pool, _rpmtclPool, fileSystem @*/
39 {
40  rpmtcl tcl;
41 
42  if (_rpmtclPool == NULL) {
43  _rpmtclPool = rpmioNewPool("tcl", sizeof(*tcl), -1, _rpmtcl_debug,
44  NULL, NULL, rpmtclFini);
45  pool = _rpmtclPool;
46  }
47  return (rpmtcl) rpmioGetPool(pool, sizeof(*tcl));
48 }
49 
50 #if defined(WITH_TCL)
51 static int rpmtclIOclose(ClientData CD, Tcl_Interp *I)
52  /*@*/
53 {
54 if (_rpmtcl_debug)
55 fprintf(stderr, "==> %s(%p, %p)\n", __FUNCTION__, CD, I);
56  return 0;
57 }
58 
59 static int rpmtclIOread(ClientData CD, char *b, int nb, int *errnop)
60  /*@*/
61 {
62 if (_rpmtcl_debug)
63 fprintf(stderr, "==> %s(%p, %p[%d], %p)\n", __FUNCTION__, CD, b, nb, errnop);
64  *errnop = EINVAL;
65  return -1;
66 }
67 
68 static int rpmtclIOwrite(ClientData CD, const char *b, int nb, int *errnop)
69  /*@*/
70 {
71  rpmtcl tcl = (rpmtcl) CD;
72 if (_rpmtcl_debug)
73 fprintf(stderr, "==> %s(%p, %p[%d], %p)\n", __FUNCTION__, CD, b, nb, errnop);
74  if (nb > 0) {
75  char * t = (char *)b;
76  int c = t[nb];
77  if (c) t[nb] = '\0';
78  (void) rpmiobAppend(tcl->iob, b, 0);
79  if (c) t[nb] = c;
80  }
81  return nb;
82 }
83 
84 static int rpmtclIOseek(ClientData CD, long off, int mode, int *errnop)
85  /*@*/
86 {
87 if (_rpmtcl_debug)
88 fprintf(stderr, "==> %s(%p, %ld, %d, %p)\n", __FUNCTION__, CD, off, mode, errnop);
89  *errnop = EINVAL;
90  return -1;
91 }
92 
93 static Tcl_ChannelType rpmtclIO = {
94  (char *)"rpmtclIO", /* Type name */
95  TCL_CHANNEL_VERSION_2, /* Tcl_ChannelTypeVersion */
96  rpmtclIOclose, /* Tcl_DriverCloseProc */
97  rpmtclIOread, /* Tcl_DriverInputProc */
98  rpmtclIOwrite, /* Tcl_DriverOutputProc */
99  rpmtclIOseek, /* Tcl_DriverSeekProc */
100  NULL, /* Tcl_DriverSetOptionProc */
101  NULL, /* Tcl_DriverGetOptionProc */
102  NULL, /* Tcl_DriverWatchProc */
103  NULL, /* Tcl_DriverGetHandleProc */
104  NULL, /* Tcl_DriverClose2Proc */
105  NULL, /* Tcl_DriverBlockModeProc */
106  NULL, /* Tcl_DriverFlushProc */
107  NULL, /* Tcl_DriverHandlerProc */
108  NULL, /* Tcl_DriverWideSeekProc */
109  NULL, /* Tcl_DriverThreadActionProc */
110 #if TCL_MAJOR_VERSION == 8 && TCL_MINOR_VERSION > 4
111  NULL, /* Tcl_DriverTruncateProc */
112 #endif
113 };
114 #endif
115 
116 static rpmtcl rpmtclI(void)
117  /*@globals _rpmtclI @*/
118  /*@modifies _rpmtclI @*/
119 {
120  if (_rpmtclI == NULL)
121  _rpmtclI = rpmtclNew(NULL, 0);
122  return _rpmtclI;
123 }
124 
125 rpmtcl rpmtclNew(char ** av, uint32_t flags)
126 {
127  rpmtcl tcl =
128 #ifdef NOTYET
129  (flags & 0x80000000) ? rpmtclI() :
130 #endif
131  rpmtclGetPool(_rpmtclPool);
132 
133 #if defined(WITH_TCL)
134  static char * _av[] = { "rpmtcl", NULL };
135  Tcl_Interp * tclI = Tcl_CreateInterp();
136  char b[32];
137  int ac;
138 
139  if (av == NULL) av = _av;
140  ac = argvCount((ARGV_t)av);
141 
142  Tcl_SetVar(tclI, "argv", Tcl_Merge(ac-1, (const char *const *)av+1), TCL_GLOBAL_ONLY);
143  (void)sprintf(b, "%d", ac-1);
144  Tcl_SetVar(tclI, "argc", b, TCL_GLOBAL_ONLY);
145  Tcl_SetVar(tclI, "argv0", av[0], TCL_GLOBAL_ONLY);
146  Tcl_SetVar(tclI, "tcl_interactive", "0", TCL_GLOBAL_ONLY);
147 
148  tcl->I = tclI;
149  { Tcl_Channel tclout = Tcl_GetStdChannel(TCL_STDOUT);
150  Tcl_SetChannelOption(tclI, tclout, "-translation", "auto");
151  Tcl_StackChannel(tclI, &rpmtclIO, tcl, TCL_WRITABLE, tclout);
152  tcl->tclout = (void *) tclout;
153  }
154 #endif
155  tcl->iob = rpmiobNew(0);
156 
157  return rpmtclLink(tcl);
158 }
159 
160 rpmRC rpmtclRunFile(rpmtcl tcl, const char * fn, const char ** resultp)
161 {
162  rpmRC rc = RPMRC_FAIL;
163 
164 if (_rpmtcl_debug)
165 fprintf(stderr, "==> %s(%p,%s)\n", __FUNCTION__, tcl, fn);
166 
167  if (tcl == NULL) tcl = rpmtclI();
168 
169 #if defined(WITH_TCL)
170  if (fn != NULL && Tcl_EvalFile((Tcl_Interp *)tcl->I, fn) == TCL_OK) {
171  rc = RPMRC_OK;
172  if (resultp)
173  *resultp = rpmiobStr(tcl->iob);
174  }
175 #endif
176  return rc;
177 }
178 
179 rpmRC rpmtclRun(rpmtcl tcl, const char * str, const char ** resultp)
180 {
181  rpmRC rc = RPMRC_FAIL;
182 
183 if (_rpmtcl_debug)
184 fprintf(stderr, "==> %s(%p,%s)\n", __FUNCTION__, tcl, str);
185 
186  if (tcl == NULL) tcl = rpmtclI();
187 
188 #if defined(WITH_TCL)
189  if (str != NULL && Tcl_Eval((Tcl_Interp *)tcl->I, str) == TCL_OK) {
190  rc = RPMRC_OK;
191  if (resultp)
192  *resultp = rpmiobStr(tcl->iob);
193  }
194 #endif
195  return rc;
196 }
const bson * b
Definition: bson.h:280
rpmtcl rpmtclLink(rpmtcl tcl)
Reference a tcl interpreter instance.
rpmtcl _rpmtclI
Definition: rpmtcl.c:17
static void rpmtclFini(void *_tcl)
Definition: rpmtcl.c:19
rpmiob rpmiobFree(rpmiob iob)
Destroy a I/O buffer instance.
rpmiob rpmiobAppend(rpmiob iob, const char *s, size_t nl)
Append string to I/O buffer.
Definition: rpmiob.c:77
const char * str
Definition: bson.h:593
rpmRC rpmtclRunFile(rpmtcl tcl, const char *fn, const char **resultp)
Execute tcl from a file.
Definition: rpmtcl.c:160
static rpmtcl rpmtclI(void)
Definition: rpmtcl.c:116
const char * mode
Definition: mongo.h:440
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
int _rpmtcl_debug
Definition: rpmtcl.c:14
struct rpmtcl_s * rpmtcl
Definition: rpmtcl.h:11
rpmioPool _rpmtclPool
Definition: rpmtcl.c:34
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
enum rpmRC_e rpmRC
RPM return codes.
char * rpmiobStr(rpmiob iob)
Return I/O buffer (as string).
Definition: rpmiob.c:112
static rpmtcl rpmtclGetPool(rpmioPool pool)
Definition: rpmtcl.c:36
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
ARGstr_t * ARGV_t
Definition: argv.h:12
rpmtcl rpmtclNew(char **av, uint32_t flags)
Create and load a tcl interpreter.
Definition: rpmtcl.c:125
rpmRC rpmtclRun(rpmtcl tcl, const char *str, const char **resultp)
Execute tcl string.
Definition: rpmtcl.c:179