#define GETLINE_MAXLEN 1000
/* C implementation of TCL proc, get_input_line */
-int getInputLine(void *pvSS, Tcl_Interp *interp,
- int nArgs, const char *azArgs[]){
+static int getInputLine(void *pvSS, Tcl_Interp *interp,
+ int nArgs, const char *azArgs[]){
if( nArgs==1 ){
char buffer[GETLINE_MAXLEN+1];
ShellExState *psx = (ShellExState *)pvSS;
}
/* C implementation of TCL proc, now_interactive */
-int nowInteractive(void *pvSS, Tcl_Interp *interp,
- int nArgs, const char *azArgs[]){
+static int nowInteractive(void *pvSS, Tcl_Interp *interp,
+ int nArgs, const char *azArgs[]){
if( nArgs==1 ){
ShellExState *psx = (ShellExState *)pvSS;
struct InSource *pis = pExtHelpers->currentInputSource(psx);
}
}
-/* ToDo: C implementation of TCL ::unknown to reflect to dot commands */
+#define UNKNOWN_RENAME "::_original_unknown"
+
+/* C implementation of TCL ::unknown to delegate to dot commands */
+static int unknown_dot_delegate(void *pvSS, Tcl_Interp *interp,
+ int nArgs, const char *azArgs[]){
+ const char *name = (nArgs>1 && *azArgs[1]=='.')? azArgs[1]+1 : 0;
+ ShellExState *psx = (ShellExState *)pvSS;
+ MetaCommand *pmc = 0;
+ int nFound = 0;
+ int ia, rc;
+
+ if( name ) pmc = pExtHelpers->findMetaCommand(name, psx, &nFound);
+ if( pmc &&nFound==1 ){
+ /* Run the dot command and interpret its returns. */
+ char *zErr = 0;
+ DotCmdRC drc = pmc->pMethods->argsCheck(pmc, &zErr, nArgs-1,
+ (char **)azArgs+1);
+ if( drc==DCR_Ok ){
+ drc = pmc->pMethods->execute(pmc, psx, &zErr, nArgs-1,
+ (char **)azArgs+1);
+ }
+ assert(!(drc==DCR_Ok && zErr!=0));
+ if( drc==DCR_Ok ) return TCL_OK;
+ else{
+ /* ToDo: Try to indicate what went wrong as part of result.
+ * This is deferred until some shell functionality helping
+ * with this is factored out and exposed for extensions. */
+ sqlite3_free(zErr);
+ return TCL_ERROR;
+ }
+ }else{
+ /* Defer to the TCL-default ::unknown command, or fail here. */
+ int haveUnkCmd = (0!=Tcl_FindCommand(interp, UNKNOWN_RENAME,
+ 0, TCL_GLOBAL_ONLY));
+ Tcl_Obj **ppo;
+ if( haveUnkCmd ){
+ ppo = sqlite3_malloc((nArgs+1)*sizeof(Tcl_Obj*));
+ if( ppo==0 ) return TCL_ERROR;
+ ppo[0] = Tcl_NewStringObj(UNKNOWN_RENAME, -1);
+ Tcl_IncrRefCount(ppo[0]);
+ for( ia=1; ia<nArgs; ++ia ){
+ ppo[ia] = Tcl_NewStringObj(azArgs[ia], -1);
+ Tcl_IncrRefCount(ppo[ia]);
+ }
+ rc = Tcl_EvalObjv(interp, nArgs, ppo, TCL_EVAL_GLOBAL);
+ for( ia=0; ia<nArgs; ++ia ) Tcl_DecrRefCount(ppo[ia]);
+ return TCL_OK;
+ }else{
+ /* Fail now (instead of recursing back into this handler.) */
+ Tcl_AppendResult(interp,
+ "Command ", azArgs[1], " does not exist.", (char *)0);
+ return TCL_ERROR;
+ }
+ }
+}
/* ToDo: ... TCL db_user command, like a (TCL) sqlite3 object except that
* it defers to shell's db and treats close subcommand as an error. */
}
}
tclcmd.interp = Tcl_CreateInterp();
+ Tcl_SetSystemEncoding(tclcmd.interp, "utf-8");
+ Sqlite3_Init(tclcmd.interp);
if( 0==Tcl_OOInitStubs(tclcmd.interp) ){
*pzErrMsg = sqlite3_mprintf("Tcl v8.6 or higher required.\n");
TclCmd_Takedown(&tclcmd);
return SQLITE_ERROR;
}
- Tcl_SetSystemEncoding(tclcmd.interp, "utf-8");
- Sqlite3_Init(tclcmd.interp);
rc = pShExtApi->registerMetaCommand(psx, sqlite3_tclshext_init, pmc);
if( rc==SQLITE_OK ){
ScriptHooks sh = { pmc, tclIsScriptLead, tclIsComplete, tclRunScript };
- pShExtApi->hookScripting(psx, sqlite3_tclshext_init, &sh);
- Tcl_CreateCommand(tclcmd.interp,
- "get_input_line", getInputLine, psx, 0);
- Tcl_CreateCommand(tclcmd.interp,
- "now_interactive", nowInteractive, psx, 0);
- pShExtLink->eid = sqlite3_tclshext_init;
+ int irc = Tcl_Init(tclcmd.interp);
+ if( irc==TCL_OK ){
+ pShExtApi->hookScripting(psx, sqlite3_tclshext_init, &sh);
+ Tcl_CreateCommand(tclcmd.interp,
+ "get_input_line", getInputLine, psx, 0);
+ Tcl_CreateCommand(tclcmd.interp,
+ "now_interactive", nowInteractive, psx, 0);
+ Tcl_Eval(tclcmd.interp, "rename unknown "UNKNOWN_RENAME);
+ Tcl_CreateCommand(tclcmd.interp,
+ "unknown", unknown_dot_delegate, psx, 0);
+ pShExtLink->eid = sqlite3_tclshext_init;
+ }else{
+ TclCmd_Takedown(&tclcmd);
+ rc = SQLITE_ERROR;
+ }
}else{
TclCmd_Takedown(&tclcmd);
}
-C Scripting\ssupport\sroughed\sin,\swith\sa\sdemo\sextension.\sMore\swork\sis\sneeded\sto\smake\sthis\struly\suseful.\sTests\sare\smissing.
-D 2022-03-23T21:03:48.356
+C TCL\sshell\sextension\sdelegates\sto\sdot\scommands
+D 2022-03-24T12:49:05.311
F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724
F ext/misc/spellfix.c 94df9bbfa514a563c1484f684a2df3d128a2f7209a84ca3ca100c68a0163e29f
F ext/misc/sqlar.c 0ace5d3c10fe736dc584bf1159a36b8e2e60fab309d310cd8a0eecd9036621b6
F ext/misc/stmt.c 35063044a388ead95557e4b84b89c1b93accc2f1c6ddea3f9710e8486a7af94a
-F ext/misc/tclshext.c.in 9e8909361fb8e26488920acd6629753b5bf38541cd0c4e6a16f6532b7bf367c6
+F ext/misc/tclshext.c.in 4c9e9c36877ea3a9bde62e4d4706e848fe0d56984e7ad36d5952de7f9d9cf308
F ext/misc/templatevtab.c 8a16a91a5ceaccfcbd6aaaa56d46828806e460dd194965b3f77bf38f14b942c4
F ext/misc/totype.c fa4aedeb07f66169005dffa8de3b0a2b621779fd44f85c103228a42afa71853b
F ext/misc/uint.c 053fed3bce2e89583afcd4bf804d75d659879bbcedac74d0fa9ed548839a030b
F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
-P 7996d3a359ab90ef9f42f501e0ddb2efa964a906739116836cb1eafe2a96a0ed
-Q +da874180d35aacdeb9c06f5b425e8909d833e2765179c4337854d56b8a624fd5
-R c463fc7c0074cded5ea87643f5ddeef3
+P abf0316b3f58646974ab8e4d3e68896c9fc03bdd338eb7dc7b2f5d4de7365298
+R ce874ae1862d105669b12cd18d25e5bc
U larrybr
-Z cf7f7bb9e5e070c2442801336636b4c2
+Z 4469eea4a17023c287722633d65da7c8
# Remove this line to create a well-formed Fossil manifest.