📄 tclstringobj.c
字号:
}/* *---------------------------------------------------------------------- * * 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. */ 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. */{ int newLength, oldLength; if (Tcl_IsShared(objPtr)) { panic("Tcl_AppendToObj called with shared object"); } if (objPtr->typePtr != &tclStringType) { ConvertToStringType(objPtr); } if (length < 0) { length = strlen(bytes); } if (length == 0) { return; } oldLength = objPtr->length; newLength = length + oldLength; if ((long)newLength > objPtr->internalRep.longValue) { /* * There isn't currently enough space in the string * representation so allocate additional space. In fact, * overallocate so that there is room for future growth without * having to reallocate again. */ Tcl_SetObjLength(objPtr, 2*newLength); } if (length > 0) { memcpy((VOID *) (objPtr->bytes + oldLength), (VOID *) bytes, (size_t) length); objPtr->length = newLength; objPtr->bytes[objPtr->length] = 0; }}/* *---------------------------------------------------------------------- * * Tcl_AppendStringsToObj -- * * This procedure appends one or more null-terminated strings * to an object. * * Results: * None. * * Side effects: * The contents of all the string arguments are appended to the * string representation of objPtr. * *---------------------------------------------------------------------- */voidTcl_AppendStringsToObj TCL_VARARGS_DEF(Tcl_Obj *,arg1){ va_list argList; register Tcl_Obj *objPtr; int newLength, oldLength; register char *string, *dst; objPtr = (Tcl_Obj *) TCL_VARARGS_START(Tcl_Obj *,arg1,argList); if (Tcl_IsShared(objPtr)) { panic("Tcl_AppendStringsToObj called with shared object"); } if (objPtr->typePtr != &tclStringType) { ConvertToStringType(objPtr); } /* * Figure out how much space is needed for all the strings, and * expand the string representation if it isn't big enough. If no * bytes would be appended, just return. */ newLength = oldLength = objPtr->length; while (1) { string = va_arg(argList, char *); if (string == NULL) { break; } newLength += strlen(string); } if (newLength == oldLength) { return; } if ((long)newLength > objPtr->internalRep.longValue) { /* * There isn't currently enough space in the string * representation so allocate additional space. If the current * string representation isn't empty (i.e. it looks like we're * doing a series of appends) then overallocate the space so * that we won't have to do as much reallocation in the future. */ Tcl_SetObjLength(objPtr, (objPtr->length == 0) ? newLength : 2*newLength); } /* * Make a second pass through the arguments, appending all the * strings to the object. */ TCL_VARARGS_START(Tcl_Obj *,arg1,argList); dst = objPtr->bytes + oldLength; while (1) { string = va_arg(argList, char *); if (string == NULL) { break; } while (*string != 0) { *dst = *string; dst++; string++; } } /* * Add a null byte to terminate the string. However, be careful: * it's possible that the object is totally empty (if it was empty * originally and there was nothing to append). In this case dst is * NULL; just leave everything alone. */ if (dst != NULL) { *dst = 0; } objPtr->length = newLength; va_end(argList);}/* *---------------------------------------------------------------------- * * ConvertToStringType -- * * This procedure converts the internal representation of an object * to "expandable string" type. * * Results: * None. * * Side effects: * Any old internal reputation for objPtr is freed and the * internal representation is set to that for an expandable string * (the field internalRep.longValue holds 1 less than the allocated * length of objPtr's string representation). * *---------------------------------------------------------------------- */static voidConvertToStringType(objPtr) register Tcl_Obj *objPtr; /* Pointer to object. Must have a * typePtr that isn't &tclStringType. */{ if (objPtr->typePtr != NULL) { if (objPtr->bytes == NULL) { objPtr->typePtr->updateStringProc(objPtr); } if (objPtr->typePtr->freeIntRepProc != NULL) { objPtr->typePtr->freeIntRepProc(objPtr); } } objPtr->typePtr = &tclStringType; if (objPtr->bytes != NULL) { objPtr->internalRep.longValue = (long)objPtr->length; } else { objPtr->internalRep.longValue = 0; objPtr->length = 0; }}/* *---------------------------------------------------------------------- * * DupStringInternalRep -- * * Initialize the internal representation of a new Tcl_Obj to a * copy of the internal representation of an existing string object. * * Results: * None. * * Side effects: * copyPtr's internal rep is set to a copy of srcPtr's internal * representation. * *---------------------------------------------------------------------- */static voidDupStringInternalRep(srcPtr, copyPtr) register Tcl_Obj *srcPtr; /* Object with internal rep to copy. Must * have an internal representation of type * "expandable string". */ register Tcl_Obj *copyPtr; /* Object with internal rep to set. Must * not currently have an internal rep.*/{ /* * Tricky point: the string value was copied by generic object * management code, so it doesn't contain any extra bytes that * might exist in the source object. */ copyPtr->internalRep.longValue = (long)copyPtr->length; copyPtr->typePtr = &tclStringType;}/* *---------------------------------------------------------------------- * * SetStringFromAny -- * * Create an internal representation of type "expandable string" * for an object. * * Results: * This operation always succeeds and returns TCL_OK. * * Side effects: * This procedure does nothing; there is no advantage in converting * the internal representation now, so we just defer it. * *---------------------------------------------------------------------- */static intSetStringFromAny(interp, objPtr) Tcl_Interp *interp; /* Used for error reporting if not NULL. */ Tcl_Obj *objPtr; /* The object to convert. */{ return TCL_OK;}/* *---------------------------------------------------------------------- * * UpdateStringOfString -- * * Update the string representation for an object whose internal * representation is "expandable string". * * Results: * None. * * Side effects: * None. * *---------------------------------------------------------------------- */static voidUpdateStringOfString(objPtr) Tcl_Obj *objPtr; /* Object with string rep to update. */{ /* * The string is almost always valid already, in which case there's * nothing for us to do. The only case we have to worry about is if * the object is totally null. In this case, set the string rep to * an empty string. */ if (objPtr->bytes == NULL) { objPtr->bytes = tclEmptyStringRep; objPtr->length = 0; } return;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -