⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 tclutil.c

📁 tcl是工具命令语言
💻 C
📖 第 1 页 / 共 5 页
字号:
    if (length < 0) {	length = strlen(string);    }    newSize = length + dsPtr->length;    /*     * Allocate a larger buffer for the string if the current one isn't     * large enough. Allocate extra space in the new buffer so that there     * will be room to grow before we have to allocate again.     */    if (newSize >= dsPtr->spaceAvl) {	dsPtr->spaceAvl = newSize * 2;	if (dsPtr->string == dsPtr->staticSpace) {	    char *newString;	    newString = (char *) ckalloc((unsigned) dsPtr->spaceAvl);	    memcpy((VOID *) newString, (VOID *) dsPtr->string,		    (size_t) dsPtr->length);	    dsPtr->string = newString;	} else {	    dsPtr->string = (char *) ckrealloc((VOID *) dsPtr->string,		    (size_t) dsPtr->spaceAvl);	}    }    /*     * Copy the new string into the buffer at the end of the old     * one.     */    for (dst = dsPtr->string + dsPtr->length, end = string+length;	    string < end; string++, dst++) {	*dst = *string;    }    *dst = '\0';    dsPtr->length += length;    return dsPtr->string;}/* *---------------------------------------------------------------------- * * Tcl_DStringAppendElement -- * *	Append a list element to the current value of a dynamic string. * * Results: *	The return value is a pointer to the dynamic string's new value. * * Side effects: *	String is reformatted as a list element and added to the current *	value of the string.  Memory gets reallocated if needed to *	accomodate the string's new size. * *---------------------------------------------------------------------- */char *Tcl_DStringAppendElement(dsPtr, string)    Tcl_DString *dsPtr;		/* Structure describing dynamic string. */    CONST char *string;		/* String to append.  Must be				 * null-terminated. */{    int newSize, flags, strSize;    char *dst;    strSize = ((string == NULL) ? 0 : strlen(string));    newSize = Tcl_ScanCountedElement(string, strSize, &flags)	+ dsPtr->length + 1;    /*     * Allocate a larger buffer for the string if the current one isn't     * large enough.  Allocate extra space in the new buffer so that there     * will be room to grow before we have to allocate again.     * SPECIAL NOTE: must use memcpy, not strcpy, to copy the string     * to a larger buffer, since there may be embedded NULLs in the     * string in some cases.     */    if (newSize >= dsPtr->spaceAvl) {	dsPtr->spaceAvl = newSize * 2;	if (dsPtr->string == dsPtr->staticSpace) {	    char *newString;	    newString = (char *) ckalloc((unsigned) dsPtr->spaceAvl);	    memcpy((VOID *) newString, (VOID *) dsPtr->string,		    (size_t) dsPtr->length);	    dsPtr->string = newString;	} else {	    dsPtr->string = (char *) ckrealloc((VOID *) dsPtr->string,		    (size_t) dsPtr->spaceAvl);	}    }    /*     * Convert the new string to a list element and copy it into the     * buffer at the end, with a space, if needed.     */    dst = dsPtr->string + dsPtr->length;    if (TclNeedSpace(dsPtr->string, dst)) {	*dst = ' ';	dst++;	dsPtr->length++;    }    dsPtr->length += Tcl_ConvertCountedElement(string, strSize, dst, flags);    return dsPtr->string;}/* *---------------------------------------------------------------------- * * Tcl_DStringSetLength -- * *	Change the length of a dynamic string.  This can cause the *	string to either grow or shrink, depending on the value of *	length. * * Results: *	None. * * Side effects: *	The length of dsPtr is changed to length and a null byte is *	stored at that position in the string.  If length is larger *	than the space allocated for dsPtr, then a panic occurs. * *---------------------------------------------------------------------- */voidTcl_DStringSetLength(dsPtr, length)    Tcl_DString *dsPtr;		/* Structure describing dynamic string. */    int length;			/* New length for dynamic string. */{    int newsize;    if (length < 0) {	length = 0;    }    if (length >= dsPtr->spaceAvl) {	/*	 * There are two interesting cases here.  In the first case, the user	 * may be trying to allocate a large buffer of a specific size.  It	 * would be wasteful to overallocate that buffer, so we just allocate	 * enough for the requested size plus the trailing null byte.  In the	 * second case, we are growing the buffer incrementally, so we need	 * behavior similar to Tcl_DStringAppend.  The requested length will	 * usually be a small delta above the current spaceAvl, so we'll end up	 * doubling the old size.  This won't grow the buffer quite as quickly,	 * but it should be close enough.	 */	newsize = dsPtr->spaceAvl * 2;	if (length < newsize) {	    dsPtr->spaceAvl = newsize;	} else {	    dsPtr->spaceAvl = length + 1;	}	if (dsPtr->string == dsPtr->staticSpace) {	    char *newString;	    newString = (char *) ckalloc((unsigned) dsPtr->spaceAvl);	    memcpy((VOID *) newString, (VOID *) dsPtr->string,		    (size_t) dsPtr->length);	    dsPtr->string = newString;	} else {	    dsPtr->string = (char *) ckrealloc((VOID *) dsPtr->string,		    (size_t) dsPtr->spaceAvl);	}    }    dsPtr->length = length;    dsPtr->string[length] = 0;}/* *---------------------------------------------------------------------- * * Tcl_DStringFree -- * *	Frees up any memory allocated for the dynamic string and *	reinitializes the string to an empty state. * * Results: *	None. * * Side effects: *	The previous contents of the dynamic string are lost, and *	the new value is an empty string. * *---------------------------------------------------------------------- */voidTcl_DStringFree(dsPtr)    Tcl_DString *dsPtr;		/* Structure describing dynamic string. */{    if (dsPtr->string != dsPtr->staticSpace) {	ckfree(dsPtr->string);    }    dsPtr->string = dsPtr->staticSpace;    dsPtr->length = 0;    dsPtr->spaceAvl = TCL_DSTRING_STATIC_SIZE;    dsPtr->staticSpace[0] = '\0';}/* *---------------------------------------------------------------------- * * Tcl_DStringResult -- * *	This procedure moves the value of a dynamic string into an *	interpreter as its string result. Afterwards, the dynamic string *	is reset to an empty string. * * Results: *	None. * * Side effects: *	The string is "moved" to interp's result, and any existing *	string result for interp is freed. dsPtr is reinitialized to *	an empty string. * *---------------------------------------------------------------------- */voidTcl_DStringResult(interp, dsPtr)    Tcl_Interp *interp;		/* Interpreter whose result is to be reset. */    Tcl_DString *dsPtr;		/* Dynamic string that is to become the				 * result of interp. */{    Tcl_ResetResult(interp);        if (dsPtr->string != dsPtr->staticSpace) {	interp->result = dsPtr->string;	interp->freeProc = TCL_DYNAMIC;    } else if (dsPtr->length < TCL_RESULT_SIZE) {	interp->result = ((Interp *) interp)->resultSpace;	strcpy(interp->result, dsPtr->string);    } else {	Tcl_SetResult(interp, dsPtr->string, TCL_VOLATILE);    }        dsPtr->string = dsPtr->staticSpace;    dsPtr->length = 0;    dsPtr->spaceAvl = TCL_DSTRING_STATIC_SIZE;    dsPtr->staticSpace[0] = '\0';}/* *---------------------------------------------------------------------- * * Tcl_DStringGetResult -- * *	This procedure moves an interpreter's result into a dynamic string. * * Results: *	None. * * Side effects: *	The interpreter's string result is cleared, and the previous *	contents of dsPtr are freed. * *	If the string result is empty, the object result is moved to the *	string result, then the object result is reset. * *---------------------------------------------------------------------- */voidTcl_DStringGetResult(interp, dsPtr)    Tcl_Interp *interp;		/* Interpreter whose result is to be reset. */    Tcl_DString *dsPtr;		/* Dynamic string that is to become the				 * result of interp. */{    Interp *iPtr = (Interp *) interp;        if (dsPtr->string != dsPtr->staticSpace) {	ckfree(dsPtr->string);    }    /*     * If the string result is empty, move the object result to the     * string result, then reset the object result.     */    if (*(iPtr->result) == 0) {	Tcl_SetResult(interp, TclGetString(Tcl_GetObjResult(interp)),	        TCL_VOLATILE);    }    dsPtr->length = strlen(iPtr->result);    if (iPtr->freeProc != NULL) {	if ((iPtr->freeProc == TCL_DYNAMIC)		|| (iPtr->freeProc == (Tcl_FreeProc *) free)) {	    dsPtr->string = iPtr->result;	    dsPtr->spaceAvl = dsPtr->length+1;	} else {	    dsPtr->string = (char *) ckalloc((unsigned) (dsPtr->length+1));	    strcpy(dsPtr->string, iPtr->result);	    (*iPtr->freeProc)(iPtr->result);	}	dsPtr->spaceAvl = dsPtr->length+1;	iPtr->freeProc = NULL;    } else {	if (dsPtr->length < TCL_DSTRING_STATIC_SIZE) {	    dsPtr->string = dsPtr->staticSpace;	    dsPtr->spaceAvl = TCL_DSTRING_STATIC_SIZE;	} else {	    dsPtr->string = (char *) ckalloc((unsigned) (dsPtr->length + 1));	    dsPtr->spaceAvl = dsPtr->length + 1;	}	strcpy(dsPtr->string, iPtr->result);    }        iPtr->result = iPtr->resultSpace;    iPtr->resultSpace[0] = 0;}/* *---------------------------------------------------------------------- * * Tcl_DStringStartSublist -- * *	This procedure adds the necessary information to a dynamic *	string (e.g. " {" to start a sublist.  Future element *	appends will be in the sublist rather than the main list. * * Results: *	None. * * Side effects: *	Characters get added to the dynamic string. * *---------------------------------------------------------------------- */voidTcl_DStringStartSublist(dsPtr)    Tcl_DString *dsPtr;			/* Dynamic string. */{    if (TclNeedSpace(dsPtr->string, dsPtr->string + dsPtr->length)) {	Tcl_DStringAppend(dsPtr, " {", -1);    } else {	Tcl_DStringAppend(dsPtr, "{", -1);    }}/* *---------------------------------------------------------------------- * * Tcl_DStringEndSublist -- * *	This procedure adds the necessary characters to a dynamic *	string to end a sublist (e.g. "}").  Future element appends *	will be in the enclosing (sub)list rather than the current *	sublist. * * Results: *	None. * * Side effects: *	None. * *---------------------------------------------------------------------- */voidTcl_DStringEndSublist(dsPtr)    Tcl_DString *dsPtr;			/* Dynamic string. */{    Tcl_DStringAppend(dsPtr, "}", -1);}/* *---------------------------------------------------------------------- * * Tcl_PrintDouble -- * *	Given a floating-point value, this procedure converts it to *	an ASCII string using. * * Results: *	The ASCII equivalent of "value" is written at "dst".  It is *	written using the current precision, and it is guaranteed to *	contain a decimal point or exponent, so that it looks like *	a floating-point value and not an integer. * * Side effects: *	None. * *---------------------------------------------------------------------- */voidTcl_PrintDouble(interp, value, dst)    Tcl_Interp *interp;			/* Interpreter whose tcl_precision					 * variable used to be used to control					 * printing.  It's ignored now. */    double value;			/* Value to print as string. */    char *dst;				/* Where to store converted value;					 * must have at least TCL_DOUBLE_SPACE					 * characters. */{    char *p, c;    Tcl_UniChar ch;    Tcl_MutexLock(&precisionMutex);    sprintf(dst, precisionFormat, value);    Tcl_MutexUnlock(&precisionMutex);    /*     * If the ASCII result looks like an integer, add ".0" so that it     * doesn't look like an integer anymore.  This prevents floating-point     * values from being converted to integers unintentionally.     * Check for ASCII specifically to speed up the function.     */    for (p = dst; *p != 0; ) {	if (UCHAR(*p) < 0x80) {	    c = *p++;	} else {	    p += Tcl_UtfToUniChar(p, &ch);	    c = UCHAR(ch);	}	if ((c == '.') || isalpha(UCHAR(c))) {	/* INTL: ISO only. */	    return;	}    }    p[0] = '.';    p[1] = '0';    p[2] = 0;}/* *---------------------------------------------------------------------- * * TclPrecTraceProc -- * *	This procedure is invoked whenever the variable "tcl_precision" *	is written. * * Results: *	Returns NULL if all went well, or an error message if the *	new value for the variable doesn't make sense. * * Side effects: *	If the new value doesn't make sense then this procedure *	undoes the effect of the variable modification.  Otherwise *	it modifies the format string that's used by Tcl_PrintDouble. * *---------------------------------------------------------------------- */	/* ARGSUSED */char *TclPrecTraceProc(clientData, interp, name1, name2, flags)    ClientData clientData;	/* Not used. */    Tcl_Interp *interp;		/* Interpreter containing variable. */    CONST char *name1;		/* Name of variable. */    CONST char *name2;		/* Second part of variable name. */    int flags;			/* Information about what happened. */{    CONST char *value;    char *end;    int prec;    /*     * If the variable is unset, then recreate the trace.     */    if (flags & TCL_TRACE_UNSETS) {	if ((flags & TCL_TRACE_DESTROYED) && !(flags & TCL_INTERP_DESTROYED)) {	    Tcl_TraceVar2(interp, name1, name2,		    TCL_GLOBAL_ONLY|TCL_TRACE_READS|TCL_TRACE_WRITES		    |TCL_TRACE_UNSETS, TclPrecTraceProc, clientData);	}	return (char *) NULL;    }    /*     * When the variable is read, reset its value from our shared     * value.  This is needed in case the variable was modified in

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -