📄 tclstringobj.c
字号:
/* * tclStringObj.c -- * * This file contains procedures that implement string operations * on Tcl objects. To do this efficiently (i.e. to allow many * appends to be done to an object without constantly reallocating * the space for the string representation) we overallocate the * space for the string and use the internal representation to keep * track of the extra space. Objects with this internal * representation are called "expandable string objects". * * Copyright (c) 1995-1997 Sun Microsystems, Inc. * * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * * SCCS: @(#) tclStringObj.c 1.31 97/10/30 13:56:35 */#include "tclInt.h"/* * Prototypes for procedures defined later in this file: */static void ConvertToStringType _ANSI_ARGS_((Tcl_Obj *objPtr));static void DupStringInternalRep _ANSI_ARGS_((Tcl_Obj *objPtr, Tcl_Obj *copyPtr));static int SetStringFromAny _ANSI_ARGS_((Tcl_Interp *interp, Tcl_Obj *objPtr));static void UpdateStringOfString _ANSI_ARGS_((Tcl_Obj *objPtr));/* * The structure below defines the string Tcl object type by means of * procedures that can be invoked by generic object code. */Tcl_ObjType tclStringType = { "string", /* name */ (Tcl_FreeInternalRepProc *) NULL, /* freeIntRepProc */ DupStringInternalRep, /* dupIntRepProc */ UpdateStringOfString, /* updateStringProc */ SetStringFromAny /* setFromAnyProc */};/* *---------------------------------------------------------------------- * * Tcl_NewStringObj -- * * This procedure is normally called when not debugging: i.e., when * TCL_MEM_DEBUG is not defined. It creates a new string object and * initializes it from the byte pointer and length arguments. * * When TCL_MEM_DEBUG is defined, this procedure just returns the * result of calling the debugging version Tcl_DbNewStringObj. * * Results: * A newly created string object is returned that has ref count zero. * * Side effects: * The new object's internal 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 type is set * to NULL. An extra NULL is added to the end of the new object's byte * array. * *---------------------------------------------------------------------- */#ifdef TCL_MEM_DEBUG#undef Tcl_NewStringObjTcl_Obj *Tcl_NewStringObj(bytes, length) register char *bytes; /* Points to the first of the length bytes * used to initialize the new object. */ register int length; /* The number of bytes to copy from "bytes" * when initializing the new object. If * negative, use bytes up to the first * NULL byte. */{ return Tcl_DbNewStringObj(bytes, length, "unknown", 0);}#else /* if not TCL_MEM_DEBUG */Tcl_Obj *Tcl_NewStringObj(bytes, length) register char *bytes; /* Points to the first of the length bytes * used to initialize the new object. */ register int length; /* The number of bytes to copy from "bytes" * when initializing the new object. If * negative, use bytes up to the first * NULL byte. */{ register Tcl_Obj *objPtr; if (length < 0) { length = (bytes? strlen(bytes) : 0); } TclNewObj(objPtr); TclInitStringRep(objPtr, bytes, length); return objPtr;}#endif /* TCL_MEM_DEBUG *//* *---------------------------------------------------------------------- * * Tcl_DbNewStringObj -- * * This procedure is normally called when debugging: i.e., when * TCL_MEM_DEBUG is defined. It creates new string objects. It is the * same as the Tcl_NewStringObj procedure above except that it calls * Tcl_DbCkalloc directly with the file name and line number from its * caller. This simplifies debugging since then the checkmem command * will report the correct file name and line number when reporting * objects that haven't been freed. * * When TCL_MEM_DEBUG is not defined, this procedure just returns the * result of calling Tcl_NewStringObj. * * Results: * A newly created string object is returned that has ref count zero. * * Side effects: * The new object's internal 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 type is set * to NULL. An extra NULL is added to the end of the new object's byte * array. * *---------------------------------------------------------------------- */#ifdef TCL_MEM_DEBUGTcl_Obj *Tcl_DbNewStringObj(bytes, length, file, line) register char *bytes; /* Points to the first of the length bytes * used to initialize the new object. */ register int length; /* The number of bytes to copy from "bytes" * when initializing the new object. If * negative, use bytes up to the first * NULL byte. */ char *file; /* The name of the source file calling this * procedure; used for debugging. */ int line; /* Line number in the source file; used * for debugging. */{ register Tcl_Obj *objPtr; if (length < 0) { length = (bytes? strlen(bytes) : 0); } TclDbNewObj(objPtr, file, line); TclInitStringRep(objPtr, bytes, length); return objPtr;}#else /* if not TCL_MEM_DEBUG */Tcl_Obj *Tcl_DbNewStringObj(bytes, length, file, line) register char *bytes; /* Points to the first of the length bytes * used to initialize the new object. */ register int length; /* The number of bytes to copy from "bytes" * when initializing the new object. If * negative, use bytes up to the first * NULL byte. */ char *file; /* The name of the source file calling this * procedure; used for debugging. */ int line; /* Line number in the source file; used * for debugging. */{ return Tcl_NewStringObj(bytes, length);}#endif /* TCL_MEM_DEBUG *//* *---------------------------------------------------------------------- * * 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. */ 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"); } Tcl_InvalidateStringRep(objPtr); if (length < 0) { length = strlen(bytes); } TclInitStringRep(objPtr, bytes, length); /* * 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_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. */{ char *new; if (Tcl_IsShared(objPtr)) { panic("Tcl_SetObjLength called with shared object"); } if (objPtr->typePtr != &tclStringType) { ConvertToStringType(objPtr); } if ((long)length > objPtr->internalRep.longValue) { /* * Not enough space in current string. Reallocate the string * space and free the old string. */ new = (char *) ckalloc((unsigned) (length+1)); if (objPtr->bytes != NULL) { memcpy((VOID *) new, (VOID *) objPtr->bytes, (size_t) objPtr->length); Tcl_InvalidateStringRep(objPtr); } objPtr->bytes = new; objPtr->internalRep.longValue = (long) length; } objPtr->length = length; if ((objPtr->bytes != NULL) && (objPtr->bytes != tclEmptyStringRep)) { objPtr->bytes[length] = 0; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -