tclstringobj.c

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

C
1,878
字号
		stringPtr = GET_STRING(objPtr);    }    if (stringPtr->hasUnicode == 0) {	/*	 * All of the characters in the Utf string are 1 byte chars,	 * so we don't store the unicode char.  We get the Utf string	 * and convert the index'th byte to a Unicode character.	 */	unichar = (Tcl_UniChar) objPtr->bytes[index];    } else {	unichar = stringPtr->unicode[index];    }    return unichar;}/* *---------------------------------------------------------------------- * * Tcl_GetUnicode -- * *	Get the Unicode form of the String object.  If *	the object is not already a String object, it will be converted *	to one.  If the String object does not have a Unicode rep, then *	one is create from the UTF string format. * * Results: *	Returns a pointer to the object's internal Unicode string. * * Side effects: *	Converts the object to have the String internal rep. * *---------------------------------------------------------------------- */Tcl_UniChar *Tcl_GetUnicode(objPtr)    Tcl_Obj *objPtr;	/* The object to find the unicode string for. */{    String *stringPtr;        SetStringFromAny(NULL, objPtr);    stringPtr = GET_STRING(objPtr);        if ((stringPtr->numChars == -1) || (stringPtr->hasUnicode == 0)) {	/*	 * We haven't yet calculated the length, or all of the characters	 * in the Utf string are 1 byte chars (so we didn't store the	 * unicode str).  Since this function must return a unicode string,	 * and one has not yet been stored, force the Unicode to be	 * calculated and stored now.	 */	FillUnicodeRep(objPtr);	/*	 * We need to fetch the pointer again because we have just	 * reallocated the structure to make room for the Unicode data.	 */		stringPtr = GET_STRING(objPtr);    }    return stringPtr->unicode;}/* *---------------------------------------------------------------------- * * Tcl_GetUnicodeFromObj -- * *	Get the Unicode form of the String object with length.  If *	the object is not already a String object, it will be converted *	to one.  If the String object does not have a Unicode rep, then *	one is create from the UTF string format. * * Results: *	Returns a pointer to the object's internal Unicode string. * * Side effects: *	Converts the object to have the String internal rep. * *---------------------------------------------------------------------- */Tcl_UniChar *Tcl_GetUnicodeFromObj(objPtr, lengthPtr)    Tcl_Obj *objPtr;	/* The object to find the unicode string for. */    int *lengthPtr;	/* If non-NULL, the location where the			 * string rep's unichar length should be			 * stored. If NULL, no length is stored. */{    String *stringPtr;        SetStringFromAny(NULL, objPtr);    stringPtr = GET_STRING(objPtr);        if ((stringPtr->numChars == -1) || (stringPtr->hasUnicode == 0)) {	/*	 * We haven't yet calculated the length, or all of the characters	 * in the Utf string are 1 byte chars (so we didn't store the	 * unicode str).  Since this function must return a unicode string,	 * and one has not yet been stored, force the Unicode to be	 * calculated and stored now.	 */	FillUnicodeRep(objPtr);	/*	 * We need to fetch the pointer again because we have just	 * reallocated the structure to make room for the Unicode data.	 */		stringPtr = GET_STRING(objPtr);    }    if (lengthPtr != NULL) {	*lengthPtr = stringPtr->numChars;    }    return stringPtr->unicode;}/* *---------------------------------------------------------------------- * * Tcl_GetRange -- * *	Create a Tcl Object that contains the chars between first and last *	of the object indicated by "objPtr".  If the object is not already *	a String object, convert it to one.  The first and last indices *	are assumed to be in the appropriate range. * * Results: *	Returns a new Tcl Object of the String type. * * Side effects: *	Changes the internal rep of "objPtr" to the String type. * *---------------------------------------------------------------------- */Tcl_Obj *Tcl_GetRange(objPtr, first, last)    Tcl_Obj *objPtr;		/* The Tcl object to find the range of. */    int first;			/* First index of the range. */    int last;			/* Last index of the range. */{    Tcl_Obj *newObjPtr;		/* The Tcl object to find the range of. */    String *stringPtr;        SetStringFromAny(NULL, objPtr);    stringPtr = GET_STRING(objPtr);    if (stringPtr->numChars == -1) {    	/*	 * We haven't yet calculated the length, so we don't have the	 * Unicode str.  We need to know the number of chars before we	 * can do indexing.	 */	Tcl_GetCharLength(objPtr);	/*	 * We need to fetch the pointer again because we may have just	 * reallocated the structure.	 */		stringPtr = GET_STRING(objPtr);    }    if (stringPtr->numChars == objPtr->length) {	char *str = Tcl_GetString(objPtr);	/*	 * All of the characters in the Utf string are 1 byte chars,	 * so we don't store the unicode char.  Create a new string	 * object containing the specified range of chars.	 */		newObjPtr = Tcl_NewStringObj(&str[first], last-first+1);	/*	 * Since we know the new string only has 1-byte chars, we	 * can set it's numChars field.	 */		SetStringFromAny(NULL, newObjPtr);	stringPtr = GET_STRING(newObjPtr);	stringPtr->numChars = last-first+1;    } else {	newObjPtr = Tcl_NewUnicodeObj(stringPtr->unicode + first,		last-first+1);    }    return newObjPtr;}/* *---------------------------------------------------------------------- * * Tcl_SetStringObj -- * *	Modify an object to hold a string that is a copy of the bytes *	indicated by the byte pointer and length arguments.  * * Results: *	None. * * Side effects: *	The object's string representation will be set to a copy of *	the "length" bytes starting at "bytes". If "length" is negative, use *	bytes up to the first NULL byte; i.e., assume "bytes" points to a *	C-style NULL-terminated string. The object's old string and internal *	representations are freed and the object's type is set NULL. * *---------------------------------------------------------------------- */voidTcl_SetStringObj(objPtr, bytes, length)    register Tcl_Obj *objPtr;	/* Object whose internal rep to init. */    CONST char *bytes;		/* Points to the first of the length bytes				 * used to initialize the object. */    register int length;	/* The number of bytes to copy from "bytes"				 * when initializing the object. If 				 * negative, use bytes up to the first				 * NULL byte.*/{    register Tcl_ObjType *oldTypePtr = objPtr->typePtr;    /*     * Free any old string rep, then set the string rep to a copy of     * the length bytes starting at "bytes".     */    if (Tcl_IsShared(objPtr)) {	panic("Tcl_SetStringObj called with shared object");    }    /*     * Set the type to NULL and free any internal rep for the old type.     */    if ((oldTypePtr != NULL) && (oldTypePtr->freeIntRepProc != NULL)) {	oldTypePtr->freeIntRepProc(objPtr);    }    objPtr->typePtr = NULL;    Tcl_InvalidateStringRep(objPtr);    if (length < 0) {	length = (bytes? strlen(bytes) : 0);    }    TclInitStringRep(objPtr, bytes, length);}/* *---------------------------------------------------------------------- * * Tcl_SetObjLength -- * *	This procedure changes the length of the string representation *	of an object. * * Results: *	None. * * Side effects: *	If the size of objPtr's string representation is greater than *	length, then it is reduced to length and a new terminating null *	byte is stored in the strength.  If the length of the string *	representation is greater than length, the storage space is *	reallocated to the given length; a null byte is stored at the *	end, but other bytes past the end of the original string *	representation are undefined.  The object's internal *	representation is changed to "expendable string". * *---------------------------------------------------------------------- */voidTcl_SetObjLength(objPtr, length)    register Tcl_Obj *objPtr;	/* Pointer to object.  This object must				 * not currently be shared. */    register int length;	/* Number of bytes desired for string				 * representation of object, not including				 * terminating null byte. */{    String *stringPtr;    if (Tcl_IsShared(objPtr)) {	panic("Tcl_SetObjLength called with shared object");    }    SetStringFromAny(NULL, objPtr);        stringPtr = GET_STRING(objPtr);        /* Check that we're not extending a pure unicode string */        if (length > (int) stringPtr->allocated && 	    (objPtr->bytes != NULL || stringPtr->hasUnicode == 0)) {	char *new;	/*	 * Not enough space in current string. Reallocate the string	 * space and free the old string.	 */	if (objPtr->bytes != tclEmptyStringRep && objPtr->bytes != NULL) {	    new = (char *) ckrealloc((char *)objPtr->bytes,		    (unsigned)(length+1));	} else {	    new = (char *) ckalloc((unsigned) (length+1));	    if (objPtr->bytes != NULL && objPtr->length != 0) {		memcpy((VOID *) new, (VOID *) objPtr->bytes,			(size_t) objPtr->length);		Tcl_InvalidateStringRep(objPtr);	    }	}	objPtr->bytes = new;	stringPtr->allocated = length;	/* Invalidate the unicode data. */	stringPtr->hasUnicode = 0;    }        if (objPtr->bytes != NULL) {        objPtr->length = length;        if (objPtr->bytes != tclEmptyStringRep) {            /* Ensure the string is NULL-terminated */            objPtr->bytes[length] = 0;        }        /* Invalidate the unicode data. */        stringPtr->numChars = -1;        stringPtr->hasUnicode = 0;    } else {        /* Changing length of pure unicode string */        size_t uallocated = STRING_UALLOC(length);        if (uallocated > stringPtr->uallocated) {            stringPtr = (String *) ckrealloc((char*) stringPtr,                    STRING_SIZE(uallocated));            SET_STRING(objPtr, stringPtr);            stringPtr->uallocated = uallocated;        }        stringPtr->numChars = length;        stringPtr->hasUnicode = (length > 0);        /* Ensure the string is NULL-terminated */        stringPtr->unicode[length] = 0;        stringPtr->allocated = 0;        objPtr->length = 0;    }}/* *---------------------------------------------------------------------- * * Tcl_AttemptSetObjLength -- * *	This procedure changes the length of the string representation *	of an object.  It uses the attempt* (non-panic'ing) memory allocators. * * Results: *	1 if the requested memory was allocated, 0 otherwise. * * Side effects: *	If the size of objPtr's string representation is greater than *	length, then it is reduced to length and a new terminating null *	byte is stored in the strength.  If the length of the string *	representation is greater than length, the storage space is *	reallocated to the given length; a null byte is stored at the *	end, but other bytes past the end of the original string *	representation are undefined.  The object's internal *	representation is changed to "expendable string". * *---------------------------------------------------------------------- */intTcl_AttemptSetObjLength(objPtr, length)    register Tcl_Obj *objPtr;	/* Pointer to object.  This object must				 * not currently be shared. */    register int length;	/* Number of bytes desired for string				 * representation of object, not including				 * terminating null byte. */{    String *stringPtr;    if (Tcl_IsShared(objPtr)) {	panic("Tcl_AttemptSetObjLength called with shared object");    }    SetStringFromAny(NULL, objPtr);            stringPtr = GET_STRING(objPtr);    /* Check that we're not extending a pure unicode string */    if (length > (int) stringPtr->allocated && 	    (objPtr->bytes != NULL || stringPtr->hasUnicode == 0)) {	char *new;	/*	 * Not enough space in current string. Reallocate the string	 * space and free the old string.	 */	if (objPtr->bytes != tclEmptyStringRep && objPtr->bytes != NULL) {	    new = (char *) attemptckrealloc((char *)objPtr->bytes,		    (unsigned)(length+1));	    if (new == NULL) {		return 0;	    }	} else {	    new = (char *) attemptckalloc((unsigned) (length+1));	    if (new == NULL) {		return 0;	    }	    if (objPtr->bytes != NULL && objPtr->length != 0) { 	    	memcpy((VOID *) new, (VOID *) objPtr->bytes, 		    	(size_t) objPtr->length); 	    	Tcl_InvalidateStringRep(objPtr);	    }	}	objPtr->bytes = new;	stringPtr->allocated = length;	/* Invalidate the unicode data. */	stringPtr->hasUnicode = 0;    }        if (objPtr->bytes != NULL) {	objPtr->length = length;	if (objPtr->bytes != tclEmptyStringRep) {	    /* Ensure the string is NULL-terminated */	    objPtr->bytes[length] = 0;	}	/* Invalidate the unicode data. */	stringPtr->numChars = -1;	stringPtr->hasUnicode = 0;    } else {	/* Changing length of pure unicode string */	size_t uallocated = STRING_UALLOC(length);	if (uallocated > stringPtr->uallocated) {	    stringPtr = (String *) attemptckrealloc((char*) stringPtr,		    STRING_SIZE(uallocated));	    if (stringPtr == NULL) {	        return 0;	    }	    SET_STRING(objPtr, stringPtr);	    stringPtr->uallocated = uallocated;	}	stringPtr->numChars = length;	stringPtr->hasUnicode = (length > 0);	/* Ensure the string is NULL-terminated */	stringPtr->unicode[length] = 0;	stringPtr->allocated = 0;	objPtr->length = 0;    }    return 1;}/* *--------------------------------------------------------------------------- * * TclSetUnicodeObj -- * *	Modify an object to hold the Unicode string indicated by "unicode". * * Results: *	None. * * Side effects: *	Memory allocated for new "String" internal rep.

⌨️ 快捷键说明

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