diff options
author | jan.nijtmans <nijtmans@users.sourceforge.net> | 2022-03-16 14:55:58 (GMT) |
---|---|---|
committer | jan.nijtmans <nijtmans@users.sourceforge.net> | 2022-03-16 14:55:58 (GMT) |
commit | df7885a1af94256673ff9ee1beb659f201ac2578 (patch) | |
tree | 6f6e2920fdc9eb2c2dc95b485fd5c8689853ef0f /generic/tclStringObj.c | |
parent | 4dd5be298811da7ad60f1cd93d3ff09e4baf34d0 (diff) | |
parent | 2041f4450bf1aca29472f00ab21b13448bcde2d4 (diff) | |
download | tcl-df7885a1af94256673ff9ee1beb659f201ac2578.zip tcl-df7885a1af94256673ff9ee1beb659f201ac2578.tar.gz tcl-df7885a1af94256673ff9ee1beb659f201ac2578.tar.bz2 |
Merge 8.7. First working version, feature complete
Diffstat (limited to 'generic/tclStringObj.c')
-rw-r--r-- | generic/tclStringObj.c | 145 |
1 files changed, 113 insertions, 32 deletions
diff --git a/generic/tclStringObj.c b/generic/tclStringObj.c index 2ab47f6..1c24716 100644 --- a/generic/tclStringObj.c +++ b/generic/tclStringObj.c @@ -89,6 +89,16 @@ static void UpdateStringOfUTF16String(Tcl_Obj *objPtr); #if TCL_UTF_MAX < 4 #define uniCharStringType tclStringType +#define GET_UNICHAR_STRING GET_STRING +#define UniCharString String +#define UNICHAR_STRING_MAXCHARS STRING_MAXCHARS +#define uniCharStringAlloc stringAlloc +#define uniCharStringRealloc stringRealloc +#define uniCharStringAttemptAlloc stringAttemptAlloc +#define uniCharStringAttemptRealloc stringAttemptRealloc +#define uniCharStringCheckLimits stringCheckLimits +#define SET_UNICHAR_STRING SET_STRING +#define UNICHAR_STRING_SIZE STRING_SIZE const Tcl_ObjType tclStringType = { "string", /* name */ @@ -168,11 +178,9 @@ DupUTF16StringInternalRep( * currently have an internal rep.*/ { String *srcStringPtr = ((String *) (srcPtr)->internalRep.twoPtrValue.ptr1); - size_t size = offsetof(String, unicode) + (((srcStringPtr->numChars) + 1U) * sizeof(unsigned short)); + size_t size = offsetof(String, unicode) + (((srcStringPtr->allocated) + 1U) * sizeof(unsigned short)); String *copyStringPtr = (String *)ckalloc(size); memcpy(copyStringPtr, srcStringPtr, size); - copyStringPtr->allocated = srcStringPtr->numChars + 1; - copyStringPtr->maxChars = srcStringPtr->numChars; copyPtr->internalRep.twoPtrValue.ptr1 = copyStringPtr; copyPtr->typePtr = &tclStringType; @@ -184,6 +192,7 @@ SetUTF16StringFromAny( Tcl_Obj *objPtr) /* The object to convert. */ { if (!TclHasInternalRep(objPtr, &tclStringType)) { + Tcl_DString ds; /* * Convert whatever we have into an untyped value. Just A String. @@ -192,30 +201,46 @@ SetUTF16StringFromAny( (void) TclGetString(objPtr); TclFreeInternalRep(objPtr); - size_t size = offsetof(String, unicode) + (((objPtr->length) + 1U) * sizeof(unsigned short)); - - String *stringPtr = (String *)ckalloc(size); - /* * Create a basic String internalrep that just points to the UTF-8 string * already in place at objPtr->bytes. */ - stringPtr->numChars = 0; - stringPtr->allocated = objPtr->length + 1; - stringPtr->maxChars = objPtr->length; + Tcl_DStringInit(&ds); + unsigned short *utf16string = Tcl_UtfToChar16DString(objPtr->bytes, objPtr->length, &ds); + size_t size = Tcl_DStringLength(&ds); + String *stringPtr = (String *)ckalloc((offsetof(String, unicode) + 2U) + size); + memcpy(stringPtr->unicode, utf16string, size); + stringPtr->unicode[size] = 0; + Tcl_DStringFree(&ds); + + size /= sizeof(unsigned short); + stringPtr->numChars = size; + stringPtr->allocated = size; + stringPtr->maxChars = size; stringPtr->hasUnicode = 1; objPtr->internalRep.twoPtrValue.ptr1 = stringPtr; objPtr->typePtr = &tclStringType; } - return TCL_OK; + return TCL_OK; } static void UpdateStringOfUTF16String( Tcl_Obj *objPtr) /* Object with string rep to update. */ { - (void)objPtr; + Tcl_DString ds; + String *stringPtr = ((String *) (objPtr)->internalRep.twoPtrValue.ptr1); + + Tcl_DStringInit(&ds); + const char *string = Tcl_Char16ToUtfDString(stringPtr->unicode, stringPtr->numChars, &ds); + + char *bytes = (char *)ckalloc(Tcl_DStringLength(&ds) + 1U); + memcpy(bytes, string, Tcl_DStringLength(&ds)); + Tcl_DStringFree(&ds); + objPtr->bytes = bytes; + objPtr->length = Tcl_DStringLength(&ds); + printf("UpdateStringOfUTF16String %d %d\n", stringPtr->unicode[0], stringPtr->unicode[1]); } #endif @@ -528,11 +553,21 @@ Tcl_NewUnicodeObj( * string. */ { Tcl_Obj *objPtr; - (void)unicode; - (void)numChars; TclNewObj(objPtr); - /* TODO JN */ + TclFreeInternalRep(objPtr); + + String *stringPtr = (String *)ckalloc((offsetof(String, unicode) + 2U) + numChars * sizeof(unsigned short)); + memcpy(stringPtr->unicode, unicode, numChars); + stringPtr->unicode[numChars] = 0; + + stringPtr->numChars = numChars; + stringPtr->allocated = numChars; + stringPtr->maxChars = numChars; + stringPtr->hasUnicode = 1; + objPtr->internalRep.twoPtrValue.ptr1 = stringPtr; + objPtr->typePtr = &tclStringType; + return objPtr; } #endif @@ -823,11 +858,15 @@ Tcl_GetUnicodeFromObj( * rep's unichar length should be stored. If * NULL, no length is stored. */ { - (void)objPtr; - (void)lengthPtr; + String *stringPtr; - /* TODO JN */ - return NULL; + SetUTF16StringFromAny(NULL, objPtr); + stringPtr = GET_STRING(objPtr); + + if (lengthPtr != NULL) { + *lengthPtr = stringPtr->numChars; + } + return stringPtr->unicode; } #endif @@ -839,12 +878,17 @@ TclGetUnicodeFromObj( * rep's unichar length should be stored. If * NULL, no length is stored. */ { - (void)objPtr; - (void)lengthPtr; - /* TODO JN */ - return NULL; + String *stringPtr; + + SetStringFromAny(NULL, objPtr); + stringPtr = GET_STRING(objPtr); + + if (lengthPtr != NULL) { + *lengthPtr = stringPtr->numChars; + } + return stringPtr->unicode; } - + /* *---------------------------------------------------------------------- * @@ -1251,11 +1295,36 @@ Tcl_SetUnicodeObj( int numChars) /* Number of characters in the unicode * string. */ { - (void)objPtr; - (void)unicode; - (void)numChars; + String *stringPtr; - /* TODO JN */ + if (numChars < 0) { + numChars = 0; + + if (unicode) { + while (numChars >= 0 && unicode[numChars] != 0) { + numChars++; + } + } + stringCheckLimits(numChars); + } + + /* + * Allocate enough space for the String structure + Unicode string. + */ + + stringCheckLimits(numChars); + stringPtr = stringAlloc(numChars); + SET_STRING(objPtr, stringPtr); + objPtr->typePtr = &tclStringType; + + stringPtr->maxChars = numChars; + memcpy(stringPtr->unicode, unicode, numChars * sizeof(unsigned char)); + stringPtr->unicode[numChars] = 0; + stringPtr->numChars = numChars; + stringPtr->hasUnicode = 1; + + TclInvalidateStringRep(objPtr); + stringPtr->allocated = numChars; } static int @@ -1490,11 +1559,23 @@ Tcl_AppendUnicodeToObj( * object. */ int length) /* Number of chars in "unicode". */ { - (void)objPtr; - (void)unicode; - (void)length; + String *stringPtr; + + if (Tcl_IsShared(objPtr)) { + Tcl_Panic("%s called with shared object", "Tcl_AppendUnicodeToObj"); + } + + if (length == 0) { + return; + } - /* TODO JN */ + SetStringFromAny(NULL, objPtr); + stringPtr = GET_STRING(objPtr); + stringPtr = stringAttemptRealloc(stringPtr, stringPtr->numChars + length); + memcpy(&stringPtr->unicode[stringPtr->numChars], unicode, length); + stringPtr->maxChars = stringPtr->allocated = stringPtr->numChars += length; + stringPtr->unicode[stringPtr->numChars] = 0; + SET_STRING(objPtr, stringPtr); } #endif |