Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Add workaround for bug in Tcl_EvalObjCmd when compiled against Tcl 8.6. |
---|---|
Downloads: | Tarball | ZIP archive |
Timelines: | family | ancestors | descendants | both | tcl-integration |
Files: | files | file ages | folders |
SHA1: |
3a6265696af8e634d1e32916f93ea1d9 |
User & Date: | mistachkin 2011-08-29 09:27:06.612 |
Context
2011-08-29
| ||
10:31 | Silence compiler warnings about unused variables in print_timeline. ... (check-in: b76ce3d5 user: mistachkin tags: tcl-integration) | |
09:27 | Add workaround for bug in Tcl_EvalObjCmd when compiled against Tcl 8.6. ... (check-in: 3a626569 user: mistachkin tags: tcl-integration) | |
01:19 | Add test to verify behavior for missing objProcs. Also, make sure Tcl integration is enabled for the tests. ... (check-in: cba0f25b user: mistachkin tags: tcl-integration) | |
Changes
Changes to src/th_tcl.c.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | /* ** This file contains code used to bridge the TH1 and Tcl scripting languages. */ #include "config.h" #include "th.h" #include "tcl.h" /* ** These macros are designed to reduce the redundant code required to marshal ** arguments from TH1 to Tcl. */ #define USE_ARGV_TO_OBJV() \ int objc; \ Tcl_Obj **objv; \ | > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | /* ** This file contains code used to bridge the TH1 and Tcl scripting languages. */ #include "config.h" #include "th.h" #include "tcl.h" /* ** Are we being compiled against Tcl 8.6 or higher? */ #if (TCL_MAJOR_VERSION > 8) || \ ((TCL_MAJOR_VERSION == 8) && (TCL_MINOR_VERSION >= 6)) /* ** Workaround NRE-specific issue in Tcl_EvalObjCmd (SF bug #3399564) by using ** Tcl_EvalObjv instead of invoking the objProc directly. */ #define USE_TCL_EVALOBJV 1 #endif /* ** These macros are designed to reduce the redundant code required to marshal ** arguments from TH1 to Tcl. */ #define USE_ARGV_TO_OBJV() \ int objc; \ Tcl_Obj **objv; \ |
︙ | ︙ | |||
157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 | Th_Interp *interp, void *ctx, int argc, const char **argv, int *argl ){ Tcl_Interp *tclInterp; Tcl_Command command; Tcl_CmdInfo cmdInfo; int rc; int nResult; const char *zResult; Tcl_Obj *objPtr; USE_ARGV_TO_OBJV(); if( argc<2 ){ return Th_WrongNumArgs(interp, "tclInvoke command ?arg ...?"); } tclInterp = (Tcl_Interp *)ctx; if( !tclInterp || Tcl_InterpDeleted(tclInterp) ){ Th_ErrorMessage(interp, "invalid Tcl interpreter", (const char *)"", 0); return TH_ERROR; } Tcl_Preserve((ClientData)tclInterp); objPtr = Tcl_NewStringObj(argv[1], argl[1]); Tcl_IncrRefCount(objPtr); command = Tcl_GetCommandFromObj(tclInterp, objPtr); if( !command || Tcl_GetCommandInfoFromToken(command,&cmdInfo)==0 ){ Th_ErrorMessage(interp, "Tcl command not found:", argv[1], argl[1]); Tcl_DecrRefCount(objPtr); Tcl_Release((ClientData)tclInterp); return TH_ERROR; } if( !cmdInfo.objProc ){ Th_ErrorMessage(interp, "Cannot invoke Tcl command:", argv[1], argl[1]); Tcl_DecrRefCount(objPtr); Tcl_Release((ClientData)tclInterp); return TH_ERROR; } Tcl_DecrRefCount(objPtr); COPY_ARGV_TO_OBJV(); Tcl_ResetResult(tclInterp); rc = cmdInfo.objProc(cmdInfo.objClientData, tclInterp, objc, objv); FREE_ARGV_TO_OBJV(); zResult = getTclResult(tclInterp, &nResult); Th_SetResult(interp, zResult, nResult); Tcl_Release((ClientData)tclInterp); return rc; } /* ** Syntax: ** ** th1Eval arg */ static int Th1EvalObjCmd( ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[] ){ | > > > > > > > > > > | > | 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 | Th_Interp *interp, void *ctx, int argc, const char **argv, int *argl ){ Tcl_Interp *tclInterp; #ifndef USE_TCL_EVALOBJV Tcl_Command command; Tcl_CmdInfo cmdInfo; #endif int rc; int nResult; const char *zResult; #ifndef USE_TCL_EVALOBJV Tcl_Obj *objPtr; #endif USE_ARGV_TO_OBJV(); if( argc<2 ){ return Th_WrongNumArgs(interp, "tclInvoke command ?arg ...?"); } tclInterp = (Tcl_Interp *)ctx; if( !tclInterp || Tcl_InterpDeleted(tclInterp) ){ Th_ErrorMessage(interp, "invalid Tcl interpreter", (const char *)"", 0); return TH_ERROR; } Tcl_Preserve((ClientData)tclInterp); #ifndef USE_TCL_EVALOBJV objPtr = Tcl_NewStringObj(argv[1], argl[1]); Tcl_IncrRefCount(objPtr); command = Tcl_GetCommandFromObj(tclInterp, objPtr); if( !command || Tcl_GetCommandInfoFromToken(command,&cmdInfo)==0 ){ Th_ErrorMessage(interp, "Tcl command not found:", argv[1], argl[1]); Tcl_DecrRefCount(objPtr); Tcl_Release((ClientData)tclInterp); return TH_ERROR; } if( !cmdInfo.objProc ){ Th_ErrorMessage(interp, "Cannot invoke Tcl command:", argv[1], argl[1]); Tcl_DecrRefCount(objPtr); Tcl_Release((ClientData)tclInterp); return TH_ERROR; } Tcl_DecrRefCount(objPtr); #endif COPY_ARGV_TO_OBJV(); #ifdef USE_TCL_EVALOBJV rc = Tcl_EvalObjv(tclInterp, objc, objv, 0); #else Tcl_ResetResult(tclInterp); rc = cmdInfo.objProc(cmdInfo.objClientData, tclInterp, objc, objv); #endif FREE_ARGV_TO_OBJV(); zResult = getTclResult(tclInterp, &nResult); Th_SetResult(interp, zResult, nResult); Tcl_Release((ClientData)tclInterp); return rc; } /* ** Syntax: ** ** th1Eval arg */ static int Th1EvalObjCmd( ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[] ){ Th_Interp *th1Interp; int nArg; const char *arg; int rc; if( objc!=2 ){ Tcl_WrongNumArgs(interp, 1, objv, "arg"); return TCL_ERROR; } th1Interp = (Th_Interp *)clientData; if( !th1Interp ){ Tcl_AppendResult(interp, "invalid TH1 interpreter", NULL); return TCL_ERROR; } arg = Tcl_GetStringFromObj(objv[1], &nArg); rc = Th_Eval(th1Interp, 0, arg, nArg); arg = Th_GetResult(th1Interp, &nArg); |
︙ | ︙ | |||
242 243 244 245 246 247 248 | */ static int Th1ExprObjCmd( ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[] ){ | | > | 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 | */ static int Th1ExprObjCmd( ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[] ){ Th_Interp *th1Interp; int nArg; const char *arg; int rc; if( objc!=2 ){ Tcl_WrongNumArgs(interp, 1, objv, "arg"); return TCL_ERROR; } th1Interp = (Th_Interp *)clientData; if( !th1Interp ){ Tcl_AppendResult(interp, "invalid TH1 interpreter", NULL); return TCL_ERROR; } arg = Tcl_GetStringFromObj(objv[1], &nArg); rc = Th_Expr(th1Interp, arg, nArg); arg = Th_GetResult(th1Interp, &nArg); |
︙ | ︙ |