Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | New utility routines: TclIsSpaceProc() and TclCountSpaceRuns() Use to replace calls to isspace() and their /* INTL */ risk. |
---|---|
Downloads: | Tarball | ZIP archive | SQL archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA1: |
ef10af814d8b9963b42f8d064cc83c85 |
User & Date: | dgp 2011-04-28 14:44:47 |
Context
2011-04-28
| ||
16:02 | More isspace() callers. check-in: 41acfe91ea user: dgp tags: trunk | |
14:44 | New utility routines: TclIsSpaceProc() and TclCountSpaceRuns() Use to replace calls to isspace() and... check-in: ef10af814d user: dgp tags: trunk | |
14:39 | New utility routines: TclIsSpaceProc() and TclCountSpaceRuns() Use to replace calls to isspace() and... check-in: b1063a174c user: dgp tags: core-8-5-branch | |
13:45 | Improved reaction to out of memory. check-in: 4363a1c212 user: dgp tags: trunk | |
Changes
Changes to ChangeLog.
1 2 3 4 5 6 7 8 9 10 | 2011-04-28 Don Porter <[email protected]> * generic/tclStringObj.c: Improved reaction to out of memory. 2011-04-27 Don Porter <[email protected]> * generic/tclCmdMZ.c: TclFreeIntRep() correction & cleanup. * generic/tclExecute.c: * generic/tclIndexObj.c: * generic/tclInt.h: | > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 | 2011-04-28 Don Porter <[email protected]> * generic/tclInt.h: New utility routines: * generic/tclParse.c: TclIsSpaceProc() and * generic/tclUtil.c: TclCountSpaceRuns() * generic/tclCmdMZ.c: Use new routines to replace calls to * generic/tclListObj.c: isspace() and their /* INTL */ risk. * generic/tclStrToD.c: * generic/tclStringObj.c: Improved reaction to out of memory. 2011-03-16 Jan Nijtmans <[email protected]> * unix/tcl.m4: Make SHLIB_LD_LIBS='${LIBS}' the default and * unix/configure: set to "" on per-platform necessary basis. Backported from TEA, but kept all original platform code which was removed from TEA. 2011-03-14 Kevin B. Kenny <[email protected]> * tools/tclZIC.tcl (onDayOfMonth): Allow for leading zeroes in month and day so that tzdata2011d parses correctly. * library/tzdata/America/Havana: * library/tzdata/America/Juneau: * library/tzdata/America/Santiago: * library/tzdata/Europe/Istanbul: * library/tzdata/Pacific/Apia: * library/tzdata/Pacific/Easter: * library/tzdata/Pacific/Honolulu: tzdata2011d 2011-04-27 Don Porter <[email protected]> * generic/tclCmdMZ.c: TclFreeIntRep() correction & cleanup. * generic/tclExecute.c: * generic/tclIndexObj.c: * generic/tclInt.h: |
︙ | ︙ |
Changes to generic/tclCmdMZ.c.
︙ | ︙ | |||
1661 1662 1663 1664 1665 1666 1667 | * the number of bytes when parsing strings with non-ASCII * characters in them. * * Skip leading spaces first. This is only really an issue * if it is the first "element" that has the failure. */ | | | 1661 1662 1663 1664 1665 1666 1667 1668 1669 1670 1671 1672 1673 1674 1675 | * the number of bytes when parsing strings with non-ASCII * characters in them. * * Skip leading spaces first. This is only really an issue * if it is the first "element" that has the failure. */ while (TclIsSpaceProc(*p)) { p++; } TclNewStringObj(tmpStr, string1, p-string1); failat = Tcl_GetCharLength(tmpStr); TclDecrRefCount(tmpStr); break; } |
︙ | ︙ |
Changes to generic/tclInt.h.
︙ | ︙ | |||
2896 2897 2898 2899 2900 2901 2902 2903 2904 2905 2906 2907 2908 2909 | MODULE_SCOPE ContLineLoc *TclContinuationsEnter(Tcl_Obj *objPtr, int num, int *loc); MODULE_SCOPE void TclContinuationsEnterDerived(Tcl_Obj *objPtr, int start, int *clNext); MODULE_SCOPE ContLineLoc *TclContinuationsGet(Tcl_Obj *objPtr); MODULE_SCOPE void TclContinuationsCopy(Tcl_Obj *objPtr, Tcl_Obj *originObjPtr); MODULE_SCOPE void TclDeleteNamespaceVars(Namespace *nsPtr); /* TIP #280 - Modified token based evulation, with line information. */ MODULE_SCOPE int TclEvalEx(Tcl_Interp *interp, const char *script, int numBytes, int flags, int line, int *clNextOuter, const char *outerScript); MODULE_SCOPE Tcl_ObjCmdProc TclFileAttrsCmd; MODULE_SCOPE Tcl_ObjCmdProc TclFileCopyCmd; | > > | 2896 2897 2898 2899 2900 2901 2902 2903 2904 2905 2906 2907 2908 2909 2910 2911 | MODULE_SCOPE ContLineLoc *TclContinuationsEnter(Tcl_Obj *objPtr, int num, int *loc); MODULE_SCOPE void TclContinuationsEnterDerived(Tcl_Obj *objPtr, int start, int *clNext); MODULE_SCOPE ContLineLoc *TclContinuationsGet(Tcl_Obj *objPtr); MODULE_SCOPE void TclContinuationsCopy(Tcl_Obj *objPtr, Tcl_Obj *originObjPtr); MODULE_SCOPE int TclCountSpaceRuns(CONST char *bytes, int numBytes, CONST char **endPtr); MODULE_SCOPE void TclDeleteNamespaceVars(Namespace *nsPtr); /* TIP #280 - Modified token based evulation, with line information. */ MODULE_SCOPE int TclEvalEx(Tcl_Interp *interp, const char *script, int numBytes, int flags, int line, int *clNextOuter, const char *outerScript); MODULE_SCOPE Tcl_ObjCmdProc TclFileAttrsCmd; MODULE_SCOPE Tcl_ObjCmdProc TclFileCopyCmd; |
︙ | ︙ | |||
2987 2988 2989 2990 2991 2992 2993 2994 2995 2996 2997 2998 2999 3000 | MODULE_SCOPE void TclInitLimitSupport(Tcl_Interp *interp); MODULE_SCOPE void TclInitNamespaceSubsystem(void); MODULE_SCOPE void TclInitNotifier(void); MODULE_SCOPE void TclInitObjSubsystem(void); MODULE_SCOPE void TclInitSubsystems(void); MODULE_SCOPE int TclInterpReady(Tcl_Interp *interp); MODULE_SCOPE int TclIsLocalScalar(const char *src, int len); MODULE_SCOPE int TclJoinThread(Tcl_ThreadId id, int *result); MODULE_SCOPE void TclLimitRemoveAllHandlers(Tcl_Interp *interp); MODULE_SCOPE Tcl_Obj * TclLindexList(Tcl_Interp *interp, Tcl_Obj *listPtr, Tcl_Obj *argPtr); MODULE_SCOPE Tcl_Obj * TclLindexFlat(Tcl_Interp *interp, Tcl_Obj *listPtr, int indexCount, Tcl_Obj *const indexArray[]); /* TIP #280 */ | > | 2989 2990 2991 2992 2993 2994 2995 2996 2997 2998 2999 3000 3001 3002 3003 | MODULE_SCOPE void TclInitLimitSupport(Tcl_Interp *interp); MODULE_SCOPE void TclInitNamespaceSubsystem(void); MODULE_SCOPE void TclInitNotifier(void); MODULE_SCOPE void TclInitObjSubsystem(void); MODULE_SCOPE void TclInitSubsystems(void); MODULE_SCOPE int TclInterpReady(Tcl_Interp *interp); MODULE_SCOPE int TclIsLocalScalar(const char *src, int len); MODULE_SCOPE int TclIsSpaceProc(char byte); MODULE_SCOPE int TclJoinThread(Tcl_ThreadId id, int *result); MODULE_SCOPE void TclLimitRemoveAllHandlers(Tcl_Interp *interp); MODULE_SCOPE Tcl_Obj * TclLindexList(Tcl_Interp *interp, Tcl_Obj *listPtr, Tcl_Obj *argPtr); MODULE_SCOPE Tcl_Obj * TclLindexFlat(Tcl_Interp *interp, Tcl_Obj *listPtr, int indexCount, Tcl_Obj *const indexArray[]); /* TIP #280 */ |
︙ | ︙ |
Changes to generic/tclListObj.c.
︙ | ︙ | |||
1785 1786 1787 1788 1789 1790 1791 | * Parse the string into separate string objects, and create a List * structure that points to the element string objects. We use a modified * version of Tcl_SplitList's implementation to avoid one malloc and a * string copy for each list element. First, estimate the number of * elements by counting the number of space characters in the list. */ | < | < < < < < | 1785 1786 1787 1788 1789 1790 1791 1792 1793 1794 1795 1796 1797 1798 1799 | * Parse the string into separate string objects, and create a List * structure that points to the element string objects. We use a modified * version of Tcl_SplitList's implementation to avoid one malloc and a * string copy for each list element. First, estimate the number of * elements by counting the number of space characters in the list. */ estCount = TclCountSpaceRuns(string, length, &limit) + 1; /* * Allocate a new List structure with enough room for "estCount" elements. * Each element is a pointer to a Tcl_Obj with the appropriate string rep. * The initial "estCount" elements are set using the corresponding "argv" * strings. */ |
︙ | ︙ |
Changes to generic/tclParse.c.
︙ | ︙ | |||
607 608 609 610 611 612 613 614 615 616 617 618 619 620 | parsePtr->commandSize = parsePtr->end - parsePtr->commandStart; return TCL_ERROR; } /* *---------------------------------------------------------------------- * * ParseWhiteSpace -- * * Scans up to numBytes bytes starting at src, consuming white space * between words as defined by Tcl's parsing rules. * * Results: * Returns the number of bytes recognized as white space. Records at | > > > > > > > > > > > > > > > > > > > > > > > > | 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 | parsePtr->commandSize = parsePtr->end - parsePtr->commandStart; return TCL_ERROR; } /* *---------------------------------------------------------------------- * * TclIsSpaceProc -- * * Report whether byte is in the set of whitespace characters used by * Tcl to separate words in scripts or elements in lists. * * Results: * Returns 1, if byte is in the set, 0 otherwise. * * Side effects: * None. * *---------------------------------------------------------------------- */ int TclIsSpaceProc( char byte) { return CHAR_TYPE(byte) & (TYPE_SPACE) || byte == '\n'; } /* *---------------------------------------------------------------------- * * ParseWhiteSpace -- * * Scans up to numBytes bytes starting at src, consuming white space * between words as defined by Tcl's parsing rules. * * Results: * Returns the number of bytes recognized as white space. Records at |
︙ | ︙ | |||
1753 1754 1755 1756 1757 1758 1759 | case '{': openBrace = 1; break; case '\n': openBrace = 0; break; case '#' : | | | 1777 1778 1779 1780 1781 1782 1783 1784 1785 1786 1787 1788 1789 1790 1791 | case '{': openBrace = 1; break; case '\n': openBrace = 0; break; case '#' : if (openBrace && TclIsSpaceProc(src[-1])) { Tcl_AppendResult(parsePtr->interp, ": possible unbalanced brace in comment", NULL); goto error; } break; } } |
︙ | ︙ |
Changes to generic/tclStrToD.c.
︙ | ︙ | |||
567 568 569 570 571 572 573 | case INITIAL: /* * Initial state. Acceptable characters are +, -, digits, period, * I, N, and whitespace. */ | | | 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 | case INITIAL: /* * Initial state. Acceptable characters are +, -, digits, period, * I, N, and whitespace. */ if (TclIsSpaceProc(c)) { if (flags & TCL_PARSE_NO_WHITESPACE) { goto endgame; } break; } else if (c == '+') { state = SIGNUM; break; |
︙ | ︙ | |||
1087 1088 1089 1090 1091 1092 1093 | case sNANHEX: if (c == ')') { state = sNANFINISH; break; } /* FALLTHROUGH */ case sNANPAREN: | | | 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 | case sNANHEX: if (c == ')') { state = sNANFINISH; break; } /* FALLTHROUGH */ case sNANPAREN: if (TclIsSpaceProc(c)) { break; } if (numSigDigs < 13) { if (c >= '0' && c <= '9') { d = c - '0'; } else if (c >= 'a' && c <= 'f') { d = 10 + c - 'a'; |
︙ | ︙ | |||
1138 1139 1140 1141 1142 1143 1144 | p = acceptPoint; len = acceptLen; if (!(flags & TCL_PARSE_NO_WHITESPACE)) { /* * Accept trailing whitespace. */ | | | 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 | p = acceptPoint; len = acceptLen; if (!(flags & TCL_PARSE_NO_WHITESPACE)) { /* * Accept trailing whitespace. */ while (len != 0 && TclIsSpaceProc(*p)) { p++; len--; } } if (endPtrPtr == NULL) { if ((len != 0) && ((numBytes > 0) || (*p != '\0'))) { status = TCL_ERROR; |
︙ | ︙ |
Changes to generic/tclUtil.c.
︙ | ︙ | |||
84 85 86 87 88 89 90 91 92 93 94 95 96 97 | UpdateStringOfEndOffset, /* updateStringProc */ SetEndOffsetFromAny }; /* *---------------------------------------------------------------------- * * TclFindElement -- * * Given a pointer into a Tcl list, locate the first (or next) element in * the list. * * Results: * The return value is normally TCL_OK, which means that the element was | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 | UpdateStringOfEndOffset, /* updateStringProc */ SetEndOffsetFromAny }; /* *---------------------------------------------------------------------- * * TclCountSpaceRuns -- * * Given 'bytes' pointing to 'numBytes' bytes, scan through them and * count the number of whitespace runs that could be list element * separators. If 'numBytes' is -1, scan to the terminating '\0'. * * Results: * Returns the count. If 'endPtr' is not NULL, writes a pointer to * the end of the string scanned there. * * Side effects: * None. * *---------------------------------------------------------------------- */ int TclCountSpaceRuns( CONST char *bytes, int numBytes, CONST char **endPtr) { int count = 0; while (numBytes) { if ((numBytes == -1) && (*bytes == '\0')) { break; } if (TclIsSpaceProc(*bytes)) { /* Space run started; bump count */ count++; do { bytes++; numBytes -= (numBytes != -1); } while (numBytes && TclIsSpaceProc(*bytes)); if (numBytes == 0) { break; } /* (*bytes) is non-space; return to counting state */ } bytes++; numBytes -= (numBytes != -1); } if (endPtr) { *endPtr = bytes; } return count; } /* *---------------------------------------------------------------------- * * TclFindElement -- * * Given a pointer into a Tcl list, locate the first (or next) element in * the list. * * Results: * The return value is normally TCL_OK, which means that the element was |
︙ | ︙ | |||
150 151 152 153 154 155 156 | /* * Skim off leading white space and check for an opening brace or quote. * We treat embedded NULLs in the list as bytes belonging to a list * element. */ limit = (list + listLength); | | | 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 | /* * Skim off leading white space and check for an opening brace or quote. * We treat embedded NULLs in the list as bytes belonging to a list * element. */ limit = (list + listLength); while ((p < limit) && (TclIsSpaceProc(*p))) { p++; } if (p == limit) { /* no element found */ elemStart = limit; goto done; } |
︙ | ︙ | |||
198 199 200 201 202 203 204 | case '}': if (openBraces > 1) { openBraces--; } else if (openBraces == 1) { size = (p - elemStart); p++; | | < | < | 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 | case '}': if (openBraces > 1) { openBraces--; } else if (openBraces == 1) { size = (p - elemStart); p++; if ((p >= limit) || TclIsSpaceProc(*p)) { goto done; } /* * Garbage after the closing brace; return an error. */ if (interp != NULL) { p2 = p; while ((p2 < limit) && (!TclIsSpaceProc(*p2)) && (p2 < p+20)) { p2++; } Tcl_SetObjResult(interp, Tcl_ObjPrintf( "list element in braces followed by \"%.*s\" " "instead of space", (int) (p2-p), p)); Tcl_SetErrorCode(interp, "TCL", "VALUE", "LIST", "JUNK", |
︙ | ︙ | |||
259 260 261 262 263 264 265 | * Double-quote: if element is in quotes then terminate it. */ case '"': if (inQuotes) { size = (p - elemStart); p++; | | < | < | 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 | * Double-quote: if element is in quotes then terminate it. */ case '"': if (inQuotes) { size = (p - elemStart); p++; if ((p >= limit) || TclIsSpaceProc(*p)) { goto done; } /* * Garbage after the closing quote; return an error. */ if (interp != NULL) { p2 = p; while ((p2 < limit) && (!TclIsSpaceProc(*p2)) && (p2 < p+20)) { p2++; } Tcl_SetObjResult(interp, Tcl_ObjPrintf( "list element in quotes followed by \"%.*s\" " "instead of space", (int) (p2-p), p)); Tcl_SetErrorCode(interp, "TCL", "VALUE", "LIST", "JUNK", |
︙ | ︙ | |||
314 315 316 317 318 319 320 | } return TCL_ERROR; } size = (p - elemStart); } done: | | | 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 | } return TCL_ERROR; } size = (p - elemStart); } done: while ((p < limit) && (TclIsSpaceProc(*p))) { p++; } *elementPtr = elemStart; *nextPtr = p; if (sizePtr != 0) { *sizePtr = size; } |
︙ | ︙ | |||
412 413 414 415 416 417 418 | * NULL, no error message is left. */ const char *list, /* Pointer to string with list structure. */ int *argcPtr, /* Pointer to location to fill in with the * number of elements in the list. */ const char ***argvPtr) /* Pointer to place to store pointer to array * of pointers to list elements. */ { | | < < < | < < < < < < < < < < < < < < < < < < | | 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 | * NULL, no error message is left. */ const char *list, /* Pointer to string with list structure. */ int *argcPtr, /* Pointer to location to fill in with the * number of elements in the list. */ const char ***argvPtr) /* Pointer to place to store pointer to array * of pointers to list elements. */ { const char **argv, *end, *element; char *p; int length, size, i, result, elSize, brace; /* * Figure out how much space to allocate. There must be enough space for * both the array of pointers and also for a copy of the list. To estimate * the number of pointers needed, count the number of space characters in * the list. */ size = TclCountSpaceRuns(list, -1, &end) + 2; length = end - list; argv = ckalloc((size * sizeof(char *)) + length + 1); for (i = 0, p = ((char *) argv) + size*sizeof(char *); *list != 0; i++) { const char *prevList = list; result = TclFindElement(interp, list, length, &element, &list, &elSize, &brace); |
︙ | ︙ |