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

📄 tclutil.c

📁 tcl是工具命令语言
💻 C
📖 第 1 页 / 共 5 页
字号:
	int length;	/*	 * Clip white space off the front and back of the string	 * to generate a neater result, and ignore any empty	 * elements.	 */	element = argv[i];	while (isspace(UCHAR(*element))) { /* INTL: ISO space. */	    element++;	}	for (length = strlen(element);		(length > 0)		&& (isspace(UCHAR(element[length-1]))) /* INTL: ISO space. */		&& ((length < 2) || (element[length-2] != '\\'));	        length--) {	    /* Null loop body. */	}	if (length == 0) {	    continue;	}	memcpy((VOID *) p, (VOID *) element, (size_t) length);	p += length;	*p = ' ';	p++;    }    if (p != result) {	p[-1] = 0;    } else {	*p = 0;    }    return result;}/* *---------------------------------------------------------------------- * * Tcl_ConcatObj -- * *	Concatenate the strings from a set of objects into a single string *	object with spaces between the original strings. * * Results: *	The return value is a new string object containing a concatenation *	of the strings in objv. Its ref count is zero. * * Side effects: *	A new object is created. * *---------------------------------------------------------------------- */Tcl_Obj *Tcl_ConcatObj(objc, objv)    int objc;			/* Number of objects to concatenate. */    Tcl_Obj *CONST objv[];	/* Array of objects to concatenate. */{    int allocSize, finalSize, length, elemLength, i;    char *p;    char *element;    char *concatStr;    Tcl_Obj *objPtr;    /*     * Check first to see if all the items are of list type.  If so,     * we will concat them together as lists, and return a list object.     * This is only valid when the lists have no current string     * representation, since we don't know what the original type was.     * An original string rep may have lost some whitespace info when     * converted which could be important.     */    for (i = 0;  i < objc;  i++) {	objPtr = objv[i];	if ((objPtr->typePtr != &tclListType) || (objPtr->bytes != NULL)) {	    break;	}    }    if (i == objc) {	Tcl_Obj **listv;	int listc;	objPtr = Tcl_NewListObj(0, NULL);	for (i = 0;  i < objc;  i++) {	    /*	     * Tcl_ListObjAppendList could be used here, but this saves	     * us a bit of type checking (since we've already done it)	     * Use of INT_MAX tells us to always put the new stuff on	     * the end.  It will be set right in Tcl_ListObjReplace.	     */	    Tcl_ListObjGetElements(NULL, objv[i], &listc, &listv);	    Tcl_ListObjReplace(NULL, objPtr, INT_MAX, 0, listc, listv);	}	return objPtr;    }    allocSize = 0;    for (i = 0;  i < objc;  i++) {	objPtr = objv[i];	element = Tcl_GetStringFromObj(objPtr, &length);	if ((element != NULL) && (length > 0)) {	    allocSize += (length + 1);	}    }    if (allocSize == 0) {	allocSize = 1;		/* enough for the NULL byte at end */    }    /*     * Allocate storage for the concatenated result. Note that allocSize     * is one more than the total number of characters, and so includes     * room for the terminating NULL byte.     */        concatStr = (char *) ckalloc((unsigned) allocSize);    /*     * Now concatenate the elements. Clip white space off the front and back     * to generate a neater result, and ignore any empty elements. Also put     * a null byte at the end.     */    finalSize = 0;    if (objc == 0) {	*concatStr = '\0';    } else {	p = concatStr;        for (i = 0;  i < objc;  i++) {	    objPtr = objv[i];	    element = Tcl_GetStringFromObj(objPtr, &elemLength);	    while ((elemLength > 0) && (UCHAR(*element) < 127)		    && isspace(UCHAR(*element))) { /* INTL: ISO C space. */	         element++;		 elemLength--;	    }	    /*	     * Trim trailing white space.  But, be careful not to trim	     * a space character if it is preceded by a backslash: in	     * this case it could be significant.	     */	    while ((elemLength > 0) && (UCHAR(element[elemLength-1]) < 127)		    && isspace(UCHAR(element[elemLength-1])) /* INTL: ISO C space. */		    && ((elemLength < 2) || (element[elemLength-2] != '\\'))) {		elemLength--;	    }	    if (elemLength == 0) {	         continue;	/* nothing left of this element */	    }	    memcpy((VOID *) p, (VOID *) element, (size_t) elemLength);	    p += elemLength;	    *p = ' ';	    p++;	    finalSize += (elemLength + 1);        }        if (p != concatStr) {	    p[-1] = 0;	    finalSize -= 1;	/* we overwrote the final ' ' */        } else {	    *p = 0;        }    }        TclNewObj(objPtr);    objPtr->bytes  = concatStr;    objPtr->length = finalSize;    return objPtr;}/* *---------------------------------------------------------------------- * * Tcl_StringMatch -- * *	See if a particular string matches a particular pattern. * * Results: *	The return value is 1 if string matches pattern, and *	0 otherwise.  The matching operation permits the following *	special characters in the pattern: *?\[] (see the manual *	entry for details on what these mean). * * Side effects: *	None. * *---------------------------------------------------------------------- */intTcl_StringMatch(string, pattern)    CONST char *string;		/* String. */    CONST char *pattern;	/* Pattern, which may contain special				 * characters. */{    return Tcl_StringCaseMatch(string, pattern, 0);}/* *---------------------------------------------------------------------- * * Tcl_StringCaseMatch -- * *	See if a particular string matches a particular pattern. *	Allows case insensitivity. * * Results: *	The return value is 1 if string matches pattern, and *	0 otherwise.  The matching operation permits the following *	special characters in the pattern: *?\[] (see the manual *	entry for details on what these mean). * * Side effects: *	None. * *---------------------------------------------------------------------- */intTcl_StringCaseMatch(string, pattern, nocase)    CONST char *string;		/* String. */    CONST char *pattern;	/* Pattern, which may contain special				 * characters. */    int nocase;			/* 0 for case sensitive, 1 for insensitive */{    int p, charLen;    CONST char *pstart = pattern;    Tcl_UniChar ch1, ch2;        while (1) {	p = *pattern;		/*	 * See if we're at the end of both the pattern and the string.  If	 * so, we succeeded.  If we're at the end of the pattern but not at	 * the end of the string, we failed.	 */		if (p == '\0') {	    return (*string == '\0');	}	if ((*string == '\0') && (p != '*')) {	    return 0;	}	/*	 * Check for a "*" as the next pattern character.  It matches	 * any substring.  We handle this by calling ourselves	 * recursively for each postfix of string, until either we	 * match or we reach the end of the string.	 */		if (p == '*') {	    /*	     * Skip all successive *'s in the pattern	     */	    while (*(++pattern) == '*') {}	    p = *pattern;	    if (p == '\0') {		return 1;	    }	    /*	     * This is a special case optimization for single-byte utf.	     */	    if (UCHAR(*pattern) < 0x80) {		ch2 = (Tcl_UniChar)		    (nocase ? tolower(UCHAR(*pattern)) : UCHAR(*pattern));	    } else {		Tcl_UtfToUniChar(pattern, &ch2);		if (nocase) {		    ch2 = Tcl_UniCharToLower(ch2);		}	    }	    while (1) {		/*		 * Optimization for matching - cruise through the string		 * quickly if the next char in the pattern isn't a special		 * character		 */		if ((p != '[') && (p != '?') && (p != '\\')) {		    if (nocase) {			while (*string) {			    charLen = TclUtfToUniChar(string, &ch1);			    if (ch2==ch1 || ch2==Tcl_UniCharToLower(ch1)) {				break;			    }			    string += charLen;			}		    } else {			/*			 * There's no point in trying to make this code			 * shorter, as the number of bytes you want to			 * compare each time is non-constant.			 */			while (*string) {			    charLen = TclUtfToUniChar(string, &ch1);			    if (ch2 == ch1) {				break;			    }			    string += charLen;			}		    }		}		if (Tcl_StringCaseMatch(string, pattern, nocase)) {		    return 1;		}		if (*string == '\0') {		    return 0;		}		string += TclUtfToUniChar(string, &ch1);	    }	}	/*	 * Check for a "?" as the next pattern character.  It matches	 * any single character.	 */	if (p == '?') {	    pattern++;	    string += TclUtfToUniChar(string, &ch1);	    continue;	}	/*	 * Check for a "[" as the next pattern character.  It is followed	 * by a list of characters that are acceptable, or by a range	 * (two characters separated by "-").	 */	if (p == '[') {	    Tcl_UniChar startChar, endChar;	    pattern++;	    if (UCHAR(*string) < 0x80) {		ch1 = (Tcl_UniChar)		    (nocase ? tolower(UCHAR(*string)) : UCHAR(*string));		string++;	    } else {		string += Tcl_UtfToUniChar(string, &ch1);		if (nocase) {		    ch1 = Tcl_UniCharToLower(ch1);		}	    }	    while (1) {		if ((*pattern == ']') || (*pattern == '\0')) {		    return 0;		}		if (UCHAR(*pattern) < 0x80) {		    startChar = (Tcl_UniChar)			(nocase ? tolower(UCHAR(*pattern)) : UCHAR(*pattern));		    pattern++;		} else {		    pattern += Tcl_UtfToUniChar(pattern, &startChar);		    if (nocase) {			startChar = Tcl_UniCharToLower(startChar);		    }		}		if (*pattern == '-') {		    pattern++;		    if (*pattern == '\0') {			return 0;		    }		    if (UCHAR(*pattern) < 0x80) {			endChar = (Tcl_UniChar)			    (nocase ? tolower(UCHAR(*pattern))				    : UCHAR(*pattern));			pattern++;		    } else {			pattern += Tcl_UtfToUniChar(pattern, &endChar);			if (nocase) {			    endChar = Tcl_UniCharToLower(endChar);			}		    }		    if (((startChar <= ch1) && (ch1 <= endChar))			    || ((endChar <= ch1) && (ch1 <= startChar))) {			/*			 * Matches ranges of form [a-z] or [z-a].			 */			break;		    }		} else if (startChar == ch1) {		    break;		}	    }	    while (*pattern != ']') {		if (*pattern == '\0') {		    pattern = Tcl_UtfPrev(pattern, pstart);		    break;		}		pattern++;	    }	    pattern++;	    continue;	}	/*	 * If the next pattern character is '\', just strip off the '\'	 * so we do exact matching on the character that follows.	 */	if (p == '\\') {	    pattern++;	    if (*pattern == '\0') {		return 0;	    }	}	/*	 * There's no special character.  Just make sure that the next	 * bytes of each string match.	 */	string  += TclUtfToUniChar(string, &ch1);	pattern += TclUtfToUniChar(pattern, &ch2);	if (nocase) {	    if (Tcl_UniCharToLower(ch1) != Tcl_UniCharToLower(ch2)) {		return 0;	    }	} else if (ch1 != ch2) {	    return 0;	}    }}/* *---------------------------------------------------------------------- * * Tcl_DStringInit -- * *	Initializes a dynamic string, discarding any previous contents *	of the string (Tcl_DStringFree should have been called already *	if the dynamic string was previously in use). * * Results: *	None. * * Side effects: *	The dynamic string is initialized to be empty. * *---------------------------------------------------------------------- */voidTcl_DStringInit(dsPtr)    Tcl_DString *dsPtr;		/* Pointer to structure for dynamic string. */{    dsPtr->string = dsPtr->staticSpace;    dsPtr->length = 0;    dsPtr->spaceAvl = TCL_DSTRING_STATIC_SIZE;    dsPtr->staticSpace[0] = '\0';}/* *---------------------------------------------------------------------- * * Tcl_DStringAppend -- * *	Append more characters to the current value of a dynamic string. * * Results: *	The return value is a pointer to the dynamic string's new value. * * Side effects: *	Length bytes from string (or all of string if length is less *	than zero) are added to the current value of the string. Memory *	gets reallocated if needed to accomodate the string's new size. * *---------------------------------------------------------------------- */char *Tcl_DStringAppend(dsPtr, string, length)    Tcl_DString *dsPtr;		/* Structure describing dynamic string. */    CONST char *string;		/* String to append.  If length is -1 then				 * this must be null-terminated. */    int length;			/* Number of characters from string to				 * append.  If < 0, then append all of string,				 * up to null at end. */{    int newSize;    char *dst;    CONST char *end;

⌨️ 快捷键说明

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