os/persistentdata/persistentstorage/sqlite3api/TEST/TCL/tcldistribution/generic/tclUtil.c
First public contribution.
4 * This file contains utility procedures that are used by many Tcl
7 * Copyright (c) 1987-1993 The Regents of the University of California.
8 * Copyright (c) 1994-1998 Sun Microsystems, Inc.
9 * Copyright (c) 2001 by Kevin B. Kenny. All rights reserved.
10 * Portions Copyright (c) 2007-2008 Nokia Corporation and/or its subsidiaries. All rights reserved.
12 * See the file "license.terms" for information on usage and redistribution
13 * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
15 * RCS: @(#) $Id: tclUtil.c,v 1.36.2.8 2007/05/10 18:23:58 dgp Exp $
20 #if defined(__SYMBIAN32__)
21 #include "tclSymbianGlobals.h"
25 * The following variable holds the full path name of the binary
26 * from which this application was executed, or NULL if it isn't
27 * know. The value of the variable is set by the procedure
28 * Tcl_FindExecutable. The storage space is dynamically allocated.
31 #if !defined(__SYMBIAN32__) || !defined(__WINSCW__)
32 char *tclExecutableName = NULL;
33 char *tclNativeExecutableName = NULL;
37 * The following values are used in the flags returned by Tcl_ScanElement
38 * and used by Tcl_ConvertElement. The value TCL_DONT_USE_BRACES is also
39 * defined in tcl.h; make sure its value doesn't overlap with any of the
42 * TCL_DONT_USE_BRACES - 1 means the string mustn't be enclosed in
43 * braces (e.g. it contains unmatched braces,
44 * or ends in a backslash character, or user
45 * just doesn't want braces); handle all
46 * special characters by adding backslashes.
47 * USE_BRACES - 1 means the string contains a special
48 * character that can be handled simply by
49 * enclosing the entire argument in braces.
50 * BRACES_UNMATCHED - 1 means that braces aren't properly matched
55 #define BRACES_UNMATCHED 4
58 * The following values determine the precision used when converting
59 * floating-point values to strings. This information is linked to all
60 * of the tcl_precision variables in all interpreters via the procedure
64 static char precisionString[10] = "12";
65 /* The string value of all the tcl_precision
67 static char precisionFormat[10] = "%.12g";
68 /* The format string actually used in calls
70 TCL_DECLARE_MUTEX(precisionMutex)
73 * Prototypes for procedures defined later in this file.
76 static void UpdateStringOfEndOffset _ANSI_ARGS_((Tcl_Obj* objPtr));
77 static int SetEndOffsetFromAny _ANSI_ARGS_((Tcl_Interp* interp,
81 * The following is the Tcl object type definition for an object
82 * that represents a list index in the form, "end-offset". It is
83 * used as a performance optimization in TclGetIntForIndex. The
84 * internal rep is an integer, so no memory management is required
88 Tcl_ObjType tclEndOffsetType = {
89 "end-offset", /* name */
90 (Tcl_FreeInternalRepProc*) NULL, /* freeIntRepProc */
91 (Tcl_DupInternalRepProc*) NULL, /* dupIntRepProc */
92 UpdateStringOfEndOffset, /* updateStringProc */
98 *----------------------------------------------------------------------
102 * Given a pointer into a Tcl list, locate the first (or next)
103 * element in the list.
106 * The return value is normally TCL_OK, which means that the
107 * element was successfully located. If TCL_ERROR is returned
108 * it means that list didn't have proper list structure;
109 * the interp's result contains a more detailed error message.
111 * If TCL_OK is returned, then *elementPtr will be set to point to the
112 * first element of list, and *nextPtr will be set to point to the
113 * character just after any white space following the last character
114 * that's part of the element. If this is the last argument in the
115 * list, then *nextPtr will point just after the last character in the
116 * list (i.e., at the character at list+listLength). If sizePtr is
117 * non-NULL, *sizePtr is filled in with the number of characters in the
118 * element. If the element is in braces, then *elementPtr will point
119 * to the character after the opening brace and *sizePtr will not
120 * include either of the braces. If there isn't an element in the list,
121 * *sizePtr will be zero, and both *elementPtr and *termPtr will point
122 * just after the last character in the list. Note: this procedure does
123 * NOT collapse backslash sequences.
128 *----------------------------------------------------------------------
132 TclFindElement(interp, list, listLength, elementPtr, nextPtr, sizePtr,
134 Tcl_Interp *interp; /* Interpreter to use for error reporting.
135 * If NULL, then no error message is left
137 CONST char *list; /* Points to the first byte of a string
138 * containing a Tcl list with zero or more
139 * elements (possibly in braces). */
140 int listLength; /* Number of bytes in the list's string. */
141 CONST char **elementPtr; /* Where to put address of first significant
142 * character in first element of list. */
143 CONST char **nextPtr; /* Fill in with location of character just
144 * after all white space following end of
145 * argument (next arg or end of list). */
146 int *sizePtr; /* If non-zero, fill in with size of
148 int *bracePtr; /* If non-zero, fill in with non-zero/zero
149 * to indicate that arg was/wasn't
152 CONST char *p = list;
153 CONST char *elemStart; /* Points to first byte of first element. */
154 CONST char *limit; /* Points just after list's last byte. */
155 int openBraces = 0; /* Brace nesting level during parse. */
157 int size = 0; /* lint. */
162 * Skim off leading white space and check for an opening brace or
163 * quote. We treat embedded NULLs in the list as bytes belonging to
167 limit = (list + listLength);
168 while ((p < limit) && (isspace(UCHAR(*p)))) { /* INTL: ISO space. */
171 if (p == limit) { /* no element found */
179 } else if (*p == '"') {
185 *bracePtr = openBraces;
189 * Find element's end (a space, close brace, or the end of the string).
196 * Open brace: don't treat specially unless the element is in
197 * braces. In this case, keep a nesting count.
201 if (openBraces != 0) {
207 * Close brace: if element is in braces, keep nesting count and
208 * quit when the last close brace is seen.
212 if (openBraces > 1) {
214 } else if (openBraces == 1) {
215 size = (p - elemStart);
218 || isspace(UCHAR(*p))) { /* INTL: ISO space. */
223 * Garbage after the closing brace; return an error.
226 if (interp != NULL) {
231 && (!isspace(UCHAR(*p2))) /* INTL: ISO space. */
236 "list element in braces followed by \"%.*s\" instead of space",
238 Tcl_SetResult(interp, buf, TCL_VOLATILE);
245 * Backslash: skip over everything up to the end of the
246 * backslash sequence.
250 Tcl_UtfBackslash(p, &numChars, NULL);
256 * Space: ignore if element is in braces or quotes; otherwise
266 if ((openBraces == 0) && !inQuotes) {
267 size = (p - elemStart);
273 * Double-quote: if element is in quotes then terminate it.
278 size = (p - elemStart);
281 || isspace(UCHAR(*p))) { /* INTL: ISO space */
286 * Garbage after the closing quote; return an error.
289 if (interp != NULL) {
294 && (!isspace(UCHAR(*p2))) /* INTL: ISO space */
299 "list element in quotes followed by \"%.*s\" %s",
300 (int) (p2-p), p, "instead of space");
301 Tcl_SetResult(interp, buf, TCL_VOLATILE);
312 * End of list: terminate element.
316 if (openBraces != 0) {
317 if (interp != NULL) {
318 Tcl_SetResult(interp, "unmatched open brace in list",
322 } else if (inQuotes) {
323 if (interp != NULL) {
324 Tcl_SetResult(interp, "unmatched open quote in list",
329 size = (p - elemStart);
333 while ((p < limit) && (isspace(UCHAR(*p)))) { /* INTL: ISO space. */
336 *elementPtr = elemStart;
345 *----------------------------------------------------------------------
347 * TclCopyAndCollapse --
349 * Copy a string and eliminate any backslashes that aren't in braces.
352 * Count characters get copied from src to dst. Along the way, if
353 * backslash sequences are found outside braces, the backslashes are
354 * eliminated in the copy. After scanning count chars from source, a
355 * null character is placed at the end of dst. Returns the number
356 * of characters that got copied.
361 *----------------------------------------------------------------------
365 TclCopyAndCollapse(count, src, dst)
366 int count; /* Number of characters to copy from src. */
367 CONST char *src; /* Copy from here... */
368 char *dst; /* ... to here. */
375 for (c = *src; count > 0; src++, c = *src, count--) {
377 backslashCount = Tcl_UtfBackslash(src, &numRead, dst);
378 dst += backslashCount;
379 newCount += backslashCount;
393 *----------------------------------------------------------------------
397 * Splits a list up into its constituent fields.
400 * The return value is normally TCL_OK, which means that
401 * the list was successfully split up. If TCL_ERROR is
402 * returned, it means that "list" didn't have proper list
403 * structure; the interp's result will contain a more detailed
406 * *argvPtr will be filled in with the address of an array
407 * whose elements point to the elements of list, in order.
408 * *argcPtr will get filled in with the number of valid elements
409 * in the array. A single block of memory is dynamically allocated
410 * to hold both the argv array and a copy of the list (with
411 * backslashes and braces removed in the standard way).
412 * The caller must eventually free this memory by calling free()
413 * on *argvPtr. Note: *argvPtr and *argcPtr are only modified
414 * if the procedure returns normally.
417 * Memory is allocated.
419 *----------------------------------------------------------------------
423 Tcl_SplitList(interp, list, argcPtr, argvPtr)
424 Tcl_Interp *interp; /* Interpreter to use for error reporting.
425 * If NULL, no error message is left. */
426 CONST char *list; /* Pointer to string with list structure. */
427 int *argcPtr; /* Pointer to location to fill in with
428 * the number of elements in the list. */
429 CONST char ***argvPtr; /* Pointer to place to store pointer to
430 * array of pointers to list elements. */
435 int length, size, i, result, elSize, brace;
439 * Figure out how much space to allocate. There must be enough
440 * space for both the array of pointers and also for a copy of
441 * the list. To estimate the number of pointers needed, count
442 * the number of space characters in the list.
445 for (size = 2, l = list; *l != 0; l++) {
446 if (isspace(UCHAR(*l))) { /* INTL: ISO space. */
448 /* Consecutive space can only count as a single list delimiter */
450 char next = *(l + 1);
455 if (isspace(UCHAR(next))) {
463 argv = (CONST char **) ckalloc((unsigned)
464 ((size * sizeof(char *)) + length + 1));
465 for (i = 0, p = ((char *) argv) + size*sizeof(char *);
467 CONST char *prevList = list;
469 result = TclFindElement(interp, list, length, &element,
470 &list, &elSize, &brace);
471 length -= (list - prevList);
472 if (result != TCL_OK) {
473 ckfree((char *) argv);
480 ckfree((char *) argv);
481 if (interp != NULL) {
482 Tcl_SetResult(interp, "internal error in Tcl_SplitList",
489 memcpy((VOID *) p, (VOID *) element, (size_t) elSize);
494 TclCopyAndCollapse(elSize, element, p);
506 *----------------------------------------------------------------------
510 * This procedure is a companion procedure to Tcl_ConvertElement.
511 * It scans a string to see what needs to be done to it (e.g. add
512 * backslashes or enclosing braces) to make the string into a
513 * valid Tcl list element.
516 * The return value is an overestimate of the number of characters
517 * that will be needed by Tcl_ConvertElement to produce a valid
518 * list element from string. The word at *flagPtr is filled in
519 * with a value needed by Tcl_ConvertElement when doing the actual
525 *----------------------------------------------------------------------
529 Tcl_ScanElement(string, flagPtr)
530 register CONST char *string; /* String to convert to list element. */
531 register int *flagPtr; /* Where to store information to guide
532 * Tcl_ConvertCountedElement. */
534 return Tcl_ScanCountedElement(string, -1, flagPtr);
538 *----------------------------------------------------------------------
540 * Tcl_ScanCountedElement --
542 * This procedure is a companion procedure to
543 * Tcl_ConvertCountedElement. It scans a string to see what
544 * needs to be done to it (e.g. add backslashes or enclosing
545 * braces) to make the string into a valid Tcl list element.
546 * If length is -1, then the string is scanned up to the first
550 * The return value is an overestimate of the number of characters
551 * that will be needed by Tcl_ConvertCountedElement to produce a
552 * valid list element from string. The word at *flagPtr is
553 * filled in with a value needed by Tcl_ConvertCountedElement
554 * when doing the actual conversion.
559 *----------------------------------------------------------------------
563 Tcl_ScanCountedElement(string, length, flagPtr)
564 CONST char *string; /* String to convert to Tcl list element. */
565 int length; /* Number of bytes in string, or -1. */
566 int *flagPtr; /* Where to store information to guide
567 * Tcl_ConvertElement. */
569 int flags, nestingLevel;
570 register CONST char *p, *lastChar;
573 * This procedure and Tcl_ConvertElement together do two things:
575 * 1. They produce a proper list, one that will yield back the
576 * argument strings when evaluated or when disassembled with
577 * Tcl_SplitList. This is the most important thing.
579 * 2. They try to produce legible output, which means minimizing the
580 * use of backslashes (using braces instead). However, there are
581 * some situations where backslashes must be used (e.g. an element
582 * like "{abc": the leading brace will have to be backslashed.
583 * For each element, one of three things must be done:
585 * (a) Use the element as-is (it doesn't contain any special
586 * characters). This is the most desirable option.
588 * (b) Enclose the element in braces, but leave the contents alone.
589 * This happens if the element contains embedded space, or if it
590 * contains characters with special interpretation ($, [, ;, or \),
591 * or if it starts with a brace or double-quote, or if there are
592 * no characters in the element.
594 * (c) Don't enclose the element in braces, but add backslashes to
595 * prevent special interpretation of special characters. This is a
596 * last resort used when the argument would normally fall under case
597 * (b) but contains unmatched braces. It also occurs if the last
598 * character of the argument is a backslash or if the element contains
599 * a backslash followed by newline.
601 * The procedure figures out how many bytes will be needed to store
602 * the result (actually, it overestimates). It also collects information
603 * about the element in the form of a flags word.
605 * Note: list elements produced by this procedure and
606 * Tcl_ConvertCountedElement must have the property that they can be
607 * enclosing in curly braces to make sub-lists. This means, for
608 * example, that we must not leave unmatched curly braces in the
609 * resulting list element. This property is necessary in order for
610 * procedures like Tcl_DStringStartSublist to work.
615 if (string == NULL) {
619 length = strlen(string);
621 lastChar = string + length;
623 if ((p == lastChar) || (*p == '{') || (*p == '"')) {
626 for ( ; p < lastChar; p++) {
633 if (nestingLevel < 0) {
634 flags |= TCL_DONT_USE_BRACES|BRACES_UNMATCHED;
649 if ((p+1 == lastChar) || (p[1] == '\n')) {
650 flags = TCL_DONT_USE_BRACES | BRACES_UNMATCHED;
654 Tcl_UtfBackslash(p, &size, NULL);
661 if (nestingLevel != 0) {
662 flags = TCL_DONT_USE_BRACES | BRACES_UNMATCHED;
667 * Allow enough space to backslash every character plus leave
668 * two spaces for braces.
671 return 2*(p-string) + 2;
675 *----------------------------------------------------------------------
677 * Tcl_ConvertElement --
679 * This is a companion procedure to Tcl_ScanElement. Given
680 * the information produced by Tcl_ScanElement, this procedure
681 * converts a string to a list element equal to that string.
684 * Information is copied to *dst in the form of a list element
685 * identical to src (i.e. if Tcl_SplitList is applied to dst it
686 * will produce a string identical to src). The return value is
687 * a count of the number of characters copied (not including the
688 * terminating NULL character).
693 *----------------------------------------------------------------------
697 Tcl_ConvertElement(src, dst, flags)
698 register CONST char *src; /* Source information for list element. */
699 register char *dst; /* Place to put list-ified element. */
700 register int flags; /* Flags produced by Tcl_ScanElement. */
702 return Tcl_ConvertCountedElement(src, -1, dst, flags);
706 *----------------------------------------------------------------------
708 * Tcl_ConvertCountedElement --
710 * This is a companion procedure to Tcl_ScanCountedElement. Given
711 * the information produced by Tcl_ScanCountedElement, this
712 * procedure converts a string to a list element equal to that
716 * Information is copied to *dst in the form of a list element
717 * identical to src (i.e. if Tcl_SplitList is applied to dst it
718 * will produce a string identical to src). The return value is
719 * a count of the number of characters copied (not including the
720 * terminating NULL character).
725 *----------------------------------------------------------------------
729 Tcl_ConvertCountedElement(src, length, dst, flags)
730 register CONST char *src; /* Source information for list element. */
731 int length; /* Number of bytes in src, or -1. */
732 char *dst; /* Place to put list-ified element. */
733 int flags; /* Flags produced by Tcl_ScanElement. */
735 register char *p = dst;
736 register CONST char *lastChar;
739 * See the comment block at the beginning of the Tcl_ScanElement
740 * code for details of how this works.
743 if (src && length == -1) {
744 length = strlen(src);
746 if ((src == NULL) || (length == 0)) {
752 lastChar = src + length;
753 if ((flags & USE_BRACES) && !(flags & TCL_DONT_USE_BRACES)) {
756 for ( ; src != lastChar; src++, p++) {
764 * Can't have a leading brace unless the whole element is
765 * enclosed in braces. Add a backslash before the brace.
766 * Furthermore, this may destroy the balance between open
767 * and close braces, so set BRACES_UNMATCHED.
774 flags |= BRACES_UNMATCHED;
776 for (; src != lastChar; src++) {
791 * It may not seem necessary to backslash braces, but
792 * it is. The reason for this is that the resulting
793 * list element may actually be an element of a sub-list
794 * enclosed in braces (e.g. if Tcl_DStringStartSublist
795 * has been invoked), so there may be a brace mismatch
796 * if the braces aren't backslashed.
799 if (flags & BRACES_UNMATCHED) {
844 *----------------------------------------------------------------------
848 * Given a collection of strings, merge them together into a
849 * single string that has proper Tcl list structured (i.e.
850 * Tcl_SplitList may be used to retrieve strings equal to the
851 * original elements, and Tcl_Eval will parse the string back
852 * into its original elements).
855 * The return value is the address of a dynamically-allocated
856 * string containing the merged list.
861 *----------------------------------------------------------------------
865 Tcl_Merge(argc, argv)
866 int argc; /* How many strings to merge. */
867 CONST char * CONST *argv; /* Array of string values. */
869 # define LOCAL_SIZE 20
870 int localFlags[LOCAL_SIZE], *flagPtr;
877 * Pass 1: estimate space, gather flags.
880 if (argc <= LOCAL_SIZE) {
881 flagPtr = localFlags;
883 flagPtr = (int *) ckalloc((unsigned) argc*sizeof(int));
886 for (i = 0; i < argc; i++) {
887 numChars += Tcl_ScanElement(argv[i], &flagPtr[i]) + 1;
891 * Pass two: copy into the result area.
894 result = (char *) ckalloc((unsigned) numChars);
896 for (i = 0; i < argc; i++) {
897 numChars = Tcl_ConvertElement(argv[i], dst, flagPtr[i]);
908 if (flagPtr != localFlags) {
909 ckfree((char *) flagPtr);
915 *----------------------------------------------------------------------
919 * Figure out how to handle a backslash sequence.
922 * The return value is the character that should be substituted
923 * in place of the backslash sequence that starts at src. If
924 * readPtr isn't NULL then it is filled in with a count of the
925 * number of characters in the backslash sequence.
930 *----------------------------------------------------------------------
934 Tcl_Backslash(src, readPtr)
935 CONST char *src; /* Points to the backslash character of
936 * a backslash sequence. */
937 int *readPtr; /* Fill in with number of characters read
938 * from src, unless NULL. */
940 char buf[TCL_UTF_MAX];
943 Tcl_UtfBackslash(src, readPtr, buf);
944 TclUtfToUniChar(buf, &ch);
949 *----------------------------------------------------------------------
953 * Concatenate a set of strings into a single large string.
956 * The return value is dynamically-allocated string containing
957 * a concatenation of all the strings in argv, with spaces between
958 * the original argv elements.
961 * Memory is allocated for the result; the caller is responsible
962 * for freeing the memory.
964 *----------------------------------------------------------------------
968 Tcl_Concat(argc, argv)
969 int argc; /* Number of strings to concatenate. */
970 CONST char * CONST *argv; /* Array of strings to concatenate. */
976 for (totalSize = 1, i = 0; i < argc; i++) {
977 totalSize += strlen(argv[i]) + 1;
979 result = (char *) ckalloc((unsigned) totalSize);
984 for (p = result, i = 0; i < argc; i++) {
989 * Clip white space off the front and back of the string
990 * to generate a neater result, and ignore any empty
995 while (isspace(UCHAR(*element))) { /* INTL: ISO space. */
998 for (length = strlen(element);
1000 && (isspace(UCHAR(element[length-1]))) /* INTL: ISO space. */
1001 && ((length < 2) || (element[length-2] != '\\'));
1003 /* Null loop body. */
1008 memcpy((VOID *) p, (VOID *) element, (size_t) length);
1022 *----------------------------------------------------------------------
1026 * Concatenate the strings from a set of objects into a single string
1027 * object with spaces between the original strings.
1030 * The return value is a new string object containing a concatenation
1031 * of the strings in objv. Its ref count is zero.
1034 * A new object is created.
1036 *----------------------------------------------------------------------
1040 Tcl_ConcatObj(objc, objv)
1041 int objc; /* Number of objects to concatenate. */
1042 Tcl_Obj *CONST objv[]; /* Array of objects to concatenate. */
1044 int allocSize, finalSize, length, elemLength, i;
1051 * Check first to see if all the items are of list type. If so,
1052 * we will concat them together as lists, and return a list object.
1053 * This is only valid when the lists have no current string
1054 * representation, since we don't know what the original type was.
1055 * An original string rep may have lost some whitespace info when
1056 * converted which could be important.
1058 for (i = 0; i < objc; i++) {
1060 if ((objPtr->typePtr != &tclListType) || (objPtr->bytes != NULL)) {
1068 objPtr = Tcl_NewListObj(0, NULL);
1069 for (i = 0; i < objc; i++) {
1071 * Tcl_ListObjAppendList could be used here, but this saves
1072 * us a bit of type checking (since we've already done it)
1073 * Use of INT_MAX tells us to always put the new stuff on
1074 * the end. It will be set right in Tcl_ListObjReplace.
1076 Tcl_ListObjGetElements(NULL, objv[i], &listc, &listv);
1077 Tcl_ListObjReplace(NULL, objPtr, INT_MAX, 0, listc, listv);
1083 for (i = 0; i < objc; i++) {
1085 element = Tcl_GetStringFromObj(objPtr, &length);
1086 if ((element != NULL) && (length > 0)) {
1087 allocSize += (length + 1);
1090 if (allocSize == 0) {
1091 allocSize = 1; /* enough for the NULL byte at end */
1095 * Allocate storage for the concatenated result. Note that allocSize
1096 * is one more than the total number of characters, and so includes
1097 * room for the terminating NULL byte.
1100 concatStr = (char *) ckalloc((unsigned) allocSize);
1103 * Now concatenate the elements. Clip white space off the front and back
1104 * to generate a neater result, and ignore any empty elements. Also put
1105 * a null byte at the end.
1113 for (i = 0; i < objc; i++) {
1115 element = Tcl_GetStringFromObj(objPtr, &elemLength);
1116 while ((elemLength > 0) && (UCHAR(*element) < 127)
1117 && isspace(UCHAR(*element))) { /* INTL: ISO C space. */
1123 * Trim trailing white space. But, be careful not to trim
1124 * a space character if it is preceded by a backslash: in
1125 * this case it could be significant.
1128 while ((elemLength > 0) && (UCHAR(element[elemLength-1]) < 127)
1129 && isspace(UCHAR(element[elemLength-1])) /* INTL: ISO C space. */
1130 && ((elemLength < 2) || (element[elemLength-2] != '\\'))) {
1133 if (elemLength == 0) {
1134 continue; /* nothing left of this element */
1136 memcpy((VOID *) p, (VOID *) element, (size_t) elemLength);
1140 finalSize += (elemLength + 1);
1142 if (p != concatStr) {
1144 finalSize -= 1; /* we overwrote the final ' ' */
1151 objPtr->bytes = concatStr;
1152 objPtr->length = finalSize;
1157 *----------------------------------------------------------------------
1159 * Tcl_StringMatch --
1161 * See if a particular string matches a particular pattern.
1164 * The return value is 1 if string matches pattern, and
1165 * 0 otherwise. The matching operation permits the following
1166 * special characters in the pattern: *?\[] (see the manual
1167 * entry for details on what these mean).
1172 *----------------------------------------------------------------------
1176 Tcl_StringMatch(string, pattern)
1177 CONST char *string; /* String. */
1178 CONST char *pattern; /* Pattern, which may contain special
1181 return Tcl_StringCaseMatch(string, pattern, 0);
1185 *----------------------------------------------------------------------
1187 * Tcl_StringCaseMatch --
1189 * See if a particular string matches a particular pattern.
1190 * Allows case insensitivity.
1193 * The return value is 1 if string matches pattern, and
1194 * 0 otherwise. The matching operation permits the following
1195 * special characters in the pattern: *?\[] (see the manual
1196 * entry for details on what these mean).
1201 *----------------------------------------------------------------------
1205 Tcl_StringCaseMatch(string, pattern, nocase)
1206 CONST char *string; /* String. */
1207 CONST char *pattern; /* Pattern, which may contain special
1209 int nocase; /* 0 for case sensitive, 1 for insensitive */
1212 CONST char *pstart = pattern;
1213 Tcl_UniChar ch1, ch2;
1219 * See if we're at the end of both the pattern and the string. If
1220 * so, we succeeded. If we're at the end of the pattern but not at
1221 * the end of the string, we failed.
1225 return (*string == '\0');
1227 if ((*string == '\0') && (p != '*')) {
1232 * Check for a "*" as the next pattern character. It matches
1233 * any substring. We handle this by calling ourselves
1234 * recursively for each postfix of string, until either we
1235 * match or we reach the end of the string.
1240 * Skip all successive *'s in the pattern
1242 while (*(++pattern) == '*') {}
1248 * This is a special case optimization for single-byte utf.
1250 if (UCHAR(*pattern) < 0x80) {
1252 (nocase ? tolower(UCHAR(*pattern)) : UCHAR(*pattern));
1254 Tcl_UtfToUniChar(pattern, &ch2);
1256 ch2 = Tcl_UniCharToLower(ch2);
1261 * Optimization for matching - cruise through the string
1262 * quickly if the next char in the pattern isn't a special
1265 if ((p != '[') && (p != '?') && (p != '\\')) {
1268 charLen = TclUtfToUniChar(string, &ch1);
1269 if (ch2==ch1 || ch2==Tcl_UniCharToLower(ch1)) {
1276 * There's no point in trying to make this code
1277 * shorter, as the number of bytes you want to
1278 * compare each time is non-constant.
1281 charLen = TclUtfToUniChar(string, &ch1);
1289 if (Tcl_StringCaseMatch(string, pattern, nocase)) {
1292 if (*string == '\0') {
1295 string += TclUtfToUniChar(string, &ch1);
1300 * Check for a "?" as the next pattern character. It matches
1301 * any single character.
1306 string += TclUtfToUniChar(string, &ch1);
1311 * Check for a "[" as the next pattern character. It is followed
1312 * by a list of characters that are acceptable, or by a range
1313 * (two characters separated by "-").
1317 Tcl_UniChar startChar, endChar;
1320 if (UCHAR(*string) < 0x80) {
1322 (nocase ? tolower(UCHAR(*string)) : UCHAR(*string));
1325 string += Tcl_UtfToUniChar(string, &ch1);
1327 ch1 = Tcl_UniCharToLower(ch1);
1331 if ((*pattern == ']') || (*pattern == '\0')) {
1334 if (UCHAR(*pattern) < 0x80) {
1335 startChar = (Tcl_UniChar)
1336 (nocase ? tolower(UCHAR(*pattern)) : UCHAR(*pattern));
1339 pattern += Tcl_UtfToUniChar(pattern, &startChar);
1341 startChar = Tcl_UniCharToLower(startChar);
1344 if (*pattern == '-') {
1346 if (*pattern == '\0') {
1349 if (UCHAR(*pattern) < 0x80) {
1350 endChar = (Tcl_UniChar)
1351 (nocase ? tolower(UCHAR(*pattern))
1355 pattern += Tcl_UtfToUniChar(pattern, &endChar);
1357 endChar = Tcl_UniCharToLower(endChar);
1360 if (((startChar <= ch1) && (ch1 <= endChar))
1361 || ((endChar <= ch1) && (ch1 <= startChar))) {
1363 * Matches ranges of form [a-z] or [z-a].
1368 } else if (startChar == ch1) {
1372 while (*pattern != ']') {
1373 if (*pattern == '\0') {
1374 pattern = Tcl_UtfPrev(pattern, pstart);
1384 * If the next pattern character is '\', just strip off the '\'
1385 * so we do exact matching on the character that follows.
1390 if (*pattern == '\0') {
1396 * There's no special character. Just make sure that the next
1397 * bytes of each string match.
1400 string += TclUtfToUniChar(string, &ch1);
1401 pattern += TclUtfToUniChar(pattern, &ch2);
1403 if (Tcl_UniCharToLower(ch1) != Tcl_UniCharToLower(ch2)) {
1406 } else if (ch1 != ch2) {
1413 *----------------------------------------------------------------------
1415 * TclMatchIsTrivial --
1417 * Test whether a particular glob pattern is a trivial pattern.
1418 * (i.e. where matching is the same as equality testing).
1421 * A boolean indicating whether the pattern is free of all of the
1422 * glob special chars.
1427 *----------------------------------------------------------------------
1431 TclMatchIsTrivial(pattern)
1432 CONST char *pattern;
1434 CONST char *p = pattern;
1450 *----------------------------------------------------------------------
1452 * Tcl_DStringInit --
1454 * Initializes a dynamic string, discarding any previous contents
1455 * of the string (Tcl_DStringFree should have been called already
1456 * if the dynamic string was previously in use).
1462 * The dynamic string is initialized to be empty.
1464 *----------------------------------------------------------------------
1468 Tcl_DStringInit(dsPtr)
1469 Tcl_DString *dsPtr; /* Pointer to structure for dynamic string. */
1471 dsPtr->string = dsPtr->staticSpace;
1473 dsPtr->spaceAvl = TCL_DSTRING_STATIC_SIZE;
1474 dsPtr->staticSpace[0] = '\0';
1478 *----------------------------------------------------------------------
1480 * Tcl_DStringAppend --
1482 * Append more characters to the current value of a dynamic string.
1485 * The return value is a pointer to the dynamic string's new value.
1488 * Length bytes from string (or all of string if length is less
1489 * than zero) are added to the current value of the string. Memory
1490 * gets reallocated if needed to accomodate the string's new size.
1492 *----------------------------------------------------------------------
1496 Tcl_DStringAppend(dsPtr, string, length)
1497 Tcl_DString *dsPtr; /* Structure describing dynamic string. */
1498 CONST char *string; /* String to append. If length is -1 then
1499 * this must be null-terminated. */
1500 int length; /* Number of characters from string to
1501 * append. If < 0, then append all of string,
1502 * up to null at end. */
1509 length = strlen(string);
1511 newSize = length + dsPtr->length;
1514 * Allocate a larger buffer for the string if the current one isn't
1515 * large enough. Allocate extra space in the new buffer so that there
1516 * will be room to grow before we have to allocate again.
1519 if (newSize >= dsPtr->spaceAvl) {
1520 dsPtr->spaceAvl = newSize * 2;
1521 if (dsPtr->string == dsPtr->staticSpace) {
1524 newString = (char *) ckalloc((unsigned) dsPtr->spaceAvl);
1525 memcpy((VOID *) newString, (VOID *) dsPtr->string,
1526 (size_t) dsPtr->length);
1527 dsPtr->string = newString;
1529 dsPtr->string = (char *) ckrealloc((VOID *) dsPtr->string,
1530 (size_t) dsPtr->spaceAvl);
1535 * Copy the new string into the buffer at the end of the old
1539 for (dst = dsPtr->string + dsPtr->length, end = string+length;
1540 string < end; string++, dst++) {
1544 dsPtr->length += length;
1545 return dsPtr->string;
1549 *----------------------------------------------------------------------
1551 * Tcl_DStringAppendElement --
1553 * Append a list element to the current value of a dynamic string.
1556 * The return value is a pointer to the dynamic string's new value.
1559 * String is reformatted as a list element and added to the current
1560 * value of the string. Memory gets reallocated if needed to
1561 * accomodate the string's new size.
1563 *----------------------------------------------------------------------
1567 Tcl_DStringAppendElement(dsPtr, string)
1568 Tcl_DString *dsPtr; /* Structure describing dynamic string. */
1569 CONST char *string; /* String to append. Must be
1570 * null-terminated. */
1572 int newSize, flags, strSize;
1575 strSize = ((string == NULL) ? 0 : strlen(string));
1576 newSize = Tcl_ScanCountedElement(string, strSize, &flags)
1577 + dsPtr->length + 1;
1580 * Allocate a larger buffer for the string if the current one isn't
1581 * large enough. Allocate extra space in the new buffer so that there
1582 * will be room to grow before we have to allocate again.
1583 * SPECIAL NOTE: must use memcpy, not strcpy, to copy the string
1584 * to a larger buffer, since there may be embedded NULLs in the
1585 * string in some cases.
1588 if (newSize >= dsPtr->spaceAvl) {
1589 dsPtr->spaceAvl = newSize * 2;
1590 if (dsPtr->string == dsPtr->staticSpace) {
1593 newString = (char *) ckalloc((unsigned) dsPtr->spaceAvl);
1594 memcpy((VOID *) newString, (VOID *) dsPtr->string,
1595 (size_t) dsPtr->length);
1596 dsPtr->string = newString;
1598 dsPtr->string = (char *) ckrealloc((VOID *) dsPtr->string,
1599 (size_t) dsPtr->spaceAvl);
1604 * Convert the new string to a list element and copy it into the
1605 * buffer at the end, with a space, if needed.
1608 dst = dsPtr->string + dsPtr->length;
1609 if (TclNeedSpace(dsPtr->string, dst)) {
1614 dsPtr->length += Tcl_ConvertCountedElement(string, strSize, dst, flags);
1615 return dsPtr->string;
1619 *----------------------------------------------------------------------
1621 * Tcl_DStringSetLength --
1623 * Change the length of a dynamic string. This can cause the
1624 * string to either grow or shrink, depending on the value of
1631 * The length of dsPtr is changed to length and a null byte is
1632 * stored at that position in the string. If length is larger
1633 * than the space allocated for dsPtr, then a panic occurs.
1635 *----------------------------------------------------------------------
1639 Tcl_DStringSetLength(dsPtr, length)
1640 Tcl_DString *dsPtr; /* Structure describing dynamic string. */
1641 int length; /* New length for dynamic string. */
1648 if (length >= dsPtr->spaceAvl) {
1650 * There are two interesting cases here. In the first case, the user
1651 * may be trying to allocate a large buffer of a specific size. It
1652 * would be wasteful to overallocate that buffer, so we just allocate
1653 * enough for the requested size plus the trailing null byte. In the
1654 * second case, we are growing the buffer incrementally, so we need
1655 * behavior similar to Tcl_DStringAppend. The requested length will
1656 * usually be a small delta above the current spaceAvl, so we'll end up
1657 * doubling the old size. This won't grow the buffer quite as quickly,
1658 * but it should be close enough.
1661 newsize = dsPtr->spaceAvl * 2;
1662 if (length < newsize) {
1663 dsPtr->spaceAvl = newsize;
1665 dsPtr->spaceAvl = length + 1;
1667 if (dsPtr->string == dsPtr->staticSpace) {
1670 newString = (char *) ckalloc((unsigned) dsPtr->spaceAvl);
1671 memcpy((VOID *) newString, (VOID *) dsPtr->string,
1672 (size_t) dsPtr->length);
1673 dsPtr->string = newString;
1675 dsPtr->string = (char *) ckrealloc((VOID *) dsPtr->string,
1676 (size_t) dsPtr->spaceAvl);
1679 dsPtr->length = length;
1680 dsPtr->string[length] = 0;
1684 *----------------------------------------------------------------------
1686 * Tcl_DStringFree --
1688 * Frees up any memory allocated for the dynamic string and
1689 * reinitializes the string to an empty state.
1695 * The previous contents of the dynamic string are lost, and
1696 * the new value is an empty string.
1698 *---------------------------------------------------------------------- */
1701 Tcl_DStringFree(dsPtr)
1702 Tcl_DString *dsPtr; /* Structure describing dynamic string. */
1704 if (dsPtr->string != dsPtr->staticSpace) {
1705 ckfree(dsPtr->string);
1707 dsPtr->string = dsPtr->staticSpace;
1709 dsPtr->spaceAvl = TCL_DSTRING_STATIC_SIZE;
1710 dsPtr->staticSpace[0] = '\0';
1714 *----------------------------------------------------------------------
1716 * Tcl_DStringResult --
1718 * This procedure moves the value of a dynamic string into an
1719 * interpreter as its string result. Afterwards, the dynamic string
1720 * is reset to an empty string.
1726 * The string is "moved" to interp's result, and any existing
1727 * string result for interp is freed. dsPtr is reinitialized to
1730 *----------------------------------------------------------------------
1734 Tcl_DStringResult(interp, dsPtr)
1735 Tcl_Interp *interp; /* Interpreter whose result is to be reset. */
1736 Tcl_DString *dsPtr; /* Dynamic string that is to become the
1737 * result of interp. */
1739 Tcl_ResetResult(interp);
1741 if (dsPtr->string != dsPtr->staticSpace) {
1742 interp->result = dsPtr->string;
1743 interp->freeProc = TCL_DYNAMIC;
1744 } else if (dsPtr->length < TCL_RESULT_SIZE) {
1745 interp->result = ((Interp *) interp)->resultSpace;
1746 strcpy(interp->result, dsPtr->string);
1748 Tcl_SetResult(interp, dsPtr->string, TCL_VOLATILE);
1751 dsPtr->string = dsPtr->staticSpace;
1753 dsPtr->spaceAvl = TCL_DSTRING_STATIC_SIZE;
1754 dsPtr->staticSpace[0] = '\0';
1758 *----------------------------------------------------------------------
1760 * Tcl_DStringGetResult --
1762 * This procedure moves an interpreter's result into a dynamic string.
1768 * The interpreter's string result is cleared, and the previous
1769 * contents of dsPtr are freed.
1771 * If the string result is empty, the object result is moved to the
1772 * string result, then the object result is reset.
1774 *----------------------------------------------------------------------
1778 Tcl_DStringGetResult(interp, dsPtr)
1779 Tcl_Interp *interp; /* Interpreter whose result is to be reset. */
1780 Tcl_DString *dsPtr; /* Dynamic string that is to become the
1781 * result of interp. */
1783 Interp *iPtr = (Interp *) interp;
1785 if (dsPtr->string != dsPtr->staticSpace) {
1786 ckfree(dsPtr->string);
1790 * If the string result is empty, move the object result to the
1791 * string result, then reset the object result.
1794 if (*(iPtr->result) == 0) {
1795 Tcl_SetResult(interp, TclGetString(Tcl_GetObjResult(interp)),
1799 dsPtr->length = strlen(iPtr->result);
1800 if (iPtr->freeProc != NULL) {
1801 if (iPtr->freeProc == TCL_DYNAMIC) {
1802 dsPtr->string = iPtr->result;
1803 dsPtr->spaceAvl = dsPtr->length+1;
1805 dsPtr->string = (char *) ckalloc((unsigned) (dsPtr->length+1));
1806 strcpy(dsPtr->string, iPtr->result);
1807 (*iPtr->freeProc)(iPtr->result);
1809 dsPtr->spaceAvl = dsPtr->length+1;
1810 iPtr->freeProc = NULL;
1812 if (dsPtr->length < TCL_DSTRING_STATIC_SIZE) {
1813 dsPtr->string = dsPtr->staticSpace;
1814 dsPtr->spaceAvl = TCL_DSTRING_STATIC_SIZE;
1816 dsPtr->string = (char *) ckalloc((unsigned) (dsPtr->length + 1));
1817 dsPtr->spaceAvl = dsPtr->length + 1;
1819 strcpy(dsPtr->string, iPtr->result);
1822 iPtr->result = iPtr->resultSpace;
1823 iPtr->resultSpace[0] = 0;
1827 *----------------------------------------------------------------------
1829 * Tcl_DStringStartSublist --
1831 * This procedure adds the necessary information to a dynamic
1832 * string (e.g. " {" to start a sublist. Future element
1833 * appends will be in the sublist rather than the main list.
1839 * Characters get added to the dynamic string.
1841 *----------------------------------------------------------------------
1845 Tcl_DStringStartSublist(dsPtr)
1846 Tcl_DString *dsPtr; /* Dynamic string. */
1848 if (TclNeedSpace(dsPtr->string, dsPtr->string + dsPtr->length)) {
1849 Tcl_DStringAppend(dsPtr, " {", -1);
1851 Tcl_DStringAppend(dsPtr, "{", -1);
1856 *----------------------------------------------------------------------
1858 * Tcl_DStringEndSublist --
1860 * This procedure adds the necessary characters to a dynamic
1861 * string to end a sublist (e.g. "}"). Future element appends
1862 * will be in the enclosing (sub)list rather than the current
1871 *----------------------------------------------------------------------
1875 Tcl_DStringEndSublist(dsPtr)
1876 Tcl_DString *dsPtr; /* Dynamic string. */
1878 Tcl_DStringAppend(dsPtr, "}", -1);
1882 *----------------------------------------------------------------------
1884 * Tcl_PrintDouble --
1886 * Given a floating-point value, this procedure converts it to
1887 * an ASCII string using.
1890 * The ASCII equivalent of "value" is written at "dst". It is
1891 * written using the current precision, and it is guaranteed to
1892 * contain a decimal point or exponent, so that it looks like
1893 * a floating-point value and not an integer.
1898 *----------------------------------------------------------------------
1902 Tcl_PrintDouble(interp, value, dst)
1903 Tcl_Interp *interp; /* Interpreter whose tcl_precision
1904 * variable used to be used to control
1905 * printing. It's ignored now. */
1906 double value; /* Value to print as string. */
1907 char *dst; /* Where to store converted value;
1908 * must have at least TCL_DOUBLE_SPACE
1914 Tcl_MutexLock(&precisionMutex);
1915 sprintf(dst, precisionFormat, value);
1916 Tcl_MutexUnlock(&precisionMutex);
1919 * If the ASCII result looks like an integer, add ".0" so that it
1920 * doesn't look like an integer anymore. This prevents floating-point
1921 * values from being converted to integers unintentionally.
1922 * Check for ASCII specifically to speed up the function.
1925 for (p = dst; *p != 0; ) {
1926 if (UCHAR(*p) < 0x80) {
1929 p += Tcl_UtfToUniChar(p, &ch);
1932 if ((c == '.') || isalpha(UCHAR(c))) { /* INTL: ISO only. */
1942 *----------------------------------------------------------------------
1944 * TclPrecTraceProc --
1946 * This procedure is invoked whenever the variable "tcl_precision"
1950 * Returns NULL if all went well, or an error message if the
1951 * new value for the variable doesn't make sense.
1954 * If the new value doesn't make sense then this procedure
1955 * undoes the effect of the variable modification. Otherwise
1956 * it modifies the format string that's used by Tcl_PrintDouble.
1958 *----------------------------------------------------------------------
1963 TclPrecTraceProc(clientData, interp, name1, name2, flags)
1964 ClientData clientData; /* Not used. */
1965 Tcl_Interp *interp; /* Interpreter containing variable. */
1966 CONST char *name1; /* Name of variable. */
1967 CONST char *name2; /* Second part of variable name. */
1968 int flags; /* Information about what happened. */
1975 * If the variable is unset, then recreate the trace.
1978 if (flags & TCL_TRACE_UNSETS) {
1979 if ((flags & TCL_TRACE_DESTROYED) && !Tcl_InterpDeleted(interp)) {
1980 Tcl_TraceVar2(interp, name1, name2,
1981 TCL_GLOBAL_ONLY|TCL_TRACE_READS|TCL_TRACE_WRITES
1982 |TCL_TRACE_UNSETS, TclPrecTraceProc, clientData);
1984 return (char *) NULL;
1988 * When the variable is read, reset its value from our shared
1989 * value. This is needed in case the variable was modified in
1990 * some other interpreter so that this interpreter's value is
1994 Tcl_MutexLock(&precisionMutex);
1996 if (flags & TCL_TRACE_READS) {
1997 Tcl_SetVar2(interp, name1, name2, precisionString,
1998 flags & TCL_GLOBAL_ONLY);
1999 Tcl_MutexUnlock(&precisionMutex);
2000 return (char *) NULL;
2004 * The variable is being written. Check the new value and disallow
2005 * it if it isn't reasonable or if this is a safe interpreter (we
2006 * don't want safe interpreters messing up the precision of other
2010 if (Tcl_IsSafe(interp)) {
2011 Tcl_SetVar2(interp, name1, name2, precisionString,
2012 flags & TCL_GLOBAL_ONLY);
2013 Tcl_MutexUnlock(&precisionMutex);
2014 return "can't modify precision from a safe interpreter";
2016 value = Tcl_GetVar2(interp, name1, name2, flags & TCL_GLOBAL_ONLY);
2017 if (value == NULL) {
2020 prec = strtoul(value, &end, 10);
2021 if ((prec <= 0) || (prec > TCL_MAX_PREC) || (prec > 100) ||
2022 (end == value) || (*end != 0)) {
2023 Tcl_SetVar2(interp, name1, name2, precisionString,
2024 flags & TCL_GLOBAL_ONLY);
2025 Tcl_MutexUnlock(&precisionMutex);
2026 return "improper value for precision";
2028 TclFormatInt(precisionString, prec);
2029 sprintf(precisionFormat, "%%.%dg", prec);
2030 Tcl_MutexUnlock(&precisionMutex);
2031 return (char *) NULL;
2035 *----------------------------------------------------------------------
2039 * This procedure checks to see whether it is appropriate to
2040 * add a space before appending a new list element to an
2044 * The return value is 1 if a space is appropriate, 0 otherwise.
2049 *----------------------------------------------------------------------
2053 TclNeedSpace(start, end)
2054 CONST char *start; /* First character in string. */
2055 CONST char *end; /* End of string (place where space will
2056 * be added, if appropriate). */
2059 * A space is needed unless either
2060 * (a) we're at the start of the string, or
2067 * (b) we're at the start of a nested list-element, quoted with an
2068 * open curly brace; we can be nested arbitrarily deep, so long
2069 * as the first curly brace starts an element, so backtrack over
2070 * open curly braces that are trailing characters of the string; and
2073 end = Tcl_UtfPrev(end, start);
2074 while (*end == '{') {
2078 end = Tcl_UtfPrev(end, start);
2082 * (c) the trailing character of the string is already a list-element
2083 * separator (according to TclFindElement); that is, one of these
2087 * \u000B \v VERTICAL TAB
2088 * \u000C \f FORM FEED
2089 * \u000D \r CARRIAGE RETURN
2091 * with the condition that the penultimate character is not a
2097 * Performance tweak. All ASCII spaces are <= 0x20. So get
2098 * a quick answer for most characters before comparing against
2099 * all spaces in the switch below.
2101 * NOTE: Remove this if other Unicode spaces ever get accepted
2102 * as list-element separators.
2113 if ((end == start) || (end[-1] != '\\')) {
2121 *----------------------------------------------------------------------
2125 * This procedure formats an integer into a sequence of decimal digit
2126 * characters in a buffer. If the integer is negative, a minus sign is
2127 * inserted at the start of the buffer. A null character is inserted at
2128 * the end of the formatted characters. It is the caller's
2129 * responsibility to ensure that enough storage is available. This
2130 * procedure has the effect of sprintf(buffer, "%d", n) but is faster.
2133 * An integer representing the number of characters formatted, not
2134 * including the terminating \0.
2137 * The formatted characters are written into the storage pointer to
2138 * by the "buffer" argument.
2140 *----------------------------------------------------------------------
2144 TclFormatInt(buffer, n)
2145 char *buffer; /* Points to the storage into which the
2146 * formatted characters are written. */
2147 long n; /* The integer to format. */
2151 int numFormatted, j;
2152 char *digits = "0123456789";
2155 * Check first whether "n" is zero.
2165 * Check whether "n" is the maximum negative value. This is
2166 * -2^(m-1) for an m-bit word, and has no positive equivalent;
2167 * negating it produces the same value.
2171 sprintf(buffer, "%ld", n);
2172 return strlen(buffer);
2176 * Generate the characters of the result backwards in the buffer.
2179 intVal = (n < 0? -n : n);
2184 buffer[i] = digits[intVal % 10];
2186 } while (intVal > 0);
2194 * Now reverse the characters.
2197 for (j = 0; j < i; j++, i--) {
2198 char tmp = buffer[i];
2199 buffer[i] = buffer[j];
2202 return numFormatted;
2206 *----------------------------------------------------------------------
2208 * TclLooksLikeInt --
2210 * This procedure decides whether the leading characters of a
2211 * string look like an integer or something else (such as a
2212 * floating-point number or string).
2215 * The return value is 1 if the leading characters of p look
2216 * like a valid Tcl integer. If they look like a floating-point
2217 * number (e.g. "e01" or "2.4"), or if they don't look like a
2218 * number at all, then 0 is returned.
2223 *----------------------------------------------------------------------
2227 TclLooksLikeInt(bytes, length)
2228 register CONST char *bytes; /* Points to first byte of the string. */
2229 int length; /* Number of bytes in the string. If < 0
2230 * bytes up to the first null byte are
2231 * considered (if they may appear in an
2234 register CONST char *p;
2236 if ((bytes == NULL) && (length > 0)) {
2237 Tcl_Panic("TclLooksLikeInt: cannot scan %d bytes from NULL", length);
2241 length = (bytes? strlen(bytes) : 0);
2245 while (length && isspace(UCHAR(*p))) { /* INTL: ISO space. */
2251 if ((*p == '+') || (*p == '-')) {
2255 return (0 != TclParseInteger(p, length));
2259 *----------------------------------------------------------------------
2261 * TclGetIntForIndex --
2263 * This procedure returns an integer corresponding to the list index
2264 * held in a Tcl object. The Tcl object's value is expected to be
2265 * either an integer or a string of the form "end([+-]integer)?".
2268 * The return value is normally TCL_OK, which means that the index was
2269 * successfully stored into the location referenced by "indexPtr". If
2270 * the Tcl object referenced by "objPtr" has the value "end", the
2271 * value stored is "endValue". If "objPtr"s values is not of the form
2272 * "end([+-]integer)?" and
2273 * can not be converted to an integer, TCL_ERROR is returned and, if
2274 * "interp" is non-NULL, an error message is left in the interpreter's
2278 * The object referenced by "objPtr" might be converted to an
2279 * integer, wide integer, or end-based-index object.
2281 *----------------------------------------------------------------------
2285 TclGetIntForIndex(interp, objPtr, endValue, indexPtr)
2286 Tcl_Interp *interp; /* Interpreter to use for error reporting.
2287 * If NULL, then no error message is left
2289 Tcl_Obj *objPtr; /* Points to an object containing either
2290 * "end" or an integer. */
2291 int endValue; /* The value to be stored at "indexPtr" if
2292 * "objPtr" holds "end". */
2293 int *indexPtr; /* Location filled in with an integer
2294 * representing an index. */
2296 if (Tcl_GetIntFromObj(NULL, objPtr, indexPtr) == TCL_OK) {
2300 if (SetEndOffsetFromAny(NULL, objPtr) == TCL_OK) {
2302 * If the object is already an offset from the end of the
2303 * list, or can be converted to one, use it.
2306 *indexPtr = endValue + objPtr->internalRep.longValue;
2310 * Report a parse error.
2313 if (interp != NULL) {
2314 char *bytes = Tcl_GetString(objPtr);
2316 * The result might not be empty; this resets it which
2317 * should be both a cheap operation, and of little problem
2318 * because this is an error-generation path anyway.
2320 Tcl_ResetResult(interp);
2321 Tcl_AppendStringsToObj(Tcl_GetObjResult(interp),
2322 "bad index \"", bytes,
2323 "\": must be integer or end?-integer?",
2325 if (!strncmp(bytes, "end-", 3)) {
2328 TclCheckBadOctal(interp, bytes);
2338 *----------------------------------------------------------------------
2340 * UpdateStringOfEndOffset --
2342 * Update the string rep of a Tcl object holding an "end-offset"
2349 * Stores a valid string in the object's string rep.
2351 * This procedure does NOT free any earlier string rep. If it is
2352 * called on an object that already has a valid string rep, it will
2355 *----------------------------------------------------------------------
2359 UpdateStringOfEndOffset(objPtr)
2360 register Tcl_Obj* objPtr;
2362 char buffer[TCL_INTEGER_SPACE + sizeof("end") + 1];
2365 strcpy(buffer, "end");
2366 len = sizeof("end") - 1;
2367 if (objPtr->internalRep.longValue != 0) {
2368 buffer[len++] = '-';
2369 len += TclFormatInt(buffer+len, -(objPtr->internalRep.longValue));
2371 objPtr->bytes = ckalloc((unsigned) (len+1));
2372 strcpy(objPtr->bytes, buffer);
2373 objPtr->length = len;
2377 *----------------------------------------------------------------------
2379 * SetEndOffsetFromAny --
2381 * Look for a string of the form "end-offset" and convert it
2382 * to an internal representation holding the offset.
2385 * Returns TCL_OK if ok, TCL_ERROR if the string was badly formed.
2388 * If interp is not NULL, stores an error message in the
2389 * interpreter result.
2391 *----------------------------------------------------------------------
2395 SetEndOffsetFromAny(interp, objPtr)
2396 Tcl_Interp* interp; /* Tcl interpreter or NULL */
2397 Tcl_Obj* objPtr; /* Pointer to the object to parse */
2399 int offset; /* Offset in the "end-offset" expression */
2400 Tcl_ObjType* oldTypePtr = objPtr->typePtr;
2401 /* Old internal rep type of the object */
2402 register char* bytes; /* String rep of the object */
2403 int length; /* Length of the object's string rep */
2405 /* If it's already the right type, we're fine. */
2407 if (objPtr->typePtr == &tclEndOffsetType) {
2411 /* Check for a string rep of the right form. */
2413 bytes = Tcl_GetStringFromObj(objPtr, &length);
2414 if ((*bytes != 'e') || (strncmp(bytes, "end",
2415 (size_t)((length > 3) ? 3 : length)) != 0)) {
2416 if (interp != NULL) {
2417 Tcl_ResetResult(interp);
2418 Tcl_AppendStringsToObj(Tcl_GetObjResult(interp),
2419 "bad index \"", bytes,
2420 "\": must be end?-integer?",
2426 /* Convert the string rep */
2430 } else if ((length > 4) && (bytes[3] == '-')) {
2432 * This is our limited string expression evaluator. Pass everything
2433 * after "end-" to Tcl_GetInt, then reverse for offset.
2435 if (Tcl_GetInt(interp, bytes+4, &offset) != TCL_OK) {
2441 * Conversion failed. Report the error.
2443 if (interp != NULL) {
2444 Tcl_ResetResult(interp);
2445 Tcl_AppendStringsToObj(Tcl_GetObjResult(interp),
2446 "bad index \"", bytes,
2447 "\": must be integer or end?-integer?",
2454 * The conversion succeeded. Free the old internal rep and set
2458 if ((oldTypePtr != NULL) && (oldTypePtr->freeIntRepProc != NULL)) {
2459 oldTypePtr->freeIntRepProc(objPtr);
2462 objPtr->internalRep.longValue = offset;
2463 objPtr->typePtr = &tclEndOffsetType;
2469 *----------------------------------------------------------------------
2471 * TclCheckBadOctal --
2473 * This procedure checks for a bad octal value and appends a
2474 * meaningful error to the interp's result.
2477 * 1 if the argument was a bad octal, else 0.
2480 * The interpreter's result is modified.
2482 *----------------------------------------------------------------------
2486 TclCheckBadOctal(interp, value)
2487 Tcl_Interp *interp; /* Interpreter to use for error reporting.
2488 * If NULL, then no error message is left
2490 CONST char *value; /* String to check. */
2492 register CONST char *p = value;
2495 * A frequent mistake is invalid octal values due to an unwanted
2496 * leading zero. Try to generate a meaningful error message.
2499 while (isspace(UCHAR(*p))) { /* INTL: ISO space. */
2502 if (*p == '+' || *p == '-') {
2506 while (isdigit(UCHAR(*p))) { /* INTL: digit. */
2509 while (isspace(UCHAR(*p))) { /* INTL: ISO space. */
2513 /* Reached end of string */
2514 if (interp != NULL) {
2516 * Don't reset the result here because we want this result
2517 * to be added to an existing error message as extra info.
2519 Tcl_AppendResult(interp, " (looks like invalid octal number)",
2529 *----------------------------------------------------------------------
2531 * Tcl_GetNameOfExecutable --
2533 * This procedure simply returns a pointer to the internal full
2534 * path name of the executable file as computed by
2535 * Tcl_FindExecutable. This procedure call is the C API
2536 * equivalent to the "info nameofexecutable" command.
2539 * A pointer to the internal string or NULL if the internal full
2540 * path name has not been computed or unknown.
2543 * The object referenced by "objPtr" might be converted to an
2546 *----------------------------------------------------------------------
2549 EXPORT_C CONST char *
2550 Tcl_GetNameOfExecutable()
2552 return tclExecutableName;
2556 *----------------------------------------------------------------------
2560 * Deprecated synonym for Tcl_GetTime.
2566 * Stores current time in the buffer designated by "timePtr"
2568 * This procedure is provided for the benefit of extensions written
2569 * before Tcl_GetTime was exported from the library.
2571 *----------------------------------------------------------------------
2575 TclpGetTime(timePtr)
2578 Tcl_GetTime(timePtr);