⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 tclcmdah.c

📁 tcl源码详细资料
💻 C
📖 第 1 页 / 共 2 页
字号:
intTcl_ForCmd(dummy, interp, argc, argv)    ClientData dummy;			/* Not used. */    Tcl_Interp *interp;			/* Current interpreter. */    int argc;				/* Number of arguments. */    char **argv;			/* Argument strings. */{    int result, value;    if (argc != 5) {	Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],		" start test next command\"", (char *) NULL);	return TCL_ERROR;    }    result = Tcl_Eval(interp, argv[1], 0, (char **) NULL);    if (result != TCL_OK) {	if (result == TCL_ERROR) {	    Tcl_AddErrorInfo(interp, "\n    (\"for\" initial command)");	}	return result;    }    while (1) {	result = Tcl_ExprBoolean(interp, argv[2], &value);	if (result != TCL_OK) {	    return result;	}	if (!value) {	    break;	}	result = Tcl_Eval(interp, argv[4], 0, (char **) NULL);	if (result == TCL_CONTINUE) {	    result = TCL_OK;	} else if (result != TCL_OK) {	    if (result == TCL_ERROR) {		char msg[60];		sprintf(msg, "\n    (\"for\" body line %d)", interp->errorLine);		Tcl_AddErrorInfo(interp, msg);	    }	    break;	}	result = Tcl_Eval(interp, argv[3], 0, (char **) NULL);	if (result == TCL_BREAK) {	    break;	} else if (result != TCL_OK) {	    if (result == TCL_ERROR) {		Tcl_AddErrorInfo(interp, "\n    (\"for\" loop-end command)");	    }	    return result;	}    }    if (result == TCL_BREAK) {	result = TCL_OK;    }    if (result == TCL_OK) {	Tcl_ResetResult(interp);    }    return result;}/* *---------------------------------------------------------------------- * * Tcl_ForeachCmd -- * *	This procedure is invoked to process the "foreach" Tcl command. *	See the user documentation for details on what it does. * * Results: *	A standard Tcl result. * * Side effects: *	See the user documentation. * *---------------------------------------------------------------------- */	/* ARGSUSED */intTcl_ForeachCmd(dummy, interp, argc, argv)    ClientData dummy;			/* Not used. */    Tcl_Interp *interp;			/* Current interpreter. */    int argc;				/* Number of arguments. */    char **argv;			/* Argument strings. */{    int listArgc, i, result;    char **listArgv;    if (argc != 4) {	Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],		" varName list command\"", (char *) NULL);	return TCL_ERROR;    }    /*     * Break the list up into elements, and execute the command once     * for each value of the element.     */    result = Tcl_SplitList(interp, argv[2], &listArgc, &listArgv);    if (result != TCL_OK) {	return result;    }    for (i = 0; i < listArgc; i++) {	if (Tcl_SetVar(interp, argv[1], listArgv[i], 0) == NULL) {	    Tcl_SetResult(interp, "couldn't set loop variable", TCL_STATIC);	    result = TCL_ERROR;	    break;	}	result = Tcl_Eval(interp, argv[3], 0, (char **) NULL);	if (result != TCL_OK) {	    if (result == TCL_CONTINUE) {		result = TCL_OK;	    } else if (result == TCL_BREAK) {		result = TCL_OK;		break;	    } else if (result == TCL_ERROR) {		char msg[100];		sprintf(msg, "\n    (\"foreach\" body line %d)",			interp->errorLine);		Tcl_AddErrorInfo(interp, msg);		break;	    } else {		break;	    }	}    }    ckfree((char *) listArgv);    if (result == TCL_OK) {	Tcl_ResetResult(interp);    }    return result;}/* *---------------------------------------------------------------------- * * Tcl_FormatCmd -- * *	This procedure is invoked to process the "format" Tcl command. *	See the user documentation for details on what it does. * * Results: *	A standard Tcl result. * * Side effects: *	See the user documentation. * *---------------------------------------------------------------------- */	/* ARGSUSED */intTcl_FormatCmd(dummy, interp, argc, argv)    ClientData dummy;			/* Not used. */    Tcl_Interp *interp;			/* Current interpreter. */    int argc;				/* Number of arguments. */    char **argv;			/* Argument strings. */{    register char *format;	/* Used to read characters from the format				 * string. */    char newFormat[40];		/* A new format specifier is generated here. */    long width;			/* Field width from field specifier, or 0 if				 * no width given. */    long precision;		/* Field precision from field specifier, or 0				 * if no precision given. */    int size;			/* Number of bytes needed for result of				 * conversion, based on type of conversion				 * ("e", "s", etc.) and width from above. */    char *oneWordValue = NULL;	/* Used to hold value to pass to sprintf, if				 * it's a one-word value. */    double twoWordValue;	/* Used to hold value to pass to sprintf if				 * it's a two-word value. */    int useTwoWords;		/* 0 means use oneWordValue, 1 means use				 * twoWordValue. */    char *dst = interp->result;	/* Where result is stored.  Starts off at				 * interp->resultSpace, but may get dynamically				 * re-allocated if this isn't enough. */    int dstSize = 0;		/* Number of non-null characters currently				 * stored at dst. */    int dstSpace = TCL_RESULT_SIZE;				/* Total amount of storage space available				 * in dst (not including null terminator. */    int noPercent;		/* Special case for speed:  indicates there's				 * no field specifier, just a string to copy. */    char **curArg;		/* Remainder of argv array. */    int useShort;		/* Value to be printed is short (half word). */    /*     * This procedure is a bit nasty.  The goal is to use sprintf to     * do most of the dirty work.  There are several problems:     * 1. this procedure can't trust its arguments.     * 2. we must be able to provide a large enough result area to hold     *    whatever's generated.  This is hard to estimate.     * 2. there's no way to move the arguments from argv to the call     *    to sprintf in a reasonable way.  This is particularly nasty     *    because some of the arguments may be two-word values (doubles).     * So, what happens here is to scan the format string one % group     * at a time, making many individual calls to sprintf.     */    if (argc < 2) {	Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],		" formatString ?arg arg ...?\"", (char *) NULL);	return TCL_ERROR;    }    curArg = argv+2;    argc -= 2;    for (format = argv[1]; *format != 0; ) {	register char *newPtr = newFormat;	width = precision = useTwoWords = noPercent = useShort = 0;	/*	 * Get rid of any characters before the next field specifier.	 * Collapse backslash sequences found along the way.	 */	if (*format != '%') {	    register char *p;	    int bsSize;	    oneWordValue = p = format;	    while ((*format != '%') && (*format != 0)) {		if (*format == '\\') {		    *p = Tcl_Backslash(format, &bsSize);		    if (*p != 0) {			p++;		    }		    format += bsSize;		} else {		    *p = *format;		    p++;		    format++;		}	    }	    size = p - oneWordValue;	    noPercent = 1;	    goto doField;	}	if (format[1] == '%') {	    oneWordValue = format;	    size = 1;	    noPercent = 1;	    format += 2;	    goto doField;	}	/*	 * Parse off a field specifier, compute how many characters	 * will be needed to store the result, and substitute for	 * "*" size specifiers.	 */	*newPtr = '%';	newPtr++;	format++;	while ((*format == '-') || (*format == '#') || (*format == '0')		|| (*format == ' ') || (*format == '+')) {	    *newPtr = *format;	    newPtr++;	    format++;	}	if (isdigit(*format)) {	    width = atoi(format);	    do {		format++;	    } while (isdigit(*format));	} else if (*format == '*') {	    if (argc <= 0) {		goto notEnoughArgs;	    }	    if (Tcl_GetInt(interp, *curArg, &width) != TCL_OK) {		goto fmtError;	    }	    argc--;	    curArg++;	    format++;	}	if (width != 0) {	    sprintf(newPtr, "%ld", width);	    while (*newPtr != 0) {		newPtr++;	    }	}	if (*format == '.') {	    *newPtr = '.';	    newPtr++;	    format++;	}	if (isdigit(*format)) {	    precision = atoi(format);	    do {		format++;	    } while (isdigit(*format));	} else if (*format == '*') {	    if (argc <= 0) {		goto notEnoughArgs;	    }	    if (Tcl_GetInt(interp, *curArg, &precision) != TCL_OK) {		goto fmtError;	    }	    argc--;	    curArg++;	    format++;	}	if (precision != 0) {	    sprintf(newPtr, "%ld", precision);	    while (*newPtr != 0) {		newPtr++;	    }	}	if (*format == 'l') {	    format++;	} else if (*format == 'h') {	    useShort = 1;	    *newPtr = 'h';	    newPtr++;	    format++;	}	*newPtr = *format;	newPtr++;	*newPtr = 0;	if (argc <= 0) {	    goto notEnoughArgs;	}	switch (*format) {	    case 'D':	    case 'O':	    case 'U':		if (!useShort) {		    newPtr++;		} else {		    useShort = 0;		}		newPtr[-1] = tolower(*format);		newPtr[-2] = 'l';		*newPtr = 0;	    case 'd':	    case 'o':	    case 'u':	    case 'x':	    case 'X':		if (Tcl_GetInt(interp, *curArg, (long *) &oneWordValue)			!= TCL_OK) {		    goto fmtError;		}		size = 40;		break;	    case 's':		oneWordValue = *curArg;		size = strlen(*curArg);		break;	    case 'c':		if (Tcl_GetInt(interp, *curArg, (long *) &oneWordValue)			!= TCL_OK) {		    goto fmtError;		}		size = 1;		break;	    case 'F':		newPtr[-1] = tolower(newPtr[-1]);	    case 'e':	    case 'E':	    case 'f':	    case 'g':	    case 'G':		if (Tcl_GetDouble(interp, *curArg, &twoWordValue) != TCL_OK) {		    goto fmtError;		}		useTwoWords = 1;		size = 320;		if (precision > 10) {		    size += precision;		}		break;	    case 0:		interp->result =			"format string ended in middle of field specifier";		goto fmtError;	    default:		sprintf(interp->result, "bad field specifier \"%c\"", *format);		goto fmtError;	}	argc--;	curArg++;	format++;	/*	 * Make sure that there's enough space to hold the formatted	 * result, then format it.	 */	doField:	if (width > size) {	    size = width;	}	if ((dstSize + size) > dstSpace) {	    char *newDst;	    int newSpace;	    newSpace = 2*(dstSize + size);	    newDst = (char *) ckalloc((unsigned) newSpace+1);	    if (dstSize != 0) {		memcpy((VOID *) newDst, (VOID *) dst, dstSize);	    }	    if (dstSpace != TCL_RESULT_SIZE) {		ckfree(dst);	    }	    dst = newDst;	    dstSpace = newSpace;	}	if (noPercent) {	    memcpy((VOID *) (dst+dstSize), (VOID *) oneWordValue, size);	    dstSize += size;	    dst[dstSize] = 0;	} else {	    if (useTwoWords) {		sprintf(dst+dstSize, newFormat, twoWordValue);	    } else if (useShort) {		/*		 * The double cast below is needed for a few machines		 * (e.g. Pyramids as of 1/93) that don't like casts		 * directly from pointers to shorts.		 */		sprintf(dst+dstSize, newFormat, (short) (int) oneWordValue);	    } else {		sprintf(dst+dstSize, newFormat, (char *) oneWordValue);	    }	    dstSize += strlen(dst+dstSize);	}    }    interp->result = dst;    if (dstSpace != TCL_RESULT_SIZE) {	interp->freeProc = (Tcl_FreeProc *) free;    } else {	interp->freeProc = 0;    }    return TCL_OK;    notEnoughArgs:    interp->result = "not enough arguments for all format specifiers";    fmtError:    if (dstSpace != TCL_RESULT_SIZE) {	ckfree(dst);    }    return TCL_ERROR;}#elsestatic const char file_name[] = "tclCmdAH.c";#endif /* EXCLUDE_TCL */

⌨️ 快捷键说明

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