source: HiSusy/trunk/Delphes/Delphes-3.0.9/external/tcl/tclStringObj.c @ 5

Last change on this file since 5 was 5, checked in by zerwas, 11 years ago

update to Delphes-3.0.9

File size: 17.1 KB
Line 
1/*
2 * tclStringObj.c --
3 *
4 *      This file contains procedures that implement string operations
5 *      on Tcl objects.  To do this efficiently (i.e. to allow many
6 *      appends to be done to an object without constantly reallocating
7 *      the space for the string representation) we overallocate the
8 *      space for the string and use the internal representation to keep
9 *      track of the extra space.  Objects with this internal
10 *      representation are called "expandable string objects".
11 *
12 * Copyright (c) 1995-1997 Sun Microsystems, Inc.
13 *
14 * See the file "license.terms" for information on usage and redistribution
15 * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
16 *
17 * RCS: @(#) $Id: tclStringObj.c,v 1.1 2008-06-04 13:58:10 demin Exp $
18 */
19
20#include "tclInt.h"
21
22/*
23 * Prototypes for procedures defined later in this file:
24 */
25
26static void             ConvertToStringType _ANSI_ARGS_((Tcl_Obj *objPtr));
27static void             DupStringInternalRep _ANSI_ARGS_((Tcl_Obj *objPtr,
28                            Tcl_Obj *copyPtr));
29static int              SetStringFromAny _ANSI_ARGS_((Tcl_Interp *interp,
30                            Tcl_Obj *objPtr));
31static void             UpdateStringOfString _ANSI_ARGS_((Tcl_Obj *objPtr));
32
33/*
34 * The structure below defines the string Tcl object type by means of
35 * procedures that can be invoked by generic object code.
36 */
37
38Tcl_ObjType tclStringType = {
39    "string",                           /* name */
40    (Tcl_FreeInternalRepProc *) NULL,   /* freeIntRepProc */
41    DupStringInternalRep,               /* dupIntRepProc */
42    UpdateStringOfString,               /* updateStringProc */
43    SetStringFromAny                    /* setFromAnyProc */
44};
45
46/*
47 *----------------------------------------------------------------------
48 *
49 * Tcl_NewStringObj --
50 *
51 *      This procedure is normally called when not debugging: i.e., when
52 *      TCL_MEM_DEBUG is not defined. It creates a new string object and
53 *      initializes it from the byte pointer and length arguments.
54 *
55 *      When TCL_MEM_DEBUG is defined, this procedure just returns the
56 *      result of calling the debugging version Tcl_DbNewStringObj.
57 *
58 * Results:
59 *      A newly created string object is returned that has ref count zero.
60 *
61 * Side effects:
62 *      The new object's internal string representation will be set to a
63 *      copy of the length bytes starting at "bytes". If "length" is
64 *      negative, use bytes up to the first NULL byte; i.e., assume "bytes"
65 *      points to a C-style NULL-terminated string. The object's type is set
66 *      to NULL. An extra NULL is added to the end of the new object's byte
67 *      array.
68 *
69 *----------------------------------------------------------------------
70 */
71
72#ifdef TCL_MEM_DEBUG
73#undef Tcl_NewStringObj
74
75Tcl_Obj *
76Tcl_NewStringObj(bytes, length)
77    register char *bytes;       /* Points to the first of the length bytes
78                                 * used to initialize the new object. */
79    register int length;        /* The number of bytes to copy from "bytes"
80                                 * when initializing the new object. If
81                                 * negative, use bytes up to the first
82                                 * NULL byte. */
83{
84    return Tcl_DbNewStringObj(bytes, length, "unknown", 0);
85}
86
87#else /* if not TCL_MEM_DEBUG */
88
89Tcl_Obj *
90Tcl_NewStringObj(bytes, length)
91    register char *bytes;       /* Points to the first of the length bytes
92                                 * used to initialize the new object. */
93    register int length;        /* The number of bytes to copy from "bytes"
94                                 * when initializing the new object. If
95                                 * negative, use bytes up to the first
96                                 * NULL byte. */
97{
98    register Tcl_Obj *objPtr;
99
100    if (length < 0) {
101        length = (bytes? strlen(bytes) : 0);
102    }
103    TclNewObj(objPtr);
104    TclInitStringRep(objPtr, bytes, length);
105    return objPtr;
106}
107#endif /* TCL_MEM_DEBUG */
108
109/*
110 *----------------------------------------------------------------------
111 *
112 * Tcl_DbNewStringObj --
113 *
114 *      This procedure is normally called when debugging: i.e., when
115 *      TCL_MEM_DEBUG is defined. It creates new string objects. It is the
116 *      same as the Tcl_NewStringObj procedure above except that it calls
117 *      Tcl_DbCkalloc directly with the file name and line number from its
118 *      caller. This simplifies debugging since then the checkmem command
119 *      will report the correct file name and line number when reporting
120 *      objects that haven't been freed.
121 *
122 *      When TCL_MEM_DEBUG is not defined, this procedure just returns the
123 *      result of calling Tcl_NewStringObj.
124 *
125 * Results:
126 *      A newly created string object is returned that has ref count zero.
127 *
128 * Side effects:
129 *      The new object's internal string representation will be set to a
130 *      copy of the length bytes starting at "bytes". If "length" is
131 *      negative, use bytes up to the first NULL byte; i.e., assume "bytes"
132 *      points to a C-style NULL-terminated string. The object's type is set
133 *      to NULL. An extra NULL is added to the end of the new object's byte
134 *      array.
135 *
136 *----------------------------------------------------------------------
137 */
138
139#ifdef TCL_MEM_DEBUG
140
141Tcl_Obj *
142Tcl_DbNewStringObj(bytes, length, file, line)
143    register char *bytes;       /* Points to the first of the length bytes
144                                 * used to initialize the new object. */
145    register int length;        /* The number of bytes to copy from "bytes"
146                                 * when initializing the new object. If
147                                 * negative, use bytes up to the first
148                                 * NULL byte. */
149    char *file;                 /* The name of the source file calling this
150                                 * procedure; used for debugging. */
151    int line;                   /* Line number in the source file; used
152                                 * for debugging. */
153{
154    register Tcl_Obj *objPtr;
155
156    if (length < 0) {
157        length = (bytes? strlen(bytes) : 0);
158    }
159    TclDbNewObj(objPtr, file, line);
160    TclInitStringRep(objPtr, bytes, length);
161    return objPtr;
162}
163
164#else /* if not TCL_MEM_DEBUG */
165
166Tcl_Obj *
167Tcl_DbNewStringObj(bytes, length, file, line)
168    register char *bytes;       /* Points to the first of the length bytes
169                                 * used to initialize the new object. */
170    register int length;        /* The number of bytes to copy from "bytes"
171                                 * when initializing the new object. If
172                                 * negative, use bytes up to the first
173                                 * NULL byte. */
174    char *file;                 /* The name of the source file calling this
175                                 * procedure; used for debugging. */
176    int line;                   /* Line number in the source file; used
177                                 * for debugging. */
178{
179    return Tcl_NewStringObj(bytes, length);
180}
181#endif /* TCL_MEM_DEBUG */
182
183/*
184 *----------------------------------------------------------------------
185 *
186 * Tcl_SetStringObj --
187 *
188 *      Modify an object to hold a string that is a copy of the bytes
189 *      indicated by the byte pointer and length arguments.
190 *
191 * Results:
192 *      None.
193 *
194 * Side effects:
195 *      The object's string representation will be set to a copy of
196 *      the "length" bytes starting at "bytes". If "length" is negative, use
197 *      bytes up to the first NULL byte; i.e., assume "bytes" points to a
198 *      C-style NULL-terminated string. The object's old string and internal
199 *      representations are freed and the object's type is set NULL.
200 *
201 *----------------------------------------------------------------------
202 */
203
204void
205Tcl_SetStringObj(objPtr, bytes, length)
206    register Tcl_Obj *objPtr;   /* Object whose internal rep to init. */
207    char *bytes;                /* Points to the first of the length bytes
208                                 * used to initialize the object. */
209    register int length;        /* The number of bytes to copy from "bytes"
210                                 * when initializing the object. If
211                                 * negative, use bytes up to the first
212                                 * NULL byte.*/
213{
214    register Tcl_ObjType *oldTypePtr = objPtr->typePtr;
215
216    /*
217     * Free any old string rep, then set the string rep to a copy of
218     * the length bytes starting at "bytes".
219     */
220
221    if (Tcl_IsShared(objPtr)) {
222        panic("Tcl_SetStringObj called with shared object");
223    }
224
225    Tcl_InvalidateStringRep(objPtr);
226    if (length < 0) {
227        length = strlen(bytes);
228    }
229    TclInitStringRep(objPtr, bytes, length);
230       
231    /*
232     * Set the type to NULL and free any internal rep for the old type.
233     */
234
235    if ((oldTypePtr != NULL) && (oldTypePtr->freeIntRepProc != NULL)) {
236        oldTypePtr->freeIntRepProc(objPtr);
237    }
238    objPtr->typePtr = NULL;
239}
240
241/*
242 *----------------------------------------------------------------------
243 *
244 * Tcl_SetObjLength --
245 *
246 *      This procedure changes the length of the string representation
247 *      of an object.
248 *
249 * Results:
250 *      None.
251 *
252 * Side effects:
253 *      If the size of objPtr's string representation is greater than
254 *      length, then it is reduced to length and a new terminating null
255 *      byte is stored in the strength.  If the length of the string
256 *      representation is greater than length, the storage space is
257 *      reallocated to the given length; a null byte is stored at the
258 *      end, but other bytes past the end of the original string
259 *      representation are undefined.  The object's internal
260 *      representation is changed to "expendable string".
261 *
262 *----------------------------------------------------------------------
263 */
264
265void
266Tcl_SetObjLength(objPtr, length)
267    register Tcl_Obj *objPtr;   /* Pointer to object.  This object must
268                                 * not currently be shared. */
269    register int length;        /* Number of bytes desired for string
270                                 * representation of object, not including
271                                 * terminating null byte. */
272{
273    char *new;
274
275    if (Tcl_IsShared(objPtr)) {
276        panic("Tcl_SetObjLength called with shared object");
277    }
278    if (objPtr->typePtr != &tclStringType) {
279        ConvertToStringType(objPtr);
280    }
281   
282    if ((long)length > objPtr->internalRep.longValue) {
283        /*
284         * Not enough space in current string. Reallocate the string
285         * space and free the old string.
286         */
287
288        new = (char *) ckalloc((unsigned) (length+1));
289        if (objPtr->bytes != NULL) {
290            memcpy((VOID *) new, (VOID *) objPtr->bytes,
291                    (size_t) objPtr->length);
292            Tcl_InvalidateStringRep(objPtr);
293        }
294        objPtr->bytes = new;
295        objPtr->internalRep.longValue = (long) length;
296    }
297    objPtr->length = length;
298    if ((objPtr->bytes != NULL) && (objPtr->bytes != tclEmptyStringRep)) {
299        objPtr->bytes[length] = 0;
300    }
301}
302
303/*
304 *----------------------------------------------------------------------
305 *
306 * Tcl_AppendToObj --
307 *
308 *      This procedure appends a sequence of bytes to an object.
309 *
310 * Results:
311 *      None.
312 *
313 * Side effects:
314 *      The bytes at *bytes are appended to the string representation
315 *      of objPtr.
316 *
317 *----------------------------------------------------------------------
318 */
319
320void
321Tcl_AppendToObj(objPtr, bytes, length)
322    register Tcl_Obj *objPtr;   /* Points to the object to append to. */
323    char *bytes;                /* Points to the bytes to append to the
324                                 * object. */
325    register int length;        /* The number of bytes to append from
326                                 * "bytes". If < 0, then append all bytes
327                                 * up to NULL byte. */
328{
329    int newLength, oldLength;
330
331    if (Tcl_IsShared(objPtr)) {
332        panic("Tcl_AppendToObj called with shared object");
333    }
334    if (objPtr->typePtr != &tclStringType) {
335        ConvertToStringType(objPtr);
336    }
337    if (length < 0) {
338        length = strlen(bytes);
339    }
340    if (length == 0) {
341        return;
342    }
343    oldLength = objPtr->length;
344    newLength = length + oldLength;
345    if ((long)newLength > objPtr->internalRep.longValue) {
346        /*
347         * There isn't currently enough space in the string
348         * representation so allocate additional space.  In fact,
349         * overallocate so that there is room for future growth without
350         * having to reallocate again.
351         */
352
353        Tcl_SetObjLength(objPtr, 2*newLength);
354    }
355    if (length > 0) {
356        memcpy((VOID *) (objPtr->bytes + oldLength), (VOID *) bytes,
357               (size_t) length);
358        objPtr->length = newLength;
359        objPtr->bytes[objPtr->length] = 0;
360    }
361}
362
363/*
364 *----------------------------------------------------------------------
365 *
366 * Tcl_AppendStringsToObj --
367 *
368 *      This procedure appends one or more null-terminated strings
369 *      to an object.
370 *
371 * Results:
372 *      None.
373 *
374 * Side effects:
375 *      The contents of all the string arguments are appended to the
376 *      string representation of objPtr.
377 *
378 *----------------------------------------------------------------------
379 */
380
381void
382Tcl_AppendStringsToObj TCL_VARARGS_DEF(Tcl_Obj *,arg1)
383{
384    va_list argList;
385    register Tcl_Obj *objPtr;
386    int newLength, oldLength;
387    register char *string, *dst;
388
389    objPtr = (Tcl_Obj *) TCL_VARARGS_START(Tcl_Obj *,arg1,argList);
390    if (Tcl_IsShared(objPtr)) {
391        panic("Tcl_AppendStringsToObj called with shared object");
392    }
393    if (objPtr->typePtr != &tclStringType) {
394        ConvertToStringType(objPtr);
395    }
396
397    /*
398     * Figure out how much space is needed for all the strings, and
399     * expand the string representation if it isn't big enough. If no
400     * bytes would be appended, just return.
401     */
402
403    newLength = oldLength = objPtr->length;
404    while (1) {
405        string = va_arg(argList, char *);
406        if (string == NULL) {
407            break;
408        }
409        newLength += strlen(string);
410    }
411    if (newLength == oldLength) {
412        return;
413    }
414
415    if ((long)newLength > objPtr->internalRep.longValue) {
416        /*
417         * There isn't currently enough space in the string
418         * representation so allocate additional space.  If the current
419         * string representation isn't empty (i.e. it looks like we're
420         * doing a series of appends) then overallocate the space so
421         * that we won't have to do as much reallocation in the future.
422         */
423
424        Tcl_SetObjLength(objPtr,
425                (objPtr->length == 0) ? newLength : 2*newLength);
426    }
427
428    /*
429     * Make a second pass through the arguments, appending all the
430     * strings to the object.
431     */
432
433    TCL_VARARGS_START(Tcl_Obj *,arg1,argList);
434    dst = objPtr->bytes + oldLength;
435    while (1) {
436        string = va_arg(argList, char *);
437        if (string == NULL) {
438            break;
439        }
440        while (*string != 0) {
441            *dst = *string;
442            dst++;
443            string++;
444        }
445    }
446
447    /*
448     * Add a null byte to terminate the string.  However, be careful:
449     * it's possible that the object is totally empty (if it was empty
450     * originally and there was nothing to append).  In this case dst is
451     * NULL; just leave everything alone.
452     */
453
454    if (dst != NULL) {
455        *dst = 0;
456    }
457    objPtr->length = newLength;
458    va_end(argList);
459}
460
461/*
462 *----------------------------------------------------------------------
463 *
464 * ConvertToStringType --
465 *
466 *      This procedure converts the internal representation of an object
467 *      to "expandable string" type.
468 *
469 * Results:
470 *      None.
471 *
472 * Side effects:
473 *      Any old internal reputation for objPtr is freed and the
474 *      internal representation is set to that for an expandable string
475 *      (the field internalRep.longValue holds 1 less than the allocated
476 *      length of objPtr's string representation).
477 *
478 *----------------------------------------------------------------------
479 */
480
481static void
482ConvertToStringType(objPtr)
483    register Tcl_Obj *objPtr;   /* Pointer to object.  Must have a
484                                 * typePtr that isn't &tclStringType. */
485{
486    if (objPtr->typePtr != NULL) {
487        if (objPtr->bytes == NULL) {
488            objPtr->typePtr->updateStringProc(objPtr);
489        }
490        if (objPtr->typePtr->freeIntRepProc != NULL) {
491            objPtr->typePtr->freeIntRepProc(objPtr);
492        }
493    }
494    objPtr->typePtr = &tclStringType;
495    if (objPtr->bytes != NULL) {
496        objPtr->internalRep.longValue = (long)objPtr->length;
497    } else {
498        objPtr->internalRep.longValue = 0;
499        objPtr->length = 0;
500    }
501}
502
503/*
504 *----------------------------------------------------------------------
505 *
506 * DupStringInternalRep --
507 *
508 *      Initialize the internal representation of a new Tcl_Obj to a
509 *      copy of the internal representation of an existing string object.
510 *
511 * Results:
512 *      None.
513 *
514 * Side effects:
515 *      copyPtr's internal rep is set to a copy of srcPtr's internal
516 *      representation.
517 *
518 *----------------------------------------------------------------------
519 */
520
521static void
522DupStringInternalRep(srcPtr, copyPtr)
523    register Tcl_Obj *srcPtr;   /* Object with internal rep to copy.  Must
524                                 * have an internal representation of type
525                                 * "expandable string". */
526    register Tcl_Obj *copyPtr;  /* Object with internal rep to set.  Must
527                                 * not currently have an internal rep.*/
528{
529    /*
530     * Tricky point: the string value was copied by generic object
531     * management code, so it doesn't contain any extra bytes that
532     * might exist in the source object.
533     */
534
535    copyPtr->internalRep.longValue = (long)copyPtr->length;
536    copyPtr->typePtr = &tclStringType;
537}
538
539/*
540 *----------------------------------------------------------------------
541 *
542 * SetStringFromAny --
543 *
544 *      Create an internal representation of type "expandable string"
545 *      for an object.
546 *
547 * Results:
548 *      This operation always succeeds and returns TCL_OK.
549 *
550 * Side effects:
551 *      This procedure does nothing; there is no advantage in converting
552 *      the internal representation now, so we just defer it.
553 *
554 *----------------------------------------------------------------------
555 */
556
557static int
558SetStringFromAny(interp, objPtr)
559    Tcl_Interp *interp;         /* Used for error reporting if not NULL. */
560    Tcl_Obj *objPtr;            /* The object to convert. */
561{
562    return TCL_OK;
563}
564
565/*
566 *----------------------------------------------------------------------
567 *
568 * UpdateStringOfString --
569 *
570 *      Update the string representation for an object whose internal
571 *      representation is "expandable string".
572 *
573 * Results:
574 *      None.
575 *
576 * Side effects:
577 *      None.
578 *
579 *----------------------------------------------------------------------
580 */
581
582static void
583UpdateStringOfString(objPtr)
584    Tcl_Obj *objPtr;            /* Object with string rep to update. */
585{
586    /*
587     * The string is almost always valid already, in which case there's
588     * nothing for us to do. The only case we have to worry about is if
589     * the object is totally null. In this case, set the string rep to
590     * an empty string.
591     */
592
593    if (objPtr->bytes == NULL) {
594        objPtr->bytes = tclEmptyStringRep;
595        objPtr->length = 0;
596    }
597    return;
598}
Note: See TracBrowser for help on using the repository browser.