diff options
author | dgp <dgp@users.sourceforge.net> | 2011-05-02 15:38:31 (GMT) |
---|---|---|
committer | dgp <dgp@users.sourceforge.net> | 2011-05-02 15:38:31 (GMT) |
commit | caea13f2776c1d71043747539553c566d4186553 (patch) | |
tree | 157fb830c0521a0dfee6f61d29b92b1153f3c44b /generic/tclUtil.c | |
parent | 92906a53a74eaca4671e76dcf8789db8c565c082 (diff) | |
download | tcl-caea13f2776c1d71043747539553c566d4186553.zip tcl-caea13f2776c1d71043747539553c566d4186553.tar.gz tcl-caea13f2776c1d71043747539553c566d4186553.tar.bz2 |
Replace TclCountSpaceRuns() with TclMaxListLength() which is the function we
actually want.
Diffstat (limited to 'generic/tclUtil.c')
-rw-r--r-- | generic/tclUtil.c | 39 |
1 files changed, 30 insertions, 9 deletions
diff --git a/generic/tclUtil.c b/generic/tclUtil.c index d542b52..76676a1 100644 --- a/generic/tclUtil.c +++ b/generic/tclUtil.c @@ -89,15 +89,19 @@ Tcl_ObjType tclEndOffsetType = { /* *---------------------------------------------------------------------- * - * TclCountSpaceRuns -- + * TclMaxListLength -- * * 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'. + * Not a full list parser. Typically used to get a quick and dirty + * overestimate of length size in order to allocate space for an + * actual list parser to operate with. * * Results: - * Returns the count. If 'endPtr' is not NULL, writes a pointer to - * the end of the string scanned there. + * Returns the largest number of list elements that could possibly + * be in this string, interpreted as a Tcl list. If 'endPtr' is not + * NULL, writes a pointer to the end of the string scanned there. * * Side effects: * None. @@ -106,13 +110,22 @@ Tcl_ObjType tclEndOffsetType = { */ int -TclCountSpaceRuns( +TclMaxListLength( CONST char *bytes, int numBytes, CONST char **endPtr) { int count = 0; + if ((numBytes == 0) || ((numBytes == -1) && (*bytes == '\0'))) { + /* Empty string case - quick exit */ + goto done; + } + + /* No list element before leading white space */ + count += 1 - TclIsSpaceProc(*bytes); + + /* Count white space runs as potential element separators */ while (numBytes) { if ((numBytes == -1) && (*bytes == '\0')) { break; @@ -132,6 +145,11 @@ TclCountSpaceRuns( bytes++; numBytes -= (numBytes != -1); } + + /* No list element following trailing white space */ + count -= TclIsSpaceProc(bytes[-1]); + + done: if (endPtr) { *endPtr = bytes; } @@ -462,16 +480,19 @@ Tcl_SplitList( 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. + * Allocate enough space to work in. A (CONST char *) for each + * (possible) list element plus one more for terminating NULL, + * plus as many bytes as in the original string value, plus one + * more for a terminating '\0'. Space used to hold element separating + * white space in the original string gets re-purposed to hold '\0' + * characters in the argv array. */ - size = TclCountSpaceRuns(list, -1, &end) + 2; + size = TclMaxListLength(list, -1, &end) + 1; length = end - list; argv = (CONST char **) ckalloc((unsigned) ((size * sizeof(char *)) + length + 1)); + for (i = 0, p = ((char *) argv) + size*sizeof(char *); *list != 0; i++) { CONST char *prevList = list; |