about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog6
-rw-r--r--Doc/Zsh/expn.yo14
-rw-r--r--Src/glob.c2
-rw-r--r--Src/subst.c31
-rw-r--r--Test/D04parameter.ztst5
-rw-r--r--Test/D07multibyte.ztst4
6 files changed, 44 insertions, 18 deletions
diff --git a/ChangeLog b/ChangeLog
index e63166c0a..b62b4dcae 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,9 @@
+2006-11-07  Peter Stephenson  <p.w.stephenson@ntlworld.com>
+
+	* 22980: Doc/Zsh/expn.yo, Src/subst.c, Test/D04paramater.ztst,
+	Test/D07multibyte.ztst: 22952 messed up optional arguments
+	to padding parameter flags.
+
 2006-11-07  Peter Stephenson  <pws@csr.com>
 
 	* 22973: arno: Completion/Unix/Command/_zip: .xpi files are
diff --git a/Doc/Zsh/expn.yo b/Doc/Zsh/expn.yo
index 584977c18..4095dab2b 100644
--- a/Doc/Zsh/expn.yo
+++ b/Doc/Zsh/expn.yo
@@ -899,11 +899,15 @@ flag or the tt(SH_WORD_SPLIT) option.
 )
 item(tt(l:)var(expr)tt(::)var(string1)tt(::)var(string2)tt(:))(
 Pad the resulting words on the left.  Each word will be truncated if
-required and placed in a field var(expr) characters wide.  The space
-to the left will be filled with var(string1) (concatenated as often
-as needed) or spaces if var(string1) is not given.  If both
-var(string1) and var(string2) are given, tt(string2) is inserted
-once directly to the left of each word, truncated if necessary, before
+required and placed in a field var(expr) characters wide.
+
+The arguments tt(:)var(string1)tt(:) and tt(:)var(string2)tt(:) are
+optional; neither, the first, or both may be given.  Note that the same
+pairs of delimiters must be used for each of the three arguments.  The
+space to the left will be filled with var(string1) (concatenated as
+often as needed) or spaces if var(string1) is not given.  If both
+var(string1) and var(string2) are given, tt(string2) is inserted once
+directly to the left of each word, truncated if necessary, before
 var(string1) is used to produce any remaining padding.
 
 If the tt(MULTIBYTE) option is in effect, the flag tt(m) may also
diff --git a/Src/glob.c b/Src/glob.c
index 394e91d01..aa0ce1ac4 100644
--- a/Src/glob.c
+++ b/Src/glob.c
@@ -1246,7 +1246,7 @@ zglob(LinkList list, LinkNode np, int nountok)
 			int arglen;
 
 			/* Find matching delimiters */
-			tt = get_strarg(s, &arglen);
+			tt = get_strarg(s, &arglen, NULL);
 			if (!*tt) {
 			    zerr("missing end of name");
 			    data = 0;
diff --git a/Src/subst.c b/Src/subst.c
index 3a5b9b353..06e16c183 100644
--- a/Src/subst.c
+++ b/Src/subst.c
@@ -1224,8 +1224,9 @@ get_strarg(char *s, int *lenp)
 
 /*
  * Get an integer argument; update *s to the end of the
- * final delimiter.  *delmatchp is set to 1 if we have matching
- * delimiters and there was no error in the evaluation, else 0.
+ * final delimiter.  *delmatchp is set to the length of the
+ * matched delimiter if we have matching, delimiters and there was no error in
+ * the evaluation, else 0.
  */
 
 /**/
@@ -1255,7 +1256,7 @@ get_intarg(char **s, int *delmatchp)
 	return -1;
     if (ret < 0)
 	ret = -ret;
-    *delmatchp = 1;
+    *delmatchp = arglen;
     return ret < 0 ? -ret : ret;
 }
 
@@ -1602,7 +1603,8 @@ paramsubst(LinkList l, LinkNode n, char **str, int qt, int ssub)
 
 	    for (s++; (c = *s) != ')' && c != Outpar; s++, tt = 0) {
 		int arglen;	/* length of modifier argument */
-		int delmatch;	/* integer delimiters matched OK */
+		int dellen;	/* length of matched delimiter, 0 if not */
+		char *del0;	/* pointer to initial delimiter */
 
 		switch (c) {
 		case ')':
@@ -1634,7 +1636,7 @@ paramsubst(LinkList l, LinkNode n, char **str, int qt, int ssub)
 		    break;
 		case 'I':
 		    s++;
-		    flnum = get_intarg(&s, &delmatch);
+		    flnum = get_intarg(&s, &dellen);
 		    if (flnum < 0)
 			goto flagerr;
 		    s--;
@@ -1734,15 +1736,21 @@ paramsubst(LinkList l, LinkNode n, char **str, int qt, int ssub)
 		/* fall through */
 		case 'r':
 		    s++;
-		    num = get_intarg(&s, &delmatch);
+		    /* delimiter position */
+		    del0 = s;
+		    num = get_intarg(&s, &dellen);
 		    if (num < 0)
 			goto flagerr;
 		    if (tt)
 			prenum = num;
 		    else
 			postnum = num;
-		    if (!delmatch)
+		    /* must have same delimiter if more arguments */
+		    if (!dellen || memcmp(del0, s, dellen)) {
+			/* decrement since loop will increment */
+			s--;
 			break;
+		    }
 		    t = get_strarg(s, &arglen);
 		    if (!*t)
 			goto flagerr;
@@ -1755,7 +1763,9 @@ paramsubst(LinkList l, LinkNode n, char **str, int qt, int ssub)
 		    *t = sav;
 		    sav = *s;
 		    s = t + arglen;
-		    if (UNTOK(*s) != UNTOK(sav)) {
+		    /* again, continue only if another start delimiter */
+		    if (memcmp(del0, s, dellen)) {
+			/* decrement since loop will increment */
 			s--;
 			break;
 		    }
@@ -1769,6 +1779,7 @@ paramsubst(LinkList l, LinkNode n, char **str, int qt, int ssub)
 		    else
 			UNTOK_AND_ESCAPE(postone, s + arglen)
 		    *t = sav;
+		    /* -1 since loop will increment */
 		    s = t + arglen - 1;
 		    break;
 
@@ -3310,7 +3321,7 @@ modify(char **str, char **ptr)
 {
     char *ptr1, *ptr2, *ptr3, *lptr, c, *test, *sep, *t, *tt, tc, *e;
     char *copy, *all, *tmp, sav, sav1, *ptr1end;
-    int gbal, wall, rec, al, nl, charlen, delmatch;
+    int gbal, wall, rec, al, nl, charlen, dellen;
     convchar_t del;
 
     test = NULL;
@@ -3436,7 +3447,7 @@ modify(char **str, char **ptr)
 		break;
 	    case 'F':
 		(*ptr)++;
-		rec = get_intarg(ptr, &delmatch);
+		rec = get_intarg(ptr, &dellen);
 		break;
 	    default:
 		*ptr = lptr;
diff --git a/Test/D04parameter.ztst b/Test/D04parameter.ztst
index ce5898f88..a2613dc1f 100644
--- a/Test/D04parameter.ztst
+++ b/Test/D04parameter.ztst
@@ -361,6 +361,11 @@
 >val1 val2
 >key1 key2 val1 val2
 
+  word="obfuscatory"
+  print !${(l.16.)word}! +${(r.16.)word}+
+0:simple padding
+>!     obfuscatory! +obfuscatory     +
+
   foo=(resulting words uproariously padded)
   print ${(pl.10..\x22..X.)foo}
 0:${(pl...)...}
diff --git a/Test/D07multibyte.ztst b/Test/D07multibyte.ztst
index 752013eec..828a5c573 100644
--- a/Test/D07multibyte.ztst
+++ b/Test/D07multibyte.ztst
@@ -306,8 +306,8 @@
 # TODO: if we get paired multibyte bracket delimiters to work
 # (as Emacs does, the smug so-and-so), the following should change.
   foo=bar
-  print ${(r£5£¥X¥)foo}
-  print ${(l«10«»Y»£HI£)foo}
+  print ${(r£5££X£)foo}
+  print ${(l«10««Y««HI«)foo}
 0:Delimiters in parameter flags
 >barXX
 >YYYYYHIbar