tclproc.c

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

C
1,707
字号
 */static intProcessProcResultCode(interp, procName, nameLen, returnCode)    Tcl_Interp *interp;		/* The interpreter in which the procedure				 * was called and returned returnCode. */    char *procName;		/* Name of the procedure. Used for error				 * messages and trace information. */    int nameLen;		/* Number of bytes in procedure's name. */    int returnCode;		/* The unexpected result code. */{    Interp *iPtr = (Interp *) interp;    char msg[100 + TCL_INTEGER_SPACE];    char *ellipsis = "";    if (returnCode == TCL_OK) {	return TCL_OK;    }    if ((returnCode > TCL_CONTINUE) || (returnCode < TCL_OK)) {	return returnCode;    }    if (returnCode == TCL_RETURN) {	return TclUpdateReturnInfo(iPtr);    }     if (returnCode != TCL_ERROR) {	Tcl_ResetResult(interp);	Tcl_AppendToObj(Tcl_GetObjResult(interp), ((returnCode == TCL_BREAK) 		? "invoked \"break\" outside of a loop"		: "invoked \"continue\" outside of a loop"), -1);    }    if (nameLen > 60) {	nameLen = 60;	ellipsis = "...";    }    sprintf(msg, "\n    (procedure \"%.*s%s\" line %d)", nameLen, procName,	    ellipsis, iPtr->errorLine);    Tcl_AddObjErrorInfo(interp, msg, -1);    return TCL_ERROR;}/* *---------------------------------------------------------------------- * * TclProcDeleteProc -- * *	This procedure is invoked just before a command procedure is *	removed from an interpreter.  Its job is to release all the *	resources allocated to the procedure. * * Results: *	None. * * Side effects: *	Memory gets freed, unless the procedure is actively being *	executed.  In this case the cleanup is delayed until the *	last call to the current procedure completes. * *---------------------------------------------------------------------- */voidTclProcDeleteProc(clientData)    ClientData clientData;		/* Procedure to be deleted. */{    Proc *procPtr = (Proc *) clientData;    procPtr->refCount--;    if (procPtr->refCount <= 0) {	TclProcCleanupProc(procPtr);    }}/* *---------------------------------------------------------------------- * * TclProcCleanupProc -- * *	This procedure does all the real work of freeing up a Proc *	structure.  It's called only when the structure's reference *	count becomes zero. * * Results: *	None. * * Side effects: *	Memory gets freed. * *---------------------------------------------------------------------- */voidTclProcCleanupProc(procPtr)    register Proc *procPtr;		/* Procedure to be deleted. */{    register CompiledLocal *localPtr;    Tcl_Obj *bodyPtr = procPtr->bodyPtr;    Tcl_Obj *defPtr;    Tcl_ResolvedVarInfo *resVarInfo;    if (bodyPtr != NULL) {	Tcl_DecrRefCount(bodyPtr);    }    for (localPtr = procPtr->firstLocalPtr;  localPtr != NULL;  ) {	CompiledLocal *nextPtr = localPtr->nextPtr;        resVarInfo = localPtr->resolveInfo;	if (resVarInfo) {	    if (resVarInfo->deleteProc) {		(*resVarInfo->deleteProc)(resVarInfo);	    } else {		ckfree((char *) resVarInfo);	    }        }	if (localPtr->defValuePtr != NULL) {	    defPtr = localPtr->defValuePtr;	    Tcl_DecrRefCount(defPtr);	}	ckfree((char *) localPtr);	localPtr = nextPtr;    }    ckfree((char *) procPtr);}/* *---------------------------------------------------------------------- * * TclUpdateReturnInfo -- * *	This procedure is called when procedures return, and at other *	points where the TCL_RETURN code is used.  It examines fields *	such as iPtr->returnCode and iPtr->errorCode and modifies *	the real return status accordingly. * * Results: *	The return value is the true completion code to use for *	the procedure, instead of TCL_RETURN. * * Side effects: *	The errorInfo and errorCode variables may get modified. * *---------------------------------------------------------------------- */intTclUpdateReturnInfo(iPtr)    Interp *iPtr;		/* Interpreter for which TCL_RETURN				 * exception is being processed. */{    int code;    char *errorCode;    code = iPtr->returnCode;    iPtr->returnCode = TCL_OK;    if (code == TCL_ERROR) {	errorCode = ((iPtr->errorCode != NULL) ? iPtr->errorCode : "NONE");	Tcl_ObjSetVar2((Tcl_Interp *) iPtr, iPtr->execEnvPtr->errorCode,	        NULL, Tcl_NewStringObj(errorCode, -1),		TCL_GLOBAL_ONLY);	iPtr->flags |= ERROR_CODE_SET;	if (iPtr->errorInfo != NULL) {	    Tcl_ObjSetVar2((Tcl_Interp *) iPtr, iPtr->execEnvPtr->errorInfo,	            NULL, Tcl_NewStringObj(iPtr->errorInfo, -1),		    TCL_GLOBAL_ONLY);	    iPtr->flags |= ERR_IN_PROGRESS;	}    }    return code;}/* *---------------------------------------------------------------------- * * TclGetInterpProc -- * *  Returns a pointer to the TclProcInterpProc procedure; this is different *  from the value obtained from the TclProcInterpProc reference on systems *  like Windows where import and export versions of a procedure exported *  by a DLL exist. * * Results: *  Returns the internal address of the TclProcInterpProc procedure. * * Side effects: *  None. * *---------------------------------------------------------------------- */TclCmdProcTypeTclGetInterpProc(){    return (TclCmdProcType) TclProcInterpProc;}/* *---------------------------------------------------------------------- * * TclGetObjInterpProc -- * *  Returns a pointer to the TclObjInterpProc procedure; this is different *  from the value obtained from the TclObjInterpProc reference on systems *  like Windows where import and export versions of a procedure exported *  by a DLL exist. * * Results: *  Returns the internal address of the TclObjInterpProc procedure. * * Side effects: *  None. * *---------------------------------------------------------------------- */TclObjCmdProcTypeTclGetObjInterpProc(){    return (TclObjCmdProcType) TclObjInterpProc;}/* *---------------------------------------------------------------------- * * TclNewProcBodyObj -- * *  Creates a new object, of type "procbody", whose internal *  representation is the given Proc struct. *  The newly created object's reference count is 0. * * Results: *  Returns a pointer to a newly allocated Tcl_Obj, 0 on error. * * Side effects: *  The reference count in the ByteCode attached to the Proc is bumped up *  by one, since the internal rep stores a pointer to it. * *---------------------------------------------------------------------- */Tcl_Obj *TclNewProcBodyObj(procPtr)    Proc *procPtr;	/* the Proc struct to store as the internal                         * representation. */{    Tcl_Obj *objPtr;    if (!procPtr) {        return (Tcl_Obj *) NULL;    }        objPtr = Tcl_NewStringObj("", 0);    if (objPtr) {        objPtr->typePtr = &tclProcBodyType;        objPtr->internalRep.otherValuePtr = (VOID *) procPtr;        procPtr->refCount++;    }    return objPtr;}/* *---------------------------------------------------------------------- * * ProcBodyDup -- * *  Tcl_ObjType's Dup function for the proc body object. *  Bumps the reference count on the Proc stored in the internal *  representation. * * Results: *  None. * * Side effects: *  Sets up the object in dupPtr to be a duplicate of the one in srcPtr. * *---------------------------------------------------------------------- */static void ProcBodyDup(srcPtr, dupPtr)    Tcl_Obj *srcPtr;		/* object to copy */    Tcl_Obj *dupPtr;		/* target object for the duplication */{    Proc *procPtr = (Proc *) srcPtr->internalRep.otherValuePtr;        dupPtr->typePtr = &tclProcBodyType;    dupPtr->internalRep.otherValuePtr = (VOID *) procPtr;    procPtr->refCount++;}/* *---------------------------------------------------------------------- * * ProcBodyFree -- * *  Tcl_ObjType's Free function for the proc body object. *  The reference count on its Proc struct is decreased by 1; if the count *  reaches 0, the proc is freed. * * Results: *  None. * * Side effects: *  If the reference count on the Proc struct reaches 0, the struct is freed. * *---------------------------------------------------------------------- */static voidProcBodyFree(objPtr)    Tcl_Obj *objPtr;		/* the object to clean up */{    Proc *procPtr = (Proc *) objPtr->internalRep.otherValuePtr;    procPtr->refCount--;    if (procPtr->refCount <= 0) {        TclProcCleanupProc(procPtr);    }}/* *---------------------------------------------------------------------- * * ProcBodySetFromAny -- * *  Tcl_ObjType's SetFromAny function for the proc body object. *  Calls panic. * * Results: *  Theoretically returns a TCL result code. * * Side effects: *  Calls panic, since we can't set the value of the object from a string *  representation (or any other internal ones). * *---------------------------------------------------------------------- */static intProcBodySetFromAny(interp, objPtr)    Tcl_Interp *interp;			/* current interpreter */    Tcl_Obj *objPtr;			/* object pointer */{    panic("called ProcBodySetFromAny");    /*     * this to keep compilers happy.     */        return TCL_OK;}/* *---------------------------------------------------------------------- * * ProcBodyUpdateString -- * *  Tcl_ObjType's UpdateString function for the proc body object. *  Calls panic. * * Results: *  None. * * Side effects: *  Calls panic, since we this type has no string representation. * *---------------------------------------------------------------------- */static voidProcBodyUpdateString(objPtr)    Tcl_Obj *objPtr;		/* the object to update */{    panic("called ProcBodyUpdateString");}/* *---------------------------------------------------------------------- * * TclCompileNoOp -- * *	Procedure called to compile noOp's * * Results: *	The return value is TCL_OK, indicating successful compilation. * * Side effects: *	Instructions are added to envPtr to execute a noOp at runtime. * *---------------------------------------------------------------------- */static intTclCompileNoOp(interp, parsePtr, envPtr)    Tcl_Interp *interp;         /* Used for error reporting. */    Tcl_Parse *parsePtr;        /* Points to a parse structure for the                                 * command created by Tcl_ParseCommand. */    CompileEnv *envPtr;         /* Holds resulting instructions. */{    Tcl_Token *tokenPtr;    int i, code;    int savedStackDepth = envPtr->currStackDepth;    tokenPtr = parsePtr->tokenPtr;    for(i = 1; i < parsePtr->numWords; i++) {	tokenPtr = tokenPtr + tokenPtr->numComponents + 1;	envPtr->currStackDepth = savedStackDepth;	if (tokenPtr->type != TCL_TOKEN_SIMPLE_WORD) { 	    code = TclCompileTokens(interp, tokenPtr+1,	            tokenPtr->numComponents, envPtr);	    if (code != TCL_OK) {		return code;	    }	    TclEmitOpcode(INST_POP, envPtr);	}     }    envPtr->currStackDepth = savedStackDepth;    TclEmitPush(TclRegisterLiteral(envPtr, "", 0, /*onHeap*/ 0), envPtr);    return TCL_OK;}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?