tclstringobj.c

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

C
1,878
字号
 * *--------------------------------------------------------------------------- */voidTcl_SetUnicodeObj(objPtr, unicode, numChars)    Tcl_Obj *objPtr;		/* The object to set the string of. */    CONST Tcl_UniChar *unicode;	/* The unicode string used to initialize				 * the object. */    int numChars;		/* Number of characters in the unicode				 * string. */{    Tcl_ObjType *typePtr;    String *stringPtr;    size_t uallocated;    if (numChars < 0) {	numChars = 0;	if (unicode) {	    while (unicode[numChars] != 0) { numChars++; }	}    }    uallocated = STRING_UALLOC(numChars);    /*     * Free the internal rep if one exists, and invalidate the string rep.     */    typePtr = objPtr->typePtr;    if ((typePtr != NULL) && (typePtr->freeIntRepProc) != NULL) {	(*typePtr->freeIntRepProc)(objPtr);    }    objPtr->typePtr = &tclStringType;    /*     * Allocate enough space for the String structure + Unicode string.     */	    stringPtr = (String *) ckalloc(STRING_SIZE(uallocated));    stringPtr->numChars = numChars;    stringPtr->uallocated = uallocated;    stringPtr->hasUnicode = (numChars > 0);    stringPtr->allocated = 0;    memcpy((VOID *) stringPtr->unicode, (VOID *) unicode, uallocated);    stringPtr->unicode[numChars] = 0;    SET_STRING(objPtr, stringPtr);    Tcl_InvalidateStringRep(objPtr);    return;}/* *---------------------------------------------------------------------- * * Tcl_AppendToObj -- * *	This procedure appends a sequence of bytes to an object. * * Results: *	None. * * Side effects: *	The bytes at *bytes are appended to the string representation *	of objPtr. * *---------------------------------------------------------------------- */voidTcl_AppendToObj(objPtr, bytes, length)    register Tcl_Obj *objPtr;	/* Points to the object to append to. */    CONST char *bytes;		/* Points to the bytes to append to the				 * object. */    register int length;	/* The number of bytes to append from				 * "bytes". If < 0, then append all bytes				 * up to NULL byte. */{    String *stringPtr;    if (Tcl_IsShared(objPtr)) {	panic("Tcl_AppendToObj called with shared object");    }        SetStringFromAny(NULL, objPtr);    if (length < 0) {	length = (bytes ? strlen(bytes) : 0);    }    if (length == 0) {	return;    }    /*     * If objPtr has a valid Unicode rep, then append the Unicode     * conversion of "bytes" to the objPtr's Unicode rep, otherwise     * append "bytes" to objPtr's string rep.     */    stringPtr = GET_STRING(objPtr);    if (stringPtr->hasUnicode != 0) {	AppendUtfToUnicodeRep(objPtr, bytes, length);	stringPtr = GET_STRING(objPtr);    } else {	AppendUtfToUtfRep(objPtr, bytes, length);    }}/* *---------------------------------------------------------------------- * * Tcl_AppendUnicodeToObj -- * *	This procedure appends a Unicode string to an object in the *	most efficient manner possible.  Length must be >= 0. * * Results: *	None. * * Side effects: *	Invalidates the string rep and creates a new Unicode string. * *---------------------------------------------------------------------- */voidTcl_AppendUnicodeToObj(objPtr, unicode, length)    register Tcl_Obj *objPtr;	/* Points to the object to append to. */    CONST Tcl_UniChar *unicode;	/* The unicode string to append to the			         * object. */    int length;			/* Number of chars in "unicode". */{    String *stringPtr;    if (Tcl_IsShared(objPtr)) {	panic("Tcl_AppendUnicodeToObj called with shared object");    }    if (length == 0) {	return;    }    SetStringFromAny(NULL, objPtr);    stringPtr = GET_STRING(objPtr);    /*     * If objPtr has a valid Unicode rep, then append the "unicode"     * to the objPtr's Unicode rep, otherwise the UTF conversion of     * "unicode" to objPtr's string rep.     */    if (stringPtr->hasUnicode != 0) {	AppendUnicodeToUnicodeRep(objPtr, unicode, length);    } else {	AppendUnicodeToUtfRep(objPtr, unicode, length);    }}/* *---------------------------------------------------------------------- * * Tcl_AppendObjToObj -- * *	This procedure appends the string rep of one object to another. *	"objPtr" cannot be a shared object. * * Results: *	None. * * Side effects: *	The string rep of appendObjPtr is appended to the string  *	representation of objPtr. * *---------------------------------------------------------------------- */voidTcl_AppendObjToObj(objPtr, appendObjPtr)    Tcl_Obj *objPtr;		/* Points to the object to append to. */    Tcl_Obj *appendObjPtr;	/* Object to append. */{    String *stringPtr;    int length, numChars, allOneByteChars;    char *bytes;    SetStringFromAny(NULL, objPtr);    /*     * If objPtr has a valid Unicode rep, then get a Unicode string     * from appendObjPtr and append it.     */    stringPtr = GET_STRING(objPtr);    if (stringPtr->hasUnicode != 0) {		/*	 * If appendObjPtr is not of the "String" type, don't convert it.	 */	if (appendObjPtr->typePtr == &tclStringType) {	    stringPtr = GET_STRING(appendObjPtr);	    if ((stringPtr->numChars == -1)		    || (stringPtr->hasUnicode == 0)) {				/*		 * If appendObjPtr is a string obj with no valid Unicode		 * rep, then fill its unicode rep.		 */		FillUnicodeRep(appendObjPtr);		stringPtr = GET_STRING(appendObjPtr);	    }	    AppendUnicodeToUnicodeRep(objPtr, stringPtr->unicode,		    stringPtr->numChars);	} else {	    bytes = Tcl_GetStringFromObj(appendObjPtr, &length);	    AppendUtfToUnicodeRep(objPtr, bytes, length);	}	return;    }    /*     * Append to objPtr's UTF string rep.  If we know the number of     * characters in both objects before appending, then set the combined     * number of characters in the final (appended-to) object.     */    bytes = Tcl_GetStringFromObj(appendObjPtr, &length);    allOneByteChars = 0;    numChars = stringPtr->numChars;    if ((numChars >= 0) && (appendObjPtr->typePtr == &tclStringType)) {	stringPtr = GET_STRING(appendObjPtr);	if ((stringPtr->numChars >= 0) && (stringPtr->numChars == length)) {	    numChars += stringPtr->numChars;	    allOneByteChars = 1;	}    }    AppendUtfToUtfRep(objPtr, bytes, length);    if (allOneByteChars) {	stringPtr = GET_STRING(objPtr);	stringPtr->numChars = numChars;    }}/* *---------------------------------------------------------------------- * * AppendUnicodeToUnicodeRep -- * *	This procedure appends the contents of "unicode" to the Unicode *	rep of "objPtr".  objPtr must already have a valid Unicode rep. * * Results: *	None. * * Side effects: *	objPtr's internal rep is reallocated. * *---------------------------------------------------------------------- */static voidAppendUnicodeToUnicodeRep(objPtr, unicode, appendNumChars)    Tcl_Obj *objPtr;	        /* Points to the object to append to. */    CONST Tcl_UniChar *unicode; /* String to append. */    int appendNumChars;	        /* Number of chars of "unicode" to append. */{    String *stringPtr, *tmpString;    size_t numChars;    if (appendNumChars < 0) {	appendNumChars = 0;	if (unicode) {	    while (unicode[appendNumChars] != 0) { appendNumChars++; }	}    }    if (appendNumChars == 0) {	return;    }    SetStringFromAny(NULL, objPtr);    stringPtr = GET_STRING(objPtr);    /*     * If not enough space has been allocated for the unicode rep,     * reallocate the internal rep object with additional space.  First     * try to double the required allocation; if that fails, try a more     * modest increase.  See the "TCL STRING GROWTH ALGORITHM" comment at     * the top of this file for an explanation of this growth algorithm.     */    numChars = stringPtr->numChars + appendNumChars;    if (STRING_UALLOC(numChars) >= stringPtr->uallocated) {     	stringPtr->uallocated = STRING_UALLOC(2 * numChars);	tmpString = (String *) attemptckrealloc((char *)stringPtr,		STRING_SIZE(stringPtr->uallocated));	if (tmpString == NULL) {	    stringPtr->uallocated =	        STRING_UALLOC(numChars + appendNumChars) 		+ TCL_GROWTH_MIN_ALLOC;	    tmpString = (String *) ckrealloc((char *)stringPtr,		    STRING_SIZE(stringPtr->uallocated));	}	stringPtr = tmpString;	SET_STRING(objPtr, stringPtr);    }    /*     * Copy the new string onto the end of the old string, then add the     * trailing null.     */    memcpy((VOID*) (stringPtr->unicode + stringPtr->numChars), unicode,	    appendNumChars * sizeof(Tcl_UniChar));    stringPtr->unicode[numChars] = 0;    stringPtr->numChars = numChars;    Tcl_InvalidateStringRep(objPtr);}/* *---------------------------------------------------------------------- * * AppendUnicodeToUtfRep -- * *	This procedure converts the contents of "unicode" to UTF and *	appends the UTF to the string rep of "objPtr". * * Results: *	None. * * Side effects: *	objPtr's internal rep is reallocated. * *---------------------------------------------------------------------- */static voidAppendUnicodeToUtfRep(objPtr, unicode, numChars)    Tcl_Obj *objPtr;	        /* Points to the object to append to. */    CONST Tcl_UniChar *unicode; /* String to convert to UTF. */    int numChars;	        /* Number of chars of "unicode" to convert. */{    Tcl_DString dsPtr;    CONST char *bytes;        if (numChars < 0) {	numChars = 0;	if (unicode) {	    while (unicode[numChars] != 0) { numChars++; }	}    }    if (numChars == 0) {	return;    }    Tcl_DStringInit(&dsPtr);    bytes = Tcl_UniCharToUtfDString(unicode, numChars, &dsPtr);    AppendUtfToUtfRep(objPtr, bytes, Tcl_DStringLength(&dsPtr));    Tcl_DStringFree(&dsPtr);}/* *---------------------------------------------------------------------- * * AppendUtfToUnicodeRep -- * *	This procedure converts the contents of "bytes" to Unicode and *	appends the Unicode to the Unicode rep of "objPtr".  objPtr must *	already have a valid Unicode rep. * * Results: *	None. * * Side effects: *	objPtr's internal rep is reallocated. * *---------------------------------------------------------------------- */static voidAppendUtfToUnicodeRep(objPtr, bytes, numBytes)    Tcl_Obj *objPtr;	/* Points to the object to append to. */    CONST char *bytes;	/* String to convert to Unicode. */    int numBytes;	/* Number of bytes of "bytes" to convert. */{    Tcl_DString dsPtr;    int numChars;    Tcl_UniChar *unicode;    if (numBytes < 0) {	numBytes = (bytes ? strlen(bytes) : 0);    }    if (numBytes == 0) {	return;    }        Tcl_DStringInit(&dsPtr);    numChars = Tcl_NumUtfChars(bytes, numBytes);    unicode = (Tcl_UniChar *)Tcl_UtfToUniCharDString(bytes, numBytes, &dsPtr);    AppendUnicodeToUnicodeRep(objPtr, unicode, numChars);    Tcl_DStringFree(&dsPtr);}/* *---------------------------------------------------------------------- * * AppendUtfToUtfRep -- * *	This procedure appends "numBytes" bytes of "bytes" to the UTF string *	rep of "objPtr".  objPtr must already have a valid String rep. * * Results: *	None. * * Side effects: *	objPtr's internal rep is reallocated. * *---------------------------------------------------------------------- */static voidAppendUtfToUtfRep(objPtr, bytes, numBytes)    Tcl_Obj *objPtr;	/* Points to the object to append to. */    CONST char *bytes;	/* String to append. */    int numBytes;	/* Number of bytes of "bytes" to append. */{    String *stringPtr;    int newLength, oldLength;    if (numBytes < 0) {	numBytes = (bytes ? strlen(bytes) : 0);    }    if (numBytes == 0) {	return;    }    /*     * Copy the new string onto the end of the old string, then add the     * trailing null.     */    oldLength = objPtr->length;    newLength = numBytes + oldLength;    stringPtr = GET_STRING(objPtr);    if (newLength > (int) stringPtr->allocated) {	/*	 * There isn't currently enough space in the string representation	 * so allocate additional space.  First, try to double the length	 * required.  If that fails, try a more modest allocation.  See the	 * "TCL STRING GROWTH ALGORITHM" comment at the top of this file for an	 * explanation of this growth algorithm.	 */	if (Tcl_AttemptSetObjLength(objPtr, 2 * newLength) == 0) {	    Tcl_SetObjLength(objPtr,		    newLength + numBytes + TCL_GROWTH_MIN_ALLOC);	}    }    /*     * Invalidate the unicode data.     */        stringPtr->numChars = -1;

⌨️ 快捷键说明

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