From 40f784e5dd093138e64826cec42bd23e0f842f78 Mon Sep 17 00:00:00 2001 From: vincentdarley Date: Tue, 17 Jun 2003 20:36:19 +0000 Subject: regsub empty string fixes, and windows build --- ChangeLog | 9 +++++++++ generic/tclCmdMZ.c | 22 ++++++++++++++++------ tests/regexp.test | 42 +++++++++++++++++++++++++++++++++++++++++- win/makefile.vc | 22 +++++++++++----------- 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 + + * 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 * 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 -- cgit v0.12