os/persistentdata/persistentstorage/sqlite3api/TEST/TCL/tcldistribution/generic/tclStringObj.c
First public contribution.
4 * This file contains procedures that implement string operations on Tcl
5 * objects. Some string operations work with UTF strings and others
6 * require Unicode format. Functions that require knowledge of the width
7 * of each character, such as indexing, operate on Unicode data.
9 * A Unicode string is an internationalized string. Conceptually, a
10 * Unicode string is an array of 16-bit quantities organized as a sequence
11 * of properly formed UTF-8 characters. There is a one-to-one map between
12 * Unicode and UTF characters. Because Unicode characters have a fixed
13 * width, operations such as indexing operate on Unicode data. The String
14 * object is optimized for the case where each UTF char in a string is
15 * only one byte. In this case, we store the value of numChars, but we
16 * don't store the Unicode data (unless Tcl_GetUnicode is explicitly
19 * The String object type stores one or both formats. The default
20 * behavior is to store UTF. Once Unicode is calculated by a function, it
21 * is stored in the internal rep for future access (without an additional
24 * To allow many appends to be done to an object without constantly
25 * reallocating the space for the string or Unicode representation, we
26 * allocate double the space for the string or Unicode and use the
27 * internal representation to keep track of how much space is used
30 * Copyright (c) 1995-1997 Sun Microsystems, Inc.
31 * Copyright (c) 1999 by Scriptics Corporation.
32 * Portions Copyright (c) 2007-2008 Nokia Corporation and/or its subsidiaries. All rights reserved.
34 * See the file "license.terms" for information on usage and redistribution
35 * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
37 * RCS: @(#) $Id: tclStringObj.c,v 1.32.2.2 2006/09/24 21:15:11 msofer Exp $ */
42 * Prototypes for procedures defined later in this file:
45 static void AppendUnicodeToUnicodeRep _ANSI_ARGS_((
46 Tcl_Obj *objPtr, CONST Tcl_UniChar *unicode,
48 static void AppendUnicodeToUtfRep _ANSI_ARGS_((
49 Tcl_Obj *objPtr, CONST Tcl_UniChar *unicode,
51 static void AppendUtfToUnicodeRep _ANSI_ARGS_((Tcl_Obj *objPtr,
52 CONST char *bytes, int numBytes));
53 static void AppendUtfToUtfRep _ANSI_ARGS_((Tcl_Obj *objPtr,
54 CONST char *bytes, int numBytes));
56 static void FillUnicodeRep _ANSI_ARGS_((Tcl_Obj *objPtr));
58 static void FreeStringInternalRep _ANSI_ARGS_((Tcl_Obj *objPtr));
59 static void DupStringInternalRep _ANSI_ARGS_((Tcl_Obj *objPtr,
61 static int SetStringFromAny _ANSI_ARGS_((Tcl_Interp *interp,
63 static void UpdateStringOfString _ANSI_ARGS_((Tcl_Obj *objPtr));
66 * The structure below defines the string Tcl object type by means of
67 * procedures that can be invoked by generic object code.
70 Tcl_ObjType tclStringType = {
72 FreeStringInternalRep, /* freeIntRepPro */
73 DupStringInternalRep, /* dupIntRepProc */
74 UpdateStringOfString, /* updateStringProc */
75 SetStringFromAny /* setFromAnyProc */
79 * The following structure is the internal rep for a String object.
80 * It keeps track of how much memory has been used and how much has been
81 * allocated for the Unicode and UTF string to enable growing and
82 * shrinking of the UTF and Unicode reps of the String object with fewer
83 * mallocs. To optimize string length and indexing operations, this
84 * structure also stores the number of characters (same of UTF and Unicode!)
85 * once that value has been computed.
88 typedef struct String {
89 int numChars; /* The number of chars in the string.
90 * -1 means this value has not been
91 * calculated. >= 0 means that there is a
92 * valid Unicode rep, or that the number
93 * of UTF bytes == the number of chars. */
94 size_t allocated; /* The amount of space actually allocated
95 * for the UTF string (minus 1 byte for
96 * the termination char). */
97 size_t uallocated; /* The amount of space actually allocated
98 * for the Unicode string (minus 2 bytes for
99 * the termination char). */
100 int hasUnicode; /* Boolean determining whether the string
101 * has a Unicode representation. */
102 Tcl_UniChar unicode[2]; /* The array of Unicode chars. The actual
103 * size of this field depends on the
104 * 'uallocated' field above. */
107 #define STRING_UALLOC(numChars) \
108 (numChars * sizeof(Tcl_UniChar))
109 #define STRING_SIZE(ualloc) \
110 ((unsigned) ((ualloc) \
111 ? sizeof(String) - sizeof(Tcl_UniChar) + (ualloc) \
113 #define GET_STRING(objPtr) \
114 ((String *) (objPtr)->internalRep.otherValuePtr)
115 #define SET_STRING(objPtr, stringPtr) \
116 (objPtr)->internalRep.otherValuePtr = (VOID *) (stringPtr)
119 * TCL STRING GROWTH ALGORITHM
121 * When growing strings (during an append, for example), the following growth
124 * Attempt to allocate 2 * (originalLength + appendLength)
126 * attempt to allocate originalLength + 2*appendLength +
127 * TCL_GROWTH_MIN_ALLOC
129 * This algorithm allows very good performance, as it rapidly increases the
130 * memory allocated for a given string, which minimizes the number of
131 * reallocations that must be performed. However, using only the doubling
132 * algorithm can lead to a significant waste of memory. In particular, it
133 * may fail even when there is sufficient memory available to complete the
134 * append request (but there is not 2 * totalLength memory available). So when
135 * the doubling fails (because there is not enough memory available), the
136 * algorithm requests a smaller amount of memory, which is still enough to
137 * cover the request, but which hopefully will be less than the total available
140 * The addition of TCL_GROWTH_MIN_ALLOC allows for efficient handling
141 * of very small appends. Without this extra slush factor, a sequence
142 * of several small appends would cause several memory allocations.
143 * As long as TCL_GROWTH_MIN_ALLOC is a reasonable size, we can
144 * avoid that behavior.
146 * The growth algorithm can be tuned by adjusting the following parameters:
148 * TCL_GROWTH_MIN_ALLOC Additional space, in bytes, to allocate when
149 * the double allocation has failed.
150 * Default is 1024 (1 kilobyte).
152 #ifndef TCL_GROWTH_MIN_ALLOC
153 #define TCL_GROWTH_MIN_ALLOC 1024
158 *----------------------------------------------------------------------
160 * Tcl_NewStringObj --
162 * This procedure is normally called when not debugging: i.e., when
163 * TCL_MEM_DEBUG is not defined. It creates a new string object and
164 * initializes it from the byte pointer and length arguments.
166 * When TCL_MEM_DEBUG is defined, this procedure just returns the
167 * result of calling the debugging version Tcl_DbNewStringObj.
170 * A newly created string object is returned that has ref count zero.
173 * The new object's internal string representation will be set to a
174 * copy of the length bytes starting at "bytes". If "length" is
175 * negative, use bytes up to the first NULL byte; i.e., assume "bytes"
176 * points to a C-style NULL-terminated string. The object's type is set
177 * to NULL. An extra NULL is added to the end of the new object's byte
180 *----------------------------------------------------------------------
184 #undef Tcl_NewStringObj
187 Tcl_NewStringObj(bytes, length)
188 CONST char *bytes; /* Points to the first of the length bytes
189 * used to initialize the new object. */
190 int length; /* The number of bytes to copy from "bytes"
191 * when initializing the new object. If
192 * negative, use bytes up to the first
195 return Tcl_DbNewStringObj(bytes, length, "unknown", 0);
198 #else /* if not TCL_MEM_DEBUG */
201 Tcl_NewStringObj(bytes, length)
202 CONST char *bytes; /* Points to the first of the length bytes
203 * used to initialize the new object. */
204 int length; /* The number of bytes to copy from "bytes"
205 * when initializing the new object. If
206 * negative, use bytes up to the first
209 register Tcl_Obj *objPtr;
212 length = (bytes? strlen(bytes) : 0);
215 TclInitStringRep(objPtr, bytes, length);
218 #endif /* TCL_MEM_DEBUG */
221 *----------------------------------------------------------------------
223 * Tcl_DbNewStringObj --
225 * This procedure is normally called when debugging: i.e., when
226 * TCL_MEM_DEBUG is defined. It creates new string objects. It is the
227 * same as the Tcl_NewStringObj procedure above except that it calls
228 * Tcl_DbCkalloc directly with the file name and line number from its
229 * caller. This simplifies debugging since then the [memory active]
230 * command will report the correct file name and line number when
231 * reporting objects that haven't been freed.
233 * When TCL_MEM_DEBUG is not defined, this procedure just returns the
234 * result of calling Tcl_NewStringObj.
237 * A newly created string object is returned that has ref count zero.
240 * The new object's internal string representation will be set to a
241 * copy of the length bytes starting at "bytes". If "length" is
242 * negative, use bytes up to the first NULL byte; i.e., assume "bytes"
243 * points to a C-style NULL-terminated string. The object's type is set
244 * to NULL. An extra NULL is added to the end of the new object's byte
247 *----------------------------------------------------------------------
253 Tcl_DbNewStringObj(bytes, length, file, line)
254 CONST char *bytes; /* Points to the first of the length bytes
255 * used to initialize the new object. */
256 int length; /* The number of bytes to copy from "bytes"
257 * when initializing the new object. If
258 * negative, use bytes up to the first
260 CONST char *file; /* The name of the source file calling this
261 * procedure; used for debugging. */
262 int line; /* Line number in the source file; used
265 register Tcl_Obj *objPtr;
268 length = (bytes? strlen(bytes) : 0);
270 TclDbNewObj(objPtr, file, line);
271 TclInitStringRep(objPtr, bytes, length);
275 #else /* if not TCL_MEM_DEBUG */
278 Tcl_DbNewStringObj(bytes, length, file, line)
279 CONST char *bytes; /* Points to the first of the length bytes
280 * used to initialize the new object. */
281 register int length; /* The number of bytes to copy from "bytes"
282 * when initializing the new object. If
283 * negative, use bytes up to the first
285 CONST char *file; /* The name of the source file calling this
286 * procedure; used for debugging. */
287 int line; /* Line number in the source file; used
290 return Tcl_NewStringObj(bytes, length);
292 #endif /* TCL_MEM_DEBUG */
295 *---------------------------------------------------------------------------
297 * Tcl_NewUnicodeObj --
299 * This procedure is creates a new String object and initializes
300 * it from the given Unicode String. If the Utf String is the same size
301 * as the Unicode string, don't duplicate the data.
304 * The newly created object is returned. This object will have no
305 * initial string representation. The returned object has a ref count
309 * Memory allocated for new object and copy of Unicode argument.
311 *---------------------------------------------------------------------------
315 Tcl_NewUnicodeObj(unicode, numChars)
316 CONST Tcl_UniChar *unicode; /* The unicode string used to initialize
318 int numChars; /* Number of characters in the unicode
328 while (unicode[numChars] != 0) { numChars++; }
331 uallocated = STRING_UALLOC(numChars);
334 * Create a new obj with an invalid string rep.
338 Tcl_InvalidateStringRep(objPtr);
339 objPtr->typePtr = &tclStringType;
341 stringPtr = (String *) ckalloc(STRING_SIZE(uallocated));
342 stringPtr->numChars = numChars;
343 stringPtr->uallocated = uallocated;
344 stringPtr->hasUnicode = (numChars > 0);
345 stringPtr->allocated = 0;
346 memcpy((VOID *) stringPtr->unicode, (VOID *) unicode, uallocated);
347 stringPtr->unicode[numChars] = 0;
348 SET_STRING(objPtr, stringPtr);
353 *----------------------------------------------------------------------
355 * Tcl_GetCharLength --
357 * Get the length of the Unicode string from the Tcl object.
360 * Pointer to unicode string representing the unicode object.
363 * Frees old internal rep. Allocates memory for new "String"
366 *----------------------------------------------------------------------
370 Tcl_GetCharLength(objPtr)
371 Tcl_Obj *objPtr; /* The String object to get the num chars of. */
375 SetStringFromAny(NULL, objPtr);
376 stringPtr = GET_STRING(objPtr);
379 * If numChars is unknown, then calculate the number of characaters
380 * while populating the Unicode string.
383 if (stringPtr->numChars == -1) {
384 register int i = objPtr->length;
385 register unsigned char *str = (unsigned char *) objPtr->bytes;
388 * This is a speed sensitive function, so run specially over the
389 * string to count continuous ascii characters before resorting
390 * to the Tcl_NumUtfChars call. This is a long form of:
391 stringPtr->numChars = Tcl_NumUtfChars(objPtr->bytes, objPtr->length);
394 while (i && (*str < 0xC0)) { i--; str++; }
395 stringPtr->numChars = objPtr->length - i;
397 stringPtr->numChars += Tcl_NumUtfChars(objPtr->bytes
398 + (objPtr->length - i), i);
401 if (stringPtr->numChars == objPtr->length) {
404 * Since we've just calculated the number of chars, and all
405 * UTF chars are 1-byte long, we don't need to store the
409 stringPtr->hasUnicode = 0;
414 * Since we've just calucalated the number of chars, and not
415 * all UTF chars are 1-byte long, go ahead and populate the
419 FillUnicodeRep(objPtr);
422 * We need to fetch the pointer again because we have just
423 * reallocated the structure to make room for the Unicode data.
426 stringPtr = GET_STRING(objPtr);
429 return stringPtr->numChars;
433 *----------------------------------------------------------------------
437 * Get the index'th Unicode character from the String object. The
438 * index is assumed to be in the appropriate range.
441 * Returns the index'th Unicode character in the Object.
444 * Fills unichar with the index'th Unicode character.
446 *----------------------------------------------------------------------
450 Tcl_GetUniChar(objPtr, index)
451 Tcl_Obj *objPtr; /* The object to get the Unicode charater from. */
452 int index; /* Get the index'th Unicode character. */
457 SetStringFromAny(NULL, objPtr);
458 stringPtr = GET_STRING(objPtr);
460 if (stringPtr->numChars == -1) {
463 * We haven't yet calculated the length, so we don't have the
464 * Unicode str. We need to know the number of chars before we
468 Tcl_GetCharLength(objPtr);
471 * We need to fetch the pointer again because we may have just
472 * reallocated the structure.
475 stringPtr = GET_STRING(objPtr);
477 if (stringPtr->hasUnicode == 0) {
480 * All of the characters in the Utf string are 1 byte chars,
481 * so we don't store the unicode char. We get the Utf string
482 * and convert the index'th byte to a Unicode character.
485 unichar = (Tcl_UniChar) objPtr->bytes[index];
487 unichar = stringPtr->unicode[index];
493 *----------------------------------------------------------------------
497 * Get the Unicode form of the String object. If
498 * the object is not already a String object, it will be converted
499 * to one. If the String object does not have a Unicode rep, then
500 * one is create from the UTF string format.
503 * Returns a pointer to the object's internal Unicode string.
506 * Converts the object to have the String internal rep.
508 *----------------------------------------------------------------------
511 EXPORT_C Tcl_UniChar *
512 Tcl_GetUnicode(objPtr)
513 Tcl_Obj *objPtr; /* The object to find the unicode string for. */
517 SetStringFromAny(NULL, objPtr);
518 stringPtr = GET_STRING(objPtr);
520 if ((stringPtr->numChars == -1) || (stringPtr->hasUnicode == 0)) {
523 * We haven't yet calculated the length, or all of the characters
524 * in the Utf string are 1 byte chars (so we didn't store the
525 * unicode str). Since this function must return a unicode string,
526 * and one has not yet been stored, force the Unicode to be
527 * calculated and stored now.
530 FillUnicodeRep(objPtr);
533 * We need to fetch the pointer again because we have just
534 * reallocated the structure to make room for the Unicode data.
537 stringPtr = GET_STRING(objPtr);
539 return stringPtr->unicode;
543 *----------------------------------------------------------------------
545 * Tcl_GetUnicodeFromObj --
547 * Get the Unicode form of the String object with length. If
548 * the object is not already a String object, it will be converted
549 * to one. If the String object does not have a Unicode rep, then
550 * one is create from the UTF string format.
553 * Returns a pointer to the object's internal Unicode string.
556 * Converts the object to have the String internal rep.
558 *----------------------------------------------------------------------
561 EXPORT_C Tcl_UniChar *
562 Tcl_GetUnicodeFromObj(objPtr, lengthPtr)
563 Tcl_Obj *objPtr; /* The object to find the unicode string for. */
564 int *lengthPtr; /* If non-NULL, the location where the
565 * string rep's unichar length should be
566 * stored. If NULL, no length is stored. */
570 SetStringFromAny(NULL, objPtr);
571 stringPtr = GET_STRING(objPtr);
573 if ((stringPtr->numChars == -1) || (stringPtr->hasUnicode == 0)) {
576 * We haven't yet calculated the length, or all of the characters
577 * in the Utf string are 1 byte chars (so we didn't store the
578 * unicode str). Since this function must return a unicode string,
579 * and one has not yet been stored, force the Unicode to be
580 * calculated and stored now.
583 FillUnicodeRep(objPtr);
586 * We need to fetch the pointer again because we have just
587 * reallocated the structure to make room for the Unicode data.
590 stringPtr = GET_STRING(objPtr);
593 if (lengthPtr != NULL) {
594 *lengthPtr = stringPtr->numChars;
596 return stringPtr->unicode;
600 *----------------------------------------------------------------------
604 * Create a Tcl Object that contains the chars between first and last
605 * of the object indicated by "objPtr". If the object is not already
606 * a String object, convert it to one. The first and last indices
607 * are assumed to be in the appropriate range.
610 * Returns a new Tcl Object of the String type.
613 * Changes the internal rep of "objPtr" to the String type.
615 *----------------------------------------------------------------------
619 Tcl_GetRange(objPtr, first, last)
620 Tcl_Obj *objPtr; /* The Tcl object to find the range of. */
621 int first; /* First index of the range. */
622 int last; /* Last index of the range. */
624 Tcl_Obj *newObjPtr; /* The Tcl object to find the range of. */
627 SetStringFromAny(NULL, objPtr);
628 stringPtr = GET_STRING(objPtr);
630 if (stringPtr->numChars == -1) {
633 * We haven't yet calculated the length, so we don't have the
634 * Unicode str. We need to know the number of chars before we
638 Tcl_GetCharLength(objPtr);
641 * We need to fetch the pointer again because we may have just
642 * reallocated the structure.
645 stringPtr = GET_STRING(objPtr);
648 if (objPtr->bytes && stringPtr->numChars == objPtr->length) {
649 char *str = Tcl_GetString(objPtr);
652 * All of the characters in the Utf string are 1 byte chars,
653 * so we don't store the unicode char. Create a new string
654 * object containing the specified range of chars.
657 newObjPtr = Tcl_NewStringObj(&str[first], last-first+1);
660 * Since we know the new string only has 1-byte chars, we
661 * can set it's numChars field.
664 SetStringFromAny(NULL, newObjPtr);
665 stringPtr = GET_STRING(newObjPtr);
666 stringPtr->numChars = last-first+1;
668 newObjPtr = Tcl_NewUnicodeObj(stringPtr->unicode + first,
675 *----------------------------------------------------------------------
677 * Tcl_SetStringObj --
679 * Modify an object to hold a string that is a copy of the bytes
680 * indicated by the byte pointer and length arguments.
686 * The object's string representation will be set to a copy of
687 * the "length" bytes starting at "bytes". If "length" is negative, use
688 * bytes up to the first NULL byte; i.e., assume "bytes" points to a
689 * C-style NULL-terminated string. The object's old string and internal
690 * representations are freed and the object's type is set NULL.
692 *----------------------------------------------------------------------
696 Tcl_SetStringObj(objPtr, bytes, length)
697 register Tcl_Obj *objPtr; /* Object whose internal rep to init. */
698 CONST char *bytes; /* Points to the first of the length bytes
699 * used to initialize the object. */
700 register int length; /* The number of bytes to copy from "bytes"
701 * when initializing the object. If
702 * negative, use bytes up to the first
705 register Tcl_ObjType *oldTypePtr = objPtr->typePtr;
708 * Free any old string rep, then set the string rep to a copy of
709 * the length bytes starting at "bytes".
712 if (Tcl_IsShared(objPtr)) {
713 panic("Tcl_SetStringObj called with shared object");
717 * Set the type to NULL and free any internal rep for the old type.
720 if ((oldTypePtr != NULL) && (oldTypePtr->freeIntRepProc != NULL)) {
721 oldTypePtr->freeIntRepProc(objPtr);
723 objPtr->typePtr = NULL;
725 Tcl_InvalidateStringRep(objPtr);
727 length = (bytes? strlen(bytes) : 0);
729 TclInitStringRep(objPtr, bytes, length);
733 *----------------------------------------------------------------------
735 * Tcl_SetObjLength --
737 * This procedure changes the length of the string representation
744 * If the size of objPtr's string representation is greater than
745 * length, then it is reduced to length and a new terminating null
746 * byte is stored in the strength. If the length of the string
747 * representation is greater than length, the storage space is
748 * reallocated to the given length; a null byte is stored at the
749 * end, but other bytes past the end of the original string
750 * representation are undefined. The object's internal
751 * representation is changed to "expendable string".
753 *----------------------------------------------------------------------
757 Tcl_SetObjLength(objPtr, length)
758 register Tcl_Obj *objPtr; /* Pointer to object. This object must
759 * not currently be shared. */
760 register int length; /* Number of bytes desired for string
761 * representation of object, not including
762 * terminating null byte. */
766 if (Tcl_IsShared(objPtr)) {
767 panic("Tcl_SetObjLength called with shared object");
769 SetStringFromAny(NULL, objPtr);
771 stringPtr = GET_STRING(objPtr);
773 /* Check that we're not extending a pure unicode string */
775 if (length > (int) stringPtr->allocated &&
776 (objPtr->bytes != NULL || stringPtr->hasUnicode == 0)) {
780 * Not enough space in current string. Reallocate the string
781 * space and free the old string.
783 if (objPtr->bytes != tclEmptyStringRep && objPtr->bytes != NULL) {
784 new = (char *) ckrealloc((char *)objPtr->bytes,
785 (unsigned)(length+1));
787 new = (char *) ckalloc((unsigned) (length+1));
788 if (objPtr->bytes != NULL && objPtr->length != 0) {
789 memcpy((VOID *) new, (VOID *) objPtr->bytes,
790 (size_t) objPtr->length);
791 Tcl_InvalidateStringRep(objPtr);
795 stringPtr->allocated = length;
796 /* Invalidate the unicode data. */
797 stringPtr->hasUnicode = 0;
800 if (objPtr->bytes != NULL) {
801 objPtr->length = length;
802 if (objPtr->bytes != tclEmptyStringRep) {
803 /* Ensure the string is NULL-terminated */
804 objPtr->bytes[length] = 0;
806 /* Invalidate the unicode data. */
807 stringPtr->numChars = -1;
808 stringPtr->hasUnicode = 0;
810 /* Changing length of pure unicode string */
811 size_t uallocated = STRING_UALLOC(length);
812 if (uallocated > stringPtr->uallocated) {
813 stringPtr = (String *) ckrealloc((char*) stringPtr,
814 STRING_SIZE(uallocated));
815 SET_STRING(objPtr, stringPtr);
816 stringPtr->uallocated = uallocated;
818 stringPtr->numChars = length;
819 stringPtr->hasUnicode = (length > 0);
820 /* Ensure the string is NULL-terminated */
821 stringPtr->unicode[length] = 0;
822 stringPtr->allocated = 0;
828 *----------------------------------------------------------------------
830 * Tcl_AttemptSetObjLength --
832 * This procedure changes the length of the string representation
833 * of an object. It uses the attempt* (non-panic'ing) memory allocators.
836 * 1 if the requested memory was allocated, 0 otherwise.
839 * If the size of objPtr's string representation is greater than
840 * length, then it is reduced to length and a new terminating null
841 * byte is stored in the strength. If the length of the string
842 * representation is greater than length, the storage space is
843 * reallocated to the given length; a null byte is stored at the
844 * end, but other bytes past the end of the original string
845 * representation are undefined. The object's internal
846 * representation is changed to "expendable string".
848 *----------------------------------------------------------------------
852 Tcl_AttemptSetObjLength(objPtr, length)
853 register Tcl_Obj *objPtr; /* Pointer to object. This object must
854 * not currently be shared. */
855 register int length; /* Number of bytes desired for string
856 * representation of object, not including
857 * terminating null byte. */
861 if (Tcl_IsShared(objPtr)) {
862 panic("Tcl_AttemptSetObjLength called with shared object");
864 SetStringFromAny(NULL, objPtr);
866 stringPtr = GET_STRING(objPtr);
868 /* Check that we're not extending a pure unicode string */
870 if (length > (int) stringPtr->allocated &&
871 (objPtr->bytes != NULL || stringPtr->hasUnicode == 0)) {
875 * Not enough space in current string. Reallocate the string
876 * space and free the old string.
878 if (objPtr->bytes != tclEmptyStringRep && objPtr->bytes != NULL) {
879 new = (char *) attemptckrealloc((char *)objPtr->bytes,
880 (unsigned)(length+1));
885 new = (char *) attemptckalloc((unsigned) (length+1));
889 if (objPtr->bytes != NULL && objPtr->length != 0) {
890 memcpy((VOID *) new, (VOID *) objPtr->bytes,
891 (size_t) objPtr->length);
892 Tcl_InvalidateStringRep(objPtr);
896 stringPtr->allocated = length;
897 /* Invalidate the unicode data. */
898 stringPtr->hasUnicode = 0;
901 if (objPtr->bytes != NULL) {
902 objPtr->length = length;
903 if (objPtr->bytes != tclEmptyStringRep) {
904 /* Ensure the string is NULL-terminated */
905 objPtr->bytes[length] = 0;
907 /* Invalidate the unicode data. */
908 stringPtr->numChars = -1;
909 stringPtr->hasUnicode = 0;
911 /* Changing length of pure unicode string */
912 size_t uallocated = STRING_UALLOC(length);
913 if (uallocated > stringPtr->uallocated) {
914 stringPtr = (String *) attemptckrealloc((char*) stringPtr,
915 STRING_SIZE(uallocated));
916 if (stringPtr == NULL) {
919 SET_STRING(objPtr, stringPtr);
920 stringPtr->uallocated = uallocated;
922 stringPtr->numChars = length;
923 stringPtr->hasUnicode = (length > 0);
924 /* Ensure the string is NULL-terminated */
925 stringPtr->unicode[length] = 0;
926 stringPtr->allocated = 0;
933 *---------------------------------------------------------------------------
935 * TclSetUnicodeObj --
937 * Modify an object to hold the Unicode string indicated by "unicode".
943 * Memory allocated for new "String" internal rep.
945 *---------------------------------------------------------------------------
949 Tcl_SetUnicodeObj(objPtr, unicode, numChars)
950 Tcl_Obj *objPtr; /* The object to set the string of. */
951 CONST Tcl_UniChar *unicode; /* The unicode string used to initialize
953 int numChars; /* Number of characters in the unicode
956 Tcl_ObjType *typePtr;
963 while (unicode[numChars] != 0) { numChars++; }
966 uallocated = STRING_UALLOC(numChars);
969 * Free the internal rep if one exists, and invalidate the string rep.
972 typePtr = objPtr->typePtr;
973 if ((typePtr != NULL) && (typePtr->freeIntRepProc) != NULL) {
974 (*typePtr->freeIntRepProc)(objPtr);
976 objPtr->typePtr = &tclStringType;
979 * Allocate enough space for the String structure + Unicode string.
982 stringPtr = (String *) ckalloc(STRING_SIZE(uallocated));
983 stringPtr->numChars = numChars;
984 stringPtr->uallocated = uallocated;
985 stringPtr->hasUnicode = (numChars > 0);
986 stringPtr->allocated = 0;
987 memcpy((VOID *) stringPtr->unicode, (VOID *) unicode, uallocated);
988 stringPtr->unicode[numChars] = 0;
989 SET_STRING(objPtr, stringPtr);
990 Tcl_InvalidateStringRep(objPtr);
995 *----------------------------------------------------------------------
999 * This procedure appends a sequence of bytes to an object.
1005 * The bytes at *bytes are appended to the string representation
1008 *----------------------------------------------------------------------
1012 Tcl_AppendToObj(objPtr, bytes, length)
1013 register Tcl_Obj *objPtr; /* Points to the object to append to. */
1014 CONST char *bytes; /* Points to the bytes to append to the
1016 register int length; /* The number of bytes to append from
1017 * "bytes". If < 0, then append all bytes
1018 * up to NULL byte. */
1022 if (Tcl_IsShared(objPtr)) {
1023 panic("Tcl_AppendToObj called with shared object");
1026 SetStringFromAny(NULL, objPtr);
1029 length = (bytes ? strlen(bytes) : 0);
1036 * If objPtr has a valid Unicode rep, then append the Unicode
1037 * conversion of "bytes" to the objPtr's Unicode rep, otherwise
1038 * append "bytes" to objPtr's string rep.
1041 stringPtr = GET_STRING(objPtr);
1042 if (stringPtr->hasUnicode != 0) {
1043 AppendUtfToUnicodeRep(objPtr, bytes, length);
1045 stringPtr = GET_STRING(objPtr);
1047 AppendUtfToUtfRep(objPtr, bytes, length);
1052 *----------------------------------------------------------------------
1054 * Tcl_AppendUnicodeToObj --
1056 * This procedure appends a Unicode string to an object in the
1057 * most efficient manner possible. Length must be >= 0.
1063 * Invalidates the string rep and creates a new Unicode string.
1065 *----------------------------------------------------------------------
1069 Tcl_AppendUnicodeToObj(objPtr, unicode, length)
1070 register Tcl_Obj *objPtr; /* Points to the object to append to. */
1071 CONST Tcl_UniChar *unicode; /* The unicode string to append to the
1073 int length; /* Number of chars in "unicode". */
1077 if (Tcl_IsShared(objPtr)) {
1078 panic("Tcl_AppendUnicodeToObj called with shared object");
1085 SetStringFromAny(NULL, objPtr);
1086 stringPtr = GET_STRING(objPtr);
1089 * If objPtr has a valid Unicode rep, then append the "unicode"
1090 * to the objPtr's Unicode rep, otherwise the UTF conversion of
1091 * "unicode" to objPtr's string rep.
1094 if (stringPtr->hasUnicode != 0) {
1095 AppendUnicodeToUnicodeRep(objPtr, unicode, length);
1097 AppendUnicodeToUtfRep(objPtr, unicode, length);
1102 *----------------------------------------------------------------------
1104 * Tcl_AppendObjToObj --
1106 * This procedure appends the string rep of one object to another.
1107 * "objPtr" cannot be a shared object.
1113 * The string rep of appendObjPtr is appended to the string
1114 * representation of objPtr.
1116 *----------------------------------------------------------------------
1120 Tcl_AppendObjToObj(objPtr, appendObjPtr)
1121 Tcl_Obj *objPtr; /* Points to the object to append to. */
1122 Tcl_Obj *appendObjPtr; /* Object to append. */
1125 int length, numChars, allOneByteChars;
1128 SetStringFromAny(NULL, objPtr);
1131 * If objPtr has a valid Unicode rep, then get a Unicode string
1132 * from appendObjPtr and append it.
1135 stringPtr = GET_STRING(objPtr);
1136 if (stringPtr->hasUnicode != 0) {
1139 * If appendObjPtr is not of the "String" type, don't convert it.
1142 if (appendObjPtr->typePtr == &tclStringType) {
1143 stringPtr = GET_STRING(appendObjPtr);
1144 if ((stringPtr->numChars == -1)
1145 || (stringPtr->hasUnicode == 0)) {
1148 * If appendObjPtr is a string obj with no valid Unicode
1149 * rep, then fill its unicode rep.
1152 FillUnicodeRep(appendObjPtr);
1153 stringPtr = GET_STRING(appendObjPtr);
1155 AppendUnicodeToUnicodeRep(objPtr, stringPtr->unicode,
1156 stringPtr->numChars);
1158 bytes = Tcl_GetStringFromObj(appendObjPtr, &length);
1159 AppendUtfToUnicodeRep(objPtr, bytes, length);
1165 * Append to objPtr's UTF string rep. If we know the number of
1166 * characters in both objects before appending, then set the combined
1167 * number of characters in the final (appended-to) object.
1170 bytes = Tcl_GetStringFromObj(appendObjPtr, &length);
1172 allOneByteChars = 0;
1173 numChars = stringPtr->numChars;
1174 if ((numChars >= 0) && (appendObjPtr->typePtr == &tclStringType)) {
1175 stringPtr = GET_STRING(appendObjPtr);
1176 if ((stringPtr->numChars >= 0) && (stringPtr->numChars == length)) {
1177 numChars += stringPtr->numChars;
1178 allOneByteChars = 1;
1182 AppendUtfToUtfRep(objPtr, bytes, length);
1184 if (allOneByteChars) {
1185 stringPtr = GET_STRING(objPtr);
1186 stringPtr->numChars = numChars;
1191 *----------------------------------------------------------------------
1193 * AppendUnicodeToUnicodeRep --
1195 * This procedure appends the contents of "unicode" to the Unicode
1196 * rep of "objPtr". objPtr must already have a valid Unicode rep.
1202 * objPtr's internal rep is reallocated.
1204 *----------------------------------------------------------------------
1208 AppendUnicodeToUnicodeRep(objPtr, unicode, appendNumChars)
1209 Tcl_Obj *objPtr; /* Points to the object to append to. */
1210 CONST Tcl_UniChar *unicode; /* String to append. */
1211 int appendNumChars; /* Number of chars of "unicode" to append. */
1213 String *stringPtr, *tmpString;
1216 if (appendNumChars < 0) {
1219 while (unicode[appendNumChars] != 0) { appendNumChars++; }
1222 if (appendNumChars == 0) {
1226 SetStringFromAny(NULL, objPtr);
1227 stringPtr = GET_STRING(objPtr);
1230 * If not enough space has been allocated for the unicode rep,
1231 * reallocate the internal rep object with additional space. First
1232 * try to double the required allocation; if that fails, try a more
1233 * modest increase. See the "TCL STRING GROWTH ALGORITHM" comment at
1234 * the top of this file for an explanation of this growth algorithm.
1237 numChars = stringPtr->numChars + appendNumChars;
1239 if (STRING_UALLOC(numChars) >= stringPtr->uallocated) {
1240 stringPtr->uallocated = STRING_UALLOC(2 * numChars);
1241 tmpString = (String *) attemptckrealloc((char *)stringPtr,
1242 STRING_SIZE(stringPtr->uallocated));
1243 if (tmpString == NULL) {
1244 stringPtr->uallocated =
1245 STRING_UALLOC(numChars + appendNumChars)
1246 + TCL_GROWTH_MIN_ALLOC;
1247 tmpString = (String *) ckrealloc((char *)stringPtr,
1248 STRING_SIZE(stringPtr->uallocated));
1250 stringPtr = tmpString;
1251 SET_STRING(objPtr, stringPtr);
1255 * Copy the new string onto the end of the old string, then add the
1259 memcpy((VOID*) (stringPtr->unicode + stringPtr->numChars), unicode,
1260 appendNumChars * sizeof(Tcl_UniChar));
1261 stringPtr->unicode[numChars] = 0;
1262 stringPtr->numChars = numChars;
1264 Tcl_InvalidateStringRep(objPtr);
1268 *----------------------------------------------------------------------
1270 * AppendUnicodeToUtfRep --
1272 * This procedure converts the contents of "unicode" to UTF and
1273 * appends the UTF to the string rep of "objPtr".
1279 * objPtr's internal rep is reallocated.
1281 *----------------------------------------------------------------------
1285 AppendUnicodeToUtfRep(objPtr, unicode, numChars)
1286 Tcl_Obj *objPtr; /* Points to the object to append to. */
1287 CONST Tcl_UniChar *unicode; /* String to convert to UTF. */
1288 int numChars; /* Number of chars of "unicode" to convert. */
1296 while (unicode[numChars] != 0) { numChars++; }
1299 if (numChars == 0) {
1303 Tcl_DStringInit(&dsPtr);
1304 bytes = Tcl_UniCharToUtfDString(unicode, numChars, &dsPtr);
1305 AppendUtfToUtfRep(objPtr, bytes, Tcl_DStringLength(&dsPtr));
1306 Tcl_DStringFree(&dsPtr);
1310 *----------------------------------------------------------------------
1312 * AppendUtfToUnicodeRep --
1314 * This procedure converts the contents of "bytes" to Unicode and
1315 * appends the Unicode to the Unicode rep of "objPtr". objPtr must
1316 * already have a valid Unicode rep.
1322 * objPtr's internal rep is reallocated.
1324 *----------------------------------------------------------------------
1328 AppendUtfToUnicodeRep(objPtr, bytes, numBytes)
1329 Tcl_Obj *objPtr; /* Points to the object to append to. */
1330 CONST char *bytes; /* String to convert to Unicode. */
1331 int numBytes; /* Number of bytes of "bytes" to convert. */
1335 Tcl_UniChar *unicode;
1338 numBytes = (bytes ? strlen(bytes) : 0);
1340 if (numBytes == 0) {
1344 Tcl_DStringInit(&dsPtr);
1345 numChars = Tcl_NumUtfChars(bytes, numBytes);
1346 unicode = (Tcl_UniChar *)Tcl_UtfToUniCharDString(bytes, numBytes, &dsPtr);
1347 AppendUnicodeToUnicodeRep(objPtr, unicode, numChars);
1348 Tcl_DStringFree(&dsPtr);
1352 *----------------------------------------------------------------------
1354 * AppendUtfToUtfRep --
1356 * This procedure appends "numBytes" bytes of "bytes" to the UTF string
1357 * rep of "objPtr". objPtr must already have a valid String rep.
1363 * objPtr's internal rep is reallocated.
1365 *----------------------------------------------------------------------
1369 AppendUtfToUtfRep(objPtr, bytes, numBytes)
1370 Tcl_Obj *objPtr; /* Points to the object to append to. */
1371 CONST char *bytes; /* String to append. */
1372 int numBytes; /* Number of bytes of "bytes" to append. */
1375 int newLength, oldLength;
1378 numBytes = (bytes ? strlen(bytes) : 0);
1380 if (numBytes == 0) {
1385 * Copy the new string onto the end of the old string, then add the
1389 oldLength = objPtr->length;
1390 newLength = numBytes + oldLength;
1392 stringPtr = GET_STRING(objPtr);
1393 if (newLength > (int) stringPtr->allocated) {
1396 * There isn't currently enough space in the string representation
1397 * so allocate additional space. First, try to double the length
1398 * required. If that fails, try a more modest allocation. See the
1399 * "TCL STRING GROWTH ALGORITHM" comment at the top of this file for an
1400 * explanation of this growth algorithm.
1403 if (Tcl_AttemptSetObjLength(objPtr, 2 * newLength) == 0) {
1404 Tcl_SetObjLength(objPtr,
1405 newLength + numBytes + TCL_GROWTH_MIN_ALLOC);
1410 * Invalidate the unicode data.
1413 stringPtr->numChars = -1;
1414 stringPtr->hasUnicode = 0;
1416 memcpy((VOID *) (objPtr->bytes + oldLength), (VOID *) bytes,
1418 objPtr->bytes[newLength] = 0;
1419 objPtr->length = newLength;
1423 *----------------------------------------------------------------------
1425 * Tcl_AppendStringsToObjVA --
1427 * This procedure appends one or more null-terminated strings
1434 * The contents of all the string arguments are appended to the
1435 * string representation of objPtr.
1437 *----------------------------------------------------------------------
1441 Tcl_AppendStringsToObjVA (objPtr, argList)
1442 Tcl_Obj *objPtr; /* Points to the object to append to. */
1443 va_list argList; /* Variable argument list. */
1445 #define STATIC_LIST_SIZE 16
1447 int newLength, oldLength, attemptLength;
1448 register char *string, *dst;
1449 char *static_list[STATIC_LIST_SIZE];
1450 char **args = static_list;
1451 int nargs_space = STATIC_LIST_SIZE;
1454 if (Tcl_IsShared(objPtr)) {
1455 panic("Tcl_AppendStringsToObj called with shared object");
1458 SetStringFromAny(NULL, objPtr);
1461 * Figure out how much space is needed for all the strings, and
1462 * expand the string representation if it isn't big enough. If no
1463 * bytes would be appended, just return. Note that on some platforms
1464 * (notably OS/390) the argList is an array so we need to use memcpy.
1469 oldLength = objPtr->length;
1471 string = va_arg(argList, char *);
1472 if (string == NULL) {
1475 if (nargs >= nargs_space) {
1477 * Expand the args buffer
1479 nargs_space += STATIC_LIST_SIZE;
1480 if (args == static_list) {
1481 args = (void *)ckalloc(nargs_space * sizeof(char *));
1482 for (i = 0; i < nargs; ++i) {
1483 args[i] = static_list[i];
1486 args = (void *)ckrealloc((void *)args,
1487 nargs_space * sizeof(char *));
1490 newLength += strlen(string);
1491 args[nargs++] = string;
1493 if (newLength == 0) {
1497 stringPtr = GET_STRING(objPtr);
1498 if (oldLength + newLength > (int) stringPtr->allocated) {
1501 * There isn't currently enough space in the string
1502 * representation, so allocate additional space. If the current
1503 * string representation isn't empty (i.e. it looks like we're
1504 * doing a series of appends) then try to allocate extra space to
1505 * accomodate future growth: first try to double the required memory;
1506 * if that fails, try a more modest allocation. See the "TCL STRING
1507 * GROWTH ALGORITHM" comment at the top of this file for an explanation
1508 * of this growth algorithm. Otherwise, if the current string
1509 * representation is empty, exactly enough memory is allocated.
1512 if (oldLength == 0) {
1513 Tcl_SetObjLength(objPtr, newLength);
1515 attemptLength = 2 * (oldLength + newLength);
1516 if (Tcl_AttemptSetObjLength(objPtr, attemptLength) == 0) {
1517 attemptLength = oldLength + (2 * newLength) +
1518 TCL_GROWTH_MIN_ALLOC;
1519 Tcl_SetObjLength(objPtr, attemptLength);
1525 * Make a second pass through the arguments, appending all the
1526 * strings to the object.
1529 dst = objPtr->bytes + oldLength;
1530 for (i = 0; i < nargs; ++i) {
1532 if (string == NULL) {
1535 while (*string != 0) {
1543 * Add a null byte to terminate the string. However, be careful:
1544 * it's possible that the object is totally empty (if it was empty
1545 * originally and there was nothing to append). In this case dst is
1546 * NULL; just leave everything alone.
1552 objPtr->length = oldLength + newLength;
1556 * If we had to allocate a buffer from the heap,
1560 if (args != static_list) {
1561 ckfree((void *)args);
1563 #undef STATIC_LIST_SIZE
1567 *----------------------------------------------------------------------
1569 * Tcl_AppendStringsToObj --
1571 * This procedure appends one or more null-terminated strings
1578 * The contents of all the string arguments are appended to the
1579 * string representation of objPtr.
1581 *----------------------------------------------------------------------
1585 Tcl_AppendStringsToObj TCL_VARARGS_DEF(Tcl_Obj *,arg1)
1587 register Tcl_Obj *objPtr;
1590 objPtr = TCL_VARARGS_START(Tcl_Obj *,arg1,argList);
1591 Tcl_AppendStringsToObjVA(objPtr, argList);
1596 *---------------------------------------------------------------------------
1600 * Populate the Unicode internal rep with the Unicode form of its string
1601 * rep. The object must alread have a "String" internal rep.
1607 * Reallocates the String internal rep.
1609 *---------------------------------------------------------------------------
1613 FillUnicodeRep(objPtr)
1614 Tcl_Obj *objPtr; /* The object in which to fill the unicode rep. */
1620 src = objPtr->bytes;
1622 stringPtr = GET_STRING(objPtr);
1623 if (stringPtr->numChars == -1) {
1624 stringPtr->numChars = Tcl_NumUtfChars(src, objPtr->length);
1626 stringPtr->hasUnicode = (stringPtr->numChars > 0);
1628 uallocated = STRING_UALLOC(stringPtr->numChars);
1629 if (uallocated > stringPtr->uallocated) {
1632 * If not enough space has been allocated for the unicode rep,
1633 * reallocate the internal rep object.
1637 * There isn't currently enough space in the Unicode
1638 * representation so allocate additional space. If the current
1639 * Unicode representation isn't empty (i.e. it looks like we've
1640 * done some appends) then overallocate the space so
1641 * that we won't have to do as much reallocation in the future.
1644 if (stringPtr->uallocated > 0) {
1647 stringPtr = (String *) ckrealloc((char*) stringPtr,
1648 STRING_SIZE(uallocated));
1649 stringPtr->uallocated = uallocated;
1653 * Convert src to Unicode and store the coverted data in "unicode".
1656 srcEnd = src + objPtr->length;
1657 for (dst = stringPtr->unicode; src < srcEnd; dst++) {
1658 src += TclUtfToUniChar(src, dst);
1662 SET_STRING(objPtr, stringPtr);
1666 *----------------------------------------------------------------------
1668 * DupStringInternalRep --
1670 * Initialize the internal representation of a new Tcl_Obj to a
1671 * copy of the internal representation of an existing string object.
1677 * copyPtr's internal rep is set to a copy of srcPtr's internal
1680 *----------------------------------------------------------------------
1684 DupStringInternalRep(srcPtr, copyPtr)
1685 register Tcl_Obj *srcPtr; /* Object with internal rep to copy. Must
1686 * have an internal rep of type "String". */
1687 register Tcl_Obj *copyPtr; /* Object with internal rep to set. Must
1688 * not currently have an internal rep.*/
1690 String *srcStringPtr = GET_STRING(srcPtr);
1691 String *copyStringPtr = NULL;
1694 * If the src obj is a string of 1-byte Utf chars, then copy the
1695 * string rep of the source object and create an "empty" Unicode
1696 * internal rep for the new object. Otherwise, copy Unicode
1697 * internal rep, and invalidate the string rep of the new object.
1700 if (srcStringPtr->hasUnicode == 0) {
1701 copyStringPtr = (String *) ckalloc(STRING_SIZE(STRING_UALLOC(0)));
1702 copyStringPtr->uallocated = STRING_UALLOC(0);
1704 copyStringPtr = (String *) ckalloc(
1705 STRING_SIZE(srcStringPtr->uallocated));
1706 copyStringPtr->uallocated = srcStringPtr->uallocated;
1708 memcpy((VOID *) copyStringPtr->unicode,
1709 (VOID *) srcStringPtr->unicode,
1710 (size_t) srcStringPtr->numChars * sizeof(Tcl_UniChar));
1711 copyStringPtr->unicode[srcStringPtr->numChars] = 0;
1713 copyStringPtr->numChars = srcStringPtr->numChars;
1714 copyStringPtr->hasUnicode = srcStringPtr->hasUnicode;
1715 copyStringPtr->allocated = srcStringPtr->allocated;
1718 * Tricky point: the string value was copied by generic object
1719 * management code, so it doesn't contain any extra bytes that
1720 * might exist in the source object.
1723 copyStringPtr->allocated = copyPtr->length;
1725 SET_STRING(copyPtr, copyStringPtr);
1726 copyPtr->typePtr = &tclStringType;
1730 *----------------------------------------------------------------------
1732 * SetStringFromAny --
1734 * Create an internal representation of type "String" for an object.
1737 * This operation always succeeds and returns TCL_OK.
1740 * Any old internal reputation for objPtr is freed and the
1741 * internal representation is set to "String".
1743 *----------------------------------------------------------------------
1747 SetStringFromAny(interp, objPtr)
1748 Tcl_Interp *interp; /* Used for error reporting if not NULL. */
1749 register Tcl_Obj *objPtr; /* The object to convert. */
1752 * The Unicode object is optimized for the case where each UTF char
1753 * in a string is only one byte. In this case, we store the value of
1754 * numChars, but we don't copy the bytes to the unicodeObj->unicode.
1757 if (objPtr->typePtr != &tclStringType) {
1760 if (objPtr->typePtr != NULL) {
1761 if (objPtr->bytes == NULL) {
1762 objPtr->typePtr->updateStringProc(objPtr);
1764 if ((objPtr->typePtr->freeIntRepProc) != NULL) {
1765 (*objPtr->typePtr->freeIntRepProc)(objPtr);
1768 objPtr->typePtr = &tclStringType;
1771 * Allocate enough space for the basic String structure.
1774 stringPtr = (String *) ckalloc(STRING_SIZE(STRING_UALLOC(0)));
1775 stringPtr->numChars = -1;
1776 stringPtr->uallocated = STRING_UALLOC(0);
1777 stringPtr->hasUnicode = 0;
1779 if (objPtr->bytes != NULL) {
1780 stringPtr->allocated = objPtr->length;
1781 objPtr->bytes[objPtr->length] = 0;
1785 SET_STRING(objPtr, stringPtr);
1791 *----------------------------------------------------------------------
1793 * UpdateStringOfString --
1795 * Update the string representation for an object whose internal
1796 * representation is "String".
1802 * The object's string may be set by converting its Unicode
1803 * represention to UTF format.
1805 *----------------------------------------------------------------------
1809 UpdateStringOfString(objPtr)
1810 Tcl_Obj *objPtr; /* Object with string rep to update. */
1813 Tcl_UniChar *unicode;
1814 char dummy[TCL_UTF_MAX];
1818 stringPtr = GET_STRING(objPtr);
1819 if ((objPtr->bytes == NULL) || (stringPtr->allocated == 0)) {
1821 if (stringPtr->numChars <= 0) {
1824 * If there is no Unicode rep, or the string has 0 chars,
1825 * then set the string rep to an empty string.
1828 objPtr->bytes = tclEmptyStringRep;
1833 unicode = stringPtr->unicode;
1836 * Translate the Unicode string to UTF. "size" will hold the
1837 * amount of space the UTF string needs.
1841 for (i = 0; i < stringPtr->numChars; i++) {
1842 size += Tcl_UniCharToUtf((int) unicode[i], dummy);
1845 dst = (char *) ckalloc((unsigned) (size + 1));
1846 objPtr->bytes = dst;
1847 objPtr->length = size;
1848 stringPtr->allocated = size;
1850 for (i = 0; i < stringPtr->numChars; i++) {
1851 dst += Tcl_UniCharToUtf(unicode[i], dst);
1859 *----------------------------------------------------------------------
1861 * FreeStringInternalRep --
1863 * Deallocate the storage associated with a String data object's
1864 * internal representation.
1872 *----------------------------------------------------------------------
1876 FreeStringInternalRep(objPtr)
1877 Tcl_Obj *objPtr; /* Object with internal rep to free. */
1879 ckfree((char *) GET_STRING(objPtr));