From 5702e695062ec36c3addd403d748af48164db8b1 Mon Sep 17 00:00:00 2001
From: dgp <dgp@users.sourceforge.net>
Date: Thu, 28 Apr 2011 14:39:42 +0000
Subject: New utility routines: TclIsSpaceProc() and TclCountSpaceRuns() Use to
 replace calls to isspace() and their /* INTL */ risk.

---
 ChangeLog            | 29 ++++++++++++++++
 generic/tclCmdMZ.c   |  2 +-
 generic/tclInt.h     |  3 ++
 generic/tclListObj.c |  8 +----
 generic/tclParse.c   | 26 +++++++++++++-
 generic/tclStrToD.c  |  6 ++--
 generic/tclUtil.c    | 95 +++++++++++++++++++++++++++++++++-------------------
 7 files changed, 123 insertions(+), 46 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index 6cfe6d1..85fdf61 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,32 @@
+2011-04-28  Don Porter  <dgp@users.sourceforge.net>
+
+	* 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:
+	
+2011-03-16  Jan Nijtmans  <nijtmans@users.sf.net>
+
+	* 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  <kennykb@acm.org>
+
+	* 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  <dgp@users.sourceforge.net>
 
 	* generic/tclListObj.c:	FreeListInternalRep() cleanup.
