rpm 5.3.7
|
00001 #include "system.h" 00002 00003 #include <argv.h> 00004 00005 #ifdef WITH_TCL 00006 #include <tcl.h> 00007 #endif 00008 #define _RPMTCL_INTERNAL 00009 #include "rpmtcl.h" 00010 00011 #include "debug.h" 00012 00013 /*@unchecked@*/ 00014 int _rpmtcl_debug = 0; 00015 00016 /*@unchecked@*/ /*@relnull@*/ 00017 rpmtcl _rpmtclI = NULL; 00018 00019 static void rpmtclFini(void * _tcl) 00020 /*@globals fileSystem @*/ 00021 /*@modifies *_tcl, fileSystem @*/ 00022 { 00023 rpmtcl tcl = _tcl; 00024 00025 #if defined(WITH_TCL) 00026 Tcl_DeleteInterp((Tcl_Interp *)tcl->I); 00027 #endif 00028 tcl->I = NULL; 00029 (void)rpmiobFree(tcl->iob); 00030 tcl->iob = NULL; 00031 } 00032 00033 /*@unchecked@*/ /*@only@*/ /*@null@*/ 00034 rpmioPool _rpmtclPool; 00035 00036 static rpmtcl rpmtclGetPool(/*@null@*/ rpmioPool pool) 00037 /*@globals _rpmtclPool, fileSystem @*/ 00038 /*@modifies pool, _rpmtclPool, fileSystem @*/ 00039 { 00040 rpmtcl tcl; 00041 00042 if (_rpmtclPool == NULL) { 00043 _rpmtclPool = rpmioNewPool("tcl", sizeof(*tcl), -1, _rpmtcl_debug, 00044 NULL, NULL, rpmtclFini); 00045 pool = _rpmtclPool; 00046 } 00047 return (rpmtcl) rpmioGetPool(pool, sizeof(*tcl)); 00048 } 00049 00050 #if defined(WITH_TCL) 00051 static int rpmtclIOclose(ClientData CD, Tcl_Interp *I) 00052 /*@*/ 00053 { 00054 if (_rpmtcl_debug) 00055 fprintf(stderr, "==> %s(%p, %p)\n", __FUNCTION__, CD, I); 00056 return 0; 00057 } 00058 00059 static int rpmtclIOread(ClientData CD, char *b, int nb, int *errnop) 00060 /*@*/ 00061 { 00062 if (_rpmtcl_debug) 00063 fprintf(stderr, "==> %s(%p, %p[%d], %p)\n", __FUNCTION__, CD, b, nb, errnop); 00064 *errnop = EINVAL; 00065 return -1; 00066 } 00067 00068 static int rpmtclIOwrite(ClientData CD, const char *b, int nb, int *errnop) 00069 /*@*/ 00070 { 00071 rpmtcl tcl = (rpmtcl) CD; 00072 if (_rpmtcl_debug) 00073 fprintf(stderr, "==> %s(%p, %p[%d], %p)\n", __FUNCTION__, CD, b, nb, errnop); 00074 if (nb > 0) { 00075 char * t = (char *)b; 00076 int c = t[nb]; 00077 if (c) t[nb] = '\0'; 00078 (void) rpmiobAppend(tcl->iob, b, 0); 00079 if (c) t[nb] = c; 00080 } 00081 return nb; 00082 } 00083 00084 static int rpmtclIOseek(ClientData CD, long off, int mode, int *errnop) 00085 /*@*/ 00086 { 00087 if (_rpmtcl_debug) 00088 fprintf(stderr, "==> %s(%p, %ld, %d, %p)\n", __FUNCTION__, CD, off, mode, errnop); 00089 *errnop = EINVAL; 00090 return -1; 00091 } 00092 00093 static Tcl_ChannelType rpmtclIO = { 00094 "rpmtclIO", /* Type name */ 00095 TCL_CHANNEL_VERSION_2, /* Tcl_ChannelTypeVersion */ 00096 rpmtclIOclose, /* Tcl_DriverCloseProc */ 00097 rpmtclIOread, /* Tcl_DriverInputProc */ 00098 rpmtclIOwrite, /* Tcl_DriverOutputProc */ 00099 rpmtclIOseek, /* Tcl_DriverSeekProc */ 00100 NULL, /* Tcl_DriverSetOptionProc */ 00101 NULL, /* Tcl_DriverGetOptionProc */ 00102 NULL, /* Tcl_DriverWatchProc */ 00103 NULL, /* Tcl_DriverGetHandleProc */ 00104 NULL, /* Tcl_DriverClose2Proc */ 00105 NULL, /* Tcl_DriverBlockModeProc */ 00106 NULL, /* Tcl_DriverFlushProc */ 00107 NULL, /* Tcl_DriverHandlerProc */ 00108 NULL, /* Tcl_DriverWideSeekProc */ 00109 NULL, /* Tcl_DriverThreadActionProc */ 00110 #if TCL_MAJOR_VERSION == 8 && TCL_MINOR_VERSION > 4 00111 NULL, /* Tcl_DriverTruncateProc */ 00112 #endif 00113 }; 00114 #endif 00115 00116 static rpmtcl rpmtclI(void) 00117 /*@globals _rpmtclI @*/ 00118 /*@modifies _rpmtclI @*/ 00119 { 00120 if (_rpmtclI == NULL) 00121 _rpmtclI = rpmtclNew(NULL, 0); 00122 return _rpmtclI; 00123 } 00124 00125 rpmtcl rpmtclNew(char ** av, uint32_t flags) 00126 { 00127 rpmtcl tcl = 00128 #ifdef NOTYET 00129 (flags & 0x80000000) ? rpmtclI() : 00130 #endif 00131 rpmtclGetPool(_rpmtclPool); 00132 00133 #if defined(WITH_TCL) 00134 static char * _av[] = { "rpmtcl", NULL }; 00135 Tcl_Interp * tclI = Tcl_CreateInterp(); 00136 char b[32]; 00137 int ac; 00138 00139 if (av == NULL) av = _av; 00140 ac = argvCount((ARGV_t)av); 00141 00142 Tcl_SetVar(tclI, "argv", Tcl_Merge(ac-1, (const char *const *)av+1), TCL_GLOBAL_ONLY); 00143 (void)sprintf(b, "%d", ac-1); 00144 Tcl_SetVar(tclI, "argc", b, TCL_GLOBAL_ONLY); 00145 Tcl_SetVar(tclI, "argv0", av[0], TCL_GLOBAL_ONLY); 00146 Tcl_SetVar(tclI, "tcl_interactive", "0", TCL_GLOBAL_ONLY); 00147 00148 tcl->I = tclI; 00149 tcl->tclout = Tcl_GetStdChannel(TCL_STDOUT); 00150 Tcl_SetChannelOption(tclI, tcl->tclout, "-translation", "auto"); 00151 Tcl_StackChannel(tclI, &rpmtclIO, tcl, TCL_WRITABLE, tcl->tclout); 00152 #endif 00153 tcl->iob = rpmiobNew(0); 00154 00155 return rpmtclLink(tcl); 00156 } 00157 00158 rpmRC rpmtclRunFile(rpmtcl tcl, const char * fn, const char ** resultp) 00159 { 00160 rpmRC rc = RPMRC_FAIL; 00161 00162 if (_rpmtcl_debug) 00163 fprintf(stderr, "==> %s(%p,%s)\n", __FUNCTION__, tcl, fn); 00164 00165 if (tcl == NULL) tcl = rpmtclI(); 00166 00167 #if defined(WITH_TCL) 00168 if (fn != NULL && Tcl_EvalFile((Tcl_Interp *)tcl->I, fn) == TCL_OK) { 00169 rc = RPMRC_OK; 00170 if (resultp) 00171 *resultp = rpmiobStr(tcl->iob); 00172 } 00173 #endif 00174 return rc; 00175 } 00176 00177 rpmRC rpmtclRun(rpmtcl tcl, const char * str, const char ** resultp) 00178 { 00179 rpmRC rc = RPMRC_FAIL; 00180 00181 if (_rpmtcl_debug) 00182 fprintf(stderr, "==> %s(%p,%s)\n", __FUNCTION__, tcl, str); 00183 00184 if (tcl == NULL) tcl = rpmtclI(); 00185 00186 #if defined(WITH_TCL) 00187 if (str != NULL && Tcl_Eval((Tcl_Interp *)tcl->I, str) == TCL_OK) { 00188 rc = RPMRC_OK; 00189 if (resultp) 00190 *resultp = rpmiobStr(tcl->iob); 00191 } 00192 #endif 00193 return rc; 00194 }