| | @@ -20,10 +20,11 @@ |
| 20 | 20 | */ |
| 21 | 21 | #include "config.h" |
| 22 | 22 | |
| 23 | 23 | #ifdef FOSSIL_ENABLE_TCL |
| 24 | 24 | |
| 25 | +#include "sqlite3.h" |
| 25 | 26 | #include "th.h" |
| 26 | 27 | #include "tcl.h" |
| 27 | 28 | |
| 28 | 29 | /* |
| 29 | 30 | ** These macros are designed to reduce the redundant code required to marshal |
| | @@ -165,11 +166,12 @@ |
| 165 | 166 | /* |
| 166 | 167 | ** HACK: Using some preprocessor magic and a private static variable, redirect |
| 167 | 168 | ** the Tcl API calls [found within this file] to the function pointers |
| 168 | 169 | ** that will be contained in our private Tcl stubs table. This takes |
| 169 | 170 | ** advantage of the fact that the Tcl headers always define the Tcl API |
| 170 | | -** functions in terms of the "tclStubsPtr" variable. |
| 171 | +** functions in terms of the "tclStubsPtr" variable when the define |
| 172 | +** USE_TCL_STUBS is present during compilation. |
| 171 | 173 | */ |
| 172 | 174 | #define tclStubsPtr privateTclStubsPtr |
| 173 | 175 | static const TclStubs *tclStubsPtr = NULL; |
| 174 | 176 | |
| 175 | 177 | /* |
| | @@ -248,10 +250,32 @@ |
| 248 | 250 | ** interpreter. Stores the created Tcl interpreter in the Tcl context supplied |
| 249 | 251 | ** by the caller. This must be declared here because quite a few functions in |
| 250 | 252 | ** this file need to use it before it can be defined. |
| 251 | 253 | */ |
| 252 | 254 | static int createTclInterp(Th_Interp *interp, void *pContext); |
| 255 | + |
| 256 | +/* |
| 257 | +** Returns a name for a Tcl return code. |
| 258 | +*/ |
| 259 | +static const char *getTclReturnCodeName( |
| 260 | + int rc, |
| 261 | + int nullIfOk |
| 262 | +){ |
| 263 | + static char zRc[32]; |
| 264 | + |
| 265 | + switch( rc ){ |
| 266 | + case TCL_OK: return nullIfOk ? 0 : "TCL_OK"; |
| 267 | + case TCL_ERROR: return "TCL_ERROR"; |
| 268 | + case TCL_BREAK: return "TCL_BREAK"; |
| 269 | + case TCL_RETURN: return "TCL_RETURN"; |
| 270 | + case TCL_CONTINUE: return "TCL_CONTINUE"; |
| 271 | + default: { |
| 272 | + sqlite3_snprintf(sizeof(zRc), zRc, "Tcl return code %d", rc); |
| 273 | + } |
| 274 | + } |
| 275 | + return zRc; |
| 276 | +} |
| 253 | 277 | |
| 254 | 278 | /* |
| 255 | 279 | ** Returns the Tcl interpreter result as a string with the associated length. |
| 256 | 280 | ** If the Tcl interpreter or the Tcl result are NULL, the length will be 0. |
| 257 | 281 | ** If the length pointer is NULL, the length will not be stored. |
| | @@ -774,16 +798,19 @@ |
| 774 | 798 | ** Tcl script succeeds, start a Tcl event loop until there are no more events |
| 775 | 799 | ** remaining to process -OR- the script calls [exit]. If the bWait argument |
| 776 | 800 | ** is zero, only process events that are already in the queue; otherwise, |
| 777 | 801 | ** process events until the script terminates the Tcl event loop. |
| 778 | 802 | */ |
| 803 | +void fossil_print(const char *zFormat, ...); /* printf.h */ |
| 804 | + |
| 779 | 805 | int evaluateTclWithEvents( |
| 780 | 806 | Th_Interp *interp, |
| 781 | 807 | void *pContext, |
| 782 | 808 | const char *zScript, |
| 783 | 809 | int nScript, |
| 784 | | - int bWait |
| 810 | + int bWait, |
| 811 | + int bVerbose |
| 785 | 812 | ){ |
| 786 | 813 | struct TclContext *tclContext = (struct TclContext *)pContext; |
| 787 | 814 | Tcl_Interp *tclInterp; |
| 788 | 815 | int rc; |
| 789 | 816 | int flags = TCL_ALL_EVENTS; |
| | @@ -791,11 +818,18 @@ |
| 791 | 818 | if( createTclInterp(interp, pContext)!=TH_OK ){ |
| 792 | 819 | return TH_ERROR; |
| 793 | 820 | } |
| 794 | 821 | tclInterp = tclContext->interp; |
| 795 | 822 | rc = Tcl_EvalEx(tclInterp, zScript, nScript, TCL_EVAL_GLOBAL); |
| 796 | | - if( rc!=TCL_OK ) return rc; |
| 823 | + if( rc!=TCL_OK ){ |
| 824 | + if( bVerbose ){ |
| 825 | + const char *zResult = getTclResult(tclInterp, 0); |
| 826 | + fossil_print("%s: ", getTclReturnCodeName(rc, 0)); |
| 827 | + fossil_print("%s\n", zResult); |
| 828 | + } |
| 829 | + return rc; |
| 830 | + } |
| 797 | 831 | if( !bWait ) flags |= TCL_DONT_WAIT; |
| 798 | 832 | while( Tcl_DoOneEvent(flags) ){ |
| 799 | 833 | /* do nothing */ |
| 800 | 834 | } |
| 801 | 835 | return rc; |
| 802 | 836 | |