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

📄 tclutil.c

📁 tcl是工具命令语言
💻 C
📖 第 1 页 / 共 5 页
字号:
    return TCL_OK;}/* *---------------------------------------------------------------------- * * Tcl_ScanElement -- * *	This procedure is a companion procedure to Tcl_ConvertElement. *	It scans a string to see what needs to be done to it (e.g. add *	backslashes or enclosing braces) to make the string into a *	valid Tcl list element. * * Results: *	The return value is an overestimate of the number of characters *	that will be needed by Tcl_ConvertElement to produce a valid *	list element from string.  The word at *flagPtr is filled in *	with a value needed by Tcl_ConvertElement when doing the actual *	conversion. * * Side effects: *	None. * *---------------------------------------------------------------------- */intTcl_ScanElement(string, flagPtr)    register CONST char *string; /* String to convert to list element. */    register int *flagPtr;	 /* Where to store information to guide				  * Tcl_ConvertCountedElement. */{    return Tcl_ScanCountedElement(string, -1, flagPtr);}/* *---------------------------------------------------------------------- * * Tcl_ScanCountedElement -- * *	This procedure is a companion procedure to *	Tcl_ConvertCountedElement.  It scans a string to see what *	needs to be done to it (e.g. add backslashes or enclosing *	braces) to make the string into a valid Tcl list element. *	If length is -1, then the string is scanned up to the first *	null byte. * * Results: *	The return value is an overestimate of the number of characters *	that will be needed by Tcl_ConvertCountedElement to produce a *	valid list element from string.  The word at *flagPtr is *	filled in with a value needed by Tcl_ConvertCountedElement *	when doing the actual conversion. * * Side effects: *	None. * *---------------------------------------------------------------------- */intTcl_ScanCountedElement(string, length, flagPtr)    CONST char *string;		/* String to convert to Tcl list element. */    int length;			/* Number of bytes in string, or -1. */    int *flagPtr;		/* Where to store information to guide				 * Tcl_ConvertElement. */{    int flags, nestingLevel;    register CONST char *p, *lastChar;    /*     * This procedure and Tcl_ConvertElement together do two things:     *     * 1. They produce a proper list, one that will yield back the     * argument strings when evaluated or when disassembled with     * Tcl_SplitList.  This is the most important thing.     *      * 2. They try to produce legible output, which means minimizing the     * use of backslashes (using braces instead).  However, there are     * some situations where backslashes must be used (e.g. an element     * like "{abc": the leading brace will have to be backslashed.     * For each element, one of three things must be done:     *     * (a) Use the element as-is (it doesn't contain any special     * characters).  This is the most desirable option.     *     * (b) Enclose the element in braces, but leave the contents alone.     * This happens if the element contains embedded space, or if it     * contains characters with special interpretation ($, [, ;, or \),     * or if it starts with a brace or double-quote, or if there are     * no characters in the element.     *     * (c) Don't enclose the element in braces, but add backslashes to     * prevent special interpretation of special characters.  This is a     * last resort used when the argument would normally fall under case     * (b) but contains unmatched braces.  It also occurs if the last     * character of the argument is a backslash or if the element contains     * a backslash followed by newline.     *     * The procedure figures out how many bytes will be needed to store     * the result (actually, it overestimates). It also collects information     * about the element in the form of a flags word.     *     * Note: list elements produced by this procedure and     * Tcl_ConvertCountedElement must have the property that they can be     * enclosing in curly braces to make sub-lists.  This means, for     * example, that we must not leave unmatched curly braces in the     * resulting list element.  This property is necessary in order for     * procedures like Tcl_DStringStartSublist to work.     */    nestingLevel = 0;    flags = 0;    if (string == NULL) {	string = "";    }    if (length == -1) {	length = strlen(string);    }    lastChar = string + length;    p = string;    if ((p == lastChar) || (*p == '{') || (*p == '"')) {	flags |= USE_BRACES;    }    for ( ; p < lastChar; p++) {	switch (*p) {	    case '{':		nestingLevel++;		break;	    case '}':		nestingLevel--;		if (nestingLevel < 0) {		    flags |= TCL_DONT_USE_BRACES|BRACES_UNMATCHED;		}		break;	    case '[':	    case '$':	    case ';':	    case ' ':	    case '\f':	    case '\n':	    case '\r':	    case '\t':	    case '\v':		flags |= USE_BRACES;		break;	    case '\\':		if ((p+1 == lastChar) || (p[1] == '\n')) {		    flags = TCL_DONT_USE_BRACES | BRACES_UNMATCHED;		} else {		    int size;		    Tcl_UtfBackslash(p, &size, NULL);		    p += size-1;		    flags |= USE_BRACES;		}		break;	}    }    if (nestingLevel != 0) {	flags = TCL_DONT_USE_BRACES | BRACES_UNMATCHED;    }    *flagPtr = flags;    /*     * Allow enough space to backslash every character plus leave     * two spaces for braces.     */    return 2*(p-string) + 2;}/* *---------------------------------------------------------------------- * * Tcl_ConvertElement -- * *	This is a companion procedure to Tcl_ScanElement.  Given *	the information produced by Tcl_ScanElement, this procedure *	converts a string to a list element equal to that string. * * Results: *	Information is copied to *dst in the form of a list element *	identical to src (i.e. if Tcl_SplitList is applied to dst it *	will produce a string identical to src).  The return value is *	a count of the number of characters copied (not including the *	terminating NULL character). * * Side effects: *	None. * *---------------------------------------------------------------------- */intTcl_ConvertElement(src, dst, flags)    register CONST char *src;	/* Source information for list element. */    register char *dst;		/* Place to put list-ified element. */    register int flags;		/* Flags produced by Tcl_ScanElement. */{    return Tcl_ConvertCountedElement(src, -1, dst, flags);}/* *---------------------------------------------------------------------- * * Tcl_ConvertCountedElement -- * *	This is a companion procedure to Tcl_ScanCountedElement.  Given *	the information produced by Tcl_ScanCountedElement, this *	procedure converts a string to a list element equal to that *	string. * * Results: *	Information is copied to *dst in the form of a list element *	identical to src (i.e. if Tcl_SplitList is applied to dst it *	will produce a string identical to src).  The return value is *	a count of the number of characters copied (not including the *	terminating NULL character). * * Side effects: *	None. * *---------------------------------------------------------------------- */intTcl_ConvertCountedElement(src, length, dst, flags)    register CONST char *src;	/* Source information for list element. */    int length;			/* Number of bytes in src, or -1. */    char *dst;			/* Place to put list-ified element. */    int flags;			/* Flags produced by Tcl_ScanElement. */{    register char *p = dst;    register CONST char *lastChar;    /*     * See the comment block at the beginning of the Tcl_ScanElement     * code for details of how this works.     */    if (src && length == -1) {	length = strlen(src);    }    if ((src == NULL) || (length == 0)) {	p[0] = '{';	p[1] = '}';	p[2] = 0;	return 2;    }    lastChar = src + length;    if ((flags & USE_BRACES) && !(flags & TCL_DONT_USE_BRACES)) {	*p = '{';	p++;	for ( ; src != lastChar; src++, p++) {	    *p = *src;	}	*p = '}';	p++;    } else {	if (*src == '{') {	    /*	     * Can't have a leading brace unless the whole element is	     * enclosed in braces.  Add a backslash before the brace.	     * Furthermore, this may destroy the balance between open	     * and close braces, so set BRACES_UNMATCHED.	     */	    p[0] = '\\';	    p[1] = '{';	    p += 2;	    src++;	    flags |= BRACES_UNMATCHED;	}	for (; src != lastChar; src++) {	    switch (*src) {		case ']':		case '[':		case '$':		case ';':		case ' ':		case '\\':		case '"':		    *p = '\\';		    p++;		    break;		case '{':		case '}':		    /*		     * It may not seem necessary to backslash braces, but		     * it is.  The reason for this is that the resulting		     * list element may actually be an element of a sub-list		     * enclosed in braces (e.g. if Tcl_DStringStartSublist		     * has been invoked), so there may be a brace mismatch		     * if the braces aren't backslashed.		     */		    if (flags & BRACES_UNMATCHED) {			*p = '\\';			p++;		    }		    break;		case '\f':		    *p = '\\';		    p++;		    *p = 'f';		    p++;		    continue;		case '\n':		    *p = '\\';		    p++;		    *p = 'n';		    p++;		    continue;		case '\r':		    *p = '\\';		    p++;		    *p = 'r';		    p++;		    continue;		case '\t':		    *p = '\\';		    p++;		    *p = 't';		    p++;		    continue;		case '\v':		    *p = '\\';		    p++;		    *p = 'v';		    p++;		    continue;	    }	    *p = *src;	    p++;	}    }    *p = '\0';    return p-dst;}/* *---------------------------------------------------------------------- * * Tcl_Merge -- * *	Given a collection of strings, merge them together into a *	single string that has proper Tcl list structured (i.e. *	Tcl_SplitList may be used to retrieve strings equal to the *	original elements, and Tcl_Eval will parse the string back *	into its original elements). * * Results: *	The return value is the address of a dynamically-allocated *	string containing the merged list. * * Side effects: *	None. * *---------------------------------------------------------------------- */char *Tcl_Merge(argc, argv)    int argc;			/* How many strings to merge. */    CONST char * CONST *argv;	/* Array of string values. */{#   define LOCAL_SIZE 20    int localFlags[LOCAL_SIZE], *flagPtr;    int numChars;    char *result;    char *dst;    int i;    /*     * Pass 1: estimate space, gather flags.     */    if (argc <= LOCAL_SIZE) {	flagPtr = localFlags;    } else {	flagPtr = (int *) ckalloc((unsigned) argc*sizeof(int));    }    numChars = 1;    for (i = 0; i < argc; i++) {	numChars += Tcl_ScanElement(argv[i], &flagPtr[i]) + 1;    }    /*     * Pass two: copy into the result area.     */    result = (char *) ckalloc((unsigned) numChars);    dst = result;    for (i = 0; i < argc; i++) {	numChars = Tcl_ConvertElement(argv[i], dst, flagPtr[i]);	dst += numChars;	*dst = ' ';	dst++;    }    if (dst == result) {	*dst = 0;    } else {	dst[-1] = 0;    }    if (flagPtr != localFlags) {	ckfree((char *) flagPtr);    }    return result;}/* *---------------------------------------------------------------------- * * Tcl_Backslash -- * *	Figure out how to handle a backslash sequence. * * Results: *	The return value is the character that should be substituted *	in place of the backslash sequence that starts at src.  If *	readPtr isn't NULL then it is filled in with a count of the *	number of characters in the backslash sequence. * * Side effects: *	None. * *---------------------------------------------------------------------- */charTcl_Backslash(src, readPtr)    CONST char *src;		/* Points to the backslash character of				 * a backslash sequence. */    int *readPtr;		/* Fill in with number of characters read				 * from src, unless NULL. */{    char buf[TCL_UTF_MAX];    Tcl_UniChar ch;    Tcl_UtfBackslash(src, readPtr, buf);    TclUtfToUniChar(buf, &ch);    return (char) ch;}/* *---------------------------------------------------------------------- * * Tcl_Concat -- * *	Concatenate a set of strings into a single large string. * * Results: *	The return value is dynamically-allocated string containing *	a concatenation of all the strings in argv, with spaces between *	the original argv elements. * * Side effects: *	Memory is allocated for the result;  the caller is responsible *	for freeing the memory. * *---------------------------------------------------------------------- */char *Tcl_Concat(argc, argv)    int argc;			/* Number of strings to concatenate. */    CONST char * CONST *argv;	/* Array of strings to concatenate. */{    int totalSize, i;    char *p;    char *result;    for (totalSize = 1, i = 0; i < argc; i++) {	totalSize += strlen(argv[i]) + 1;    }    result = (char *) ckalloc((unsigned) totalSize);    if (argc == 0) {	*result = '\0';	return result;    }    for (p = result, i = 0; i < argc; i++) {	CONST char *element;

⌨️ 快捷键说明

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