📄 tclcmdil.c
字号:
* Returns TCL_OK is successful and TCL_ERROR is there is an error. * * Side effects: * Returns a result in the interpreter's result object. If there is * an error, the result is an error message. * *---------------------------------------------------------------------- */static intInfoArgsCmd(dummy, interp, objc, objv) ClientData dummy; /* Not used. */ Tcl_Interp *interp; /* Current interpreter. */ int objc; /* Number of arguments. */ Tcl_Obj *CONST objv[]; /* Argument objects. */{ register Interp *iPtr = (Interp *) interp; char *name; Proc *procPtr; CompiledLocal *localPtr; Tcl_Obj *listObjPtr; if (objc != 3) { Tcl_WrongNumArgs(interp, 2, objv, "procname"); return TCL_ERROR; } name = Tcl_GetStringFromObj(objv[2], (int *) NULL); procPtr = TclFindProc(iPtr, name); if (procPtr == NULL) { Tcl_AppendStringsToObj(Tcl_GetObjResult(interp), "\"", name, "\" isn't a procedure", (char *) NULL); return TCL_ERROR; } /* * Build a return list containing the arguments. */ listObjPtr = Tcl_NewListObj(0, (Tcl_Obj **) NULL); for (localPtr = procPtr->firstLocalPtr; localPtr != NULL; localPtr = localPtr->nextPtr) { if (TclIsVarArgument(localPtr)) { Tcl_ListObjAppendElement(interp, listObjPtr, Tcl_NewStringObj(localPtr->name, -1)); } } Tcl_SetObjResult(interp, listObjPtr); return TCL_OK;}/* *---------------------------------------------------------------------- * * InfoBodyCmd -- * * Called to implement the "info body" command that returns the body * for a procedure. Handles the following syntax: * * info body procName * * Results: * Returns TCL_OK is successful and TCL_ERROR is there is an error. * * Side effects: * Returns a result in the interpreter's result object. If there is * an error, the result is an error message. * *---------------------------------------------------------------------- */static intInfoBodyCmd(dummy, interp, objc, objv) ClientData dummy; /* Not used. */ Tcl_Interp *interp; /* Current interpreter. */ int objc; /* Number of arguments. */ Tcl_Obj *CONST objv[]; /* Argument objects. */{ register Interp *iPtr = (Interp *) interp; char *name; Proc *procPtr; Tcl_Obj *bodyPtr, *resultPtr; if (objc != 3) { Tcl_WrongNumArgs(interp, 2, objv, "procname"); return TCL_ERROR; } name = Tcl_GetStringFromObj(objv[2], (int *) NULL); procPtr = TclFindProc(iPtr, name); if (procPtr == NULL) { Tcl_AppendStringsToObj(Tcl_GetObjResult(interp), "\"", name, "\" isn't a procedure", (char *) NULL); return TCL_ERROR; } /* * we need to check if the body from this procedure had been generated * from a precompiled body. If that is the case, then the bodyPtr's * string representation is bogus, since sources are not available. * In order to make sure that later manipulations of the object do not * invalidate the internal representation, we make a copy of the string * representation and return that one, instead. */ bodyPtr = procPtr->bodyPtr; resultPtr = bodyPtr; if (bodyPtr->typePtr == &tclByteCodeType) { ByteCode *codePtr = (ByteCode *) bodyPtr->internalRep.otherValuePtr; if (codePtr->flags & TCL_BYTECODE_PRECOMPILED) { resultPtr = Tcl_NewStringObj(bodyPtr->bytes, bodyPtr->length); } } Tcl_SetObjResult(interp, resultPtr); return TCL_OK;}/* *---------------------------------------------------------------------- * * InfoCmdCountCmd -- * * Called to implement the "info cmdcount" command that returns the * number of commands that have been executed. Handles the following * syntax: * * info cmdcount * * Results: * Returns TCL_OK is successful and TCL_ERROR is there is an error. * * Side effects: * Returns a result in the interpreter's result object. If there is * an error, the result is an error message. * *---------------------------------------------------------------------- */static intInfoCmdCountCmd(dummy, interp, objc, objv) ClientData dummy; /* Not used. */ Tcl_Interp *interp; /* Current interpreter. */ int objc; /* Number of arguments. */ Tcl_Obj *CONST objv[]; /* Argument objects. */{ Interp *iPtr = (Interp *) interp; if (objc != 2) { Tcl_WrongNumArgs(interp, 2, objv, NULL); return TCL_ERROR; } Tcl_SetIntObj(Tcl_GetObjResult(interp), iPtr->cmdCount); return TCL_OK;}/* *---------------------------------------------------------------------- * * InfoCommandsCmd -- * * Called to implement the "info commands" command that returns the * list of commands in the interpreter that match an optional pattern. * The pattern, if any, consists of an optional sequence of namespace * names separated by "::" qualifiers, which is followed by a * glob-style pattern that restricts which commands are returned. * Handles the following syntax: * * info commands ?pattern? * * Results: * Returns TCL_OK is successful and TCL_ERROR is there is an error. * * Side effects: * Returns a result in the interpreter's result object. If there is * an error, the result is an error message. * *---------------------------------------------------------------------- */static intInfoCommandsCmd(dummy, interp, objc, objv) ClientData dummy; /* Not used. */ Tcl_Interp *interp; /* Current interpreter. */ int objc; /* Number of arguments. */ Tcl_Obj *CONST objv[]; /* Argument objects. */{ char *cmdName, *pattern, *simplePattern; register Tcl_HashEntry *entryPtr; Tcl_HashSearch search; Namespace *nsPtr; Namespace *globalNsPtr = (Namespace *) Tcl_GetGlobalNamespace(interp); Namespace *currNsPtr = (Namespace *) Tcl_GetCurrentNamespace(interp); Tcl_Obj *listPtr, *elemObjPtr; int specificNsInPattern = 0; /* Init. to avoid compiler warning. */ Tcl_Command cmd; int result; /* * Get the pattern and find the "effective namespace" in which to * list commands. */ if (objc == 2) { simplePattern = NULL; nsPtr = currNsPtr; specificNsInPattern = 0; } else if (objc == 3) { /* * From the pattern, get the effective namespace and the simple * pattern (no namespace qualifiers or ::'s) at the end. If an * error was found while parsing the pattern, return it. Otherwise, * if the namespace wasn't found, just leave nsPtr NULL: we will * return an empty list since no commands there can be found. */ Namespace *dummy1NsPtr, *dummy2NsPtr; pattern = Tcl_GetStringFromObj(objv[2], (int *) NULL); result = TclGetNamespaceForQualName(interp, pattern, (Namespace *) NULL, /*flags*/ TCL_LEAVE_ERR_MSG, &nsPtr, &dummy1NsPtr, &dummy2NsPtr, &simplePattern); if (result != TCL_OK) { return TCL_ERROR; } if (nsPtr != NULL) { /* we successfully found the pattern's ns */ specificNsInPattern = (strcmp(simplePattern, pattern) != 0); } } else { Tcl_WrongNumArgs(interp, 2, objv, "?pattern?"); return TCL_ERROR; } /* * Scan through the effective namespace's command table and create a * list with all commands that match the pattern. If a specific * namespace was requested in the pattern, qualify the command names * with the namespace name. */ listPtr = Tcl_NewListObj(0, (Tcl_Obj **) NULL); if (nsPtr != NULL) { entryPtr = Tcl_FirstHashEntry(&nsPtr->cmdTable, &search); while (entryPtr != NULL) { cmdName = Tcl_GetHashKey(&nsPtr->cmdTable, entryPtr); if ((simplePattern == NULL) || Tcl_StringMatch(cmdName, simplePattern)) { if (specificNsInPattern) { cmd = (Tcl_Command) Tcl_GetHashValue(entryPtr); elemObjPtr = Tcl_NewObj(); Tcl_GetCommandFullName(interp, cmd, elemObjPtr); } else { elemObjPtr = Tcl_NewStringObj(cmdName, -1); } Tcl_ListObjAppendElement(interp, listPtr, elemObjPtr); } entryPtr = Tcl_NextHashEntry(&search); } /* * If the effective namespace isn't the global :: namespace, and a * specific namespace wasn't requested in the pattern, then add in * all global :: commands that match the simple pattern. Of course, * we add in only those commands that aren't hidden by a command in * the effective namespace. */ if ((nsPtr != globalNsPtr) && !specificNsInPattern) { entryPtr = Tcl_FirstHashEntry(&globalNsPtr->cmdTable, &search); while (entryPtr != NULL) { cmdName = Tcl_GetHashKey(&globalNsPtr->cmdTable, entryPtr); if ((simplePattern == NULL) || Tcl_StringMatch(cmdName, simplePattern)) { if (Tcl_FindHashEntry(&nsPtr->cmdTable, cmdName) == NULL) { Tcl_ListObjAppendElement(interp, listPtr, Tcl_NewStringObj(cmdName, -1)); } } entryPtr = Tcl_NextHashEntry(&search); } } } Tcl_SetObjResult(interp, listPtr); return TCL_OK;}/* *---------------------------------------------------------------------- * * InfoCompleteCmd -- * * Called to implement the "info complete" command that determines * whether a string is a complete Tcl command. Handles the following * syntax: * * info complete command * * Results: * Returns TCL_OK is successful and TCL_ERROR is there is an error. * * Side effects: * Returns a result in the interpreter's result object. If there is * an error, the result is an error message. * *---------------------------------------------------------------------- */static intInfoCompleteCmd(dummy, interp, objc, objv) ClientData dummy; /* Not used. */ Tcl_Interp *interp; /* Current interpreter. */ int objc; /* Number of arguments. */ Tcl_Obj *CONST objv[]; /* Argument objects. */{ char *command; if (objc != 3) { Tcl_WrongNumArgs(interp, 2, objv, "command"); return TCL_ERROR; } command = Tcl_GetStringFromObj(objv[2], (int *) NULL); if (Tcl_CommandComplete(command)) { Tcl_SetIntObj(Tcl_GetObjResult(interp), 1); } else { Tcl_SetIntObj(Tcl_GetObjResult(interp), 0); } return TCL_OK;}/* *---------------------------------------------------------------------- * * InfoDefaultCmd -- * * Called to implement the "info default" command that returns the * default value for a procedure argument. Handles the following * syntax: * * info default procName arg varName * * Results: * Returns TCL_OK is successful and TCL_ERROR is there is an error. * * Side effects: * Returns a result in the interpreter's result object. If there is * an error, the result is an error message. * *---------------------------------------------------------------------- */static intInfoDefaultCmd(dummy, interp, objc, objv) ClientData dummy; /* Not used. */ Tcl_Interp *interp; /* Current interpreter. */ int objc; /* Number of arguments. */ Tcl_Obj *CONST objv[]; /* Argument objects. */{ Interp *iPtr = (Interp *) interp; char *procName, *argName, *varName; Proc *procPtr; CompiledLocal *localPtr; Tcl_Obj *valueObjPtr; if (objc != 5) { Tcl_WrongNumArgs(interp, 2, objv, "procname arg varname"); return TCL_ERROR; } procName = Tcl_GetStringFromObj(objv[2], (int *) NULL); argName = Tcl_GetStringFromObj(objv[3], (int *) NULL); procPtr = TclFindProc(iPtr, procName); if (procPtr == NULL) { Tcl_AppendStringsToObj(Tcl_GetObjResult(interp), "\"", procName, "\" isn't a procedure", (char *) NULL); return TCL_ERROR; } for (localPtr = procPtr->firstLocalPtr; localPtr != NULL; localPtr = localPtr->nextPtr) { if (TclIsVarArgument(localPtr) && (strcmp(argName, localPtr->name) == 0)) { if (localPtr->defValuePtr != NULL) { valueObjPtr = Tcl_ObjSetVar2(interp, objv[4], NULL, localPtr->defValuePtr, 0); if (valueObjPtr == NULL) { defStoreError: varName = Tcl_GetStringFromObj(objv[4], (int *) NULL); Tcl_AppendStringsToObj(Tcl_GetObjResult(interp), "couldn't store default value in variable \"", varName, "\"", (char *) NULL); return TCL_ERROR; } Tcl_SetIntObj(Tcl_GetObjResult(interp), 1); } else { Tcl_Obj *nullObjPtr = Tcl_NewObj(); valueObjPtr = Tcl_ObjSetVar2(interp, objv[4], NULL, nullObjPtr, 0); if (valueObjPtr == NULL) { Tcl_DecrRefCount(nullObjPtr); /* free unneeded obj */ goto defStoreError; } Tcl_SetIntObj(Tcl_GetObjResult(interp), 0); } return TCL_OK; } } Tcl_AppendStringsToObj(Tcl_GetObjResult(interp), "procedure \"", procName, "\" doesn't have an argument \"", argName, "\"", (char *) NULL); return TCL_ERROR;}/* *---------------------------------------------------------------------- * * InfoExistsCmd -- * * Called to implement the "info exists" command that determines * whether a variable exists. Handles the following syntax: * * info exists varName * * Results: * Returns TCL_OK is successful and TCL_ERROR is there is an error. * * Side effects: * Returns a result in the interpreter's result object. If there is * an error, the result is an error message. * *---------------------------------------------------------------------- */static intInfoExistsCmd(dummy, interp, objc, objv) ClientData dummy; /* Not used. */ Tcl_Interp *interp; /* Current interpreter. */ int objc; /* Number of arguments. */ Tcl_Obj *CONST objv[]; /* Argument objects. */{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -