tclinterp.c
来自「tcl是工具命令语言」· C语言 代码 · 共 2,256 行 · 第 1/5 页
C
2,256 行
SlaveObjCmd, (ClientData) slaveInterp, SlaveObjCmdDeleteProc); Tcl_InitHashTable(&slavePtr->aliasTable, TCL_STRING_KEYS); Tcl_SetHashValue(hPtr, (ClientData) slavePtr); Tcl_SetVar(slaveInterp, "tcl_interactive", "0", TCL_GLOBAL_ONLY); /* * Inherit the recursion limit. */ ((Interp *) slaveInterp)->maxNestingDepth = ((Interp *) masterInterp)->maxNestingDepth ; if (safe) { if (Tcl_MakeSafe(slaveInterp) == TCL_ERROR) { goto error; } } else { if (Tcl_Init(slaveInterp) == TCL_ERROR) { goto error; } /* * This will create the "memory" command in slave interpreters * if we compiled with TCL_MEM_DEBUG, otherwise it does nothing. */ Tcl_InitMemory(slaveInterp); } return slaveInterp; error: TclTransferResult(slaveInterp, TCL_ERROR, interp); Tcl_DeleteInterp(slaveInterp); return NULL;}/* *---------------------------------------------------------------------- * * SlaveObjCmd -- * * Command to manipulate an interpreter, e.g. to send commands to it * to be evaluated. One such command exists for each slave interpreter. * * Results: * A standard Tcl result. * * Side effects: * See user documentation for details. * *---------------------------------------------------------------------- */static intSlaveObjCmd(clientData, interp, objc, objv) ClientData clientData; /* Slave interpreter. */ Tcl_Interp *interp; /* Current interpreter. */ int objc; /* Number of arguments. */ Tcl_Obj *CONST objv[]; /* Argument objects. */{ Tcl_Interp *slaveInterp; int index; static CONST char *options[] = { "alias", "aliases", "eval", "expose", "hide", "hidden", "issafe", "invokehidden", "marktrusted", "recursionlimit", NULL }; enum options { OPT_ALIAS, OPT_ALIASES, OPT_EVAL, OPT_EXPOSE, OPT_HIDE, OPT_HIDDEN, OPT_ISSAFE, OPT_INVOKEHIDDEN, OPT_MARKTRUSTED, OPT_RECLIMIT }; slaveInterp = (Tcl_Interp *) clientData; if (slaveInterp == NULL) { panic("SlaveObjCmd: interpreter has been deleted"); } if (objc < 2) { Tcl_WrongNumArgs(interp, 1, objv, "cmd ?arg ...?"); return TCL_ERROR; } if (Tcl_GetIndexFromObj(interp, objv[1], options, "option", 0, &index) != TCL_OK) { return TCL_ERROR; } switch ((enum options) index) { case OPT_ALIAS: { if (objc > 2) { if (objc == 3) { return AliasDescribe(interp, slaveInterp, objv[2]); } if (Tcl_GetString(objv[3])[0] == '\0') { if (objc == 4) { return AliasDelete(interp, slaveInterp, objv[2]); } } else { return AliasCreate(interp, slaveInterp, interp, objv[2], objv[3], objc - 4, objv + 4); } } Tcl_WrongNumArgs(interp, 2, objv, "aliasName ?targetName? ?args..?"); return TCL_ERROR; } case OPT_ALIASES: { if (objc != 2) { Tcl_WrongNumArgs(interp, 2, objv, (char *) NULL); return TCL_ERROR; } return AliasList(interp, slaveInterp); } case OPT_EVAL: { if (objc < 3) { Tcl_WrongNumArgs(interp, 2, objv, "arg ?arg ...?"); return TCL_ERROR; } return SlaveEval(interp, slaveInterp, objc - 2, objv + 2); } case OPT_EXPOSE: { if ((objc < 3) || (objc > 4)) { Tcl_WrongNumArgs(interp, 2, objv, "hiddenCmdName ?cmdName?"); return TCL_ERROR; } return SlaveExpose(interp, slaveInterp, objc - 2, objv + 2); } case OPT_HIDE: { if ((objc < 3) || (objc > 4)) { Tcl_WrongNumArgs(interp, 2, objv, "cmdName ?hiddenCmdName?"); return TCL_ERROR; } return SlaveHide(interp, slaveInterp, objc - 2, objv + 2); } case OPT_HIDDEN: { if (objc != 2) { Tcl_WrongNumArgs(interp, 2, objv, NULL); return TCL_ERROR; } return SlaveHidden(interp, slaveInterp); } case OPT_ISSAFE: { if (objc != 2) { Tcl_WrongNumArgs(interp, 2, objv, (char *) NULL); return TCL_ERROR; } Tcl_SetIntObj(Tcl_GetObjResult(interp), Tcl_IsSafe(slaveInterp)); return TCL_OK; } case OPT_INVOKEHIDDEN: { int global, i, index; static CONST char *hiddenOptions[] = { "-global", "--", NULL }; enum hiddenOption { OPT_GLOBAL, OPT_LAST }; global = 0; for (i = 2; i < objc; i++) { if (Tcl_GetString(objv[i])[0] != '-') { break; } if (Tcl_GetIndexFromObj(interp, objv[i], hiddenOptions, "option", 0, &index) != TCL_OK) { return TCL_ERROR; } if (index == OPT_GLOBAL) { global = 1; } else { i++; break; } } if (objc - i < 1) { Tcl_WrongNumArgs(interp, 2, objv, "?-global? ?--? cmd ?arg ..?"); return TCL_ERROR; } return SlaveInvokeHidden(interp, slaveInterp, global, objc - i, objv + i); } case OPT_MARKTRUSTED: { if (objc != 2) { Tcl_WrongNumArgs(interp, 2, objv, NULL); return TCL_ERROR; } return SlaveMarkTrusted(interp, slaveInterp); } case OPT_RECLIMIT: { if (objc != 2 && objc != 3) { Tcl_WrongNumArgs(interp, 2, objv, "?newlimit?"); return TCL_ERROR; } return SlaveRecursionLimit(interp, slaveInterp, objc - 2, objv + 2); } } return TCL_ERROR;}/* *---------------------------------------------------------------------- * * SlaveObjCmdDeleteProc -- * * Invoked when an object command for a slave interpreter is deleted; * cleans up all state associated with the slave interpreter and destroys * the slave interpreter. * * Results: * None. * * Side effects: * Cleans up all state associated with the slave interpreter and * destroys the slave interpreter. * *---------------------------------------------------------------------- */static voidSlaveObjCmdDeleteProc(clientData) ClientData clientData; /* The SlaveRecord for the command. */{ Slave *slavePtr; /* Interim storage for Slave record. */ Tcl_Interp *slaveInterp; /* And for a slave interp. */ slaveInterp = (Tcl_Interp *) clientData; slavePtr = &((InterpInfo *) ((Interp *) slaveInterp)->interpInfo)->slave; /* * Unlink the slave from its master interpreter. */ Tcl_DeleteHashEntry(slavePtr->slaveEntryPtr); /* * Set to NULL so that when the InterpInfo is cleaned up in the slave * it does not try to delete the command causing all sorts of grief. * See SlaveRecordDeleteProc(). */ slavePtr->interpCmd = NULL; if (slavePtr->slaveInterp != NULL) { Tcl_DeleteInterp(slavePtr->slaveInterp); }}/* *---------------------------------------------------------------------- * * SlaveEval -- * * Helper function to evaluate a command in a slave interpreter. * * Results: * A standard Tcl result. * * Side effects: * Whatever the command does. * *---------------------------------------------------------------------- */static intSlaveEval(interp, slaveInterp, objc, objv) Tcl_Interp *interp; /* Interp for error return. */ Tcl_Interp *slaveInterp; /* The slave interpreter in which command * will be evaluated. */ int objc; /* Number of arguments. */ Tcl_Obj *CONST objv[]; /* Argument objects. */{ int result; Tcl_Obj *objPtr; Tcl_Preserve((ClientData) slaveInterp); Tcl_AllowExceptions(slaveInterp); if (objc == 1) { result = Tcl_EvalObjEx(slaveInterp, objv[0], 0); } else { objPtr = Tcl_ConcatObj(objc, objv); Tcl_IncrRefCount(objPtr); result = Tcl_EvalObjEx(slaveInterp, objPtr, 0); Tcl_DecrRefCount(objPtr); } TclTransferResult(slaveInterp, result, interp); Tcl_Release((ClientData) slaveInterp); return result;}/* *---------------------------------------------------------------------- * * SlaveExpose -- * * Helper function to expose a command in a slave interpreter. * * Results: * A standard Tcl result. * * Side effects: * After this call scripts in the slave will be able to invoke * the newly exposed command. * *---------------------------------------------------------------------- */static intSlaveExpose(interp, slaveInterp, objc, objv) Tcl_Interp *interp; /* Interp for error return. */ Tcl_Interp *slaveInterp; /* Interp in which command will be exposed. */ int objc; /* Number of arguments. */ Tcl_Obj *CONST objv[]; /* Argument strings. */{ char *name; if (Tcl_IsSafe(interp)) { Tcl_AppendStringsToObj(Tcl_GetObjResult(interp), "permission denied: safe interpreter cannot expose commands", (char *) NULL); return TCL_ERROR; } name = Tcl_GetString(objv[(objc == 1) ? 0 : 1]); if (Tcl_ExposeCommand(slaveInterp, Tcl_GetString(objv[0]), name) != TCL_OK) { TclTransferResult(slaveInterp, TCL_ERROR, interp); return TCL_ERROR; } return TCL_OK;}/* *---------------------------------------------------------------------- * * SlaveRecursionLimit -- * * Helper function to set/query the Recursion limit of an interp * * Results: * A standard Tcl result. * * Side effects: * When (objc == 1), slaveInterp will be set to a new recursion * limit of objv[0]. * *---------------------------------------------------------------------- */static intSlaveRecursionLimit(interp, slaveInterp, objc, objv) Tcl_Interp *interp; /* Interp for error return. */ Tcl_Interp *slaveInterp; /* Interp in which limit is set/queried. */ int objc; /* Set or Query. */ Tcl_Obj *CONST objv[]; /* Argument strings. */{ Interp *iPtr; int limit; if (objc) { if (Tcl_IsSafe(interp)) { Tcl_AppendStringsToObj(Tcl_GetObjResult(interp), "permission denied: ", "safe interpreters cannot change recursion limit", (char *) NULL); return TCL_ERROR; } if (Tcl_GetIntFromObj(interp, objv[0], &limit) == TCL_ERROR) { return TCL_ERROR; } if (limit <= 0) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "recursion limit must be > 0", -1)); return TCL_ERROR; } Tcl_SetRecursionLimit(slaveInterp, limit); iPtr = (Interp *) slaveInterp; if (interp == slaveInterp && iPtr->numLevels > limit) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "falling back due to new recursion limit", -1)); return TCL_ERROR; } Tcl_SetObjResult(interp, objv[0]); return TCL_OK; } else { limit = Tcl_SetRecursionLimit(slaveInterp, 0); Tcl_SetObjResult(interp, Tcl_NewIntObj(limit)); return TCL_OK; }}/* *---------------------------------------------------------------------- * * SlaveHide -- * * Helper function to hide a command in a slave interpreter. * * Results: * A standard Tcl result. * * Side effects: * After this call scripts in the slave will no longer be able * to invoke the named command. * *---------------------------------------------------------------------- */static intSlaveHide(interp, slaveInterp, objc, objv) Tcl_Interp *interp; /* Interp for error return. */ Tcl_Interp *slaveInterp; /* Interp in which command will be exposed. */ int objc; /* Number of arguments. */ Tcl_Obj *CONST objv[]; /* Argument strings. */{ char *name; if (Tcl_IsSafe(interp)) { Tcl_AppendStringsToObj(Tcl_GetObjResult(interp), "permission denied: safe interpreter cannot hide commands", (char *) NULL); return TCL_ERROR; } name = Tcl_GetString(objv[(objc == 1) ? 0 : 1]); if (Tcl_HideCommand(slaveInterp, Tcl_GetString(objv[0]), name) != TCL_OK) { TclTransferResult(slaveInterp, TCL_ERROR, interp); return TCL_ERROR; } return TCL_OK;}/* *---------------------------------------------------------------------- * * SlaveHidden -- * * Helper function to compute list of hidden commands in a slave * interpreter. * * Results: * A standard Tcl result. * * Side effects: * None. * *---------------------------------
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?