tclcmdah.c

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

C
2,394
字号
		Tcl_SetStringObj(Tcl_GetObjResult(interp),			Tcl_DStringValue(&ds), Tcl_DStringLength(&ds));		Tcl_DStringFree(&ds);	    } else {		/*		 * Store the result as binary data.		 */		string = Tcl_GetStringFromObj(data, &length);		Tcl_UtfToExternalDString(encoding, string, length, &ds);		resultPtr = Tcl_GetObjResult(interp);		Tcl_SetByteArrayObj(resultPtr, 			(unsigned char *) Tcl_DStringValue(&ds),			Tcl_DStringLength(&ds));		Tcl_DStringFree(&ds);	    }	    Tcl_FreeEncoding(encoding);	    break;	}	case ENC_NAMES: {	    if (objc > 2) {		Tcl_WrongNumArgs(interp, 2, objv, NULL);		return TCL_ERROR;	    }	    Tcl_GetEncodingNames(interp);	    break;	}	case ENC_SYSTEM: {	    if (objc > 3) {		Tcl_WrongNumArgs(interp, 2, objv, "?encoding?");		return TCL_ERROR;	    }	    if (objc == 2) {		Tcl_SetStringObj(Tcl_GetObjResult(interp),			Tcl_GetEncodingName(NULL), -1);	    } else {	        return Tcl_SetSystemEncoding(interp,			Tcl_GetStringFromObj(objv[2], NULL));	    }	    break;	}    }    return TCL_OK;}/* *---------------------------------------------------------------------- * * Tcl_ErrorObjCmd -- * *	This procedure is invoked to process the "error" Tcl command. *	See the user documentation for details on what it does. * * Results: *	A standard Tcl object result. * * Side effects: *	See the user documentation. * *---------------------------------------------------------------------- */	/* ARGSUSED */intTcl_ErrorObjCmd(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 *info;    int infoLen;    if ((objc < 2) || (objc > 4)) {	Tcl_WrongNumArgs(interp, 1, objv, "message ?errorInfo? ?errorCode?");	return TCL_ERROR;    }        if (objc >= 3) {		/* process the optional info argument */	info = Tcl_GetStringFromObj(objv[2], &infoLen);	if (*info != 0) {	    Tcl_AddObjErrorInfo(interp, info, infoLen);	    iPtr->flags |= ERR_ALREADY_LOGGED;	}    }        if (objc == 4) {	Tcl_SetVar2Ex(interp, "errorCode", NULL, objv[3], TCL_GLOBAL_ONLY);	iPtr->flags |= ERROR_CODE_SET;    }        Tcl_SetObjResult(interp, objv[1]);    return TCL_ERROR;}/* *---------------------------------------------------------------------- * * Tcl_EvalObjCmd -- * *	This object-based procedure is invoked to process the "eval" Tcl  *	command. See the user documentation for details on what it does. * * Results: *	A standard Tcl object result. * * Side effects: *	See the user documentation. * *---------------------------------------------------------------------- */	/* ARGSUSED */intTcl_EvalObjCmd(dummy, interp, objc, objv)    ClientData dummy;		/* Not used. */    Tcl_Interp *interp;		/* Current interpreter. */    int objc;			/* Number of arguments. */    Tcl_Obj *CONST objv[];	/* Argument objects. */{    int result;    register Tcl_Obj *objPtr;    if (objc < 2) {	Tcl_WrongNumArgs(interp, 1, objv, "arg ?arg ...?");	return TCL_ERROR;    }        if (objc == 2) {	result = Tcl_EvalObjEx(interp, objv[1], TCL_EVAL_DIRECT);    } else {	/*	 * More than one argument: concatenate them together with spaces	 * between, then evaluate the result.  Tcl_EvalObjEx will delete	 * the object when it decrements its refcount after eval'ing it.	 */    	objPtr = Tcl_ConcatObj(objc-1, objv+1);	result = Tcl_EvalObjEx(interp, objPtr, TCL_EVAL_DIRECT);    }    if (result == TCL_ERROR) {	char msg[32 + TCL_INTEGER_SPACE];	sprintf(msg, "\n    (\"eval\" body line %d)", interp->errorLine);	Tcl_AddObjErrorInfo(interp, msg, -1);    }    return result;}/* *---------------------------------------------------------------------- * * Tcl_ExitObjCmd -- * *	This procedure is invoked to process the "exit" Tcl command. *	See the user documentation for details on what it does. * * Results: *	A standard Tcl object result. * * Side effects: *	See the user documentation. * *---------------------------------------------------------------------- */	/* ARGSUSED */intTcl_ExitObjCmd(dummy, interp, objc, objv)    ClientData dummy;		/* Not used. */    Tcl_Interp *interp;		/* Current interpreter. */    int objc;			/* Number of arguments. */    Tcl_Obj *CONST objv[];	/* Argument objects. */{    int value;    if ((objc != 1) && (objc != 2)) {	Tcl_WrongNumArgs(interp, 1, objv, "?returnCode?");	return TCL_ERROR;    }        if (objc == 1) {	value = 0;    } else if (Tcl_GetIntFromObj(interp, objv[1], &value) != TCL_OK) {	return TCL_ERROR;    }    Tcl_Exit(value);    /*NOTREACHED*/    return TCL_OK;			/* Better not ever reach this! */}/* *---------------------------------------------------------------------- * * Tcl_ExprObjCmd -- * *	This object-based procedure is invoked to process the "expr" Tcl *	command. See the user documentation for details on what it does. * *	With the bytecode compiler, this procedure is called in two *	circumstances: 1) to execute expr commands that are too complicated *	or too unsafe to try compiling directly into an inline sequence of *	instructions, and 2) to execute commands where the command name is *	computed at runtime and is "expr" or the name to which "expr" was *	renamed (e.g., "set z expr; $z 2+3") * * Results: *	A standard Tcl object result. * * Side effects: *	See the user documentation. * *---------------------------------------------------------------------- */	/* ARGSUSED */intTcl_ExprObjCmd(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 Tcl_Obj *objPtr;    Tcl_Obj *resultPtr;    register char *bytes;    int length, i, result;    if (objc < 2) {	Tcl_WrongNumArgs(interp, 1, objv, "arg ?arg ...?");	return TCL_ERROR;    }    if (objc == 2) {	result = Tcl_ExprObj(interp, objv[1], &resultPtr);	if (result == TCL_OK) {	    Tcl_SetObjResult(interp, resultPtr);	    Tcl_DecrRefCount(resultPtr);  /* done with the result object */	}	return result;    }    /*     * Create a new object holding the concatenated argument strings.     */    /*** QUESTION: Do we need to copy the slow way? ***/    bytes = Tcl_GetStringFromObj(objv[1], &length);    objPtr = Tcl_NewStringObj(bytes, length);    Tcl_IncrRefCount(objPtr);    for (i = 2;  i < objc;  i++) {	Tcl_AppendToObj(objPtr, " ", 1);	bytes = Tcl_GetStringFromObj(objv[i], &length);	Tcl_AppendToObj(objPtr, bytes, length);    }    /*     * Evaluate the concatenated string object.     */    result = Tcl_ExprObj(interp, objPtr, &resultPtr);    if (result == TCL_OK) {	Tcl_SetObjResult(interp, resultPtr);	Tcl_DecrRefCount(resultPtr);  /* done with the result object */    }    /*     * Free allocated resources.     */        Tcl_DecrRefCount(objPtr);    return result;}/* *---------------------------------------------------------------------- * * Tcl_FileObjCmd -- * *	This procedure is invoked to process the "file" Tcl command. *	See the user documentation for details on what it does. *	PLEASE NOTE THAT THIS FAILS WITH FILENAMES AND PATHS WITH *	EMBEDDED NULLS, WHICH COULD THEORETICALLY HAPPEN ON A MAC. *      With the object-based Tcl_FS APIs, the above NOTE may no *      longer be true.  In any case this assertion should be tested. *       * Results: *	A standard Tcl result. * * Side effects: *	See the user documentation. * *---------------------------------------------------------------------- */	/* ARGSUSED */intTcl_FileObjCmd(dummy, interp, objc, objv)    ClientData dummy;		/* Not used. */    Tcl_Interp *interp;		/* Current interpreter. */    int objc;			/* Number of arguments. */    Tcl_Obj *CONST objv[];	/* Argument objects. */{    int index;/* * This list of constants should match the fileOption string array below. */    static CONST char *fileOptions[] = {	"atime",	"attributes",	"channels",	"copy",	"delete",	"dirname",	"executable",	"exists",	"extension",	"isdirectory",	"isfile",	"join",		"link",	"lstat",        "mtime",	"mkdir",	"nativename",		"normalize",    "owned",	"pathtype",	"readable",	"readlink",	"rename",	"rootname",	"separator",    "size",		"split",		"stat",         "system", 	"tail",		"type",		"volumes",	"writable",	(char *) NULL    };    enum options {	FILE_ATIME,	FILE_ATTRIBUTES, FILE_CHANNELS,	FILE_COPY,	FILE_DELETE,	FILE_DIRNAME,	FILE_EXECUTABLE, FILE_EXISTS,	FILE_EXTENSION,	FILE_ISDIRECTORY, FILE_ISFILE,	FILE_JOIN,	FILE_LINK, 	FILE_LSTAT,     FILE_MTIME,	FILE_MKDIR,	FILE_NATIVENAME, 	FILE_NORMALIZE, FILE_OWNED,	FILE_PATHTYPE,	FILE_READABLE,	FILE_READLINK,	FILE_RENAME,	FILE_ROOTNAME,	FILE_SEPARATOR, FILE_SIZE,	FILE_SPLIT,		FILE_STAT,      FILE_SYSTEM, 	FILE_TAIL,	FILE_TYPE,	FILE_VOLUMES,	FILE_WRITABLE    };    if (objc < 2) {    	Tcl_WrongNumArgs(interp, 1, objv, "option ?arg ...?");        return TCL_ERROR;    }    if (Tcl_GetIndexFromObj(interp, objv[1], fileOptions, "option", 0,	    &index) != TCL_OK) {    	return TCL_ERROR;    }    switch ((enum options) index) {    	case FILE_ATIME: {	    Tcl_StatBuf buf;	    struct utimbuf tval;	    if ((objc < 3) || (objc > 4)) {		Tcl_WrongNumArgs(interp, 2, objv, "name ?time?");		return TCL_ERROR;	    }	    if (GetStatBuf(interp, objv[2], Tcl_FSStat, &buf) != TCL_OK) {		return TCL_ERROR;	    }	    if (objc == 4) {		if (Tcl_GetLongFromObj(interp, objv[3],			(long*)(&buf.st_atime)) != TCL_OK) {		    return TCL_ERROR;		}		tval.actime = buf.st_atime;		tval.modtime = buf.st_mtime;		if (Tcl_FSUtime(objv[2], &tval) != 0) {		    Tcl_AppendStringsToObj(Tcl_GetObjResult(interp),			    "could not set access time for file \"",			    Tcl_GetString(objv[2]), "\": ",			    Tcl_PosixError(interp), (char *) NULL);		    return TCL_ERROR;		}		/*		 * Do another stat to ensure that the we return the		 * new recognized atime - hopefully the same as the		 * one we sent in.  However, fs's like FAT don't		 * even know what atime is.		 */		if (GetStatBuf(interp, objv[2], Tcl_FSStat, &buf) != TCL_OK) {		    return TCL_ERROR;		}	    }	    Tcl_SetLongObj(Tcl_GetObjResult(interp), (long) buf.st_atime);	    return TCL_OK;	}	case FILE_ATTRIBUTES: {            return TclFileAttrsCmd(interp, objc, objv);	}	case FILE_CHANNELS: {	    if ((objc < 2) || (objc > 3)) {		Tcl_WrongNumArgs(interp, 2, objv, "?pattern?");		return TCL_ERROR;	    }	    return Tcl_GetChannelNamesEx(interp,		    ((objc == 2) ? NULL : Tcl_GetString(objv[2])));	}	case FILE_COPY: {	    return TclFileCopyCmd(interp, objc, objv);	}	    	case FILE_DELETE: {	    return TclFileDeleteCmd(interp, objc, objv);	}    	case FILE_DIRNAME: {	    Tcl_Obj *dirPtr;	    if (objc != 3) {		goto only3Args;	    }	    dirPtr = TclFileDirname(interp, objv[2]);	    if (dirPtr == NULL) {	        return TCL_ERROR;	    } else {		Tcl_SetObjResult(interp, dirPtr);		Tcl_DecrRefCount(dirPtr);		return TCL_OK;	    }	}	case FILE_EXECUTABLE: {	    if (objc != 3) {		goto only3Args;	    }	    return CheckAccess(interp, objv[2], X_OK);	}	case FILE_EXISTS: {	    if (objc != 3) {		goto only3Args;	    }	    return CheckAccess(interp, objv[2], F_OK);	}	case FILE_EXTENSION: {	    char *fileName, *extension;	    if (objc != 3) {	    	goto only3Args;	    }	    fileName = Tcl_GetString(objv[2]);	    extension = TclGetExtension(fileName);	    if (extension != NULL) {	    	Tcl_SetStringObj(Tcl_GetObjResult(interp), extension, -1);	    }	    return TCL_OK;	}    	case FILE_ISDIRECTORY: {	    int value;	    Tcl_StatBuf buf;	    if (objc != 3) {		goto only3Args;	    }	    value = 0;	    if (GetStatBuf(NULL, objv[2], Tcl_FSStat, &buf) == TCL_OK) {		value = S_ISDIR(buf.st_mode);	    }	    Tcl_SetBooleanObj(Tcl_GetObjResult(interp), value);	    return TCL_OK;	}    	case FILE_ISFILE: {	    int value;	    Tcl_StatBuf buf;	        	    if (objc != 3) {    	    	goto only3Args;    	    }	    value = 0;	    if (GetStatBuf(NULL, objv[2], Tcl_FSStat, &buf) == TCL_OK) {		value = S_ISREG(buf.st_mode);	    }	    Tcl_SetBooleanObj(Tcl_GetObjResult(interp), value);	    return TCL_OK;	}	case FILE_JOIN: {	    Tcl_Obj *resObj;	    if (objc < 3) {		Tcl_WrongNumArgs(interp, 2, objv, "name ?name ...?");		return TCL_ERROR;	    }	    resObj = Tcl_FSJoinToPath(NULL, objc - 2, objv + 2);	    Tcl_SetObjResult(interp, resObj);	    return TCL_OK;	}	case FILE_LINK: {

⌨️ 快捷键说明

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