summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorvincentdarley <vincentdarley>2003-06-17 20:36:19 (GMT)
committervincentdarley <vincentdarley>2003-06-17 20:36:19 (GMT)
commit40f784e5dd093138e64826cec42bd23e0f842f78 (patch)
tree98079f2944e00af30b4417532b30ad4cecc4a4f3
parent1268ac3113dd4f5b5627c98afd15addcf608875a (diff)
downloadtcl-40f784e5dd093138e64826cec42bd23e0f842f78.zip
tcl-40f784e5dd093138e64826cec42bd23e0f842f78.tar.gz
tcl-40f784e5dd093138e64826cec42bd23e0f842f78.tar.bz2
regsub empty string fixes, and windows build
-rw-r--r--ChangeLog9
-rw-r--r--generic/tclCmdMZ.c22
-rw-r--r--tests/regexp.test42
-rw-r--r--win/makefile.vc22
4 files changed, 77 insertions, 18 deletions
diff --git a/ChangeLog b/ChangeLog
index 0b5ea23..71de974 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,12 @@
+2003-06-17 Vince Darley <vincentdarley@users.sourceforge.net>
+
+ * win/makefile.vc: fixes to check-in below so compilation now
+ works again on Windows.
+
+ * generic/tclCmdMZ.c:
+ * tests/regexp.test: fixing of bugs related to regexp and regsub
+ matching of empty strings. Addition of a number of new tests.
+
2003-06-16 Andreas Kupries <andreask@activestate.com>
* win/Makefile.in: Haven't heard back from David for a week.
diff --git a/generic/tclCmdMZ.c b/generic/tclCmdMZ.c
index 6a2915f..48d8e75 100644
--- a/generic/tclCmdMZ.c
+++ b/generic/tclCmdMZ.c
@@ -14,7 +14,7 @@
* See the file "license.terms" for information on usage and redistribution
* of this file, and for a DISCLAIMER OF ALL WARRANTIES.
*
- * RCS: @(#) $Id: tclCmdMZ.c,v 1.90 2003/05/10 23:54:37 hobbs Exp $
+ * RCS: @(#) $Id: tclCmdMZ.c,v 1.91 2003/06/17 20:36:20 vincentdarley Exp $
*/
#include "tclInt.h"
@@ -368,7 +368,10 @@ Tcl_RegexpObjCmd(dummy, interp, objc, objv)
while (1) {
match = Tcl_RegExpExecObj(interp, regExpr, objPtr,
- offset /* offset */, numMatchesSaved, eflags);
+ offset /* offset */, numMatchesSaved, eflags
+ | ((offset > 0 &&
+ (Tcl_GetUniChar(objPtr,offset-1) != (Tcl_UniChar)'\n'))
+ ? TCL_REG_NOTBOL : 0));
if (match < 0) {
return TCL_ERROR;
@@ -719,11 +722,14 @@ Tcl_RegsubObjCmd(dummy, interp, objc, objv)
* The following loop is to handle multiple matches within the
* same source string; each iteration handles one match and its
* corresponding substitution. If "-all" hasn't been specified
- * then the loop body only gets executed once.
+ * then the loop body only gets executed once. We must use
+ * 'offset <= wlen' in particular for the case where the regexp
+ * pattern can match the empty string - this is useful when
+ * doing, say, 'regsub -- ^ $str ...' when $str might be empty.
*/
numMatches = 0;
- for ( ; offset < wlen; ) {
+ for ( ; offset <= wlen; ) {
/*
* The flags argument is set if string is part of a larger string,
@@ -731,7 +737,9 @@ Tcl_RegsubObjCmd(dummy, interp, objc, objv)
*/
match = Tcl_RegExpExecObj(interp, regExpr, objPtr, offset,
- 10 /* matches */, ((offset > 0) ? TCL_REG_NOTBOL : 0));
+ 10 /* matches */, ((offset > 0 &&
+ (Tcl_GetUniChar(objPtr,offset-1) != (Tcl_UniChar)'\n'))
+ ? TCL_REG_NOTBOL : 0));
if (match < 0) {
result = TCL_ERROR;
@@ -819,7 +827,9 @@ Tcl_RegsubObjCmd(dummy, interp, objc, objv)
* in order to prevent infinite loops.
*/
- Tcl_AppendUnicodeToObj(resultPtr, wstring + offset, 1);
+ if (offset < wlen) {
+ Tcl_AppendUnicodeToObj(resultPtr, wstring + offset, 1);
+ }
offset++;
} else {
offset += end;
diff --git a/tests/regexp.test b/tests/regexp.test
index 2bb017e..e5b2bd8 100644
--- a/tests/regexp.test
+++ b/tests/regexp.test
@@ -11,7 +11,7 @@
# See the file "license.terms" for information on usage and redistribution
# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
#
-# RCS: @(#) $Id: regexp.test,v 1.22 2002/07/10 11:56:44 dgp Exp $
+# RCS: @(#) $Id: regexp.test,v 1.23 2003/06/17 20:36:20 vincentdarley Exp $
if {[lsearch [namespace children] ::tcltest] == -1} {
package require tcltest
@@ -572,6 +572,46 @@ test regexp-20.2 {regsub shared object shimmering with -about} {
eval regexp -about abc
} {0 {}}
+test regexp-21.1 {regsub works with empty string} {
+ regsub -- ^ {} foo
+} {foo}
+
+test regexp-21.2 {regsub works with empty string} {
+ regsub -- \$ {} foo
+} {foo}
+
+test regexp-21.3 {regsub works with empty string offset} {
+ regsub -start 0 -- ^ {} foo
+} {foo}
+
+test regexp-21.4 {regsub works with empty string offset} {
+ regsub -start 0 -- \$ {} foo
+} {foo}
+
+test regexp-21.5 {regsub works with empty string offset} {
+ regsub -start 3 -- \$ {123} foo
+} {123foo}
+
+test regexp-21.6 {regexp works with empty string} {
+ regexp -- ^ {}
+} {1}
+
+test regexp-21.7 {regexp works with empty string} {
+ regexp -start 0 -- ^ {}
+} {1}
+
+test regexp-21.8 {regexp works with empty string offset} {
+ regexp -start 3 -- ^ {123}
+} {0}
+
+test regexp-21.9 {regexp works with empty string offset} {
+ regexp -start 3 -- \$ {123}
+} {1}
+
+test regexp-21.10 {multiple matches handle newlines} {
+ regsub -all -lineanchor -- {^#[^\n]*\n} "#one\n#two\n#three\n" foo\n
+} "foo\nfoo\nfoo\n"
+
# cleanup
::tcltest::cleanupTests
return
diff --git a/win/makefile.vc b/win/makefile.vc
index b71344f..9d2d6a3 100644
--- a/win/makefile.vc
+++ b/win/makefile.vc
@@ -12,7 +12,7 @@
# Copyright (c) 2001-2002 David Gravereaux.
#
#------------------------------------------------------------------------------
-# RCS: @(#) $Id: makefile.vc,v 1.108 2003/06/16 18:36:45 andreas_kupries Exp $
+# RCS: @(#) $Id: makefile.vc,v 1.109 2003/06/17 20:36:20 vincentdarley Exp $
#------------------------------------------------------------------------------
!if "$(MSVCDIR)" == ""
@@ -623,16 +623,16 @@ $(TMP_DIR)\tclWinTest.obj: $(WINDIR)\tclWinTest.c
$(TMP_DIR)\tclPkgConfig.obj: $(GENERICDIR)\tclPkgConfig.c
$(cc32) -DBUILD_tcl $(TCL_CFLAGS) \
- -DCFG_INSTALL_LIBDIR=\"$(LIB_INSTALL_DIR)\" \
- -DCFG_INSTALL_BINDIR=\"$(BIN_INSTALL_DIR)\" \
- -DCFG_INSTALL_SCRDIR=\"$(SCRIPT_INSTALL_DIR)\" \
- -DCFG_INSTALL_INCDIR=\"$(INCLUDE_INSTALL_DIR)\" \
- -DCFG_INSTALL_DOCDIR=\"$(DOC_INSTALL_DIR)\" \
- -DCFG_RUNTIME_LIBDIR=\"$(LIB_INSTALL_DIR)\" \
- -DCFG_RUNTIME_BINDIR=\"$(BIN_INSTALL_DIR)\" \
- -DCFG_RUNTIME_SCRDIR=\"$(SCRIPT_INSTALL_DIR)\" \
- -DCFG_RUNTIME_INCDIR=\"$(INCLUDE_INSTALL_DIR)\" \
- -DCFG_RUNTIME_DOCDIR=\"$(DOC_INSTALL_DIR)\" \
+ -DCFG_INSTALL_LIBDIR="\"$(LIB_INSTALL_DIR:\=\\)\"" \
+ -DCFG_INSTALL_BINDIR="\"$(BIN_INSTALL_DIR:\=\\)\"" \
+ -DCFG_INSTALL_SCRDIR="\"$(SCRIPT_INSTALL_DIR:\=\\)\"" \
+ -DCFG_INSTALL_INCDIR="\"$(INCLUDE_INSTALL_DIR:\=\\)\"" \
+ -DCFG_INSTALL_DOCDIR="\"$(DOC_INSTALL_DIR:\=\\)\"" \
+ -DCFG_RUNTIME_LIBDIR="\"$(LIB_INSTALL_DIR:\=\\)\"" \
+ -DCFG_RUNTIME_BINDIR="\"$(BIN_INSTALL_DIR:\=\\)\"" \
+ -DCFG_RUNTIME_SCRDIR="\"$(SCRIPT_INSTALL_DIR:\=\\)\"" \
+ -DCFG_RUNTIME_INCDIR="\"$(INCLUDE_INSTALL_DIR:\=\\)\"" \
+ -DCFG_RUNTIME_DOCDIR="\"$(DOC_INSTALL_DIR:\=\\)\"" \
-Fo$@ $?
$(TMP_DIR)\tclAppInit.obj: $(WINDIR)\tclAppInit.c