2 * CDE - Common Desktop Environment
4 * Copyright (c) 1993-2012, The Open Group. All rights reserved.
6 * These libraries and programs are free software; you can
7 * redistribute them and/or modify them under the terms of the GNU
8 * Lesser General Public License as published by the Free Software
9 * Foundation; either version 2 of the License, or (at your option)
12 * These libraries and programs are distributed in the hope that
13 * they will be useful, but WITHOUT ANY WARRANTY; without even the
14 * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
15 * PURPOSE. See the GNU Lesser General Public License for more
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with these librararies and programs; if not, write
20 * to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
21 * Floor, Boston, MA 02110-1301 USA
23 /* $XConsortium: tclUtil.c /main/5 1996/08/08 14:47:12 cde-hp $ */
27 * This file contains utility procedures that are used by many Tcl
30 * Copyright (c) 1987-1993 The Regents of the University of California.
31 * Copyright (c) 1994-1995 Sun Microsystems, Inc.
33 * See the file "license.terms" for information on usage and redistribution
34 * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
36 * SCCS: @(#) tclUtil.c 1.112 96/02/15 11:42:52
43 * The following values are used in the flags returned by Tcl_ScanElement
44 * and used by Tcl_ConvertElement. The value TCL_DONT_USE_BRACES is also
45 * defined in tcl.h; make sure its value doesn't overlap with any of the
48 * TCL_DONT_USE_BRACES - 1 means the string mustn't be enclosed in
49 * braces (e.g. it contains unmatched braces,
50 * or ends in a backslash character, or user
51 * just doesn't want braces); handle all
52 * special characters by adding backslashes.
53 * USE_BRACES - 1 means the string contains a special
54 * character that can be handled simply by
55 * enclosing the entire argument in braces.
56 * BRACES_UNMATCHED - 1 means that braces aren't properly matched
61 #define BRACES_UNMATCHED 4
64 * Function prototypes for local procedures in this file:
67 static void SetupAppendBuffer _ANSI_ARGS_((Interp *iPtr,
71 *----------------------------------------------------------------------
75 * Given a pointer into a Tcl list, locate the first (or next)
76 * element in the list.
79 * The return value is normally TCL_OK, which means that the
80 * element was successfully located. If TCL_ERROR is returned
81 * it means that list didn't have proper list structure;
82 * interp->result contains a more detailed error message.
84 * If TCL_OK is returned, then *elementPtr will be set to point
85 * to the first element of list, and *nextPtr will be set to point
86 * to the character just after any white space following the last
87 * character that's part of the element. If this is the last argument
88 * in the list, then *nextPtr will point to the NULL character at the
89 * end of list. If sizePtr is non-NULL, *sizePtr is filled in with
90 * the number of characters in the element. If the element is in
91 * braces, then *elementPtr will point to the character after the
92 * opening brace and *sizePtr will not include either of the braces.
93 * If there isn't an element in the list, *sizePtr will be zero, and
94 * both *elementPtr and *termPtr will refer to the null character at
95 * the end of list. Note: this procedure does NOT collapse backslash
101 *----------------------------------------------------------------------
105 TclFindElement(interp, list, elementPtr, nextPtr, sizePtr, bracePtr)
106 Tcl_Interp *interp; /* Interpreter to use for error reporting.
107 * If NULL, then no error message is left
109 register char *list; /* String containing Tcl list with zero
110 * or more elements (possibly in braces). */
111 char **elementPtr; /* Fill in with location of first significant
112 * character in first element of list. */
113 char **nextPtr; /* Fill in with location of character just
114 * after all white space following end of
115 * argument (i.e. next argument or end of
117 int *sizePtr; /* If non-zero, fill in with size of
119 int *bracePtr; /* If non-zero fill in with non-zero/zero
120 * to indicate that arg was/wasn't
129 * Skim off leading white space and check for an opening brace or
130 * quote. Note: use of "isascii" below and elsewhere in this
131 * procedure is a temporary hack (7/27/90) because Mx uses characters
132 * with the high-order bit set for some things. This should probably
133 * be changed back eventually, or all of Tcl should call isascii.
136 while (isspace(UCHAR(*list))) {
142 } else if (*list == '"') {
147 *bracePtr = openBraces;
152 * Find the end of the element (either a space or a close brace or
153 * the end of the string).
160 * Open brace: don't treat specially unless the element is
161 * in braces. In this case, keep a nesting count.
165 if (openBraces != 0) {
171 * Close brace: if element is in braces, keep nesting
172 * count and quit when the last close brace is seen.
176 if (openBraces == 1) {
181 if (isspace(UCHAR(*p)) || (*p == 0)) {
184 for (p2 = p; (*p2 != 0) && (!isspace(UCHAR(*p2)))
185 && (p2 < p+20); p2++) {
188 if (interp != NULL) {
189 Tcl_ResetResult(interp);
190 sprintf(interp->result,
191 "list element in braces followed by \"%.*s\" instead of space",
195 } else if (openBraces != 0) {
201 * Backslash: skip over everything up to the end of the
202 * backslash sequence.
208 (void) Tcl_Backslash(p, &size);
214 * Space: ignore if element is in braces or quotes; otherwise
224 if ((openBraces == 0) && !inQuotes) {
231 * Double-quote: if element is in quotes then terminate it.
240 if (isspace(UCHAR(*p)) || (*p == 0)) {
243 for (p2 = p; (*p2 != 0) && (!isspace(UCHAR(*p2)))
244 && (p2 < p+20); p2++) {
247 if (interp != NULL) {
248 Tcl_ResetResult(interp);
249 sprintf(interp->result,
250 "list element in quotes followed by \"%.*s\" %s", (int) (p2-p), p,
258 * End of list: terminate element.
262 if (openBraces != 0) {
263 if (interp != NULL) {
264 Tcl_SetResult(interp, "unmatched open brace in list",
268 } else if (inQuotes) {
269 if (interp != NULL) {
270 Tcl_SetResult(interp, "unmatched open quote in list",
283 while (isspace(UCHAR(*p))) {
295 *----------------------------------------------------------------------
297 * TclCopyAndCollapse --
299 * Copy a string and eliminate any backslashes that aren't in braces.
302 * There is no return value. Count chars. get copied from src
303 * to dst. Along the way, if backslash sequences are found outside
304 * braces, the backslashes are eliminated in the copy.
305 * After scanning count chars. from source, a null character is
306 * placed at the end of dst.
311 *----------------------------------------------------------------------
315 TclCopyAndCollapse(count, src, dst)
316 int count; /* Total number of characters to copy
318 register char *src; /* Copy from here... */
319 register char *dst; /* ... to here. */
324 for (c = *src; count > 0; src++, c = *src, count--) {
326 *dst = Tcl_Backslash(src, &numRead);
339 *----------------------------------------------------------------------
343 * Splits a list up into its constituent fields.
346 * The return value is normally TCL_OK, which means that
347 * the list was successfully split up. If TCL_ERROR is
348 * returned, it means that "list" didn't have proper list
349 * structure; interp->result will contain a more detailed
352 * *argvPtr will be filled in with the address of an array
353 * whose elements point to the elements of list, in order.
354 * *argcPtr will get filled in with the number of valid elements
355 * in the array. A single block of memory is dynamically allocated
356 * to hold both the argv array and a copy of the list (with
357 * backslashes and braces removed in the standard way).
358 * The caller must eventually free this memory by calling free()
359 * on *argvPtr. Note: *argvPtr and *argcPtr are only modified
360 * if the procedure returns normally.
363 * Memory is allocated.
365 *----------------------------------------------------------------------
369 Tcl_SplitList(interp, list, argcPtr, argvPtr)
370 Tcl_Interp *interp; /* Interpreter to use for error reporting.
371 * If NULL, then no error message is left. */
372 char *list; /* Pointer to string with list structure. */
373 int *argcPtr; /* Pointer to location to fill in with
374 * the number of elements in the list. */
375 char ***argvPtr; /* Pointer to place to store pointer to array
376 * of pointers to list elements. */
380 int size, i, result, elSize, brace;
384 * Figure out how much space to allocate. There must be enough
385 * space for both the array of pointers and also for a copy of
386 * the list. To estimate the number of pointers needed, count
387 * the number of space characters in the list.
390 for (size = 1, p = list; *p != 0; p++) {
391 if (isspace(UCHAR(*p))) {
395 size++; /* Leave space for final NULL pointer. */
396 argv = (char **) ckalloc((unsigned)
397 ((size * sizeof(char *)) + (p - list) + 1));
398 for (i = 0, p = ((char *) argv) + size*sizeof(char *);
400 result = TclFindElement(interp, list, &element, &list, &elSize, &brace);
401 if (result != TCL_OK) {
402 ckfree((char *) argv);
409 ckfree((char *) argv);
410 if (interp != NULL) {
411 Tcl_SetResult(interp, "internal error in Tcl_SplitList",
418 strncpy(p, element, (size_t) elSize);
423 TclCopyAndCollapse(elSize, element, p);
435 *----------------------------------------------------------------------
439 * This procedure is a companion procedure to Tcl_ConvertElement.
440 * It scans a string to see what needs to be done to it (e.g.
441 * add backslashes or enclosing braces) to make the string into
442 * a valid Tcl list element.
445 * The return value is an overestimate of the number of characters
446 * that will be needed by Tcl_ConvertElement to produce a valid
447 * list element from string. The word at *flagPtr is filled in
448 * with a value needed by Tcl_ConvertElement when doing the actual
454 *----------------------------------------------------------------------
458 Tcl_ScanElement(string, flagPtr)
459 char *string; /* String to convert to Tcl list element. */
460 int *flagPtr; /* Where to store information to guide
461 * Tcl_ConvertElement. */
463 int flags, nestingLevel;
467 * This procedure and Tcl_ConvertElement together do two things:
469 * 1. They produce a proper list, one that will yield back the
470 * argument strings when evaluated or when disassembled with
471 * Tcl_SplitList. This is the most important thing.
473 * 2. They try to produce legible output, which means minimizing the
474 * use of backslashes (using braces instead). However, there are
475 * some situations where backslashes must be used (e.g. an element
476 * like "{abc": the leading brace will have to be backslashed. For
477 * each element, one of three things must be done:
479 * (a) Use the element as-is (it doesn't contain anything special
480 * characters). This is the most desirable option.
482 * (b) Enclose the element in braces, but leave the contents alone.
483 * This happens if the element contains embedded space, or if it
484 * contains characters with special interpretation ($, [, ;, or \),
485 * or if it starts with a brace or double-quote, or if there are
486 * no characters in the element.
488 * (c) Don't enclose the element in braces, but add backslashes to
489 * prevent special interpretation of special characters. This is a
490 * last resort used when the argument would normally fall under case
491 * (b) but contains unmatched braces. It also occurs if the last
492 * character of the argument is a backslash or if the element contains
493 * a backslash followed by newline.
495 * The procedure figures out how many bytes will be needed to store
496 * the result (actually, it overestimates). It also collects information
497 * about the element in the form of a flags word.
502 if (string == NULL) {
506 if ((*p == '{') || (*p == '"') || (*p == 0)) {
509 for ( ; *p != 0; p++) {
516 if (nestingLevel < 0) {
517 flags |= TCL_DONT_USE_BRACES|BRACES_UNMATCHED;
532 if ((p[1] == 0) || (p[1] == '\n')) {
533 flags = TCL_DONT_USE_BRACES;
537 (void) Tcl_Backslash(p, &size);
544 if (nestingLevel != 0) {
545 flags = TCL_DONT_USE_BRACES | BRACES_UNMATCHED;
550 * Allow enough space to backslash every character plus leave
551 * two spaces for braces.
554 return 2*(p-string) + 2;
558 *----------------------------------------------------------------------
560 * Tcl_ConvertElement --
562 * This is a companion procedure to Tcl_ScanElement. Given the
563 * information produced by Tcl_ScanElement, this procedure converts
564 * a string to a list element equal to that string.
567 * Information is copied to *dst in the form of a list element
568 * identical to src (i.e. if Tcl_SplitList is applied to dst it
569 * will produce a string identical to src). The return value is
570 * a count of the number of characters copied (not including the
571 * terminating NULL character).
576 *----------------------------------------------------------------------
580 Tcl_ConvertElement(src, dst, flags)
581 register char *src; /* Source information for list element. */
582 char *dst; /* Place to put list-ified element. */
583 int flags; /* Flags produced by Tcl_ScanElement. */
585 register char *p = dst;
588 * See the comment block at the beginning of the Tcl_ScanElement
589 * code for details of how this works.
592 if ((src == NULL) || (*src == 0)) {
598 if ((flags & USE_BRACES) && !(flags & TCL_DONT_USE_BRACES)) {
601 for ( ; *src != 0; src++, p++) {
609 * Can't have a leading brace unless the whole element is
610 * enclosed in braces. Add a backslash before the brace.
611 * Furthermore, this may destroy the balance between open
612 * and close braces, so set BRACES_UNMATCHED.
619 flags |= BRACES_UNMATCHED;
621 for (; *src != 0 ; src++) {
636 * It may not seem necessary to backslash braces, but
637 * it is. The reason for this is that the resulting
638 * list element may actually be an element of a sub-list
639 * enclosed in braces (e.g. if Tcl_DStringStartSublist
640 * has been invoked), so there may be a brace mismatch
641 * if the braces aren't backslashed.
644 if (flags & BRACES_UNMATCHED) {
689 *----------------------------------------------------------------------
693 * Given a collection of strings, merge them together into a
694 * single string that has proper Tcl list structured (i.e.
695 * Tcl_SplitList may be used to retrieve strings equal to the
696 * original elements, and Tcl_Eval will parse the string back
697 * into its original elements).
700 * The return value is the address of a dynamically-allocated
701 * string containing the merged list.
706 *----------------------------------------------------------------------
710 Tcl_Merge(argc, argv)
711 int argc; /* How many strings to merge. */
712 char **argv; /* Array of string values. */
714 # define LOCAL_SIZE 20
715 int localFlags[LOCAL_SIZE], *flagPtr;
722 * Pass 1: estimate space, gather flags.
725 if (argc <= LOCAL_SIZE) {
726 flagPtr = localFlags;
728 flagPtr = (int *) ckalloc((unsigned) argc*sizeof(int));
731 for (i = 0; i < argc; i++) {
732 numChars += Tcl_ScanElement(argv[i], &flagPtr[i]) + 1;
736 * Pass two: copy into the result area.
739 result = (char *) ckalloc((unsigned) numChars);
741 for (i = 0; i < argc; i++) {
742 numChars = Tcl_ConvertElement(argv[i], dst, flagPtr[i]);
753 if (flagPtr != localFlags) {
754 ckfree((char *) flagPtr);
760 *----------------------------------------------------------------------
764 * Concatenate a set of strings into a single large string.
767 * The return value is dynamically-allocated string containing
768 * a concatenation of all the strings in argv, with spaces between
769 * the original argv elements.
772 * Memory is allocated for the result; the caller is responsible
773 * for freeing the memory.
775 *----------------------------------------------------------------------
779 Tcl_Concat(argc, argv)
780 int argc; /* Number of strings to concatenate. */
781 char **argv; /* Array of strings to concatenate. */
787 for (totalSize = 1, i = 0; i < argc; i++) {
788 totalSize += strlen(argv[i]) + 1;
790 result = (char *) ckalloc((unsigned) totalSize);
795 for (p = result, i = 0; i < argc; i++) {
800 * Clip white space off the front and back of the string
801 * to generate a neater result, and ignore any empty
806 while (isspace(UCHAR(*element))) {
809 for (length = strlen(element);
810 (length > 0) && (isspace(UCHAR(element[length-1])));
812 /* Null loop body. */
817 (void) strncpy(p, element, (size_t) length);
831 *----------------------------------------------------------------------
835 * See if a particular string matches a particular pattern.
838 * The return value is 1 if string matches pattern, and
839 * 0 otherwise. The matching operation permits the following
840 * special characters in the pattern: *?\[] (see the manual
841 * entry for details on what these mean).
846 *----------------------------------------------------------------------
850 Tcl_StringMatch(string, pattern)
851 register char *string; /* String. */
852 register char *pattern; /* Pattern, which may contain
853 * special characters. */
858 /* See if we're at the end of both the pattern and the string.
859 * If so, we succeeded. If we're at the end of the pattern
860 * but not at the end of the string, we failed.
870 if ((*string == 0) && (*pattern != '*')) {
874 /* Check for a "*" as the next pattern character. It matches
875 * any substring. We handle this by calling ourselves
876 * recursively for each postfix of string, until either we
877 * match or we reach the end of the string.
880 if (*pattern == '*') {
886 if (Tcl_StringMatch(string, pattern)) {
896 /* Check for a "?" as the next pattern character. It matches
897 * any single character.
900 if (*pattern == '?') {
904 /* Check for a "[" as the next pattern character. It is followed
905 * by a list of characters that are acceptable, or by a range
906 * (two characters separated by "-").
909 if (*pattern == '[') {
912 if ((*pattern == ']') || (*pattern == 0)) {
915 if (*pattern == *string) {
918 if (pattern[1] == '-') {
923 if ((*pattern <= *string) && (c2 >= *string)) {
926 if ((*pattern >= *string) && (c2 <= *string)) {
933 while (*pattern != ']') {
943 /* If the next pattern character is '/', just strip off the '/'
944 * so we do exact matching on the character that follows.
947 if (*pattern == '\\') {
954 /* There's no special character. Just make sure that the next
955 * characters of each string match.
958 if (*pattern != *string) {
962 thisCharOK: pattern += 1;
968 *----------------------------------------------------------------------
972 * Arrange for "string" to be the Tcl return value.
978 * interp->result is left pointing either to "string" (if "copy" is 0)
979 * or to a copy of string.
981 *----------------------------------------------------------------------
985 Tcl_SetResult(interp, string, freeProc)
986 Tcl_Interp *interp; /* Interpreter with which to associate the
988 char *string; /* Value to be returned. If NULL,
989 * the result is set to an empty string. */
990 Tcl_FreeProc *freeProc; /* Gives information about the string:
991 * TCL_STATIC, TCL_VOLATILE, or the address
992 * of a Tcl_FreeProc such as free. */
994 register Interp *iPtr = (Interp *) interp;
996 Tcl_FreeProc *oldFreeProc = iPtr->freeProc;
997 char *oldResult = iPtr->result;
999 if (string == NULL) {
1000 iPtr->resultSpace[0] = 0;
1001 iPtr->result = iPtr->resultSpace;
1003 } else if (freeProc == TCL_DYNAMIC) {
1004 iPtr->result = string;
1005 iPtr->freeProc = TCL_DYNAMIC;
1006 } else if (freeProc == TCL_VOLATILE) {
1007 length = strlen(string);
1008 if (length > TCL_RESULT_SIZE) {
1009 iPtr->result = (char *) ckalloc((unsigned) length+1);
1010 iPtr->freeProc = TCL_DYNAMIC;
1012 iPtr->result = iPtr->resultSpace;
1015 strcpy(iPtr->result, string);
1017 iPtr->result = string;
1018 iPtr->freeProc = freeProc;
1022 * If the old result was dynamically-allocated, free it up. Do it
1023 * here, rather than at the beginning, in case the new result value
1024 * was part of the old result value.
1027 if (oldFreeProc != 0) {
1028 if ((oldFreeProc == TCL_DYNAMIC)
1029 || (oldFreeProc == (Tcl_FreeProc *) free)) {
1032 (*oldFreeProc)(oldResult);
1038 *----------------------------------------------------------------------
1040 * Tcl_AppendResult --
1042 * Append a variable number of strings onto the result already
1043 * present for an interpreter.
1049 * The result in the interpreter given by the first argument
1050 * is extended by the strings given by the second and following
1051 * arguments (up to a terminating NULL argument).
1053 *----------------------------------------------------------------------
1058 Tcl_AppendResult TCL_VARARGS_DEF(Tcl_Interp *,arg1)
1061 register Interp *iPtr;
1066 * First, scan through all the arguments to see how much space is
1070 iPtr = (Interp *)arg1;
1071 va_start(argList, arg1);
1074 string = va_arg(argList, char *);
1075 if (string == NULL) {
1078 newSpace += strlen(string);
1083 * If the append buffer isn't already setup and large enough
1084 * to hold the new data, set it up.
1087 if ((iPtr->result != iPtr->appendResult)
1088 || (iPtr->appendResult[iPtr->appendUsed] != 0)
1089 || ((newSpace + iPtr->appendUsed) >= iPtr->appendAvl)) {
1090 SetupAppendBuffer(iPtr, newSpace);
1094 * Final step: go through all the argument strings again, copying
1095 * them into the buffer.
1098 va_start(argList, arg1);
1100 string = va_arg(argList, char *);
1101 if (string == NULL) {
1104 strcpy(iPtr->appendResult + iPtr->appendUsed, string);
1105 iPtr->appendUsed += strlen(string);
1111 *----------------------------------------------------------------------
1113 * Tcl_AppendElement --
1115 * Convert a string to a valid Tcl list element and append it
1116 * to the current result (which is ostensibly a list).
1122 * The result in the interpreter given by the first argument
1123 * is extended with a list element converted from string. A
1124 * separator space is added before the converted list element
1125 * unless the current result is empty, contains the single
1126 * character "{", or ends in " {".
1128 *----------------------------------------------------------------------
1132 Tcl_AppendElement(interp, string)
1133 Tcl_Interp *interp; /* Interpreter whose result is to be
1135 char *string; /* String to convert to list element and
1138 register Interp *iPtr = (Interp *) interp;
1143 * See how much space is needed, and grow the append buffer if
1144 * needed to accommodate the list element.
1147 size = Tcl_ScanElement(string, &flags) + 1;
1148 if ((iPtr->result != iPtr->appendResult)
1149 || (iPtr->appendResult[iPtr->appendUsed] != 0)
1150 || ((size + iPtr->appendUsed) >= iPtr->appendAvl)) {
1151 SetupAppendBuffer(iPtr, size+iPtr->appendUsed);
1155 * Convert the string into a list element and copy it to the
1156 * buffer that's forming, with a space separator if needed.
1159 dst = iPtr->appendResult + iPtr->appendUsed;
1160 if (TclNeedSpace(iPtr->appendResult, dst)) {
1165 iPtr->appendUsed += Tcl_ConvertElement(string, dst, flags);
1169 *----------------------------------------------------------------------
1171 * SetupAppendBuffer --
1173 * This procedure makes sure that there is an append buffer
1174 * properly initialized for interp, and that it has at least
1175 * enough room to accommodate newSpace new bytes of information.
1183 *----------------------------------------------------------------------
1187 SetupAppendBuffer(iPtr, newSpace)
1188 register Interp *iPtr; /* Interpreter whose result is being set up. */
1189 int newSpace; /* Make sure that at least this many bytes
1190 * of new information may be added. */
1195 * Make the append buffer larger, if that's necessary, then
1196 * copy the current result into the append buffer and make the
1197 * append buffer the official Tcl result.
1200 if (iPtr->result != iPtr->appendResult) {
1202 * If an oversized buffer was used recently, then free it up
1203 * so we go back to a smaller buffer. This avoids tying up
1204 * memory forever after a large operation.
1207 if (iPtr->appendAvl > 500) {
1208 ckfree(iPtr->appendResult);
1209 iPtr->appendResult = NULL;
1210 iPtr->appendAvl = 0;
1212 iPtr->appendUsed = strlen(iPtr->result);
1213 } else if (iPtr->result[iPtr->appendUsed] != 0) {
1215 * Most likely someone has modified a result created by
1216 * Tcl_AppendResult et al. so that it has a different size.
1217 * Just recompute the size.
1220 iPtr->appendUsed = strlen(iPtr->result);
1222 totalSpace = newSpace + iPtr->appendUsed;
1223 if (totalSpace >= iPtr->appendAvl) {
1226 if (totalSpace < 100) {
1231 new = (char *) ckalloc((unsigned) totalSpace);
1232 strcpy(new, iPtr->result);
1233 if (iPtr->appendResult != NULL) {
1234 ckfree(iPtr->appendResult);
1236 iPtr->appendResult = new;
1237 iPtr->appendAvl = totalSpace;
1238 } else if (iPtr->result != iPtr->appendResult) {
1239 strcpy(iPtr->appendResult, iPtr->result);
1241 Tcl_FreeResult(iPtr);
1242 iPtr->result = iPtr->appendResult;
1246 *----------------------------------------------------------------------
1248 * Tcl_ResetResult --
1250 * This procedure restores the result area for an interpreter
1251 * to its default initialized state, freeing up any memory that
1252 * may have been allocated for the result and clearing any
1253 * error information for the interpreter.
1261 *----------------------------------------------------------------------
1265 Tcl_ResetResult(interp)
1266 Tcl_Interp *interp; /* Interpreter for which to clear result. */
1268 register Interp *iPtr = (Interp *) interp;
1270 Tcl_FreeResult(iPtr);
1271 iPtr->result = iPtr->resultSpace;
1272 iPtr->resultSpace[0] = 0;
1274 ~(ERR_ALREADY_LOGGED | ERR_IN_PROGRESS | ERROR_CODE_SET);
1278 *----------------------------------------------------------------------
1280 * Tcl_SetErrorCode --
1282 * This procedure is called to record machine-readable information
1283 * about an error that is about to be returned.
1289 * The errorCode global variable is modified to hold all of the
1290 * arguments to this procedure, in a list form with each argument
1291 * becoming one element of the list. A flag is set internally
1292 * to remember that errorCode has been set, so the variable doesn't
1293 * get set automatically when the error is returned.
1295 *----------------------------------------------------------------------
1299 Tcl_SetErrorCode TCL_VARARGS_DEF(Tcl_Interp *,arg1)
1307 * Scan through the arguments one at a time, appending them to
1308 * $errorCode as list elements.
1311 iPtr = (Interp *)arg1;
1312 va_start(argList, arg1);
1313 flags = TCL_GLOBAL_ONLY | TCL_LIST_ELEMENT;
1315 string = va_arg(argList, char *);
1316 if (string == NULL) {
1319 (void) Tcl_SetVar2((Tcl_Interp *) iPtr, "errorCode",
1320 (char *) NULL, string, flags);
1321 flags |= TCL_APPEND_VALUE;
1324 iPtr->flags |= ERROR_CODE_SET;
1328 *----------------------------------------------------------------------
1330 * TclGetListIndex --
1332 * Parse a list index, which may be either an integer or the
1336 * The return value is either TCL_OK or TCL_ERROR. If it is
1337 * TCL_OK, then the index corresponding to string is left in
1338 * *indexPtr. If the return value is TCL_ERROR, then string
1339 * was bogus; an error message is returned in interp->result.
1340 * If a negative index is specified, it is rounded up to 0.
1341 * The index value may be larger than the size of the list
1342 * (this happens when "end" is specified).
1347 *----------------------------------------------------------------------
1351 TclGetListIndex(interp, string, indexPtr)
1352 Tcl_Interp *interp; /* Interpreter for error reporting. */
1353 char *string; /* String containing list index. */
1354 int *indexPtr; /* Where to store index. */
1356 if (isdigit(UCHAR(*string)) || (*string == '-')) {
1357 if (Tcl_GetInt(interp, string, indexPtr) != TCL_OK) {
1360 if (*indexPtr < 0) {
1363 } else if (strncmp(string, "end", strlen(string)) == 0) {
1364 *indexPtr = INT_MAX;
1366 Tcl_AppendResult(interp, "bad index \"", string,
1367 "\": must be integer or \"end\"", (char *) NULL);
1374 *----------------------------------------------------------------------
1376 * Tcl_RegExpCompile --
1378 * Compile a regular expression into a form suitable for fast
1379 * matching. This procedure retains a small cache of pre-compiled
1380 * regular expressions in the interpreter, in order to avoid
1381 * compilation costs as much as possible.
1384 * The return value is a pointer to the compiled form of string,
1385 * suitable for passing to Tcl_RegExpExec. This compiled form
1386 * is only valid up until the next call to this procedure, so
1387 * don't keep these around for a long time! If an error occurred
1388 * while compiling the pattern, then NULL is returned and an error
1389 * message is left in interp->result.
1392 * The cache of compiled regexp's in interp will be modified to
1393 * hold information for string, if such information isn't already
1394 * present in the cache.
1396 *----------------------------------------------------------------------
1400 Tcl_RegExpCompile(interp, string)
1401 Tcl_Interp *interp; /* For use in error reporting. */
1402 char *string; /* String for which to produce
1403 * compiled regular expression. */
1405 register Interp *iPtr = (Interp *) interp;
1409 length = strlen(string);
1410 for (i = 0; i < NUM_REGEXPS; i++) {
1411 if ((length == iPtr->patLengths[i])
1412 && (strcmp(string, iPtr->patterns[i]) == 0)) {
1414 * Move the matched pattern to the first slot in the
1415 * cache and shift the other patterns down one position.
1422 cachedString = iPtr->patterns[i];
1423 result = iPtr->regexps[i];
1424 for (j = i-1; j >= 0; j--) {
1425 iPtr->patterns[j+1] = iPtr->patterns[j];
1426 iPtr->patLengths[j+1] = iPtr->patLengths[j];
1427 iPtr->regexps[j+1] = iPtr->regexps[j];
1429 iPtr->patterns[0] = cachedString;
1430 iPtr->patLengths[0] = length;
1431 iPtr->regexps[0] = result;
1433 return (Tcl_RegExp) iPtr->regexps[0];
1438 * No match in the cache. Compile the string and add it to the
1442 TclRegError((char *) NULL);
1443 result = TclRegComp(string);
1444 if (TclGetRegError() != NULL) {
1445 Tcl_AppendResult(interp,
1446 "couldn't compile regular expression pattern: ",
1447 TclGetRegError(), (char *) NULL);
1450 if (iPtr->patterns[NUM_REGEXPS-1] != NULL) {
1451 ckfree(iPtr->patterns[NUM_REGEXPS-1]);
1452 ckfree((char *) iPtr->regexps[NUM_REGEXPS-1]);
1454 for (i = NUM_REGEXPS - 2; i >= 0; i--) {
1455 iPtr->patterns[i+1] = iPtr->patterns[i];
1456 iPtr->patLengths[i+1] = iPtr->patLengths[i];
1457 iPtr->regexps[i+1] = iPtr->regexps[i];
1459 iPtr->patterns[0] = (char *) ckalloc((unsigned) (length+1));
1460 strcpy(iPtr->patterns[0], string);
1461 iPtr->patLengths[0] = length;
1462 iPtr->regexps[0] = result;
1463 return (Tcl_RegExp) result;
1467 *----------------------------------------------------------------------
1471 * Execute the regular expression matcher using a compiled form
1472 * of a regular expression and save information about any match
1476 * If an error occurs during the matching operation then -1
1477 * is returned and interp->result contains an error message.
1478 * Otherwise the return value is 1 if a matching range is
1479 * found and 0 if there is no matching range.
1484 *----------------------------------------------------------------------
1488 Tcl_RegExpExec(interp, re, string, start)
1489 Tcl_Interp *interp; /* Interpreter to use for error reporting. */
1490 Tcl_RegExp re; /* Compiled regular expression; must have
1491 * been returned by previous call to
1492 * Tcl_RegExpCompile. */
1493 char *string; /* String against which to match re. */
1494 char *start; /* If string is part of a larger string,
1495 * this identifies beginning of larger
1496 * string, so that "^" won't match. */
1500 regexp *regexpPtr = (regexp *) re;
1501 TclRegError((char *) NULL);
1502 match = TclRegExec(regexpPtr, string, start);
1503 if (TclGetRegError() != NULL) {
1504 Tcl_ResetResult(interp);
1505 Tcl_AppendResult(interp, "error while matching regular expression: ",
1506 TclGetRegError(), (char *) NULL);
1513 *----------------------------------------------------------------------
1515 * Tcl_RegExpRange --
1517 * Returns pointers describing the range of a regular expression match,
1518 * or one of the subranges within the match.
1521 * The variables at *startPtr and *endPtr are modified to hold the
1522 * addresses of the endpoints of the range given by index. If the
1523 * specified range doesn't exist then NULLs are returned.
1528 *----------------------------------------------------------------------
1532 Tcl_RegExpRange(re, index, startPtr, endPtr)
1533 Tcl_RegExp re; /* Compiled regular expression that has
1534 * been passed to Tcl_RegExpExec. */
1535 int index; /* 0 means give the range of the entire
1536 * match, > 0 means give the range of
1537 * a matching subrange. Must be no greater
1539 char **startPtr; /* Store address of first character in
1540 * (sub-) range here. */
1541 char **endPtr; /* Store address of character just after last
1542 * in (sub-) range here. */
1544 regexp *regexpPtr = (regexp *) re;
1546 if (index >= NSUBEXP) {
1547 *startPtr = *endPtr = NULL;
1549 *startPtr = regexpPtr->startp[index];
1550 *endPtr = regexpPtr->endp[index];
1555 *----------------------------------------------------------------------
1557 * Tcl_RegExpMatch --
1559 * See if a string matches a regular expression.
1562 * If an error occurs during the matching operation then -1
1563 * is returned and interp->result contains an error message.
1564 * Otherwise the return value is 1 if "string" matches "pattern"
1570 *----------------------------------------------------------------------
1574 Tcl_RegExpMatch(interp, string, pattern)
1575 Tcl_Interp *interp; /* Used for error reporting. */
1576 char *string; /* String. */
1577 char *pattern; /* Regular expression to match against
1582 re = Tcl_RegExpCompile(interp, pattern);
1586 return Tcl_RegExpExec(interp, re, string, string);
1590 *----------------------------------------------------------------------
1592 * Tcl_DStringInit --
1594 * Initializes a dynamic string, discarding any previous contents
1595 * of the string (Tcl_DStringFree should have been called already
1596 * if the dynamic string was previously in use).
1602 * The dynamic string is initialized to be empty.
1604 *----------------------------------------------------------------------
1608 Tcl_DStringInit(dsPtr)
1609 register Tcl_DString *dsPtr; /* Pointer to structure for
1610 * dynamic string. */
1612 dsPtr->string = dsPtr->staticSpace;
1614 dsPtr->spaceAvl = TCL_DSTRING_STATIC_SIZE;
1615 dsPtr->staticSpace[0] = 0;
1619 *----------------------------------------------------------------------
1621 * Tcl_DStringAppend --
1623 * Append more characters to the current value of a dynamic string.
1626 * The return value is a pointer to the dynamic string's new value.
1629 * Length bytes from string (or all of string if length is less
1630 * than zero) are added to the current value of the string. Memory
1631 * gets reallocated if needed to accomodate the string's new size.
1633 *----------------------------------------------------------------------
1637 Tcl_DStringAppend(dsPtr, string, length)
1638 register Tcl_DString *dsPtr; /* Structure describing dynamic
1640 char *string; /* String to append. If length is
1641 * -1 then this must be
1642 * null-terminated. */
1643 int length; /* Number of characters from string
1644 * to append. If < 0, then append all
1645 * of string, up to null at end. */
1648 char *newString, *dst, *end;
1651 length = strlen(string);
1653 newSize = length + dsPtr->length;
1656 * Allocate a larger buffer for the string if the current one isn't
1657 * large enough. Allocate extra space in the new buffer so that there
1658 * will be room to grow before we have to allocate again.
1661 if (newSize >= dsPtr->spaceAvl) {
1662 dsPtr->spaceAvl = newSize*2;
1663 newString = (char *) ckalloc((unsigned) dsPtr->spaceAvl);
1664 memcpy((VOID *)newString, (VOID *) dsPtr->string,
1665 (size_t) dsPtr->length);
1666 if (dsPtr->string != dsPtr->staticSpace) {
1667 ckfree(dsPtr->string);
1669 dsPtr->string = newString;
1673 * Copy the new string into the buffer at the end of the old
1677 for (dst = dsPtr->string + dsPtr->length, end = string+length;
1678 string < end; string++, dst++) {
1682 dsPtr->length += length;
1683 return dsPtr->string;
1687 *----------------------------------------------------------------------
1689 * Tcl_DStringAppendElement --
1691 * Append a list element to the current value of a dynamic string.
1694 * The return value is a pointer to the dynamic string's new value.
1697 * String is reformatted as a list element and added to the current
1698 * value of the string. Memory gets reallocated if needed to
1699 * accomodate the string's new size.
1701 *----------------------------------------------------------------------
1705 Tcl_DStringAppendElement(dsPtr, string)
1706 register Tcl_DString *dsPtr; /* Structure describing dynamic
1708 char *string; /* String to append. Must be
1709 * null-terminated. */
1712 char *dst, *newString;
1714 newSize = Tcl_ScanElement(string, &flags) + dsPtr->length + 1;
1717 * Allocate a larger buffer for the string if the current one isn't
1718 * large enough. Allocate extra space in the new buffer so that there
1719 * will be room to grow before we have to allocate again.
1720 * SPECIAL NOTE: must use memcpy, not strcpy, to copy the string
1721 * to a larger buffer, since there may be embedded NULLs in the
1722 * string in some cases.
1725 if (newSize >= dsPtr->spaceAvl) {
1726 dsPtr->spaceAvl = newSize*2;
1727 newString = (char *) ckalloc((unsigned) dsPtr->spaceAvl);
1728 memcpy((VOID *) newString, (VOID *) dsPtr->string,
1729 (size_t) dsPtr->length);
1730 if (dsPtr->string != dsPtr->staticSpace) {
1731 ckfree(dsPtr->string);
1733 dsPtr->string = newString;
1737 * Convert the new string to a list element and copy it into the
1738 * buffer at the end, with a space, if needed.
1741 dst = dsPtr->string + dsPtr->length;
1742 if (TclNeedSpace(dsPtr->string, dst)) {
1747 dsPtr->length += Tcl_ConvertElement(string, dst, flags);
1748 return dsPtr->string;
1752 *----------------------------------------------------------------------
1754 * Tcl_DStringSetLength --
1756 * Change the length of a dynamic string. This can cause the
1757 * string to either grow or shrink, depending on the value of
1764 * The length of dsPtr is changed to length and a null byte is
1765 * stored at that position in the string. If length is larger
1766 * than the space allocated for dsPtr, then a panic occurs.
1768 *----------------------------------------------------------------------
1772 Tcl_DStringSetLength(dsPtr, length)
1773 register Tcl_DString *dsPtr; /* Structure describing dynamic
1775 int length; /* New length for dynamic string. */
1780 if (length >= dsPtr->spaceAvl) {
1783 dsPtr->spaceAvl = length+1;
1784 newString = (char *) ckalloc((unsigned) dsPtr->spaceAvl);
1787 * SPECIAL NOTE: must use memcpy, not strcpy, to copy the string
1788 * to a larger buffer, since there may be embedded NULLs in the
1789 * string in some cases.
1792 memcpy((VOID *) newString, (VOID *) dsPtr->string,
1793 (size_t) dsPtr->length);
1794 if (dsPtr->string != dsPtr->staticSpace) {
1795 ckfree(dsPtr->string);
1797 dsPtr->string = newString;
1799 dsPtr->length = length;
1800 dsPtr->string[length] = 0;
1804 *----------------------------------------------------------------------
1806 * Tcl_DStringFree --
1808 * Frees up any memory allocated for the dynamic string and
1809 * reinitializes the string to an empty state.
1815 * The previous contents of the dynamic string are lost, and
1816 * the new value is an empty string.
1818 *----------------------------------------------------------------------
1822 Tcl_DStringFree(dsPtr)
1823 register Tcl_DString *dsPtr; /* Structure describing dynamic
1826 if (dsPtr->string != dsPtr->staticSpace) {
1827 ckfree(dsPtr->string);
1829 dsPtr->string = dsPtr->staticSpace;
1831 dsPtr->spaceAvl = TCL_DSTRING_STATIC_SIZE;
1832 dsPtr->staticSpace[0] = 0;
1836 *----------------------------------------------------------------------
1838 * Tcl_DStringResult --
1840 * This procedure moves the value of a dynamic string into an
1841 * interpreter as its result. The string itself is reinitialized
1842 * to an empty string.
1848 * The string is "moved" to interp's result, and any existing
1849 * result for interp is freed up. DsPtr is reinitialized to
1852 *----------------------------------------------------------------------
1856 Tcl_DStringResult(interp, dsPtr)
1857 Tcl_Interp *interp; /* Interpreter whose result is to be
1859 Tcl_DString *dsPtr; /* Dynamic string that is to become
1860 * the result of interp. */
1862 Tcl_ResetResult(interp);
1863 if (dsPtr->string != dsPtr->staticSpace) {
1864 interp->result = dsPtr->string;
1865 interp->freeProc = TCL_DYNAMIC;
1866 } else if (dsPtr->length < TCL_RESULT_SIZE) {
1867 interp->result = ((Interp *) interp)->resultSpace;
1868 strcpy(interp->result, dsPtr->string);
1870 Tcl_SetResult(interp, dsPtr->string, TCL_VOLATILE);
1872 dsPtr->string = dsPtr->staticSpace;
1874 dsPtr->spaceAvl = TCL_DSTRING_STATIC_SIZE;
1875 dsPtr->staticSpace[0] = 0;
1879 *----------------------------------------------------------------------
1881 * Tcl_DStringGetResult --
1883 * This procedure moves the result of an interpreter into a
1890 * The interpreter's result is cleared, and the previous contents
1891 * of dsPtr are freed.
1893 *----------------------------------------------------------------------
1897 Tcl_DStringGetResult(interp, dsPtr)
1898 Tcl_Interp *interp; /* Interpreter whose result is to be
1900 Tcl_DString *dsPtr; /* Dynamic string that is to become
1901 * the result of interp. */
1903 Interp *iPtr = (Interp *) interp;
1904 if (dsPtr->string != dsPtr->staticSpace) {
1905 ckfree(dsPtr->string);
1907 dsPtr->length = strlen(iPtr->result);
1908 if (iPtr->freeProc != NULL) {
1909 if ((iPtr->freeProc == TCL_DYNAMIC)
1910 || (iPtr->freeProc == (Tcl_FreeProc *) free)) {
1911 dsPtr->string = iPtr->result;
1912 dsPtr->spaceAvl = dsPtr->length+1;
1914 dsPtr->string = (char *) ckalloc((unsigned) (dsPtr->length+1));
1915 strcpy(dsPtr->string, iPtr->result);
1916 (*iPtr->freeProc)(iPtr->result);
1918 dsPtr->spaceAvl = dsPtr->length+1;
1919 iPtr->freeProc = NULL;
1921 if (dsPtr->length < TCL_DSTRING_STATIC_SIZE) {
1922 dsPtr->string = dsPtr->staticSpace;
1923 dsPtr->spaceAvl = TCL_DSTRING_STATIC_SIZE;
1925 dsPtr->string = (char *) ckalloc((unsigned) (dsPtr->length + 1));
1926 dsPtr->spaceAvl = dsPtr->length + 1;
1928 strcpy(dsPtr->string, iPtr->result);
1930 iPtr->result = iPtr->resultSpace;
1931 iPtr->resultSpace[0] = 0;
1935 *----------------------------------------------------------------------
1937 * Tcl_DStringStartSublist --
1939 * This procedure adds the necessary information to a dynamic
1940 * string (e.g. " {" to start a sublist. Future element
1941 * appends will be in the sublist rather than the main list.
1947 * Characters get added to the dynamic string.
1949 *----------------------------------------------------------------------
1953 Tcl_DStringStartSublist(dsPtr)
1954 Tcl_DString *dsPtr; /* Dynamic string. */
1956 if (TclNeedSpace(dsPtr->string, dsPtr->string + dsPtr->length)) {
1957 Tcl_DStringAppend(dsPtr, " {", -1);
1959 Tcl_DStringAppend(dsPtr, "{", -1);
1964 *----------------------------------------------------------------------
1966 * Tcl_DStringEndSublist --
1968 * This procedure adds the necessary characters to a dynamic
1969 * string to end a sublist (e.g. "}"). Future element appends
1970 * will be in the enclosing (sub)list rather than the current
1979 *----------------------------------------------------------------------
1983 Tcl_DStringEndSublist(dsPtr)
1984 Tcl_DString *dsPtr; /* Dynamic string. */
1986 Tcl_DStringAppend(dsPtr, "}", -1);
1990 *----------------------------------------------------------------------
1992 * Tcl_PrintDouble --
1994 * Given a floating-point value, this procedure converts it to
1995 * an ASCII string using.
1998 * The ASCII equivalent of "value" is written at "dst". It is
1999 * written using the current precision, and it is guaranteed to
2000 * contain a decimal point or exponent, so that it looks like
2001 * a floating-point value and not an integer.
2006 *----------------------------------------------------------------------
2010 Tcl_PrintDouble(interp, value, dst)
2011 Tcl_Interp *interp; /* Interpreter whose tcl_precision
2012 * variable controls printing. */
2013 double value; /* Value to print as string. */
2014 char *dst; /* Where to store converted value;
2015 * must have at least TCL_DOUBLE_SPACE
2019 sprintf(dst, ((Interp *) interp)->pdFormat, value);
2022 * If the ASCII result looks like an integer, add ".0" so that it
2023 * doesn't look like an integer anymore. This prevents floating-point
2024 * values from being converted to integers unintentionally.
2027 for (p = dst; *p != 0; p++) {
2028 if ((*p == '.') || (isalpha(UCHAR(*p)))) {
2038 *----------------------------------------------------------------------
2040 * TclPrecTraceProc --
2042 * This procedure is invoked whenever the variable "tcl_precision"
2046 * Returns NULL if all went well, or an error message if the
2047 * new value for the variable doesn't make sense.
2050 * If the new value doesn't make sense then this procedure
2051 * undoes the effect of the variable modification. Otherwise
2052 * it modifies the format string that's used by Tcl_PrintDouble.
2054 *----------------------------------------------------------------------
2059 TclPrecTraceProc(clientData, interp, name1, name2, flags)
2060 ClientData clientData; /* Not used. */
2061 Tcl_Interp *interp; /* Interpreter containing variable. */
2062 char *name1; /* Name of variable. */
2063 char *name2; /* Second part of variable name. */
2064 int flags; /* Information about what happened. */
2066 register Interp *iPtr = (Interp *) interp;
2071 * If the variable is unset, then recreate the trace and restore
2072 * the default value of the format string.
2075 if (flags & TCL_TRACE_UNSETS) {
2076 if ((flags & TCL_TRACE_DESTROYED) && !(flags & TCL_INTERP_DESTROYED)) {
2077 Tcl_TraceVar2(interp, name1, name2,
2078 TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS,
2079 TclPrecTraceProc, clientData);
2081 strcpy(iPtr->pdFormat, DEFAULT_PD_FORMAT);
2082 iPtr->pdPrec = DEFAULT_PD_PREC;
2083 return (char *) NULL;
2086 value = Tcl_GetVar2(interp, name1, name2, flags & TCL_GLOBAL_ONLY);
2087 if (value == NULL) {
2090 prec = strtoul(value, &end, 10);
2091 if ((prec <= 0) || (prec > TCL_MAX_PREC) || (prec > 100) ||
2092 (end == value) || (*end != 0)) {
2095 sprintf(oldValue, "%d", iPtr->pdPrec);
2096 Tcl_SetVar2(interp, name1, name2, oldValue, flags & TCL_GLOBAL_ONLY);
2097 return "improper value for precision";
2099 sprintf(iPtr->pdFormat, "%%.%dg", prec);
2100 iPtr->pdPrec = prec;
2101 return (char *) NULL;
2105 *----------------------------------------------------------------------
2109 * This procedure checks to see whether it is appropriate to
2110 * add a space before appending a new list element to an
2114 * The return value is 1 if a space is appropriate, 0 otherwise.
2119 *----------------------------------------------------------------------
2123 TclNeedSpace(start, end)
2124 char *start; /* First character in string. */
2125 char *end; /* End of string (place where space will
2126 * be added, if appropriate). */
2129 * A space is needed unless either
2130 * (a) we're at the start of the string, or
2131 * (b) the trailing characters of the string consist of one or more
2132 * open curly braces preceded by a space or extending back to
2133 * the beginning of the string.
2134 * (c) the trailing characters of the string consist of a space
2135 * preceded by a character other than backslash.
2143 if (isspace(UCHAR(*end)) && ((end == start) || (end[-1] != '\\'))) {
2153 } while (*end == '{');
2154 if (isspace(UCHAR(*end))) {