diff --git a/generic/tclCmdMZ.c b/generic/tclCmdMZ.c
index 7c3855c..5390cf0 100644
--- a/generic/tclCmdMZ.c
+++ b/generic/tclCmdMZ.c
@@ -1643,7 +1643,7 @@ StringIsCmd(
 		     * if it is the first "element" that has the failure.
 		     */
 
-		    while (isspace(UCHAR(*p))) {		/* INTL: ? */
+		    while (TclIsSpaceProc(*p)) {
 			p++;
 		    }
 		    TclNewStringObj(tmpStr, string1, p-string1);
diff --git a/generic/tclInt.h b/generic/tclInt.h
index 0705492..a560fe8 100644
--- a/generic/tclInt.h
+++ b/generic/tclInt.h
@@ -2573,6 +2573,8 @@ MODULE_SCOPE void	TclContinuationsEnterDerived(Tcl_Obj *objPtr,
 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,
@@ -2659,6 +2661,7 @@ 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,
diff --git a/generic/tclListObj.c b/generic/tclListObj.c
index 3b9dce6..d3465b0 100644
--- a/generic/tclListObj.c
+++ b/generic/tclListObj.c
@@ -1765,13 +1765,7 @@ SetListFromAny(
      * elements by counting the number of space characters in the list.
      */
 
-    limit = string + length;
-    estCount = 1;
-    for (p = string;  p < limit;  p++) {
-	if (isspace(UCHAR(*p))) { /* INTL: ISO space. */
-	    estCount++;
-	}
-    }
+    estCount = TclCountSpaceRuns(string, length, &limit) + 1;
 
     /*
      * Allocate a new List structure with enough room for "estCount" elements.
diff --git a/generic/tclParse.c b/generic/tclParse.c
index 94d9c50..4e1e8b0 100644
--- a/generic/tclParse.c
+++ b/generic/tclParse.c
@@ -610,6 +610,30 @@ Tcl_ParseCommand(
 /*
  *----------------------------------------------------------------------
  *
+ * 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
@@ -1758,7 +1782,7 @@ Tcl_ParseBraces(
 		openBrace = 0;
 		break;
 	    case '#' :
-		if (openBrace && isspace(UCHAR(src[-1]))) {
+		if (openBrace && TclIsSpaceProc(src[-1])) {
 		    Tcl_AppendResult(parsePtr->interp,
 			    ": possible unbalanced brace in comment", NULL);
 		    goto error;
diff --git a/generic/tclStrToD.c b/generic/tclStrToD.c
index 139b8f2..e8b7538 100755
--- a/generic/tclStrToD.c
+++ b/generic/tclStrToD.c
@@ -536,7 +536,7 @@ TclParseNumber(
 	     * I, N, and whitespace.
 	     */
 
-	    if (isspace(UCHAR(c))) {
+	    if (TclIsSpaceProc(c)) {
 		if (flags & TCL_PARSE_NO_WHITESPACE) {
 		    goto endgame;
 		}
@@ -1050,7 +1050,7 @@ TclParseNumber(
 	    }
 	    /* FALLTHROUGH */
 	case sNANPAREN:
-	    if (isspace(UCHAR(c))) {
+	    if (TclIsSpaceProc(c)) {
 		break;
 	    }
 	    if (numSigDigs < 13) {
@@ -1101,7 +1101,7 @@ TclParseNumber(
 	     * Accept trailing whitespace.
 	     */
 
-	    while (len != 0 && isspace(UCHAR(*p))) {
+	    while (len != 0 && TclIsSpaceProc(*p)) {
 		p++;
 		len--;
 	    }
diff --git a/generic/tclUtil.c b/generic/tclUtil.c
index b3e1e08..4a7f79f 100644
--- a/generic/tclUtil.c
+++ b/generic/tclUtil.c
@@ -89,6 +89,58 @@ Tcl_ObjType tclEndOffsetType = {
 /*
  *----------------------------------------------------------------------
  *
+ * 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
@@ -155,7 +207,7 @@ TclFindElement(
      */
 
     limit = (list + listLength);
-    while ((p < limit) && (isspace(UCHAR(*p)))) { /* INTL: ISO space. */
+    while ((p < limit) && (TclIsSpaceProc(*p))) {
 	p++;
     }
     if (p == limit) {		/* no element found */
@@ -203,8 +255,7 @@ TclFindElement(
 	    } else if (openBraces == 1) {
 		size = (p - elemStart);
 		p++;
-		if ((p >= limit)
-			|| isspace(UCHAR(*p))) {	/* INTL: ISO space. */
+		if ((p >= limit) || TclIsSpaceProc(*p)) {
 		    goto done;
 		}
 
@@ -214,8 +265,7 @@ TclFindElement(
 
 		if (interp != NULL) {
 		    p2 = p;
-		    while ((p2 < limit)
-			    && (!isspace(UCHAR(*p2)))	/* INTL: ISO space. */
+		    while ((p2 < limit) && (!TclIsSpaceProc(*p2))
 			    && (p2 < p+20)) {
 			p2++;
 		    }
@@ -262,8 +312,7 @@ TclFindElement(
 	    if (inQuotes) {
 		size = (p - elemStart);
 		p++;
-		if ((p >= limit)
-			|| isspace(UCHAR(*p))) {	/* INTL: ISO space */
+		if ((p >= limit) || TclIsSpaceProc(*p)) {
 		    goto done;
 		}
 
@@ -273,8 +322,7 @@ TclFindElement(
 
 		if (interp != NULL) {
 		    p2 = p;
-		    while ((p2 < limit)
-			    && (!isspace(UCHAR(*p2)))	/* INTL: ISO space */
+		    while ((p2 < limit) && (!TclIsSpaceProc(*p2))
 			    && (p2 < p+20)) {
 			p2++;
 		    }
@@ -311,7 +359,7 @@ TclFindElement(
     }
 
   done:
-    while ((p < limit) && (isspace(UCHAR(*p)))) { /* INTL: ISO space. */
+    while ((p < limit) && (TclIsSpaceProc(*p))) {
 	p++;
     }
     *elementPtr = elemStart;
@@ -409,7 +457,7 @@ Tcl_SplitList(
     CONST char ***argvPtr)	/* Pointer to place to store pointer to array
 				 * of pointers to list elements. */
 {
-    CONST char **argv, *l, *element;
+    CONST char **argv, *end, *element;
     char *p;
     int length, size, i, result, elSize, brace;
 
@@ -420,29 +468,8 @@ Tcl_SplitList(
      * the list.
      */
 
-    for (size = 2, l = list; *l != 0; l++) {
-	if (isspace(UCHAR(*l))) {			/* INTL: ISO space. */
-	    size++;
-
-	    /*
-	     * Consecutive space can only count as a single list delimiter.
-	     */
-
-	    while (1) {
-		char next = *(l + 1);
-
-		if (next == '\0') {
-		    break;
-		}
-		++l;
-		if (isspace(UCHAR(next))) {		/* INTL: ISO space. */
-		    continue;
-		}
-		break;
-	    }
-	}
-    }
-    length = l - list;
+    size = TclCountSpaceRuns(list, -1, &end) + 2;
+    length = end - list;
     argv = (CONST char **) ckalloc((unsigned)
 	    ((size * sizeof(char *)) + length + 1));
     for (i = 0, p = ((char *) argv) + size*sizeof(char *);
-- 
cgit v0.12

