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 + -
显示快捷键?