tclcmdil.c

来自「tcl是工具命令语言」· C语言 代码 · 共 2,174 行 · 第 1/5 页

C
2,174
字号
 *	an error, the result is an error message. * *---------------------------------------------------------------------- */static intInfoLocalsCmd(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 *pattern;    Tcl_Obj *listPtr;    if (objc == 2) {        pattern = NULL;    } else if (objc == 3) {        pattern = Tcl_GetString(objv[2]);    } else {        Tcl_WrongNumArgs(interp, 2, objv, "?pattern?");        return TCL_ERROR;    }        if (iPtr->varFramePtr == NULL || !iPtr->varFramePtr->isProcCallFrame) {        return TCL_OK;    }    /*     * Return a list containing names of first the compiled locals (i.e. the     * ones stored in the call frame), then the variables in the local hash     * table (if one exists).     */        listPtr = Tcl_NewListObj(0, (Tcl_Obj **) NULL);    AppendLocals(interp, listPtr, pattern, 0);    Tcl_SetObjResult(interp, listPtr);    return TCL_OK;}/* *---------------------------------------------------------------------- * * AppendLocals -- * *	Append the local variables for the current frame to the *	specified list object. * * Results: *	None. * * Side effects: *	None. * *---------------------------------------------------------------------- */static voidAppendLocals(interp, listPtr, pattern, includeLinks)    Tcl_Interp *interp;		/* Current interpreter. */    Tcl_Obj *listPtr;		/* List object to append names to. */    CONST char *pattern;	/* Pattern to match against. */    int includeLinks;		/* 1 if upvars should be included, else 0. */{    Interp *iPtr = (Interp *) interp;    CompiledLocal *localPtr;    Var *varPtr;    int i, localVarCt;    char *varName;    Tcl_HashTable *localVarTablePtr;    register Tcl_HashEntry *entryPtr;    Tcl_HashSearch search;    localPtr = iPtr->varFramePtr->procPtr->firstLocalPtr;    localVarCt = iPtr->varFramePtr->numCompiledLocals;    varPtr = iPtr->varFramePtr->compiledLocals;    localVarTablePtr = iPtr->varFramePtr->varTablePtr;    for (i = 0; i < localVarCt; i++) {	/*	 * Skip nameless (temporary) variables and undefined variables	 */	if (!TclIsVarTemporary(localPtr) && !TclIsVarUndefined(varPtr)	        && (includeLinks || !TclIsVarLink(varPtr))) {	    varName = varPtr->name;	    if ((pattern == NULL) || Tcl_StringMatch(varName, pattern)) {		Tcl_ListObjAppendElement(interp, listPtr,		        Tcl_NewStringObj(varName, -1));	    }        }	varPtr++;	localPtr = localPtr->nextPtr;    }        if (localVarTablePtr != NULL) {	for (entryPtr = Tcl_FirstHashEntry(localVarTablePtr, &search);	        entryPtr != NULL;                entryPtr = Tcl_NextHashEntry(&search)) {	    varPtr = (Var *) Tcl_GetHashValue(entryPtr);	    if (!TclIsVarUndefined(varPtr)		    && (includeLinks || !TclIsVarLink(varPtr))) {		varName = Tcl_GetHashKey(localVarTablePtr, entryPtr);		if ((pattern == NULL)		        || Tcl_StringMatch(varName, pattern)) {		    Tcl_ListObjAppendElement(interp, listPtr,			    Tcl_NewStringObj(varName, -1));		}	    }	}    }}/* *---------------------------------------------------------------------- * * InfoNameOfExecutableCmd -- * *      Called to implement the "info nameofexecutable" command that returns *      the name of the binary file running this application. Handles the *      following syntax: * *          info nameofexecutable * * Results: *      Returns TCL_OK if successful and TCL_ERROR if 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 intInfoNameOfExecutableCmd(dummy, interp, objc, objv)    ClientData dummy;		/* Not used. */    Tcl_Interp *interp;		/* Current interpreter. */    int objc;			/* Number of arguments. */    Tcl_Obj *CONST objv[];	/* Argument objects. */{    CONST char *nameOfExecutable;    if (objc != 2) {        Tcl_WrongNumArgs(interp, 2, objv, NULL);        return TCL_ERROR;    }    nameOfExecutable = Tcl_GetNameOfExecutable();        if (nameOfExecutable != NULL) {	Tcl_SetStringObj(Tcl_GetObjResult(interp), nameOfExecutable, -1);    }    return TCL_OK;}/* *---------------------------------------------------------------------- * * InfoPatchLevelCmd -- * *      Called to implement the "info patchlevel" command that returns the *      default value for an argument to a procedure. Handles the following *      syntax: * *          info patchlevel * * Results: *      Returns TCL_OK if successful and TCL_ERROR if 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 intInfoPatchLevelCmd(dummy, interp, objc, objv)    ClientData dummy;		/* Not used. */    Tcl_Interp *interp;		/* Current interpreter. */    int objc;			/* Number of arguments. */    Tcl_Obj *CONST objv[];	/* Argument objects. */{    CONST char *patchlevel;    if (objc != 2) {        Tcl_WrongNumArgs(interp, 2, objv, NULL);        return TCL_ERROR;    }    patchlevel = Tcl_GetVar(interp, "tcl_patchLevel",            (TCL_GLOBAL_ONLY | TCL_LEAVE_ERR_MSG));    if (patchlevel != NULL) {        Tcl_SetStringObj(Tcl_GetObjResult(interp), patchlevel, -1);        return TCL_OK;    }    return TCL_ERROR;}/* *---------------------------------------------------------------------- * * InfoProcsCmd -- * *	Called to implement the "info procs" command that returns the *	list of procedures 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 procs ?pattern? * * Results: *      Returns TCL_OK if successful and TCL_ERROR if 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 intInfoProcsCmd(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;    CONST char *simplePattern;    Namespace *nsPtr;#ifdef INFO_PROCS_SEARCH_GLOBAL_NS    Namespace *globalNsPtr = (Namespace *) Tcl_GetGlobalNamespace(interp);#endif    Namespace *currNsPtr   = (Namespace *) Tcl_GetCurrentNamespace(interp);    Tcl_Obj *listPtr, *elemObjPtr;    int specificNsInPattern = 0;  /* Init. to avoid compiler warning. */    register Tcl_HashEntry *entryPtr;    Tcl_HashSearch search;    Command *cmdPtr, *realCmdPtr;    /*     * Get the pattern and find the "effective namespace" in which to     * list procs.     */    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_GetString(objv[2]);	TclGetNamespaceForQualName(interp, pattern, (Namespace *) NULL,		/*flags*/ 0, &nsPtr, &dummy1NsPtr, &dummy2NsPtr,		&simplePattern);	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 procs 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)) {		cmdPtr = (Command *) Tcl_GetHashValue(entryPtr);		realCmdPtr = (Command *)		    TclGetOriginalCommand((Tcl_Command) cmdPtr);		if (TclIsProc(cmdPtr)		        || ((realCmdPtr != NULL) && TclIsProc(realCmdPtr))) {		    if (specificNsInPattern) {			elemObjPtr = Tcl_NewObj();			Tcl_GetCommandFullName(interp, (Tcl_Command) cmdPtr,				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 :: procs that match the simple pattern. Of course,	 * we add in only those procs that aren't hidden by a proc in	 * the effective namespace.	 */#ifdef INFO_PROCS_SEARCH_GLOBAL_NS	/*	 * If "info procs" worked like "info commands", returning the	 * commands also seen in the global namespace, then you would	 * include this code.  As this could break backwards compatibilty	 * with 8.0-8.2, we decided not to "fix" it in 8.3, leaving the	 * behavior slightly different.	 */	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) {			cmdPtr = (Command *) Tcl_GetHashValue(entryPtr);			realCmdPtr = (Command *) TclGetOriginalCommand(			        (Tcl_Command) cmdPtr);			if (TclIsProc(cmdPtr) || ((realCmdPtr != NULL)				&& TclIsProc(realCmdPtr))) {			    Tcl_ListObjAppendElement(interp, listPtr,			            Tcl_NewStringObj(cmdName, -1));			}		    }		}		entryPtr = Tcl_NextHashEntry(&search);	    }	}#endif    }    Tcl_SetObjResult(interp, listPtr);    return TCL_OK;}/* *---------------------------------------------------------------------- * * InfoScriptCmd -- * *      Called to implement the "info script" command that returns the *      script file that is currently being evaluated. Handles the *      following syntax: * *          info script ?newName? * *	If newName is specified, it will set that as the internal name. * * Results: *      Returns TCL_OK if successful and TCL_ERROR if 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.  It may change the *	internal script filename. * *---------------------------------------------------------------------- */static intInfoScriptCmd(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) && (objc != 3)) {        Tcl_WrongNumArgs(interp, 2, objv, "?filename?");        return TCL_ERROR;    }    if (objc == 3) {	if (iPtr->scriptFile != NULL) {	    Tcl_DecrRefCount(iPtr->scriptFile);	}	iPtr->scriptFile = objv[2];	Tcl_IncrRefCount(iPtr->scriptFile);    }    if (iPtr->scriptFile != NULL) {        Tcl_SetObjResult(interp, iPtr->scriptFile);    }    return TCL_OK;}/* *---------------------------------------------------------------------- * * InfoSharedlibCmd -- * *      Called to implement the "info sharedlibextension" command that *      returns the file extension used for shared libraries. Handles the *      following syntax: * *          info sharedlibextension * * Results: *      Returns TCL_OK if successful and TCL_ERROR if 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 intInfoSharedlibCmd(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 + =
减小字号Ctrl + -
显示快捷键?