1 /****************************************************************************
4 ****************************************************************************/
9 * This header file describes the externally-visible facilities
10 * of the Tcl interpreter.
12 * Copyright (c) 1987-1994 The Regents of the University of California.
13 * Copyright (c) 1994-1996 Sun Microsystems, Inc.
15 * See the file "license.terms" for information on usage and redistribution
16 * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
18 * SCCS: @(#) tcl.h 1.283 96/10/02 17:17:39
28 #include "str_strsafe.h"
31 *----------------------------------------------------------------------
35 * Initializes a dynamic string, discarding any previous contents
36 * of the string (DStringFree should have been called already
37 * if the dynamic string was previously in use).
43 * The dynamic string is initialized to be empty.
45 *----------------------------------------------------------------------
49 DStringInit(DString
* pDs
)
51 pDs
->pString
= pDs
->staticSpace
;
53 pDs
->spaceAvl
= kDstringStaticSize
;
54 pDs
->staticSpace
[0] = 0;
58 *----------------------------------------------------------------------
62 * Append more characters to the current value of a dynamic string.
65 * The return value is a pointer to the dynamic string's new value.
68 * Length bytes from string (or all of string if length is less
69 * than zero) are added to the current value of the string. Memory
70 * gets reallocated if needed to accomodate the string's new size.
72 *----------------------------------------------------------------------
76 DStringAppend(DString
*pDs
,
86 length
= strlen(string
);
88 newSize
= length
+ pDs
->length
;
91 * Allocate a larger buffer for the string if the current one isn't
92 * large enough. Allocate extra space in the new buffer so that there
93 * will be room to grow before we have to allocate again.
96 if (newSize
>= pDs
->spaceAvl
) {
97 pDs
->spaceAvl
= newSize
*2;
98 newString
= (char *) malloc((unsigned) pDs
->spaceAvl
);
99 memcpy((void *)newString
, (void *) pDs
->pString
,
100 (size_t) pDs
->length
);
101 if (pDs
->pString
!= pDs
->staticSpace
) {
104 pDs
->pString
= newString
;
108 * Copy the new string into the buffer at the end of the old
112 for (dst
= pDs
->pString
+ pDs
->length
, end
= string
+length
;
113 string
< end
; string
++, dst
++) {
117 pDs
->length
+= length
;
122 *----------------------------------------------------------------------
124 * DStringSetLength --
126 * Change the length of a dynamic string. This can cause the
127 * string to either grow or shrink, depending on the value of
134 * The length of pDsis changed to length and a null byte is
135 * stored at that position in the string. If length is larger
136 * than the space allocated for pDs, then a panic occurs.
138 *----------------------------------------------------------------------
142 DStringSetLength(DString
* pDs
,
148 if (length
>= pDs
->spaceAvl
) {
151 pDs
->spaceAvl
= length
+1;
152 newString
= (char *) malloc((unsigned) pDs
->spaceAvl
);
155 * SPECIAL NOTE: must use memcpy, not strcpy, to copy the string
156 * to a larger buffer, since there may be embedded NULLs in the
157 * string in some cases.
160 memcpy((void *) newString
, (void*) pDs
->pString
,
161 (size_t) pDs
->length
);
162 if (pDs
->pString
!= pDs
->staticSpace
) {
165 pDs
->pString
= newString
;
167 pDs
->length
= length
;
168 pDs
->pString
[length
] = 0;
172 *----------------------------------------------------------------------
176 * Frees up any memory allocated for the dynamic string and
177 * reinitializes the string to an empty state.
183 * The previous contents of the dynamic string are lost, and
184 * the new value is an empty string.
186 *----------------------------------------------------------------------
190 DStringFree(DString
* pDs
)
192 if (pDs
->pString
!= pDs
->staticSpace
) {
195 pDs
->pString
= pDs
->staticSpace
;
197 pDs
->spaceAvl
= kDstringStaticSize
;
198 pDs
->staticSpace
[0] = 0;
204 * Append a formatted string to a dstring
208 DStringSprintf(DString
* pDs
,
218 char * result
= NULL
;
221 bufCchSize
= sizeof(message
);
223 va_start(args
, pFormat
);
226 /* TODO: this only works on windows with recent C library */
227 hr
= StringCchVPrintfA(buf
, bufCchSize
, pFormat
, args
);
230 if (STRSAFE_E_INSUFFICIENT_BUFFER
!= hr
)
232 /* any error other than buffer not big enough:
234 b) means we give up */
237 /* we have to make the buffer bigger. The algorithm used to calculate
238 the new size is arbitrary (aka. educated guess) */
239 if (buf
!= &(message
[0]))
241 if (bufCchSize
< 4*1024)
242 bufCchSize
+= bufCchSize
;
245 buf
= (char *)malloc(bufCchSize
*sizeof(char));
251 DStringAppend(pDs
, buf
, -1);
253 if (buf
!= &(message
[0]))
261 va_start(args
, pFormat
);
262 len
= vasprintf(&pBuffer
, pFormat
, args
);
263 DStringAppend(pDs
, pBuffer
, len
);
269 /****************************************************************************
270 * DStringAppendLowerCase --
272 * Append text to a dstring lowercased
276 DStringAppendLowerCase(DString
* pDs
,
286 length
= strlen(string
);
288 newSize
= length
+ pDs
->length
;
291 * Allocate a larger buffer for the string if the current one isn't
292 * large enough. Allocate extra space in the new buffer so that there
293 * will be room to grow before we have to allocate again.
296 if (newSize
>= pDs
->spaceAvl
) {
297 pDs
->spaceAvl
= newSize
*2;
298 newString
= (char *) malloc((unsigned) pDs
->spaceAvl
);
299 memcpy((void *)newString
, (void *) pDs
->pString
,
300 (size_t) pDs
->length
);
301 if (pDs
->pString
!= pDs
->staticSpace
) {
304 pDs
->pString
= newString
;
308 * Copy the new string into the buffer at the end of the old
312 for (dst
= pDs
->pString
+ pDs
->length
, end
= string
+length
;
313 string
< end
; string
++, dst
++) {
314 *dst
= tolower(*string
);
317 pDs
->length
+= length
;