about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog5
-rw-r--r--Doc/Zsh/builtins.yo7
-rw-r--r--Src/builtin.c46
3 files changed, 36 insertions, 22 deletions
diff --git a/ChangeLog b/ChangeLog
index a4604422f..9a7629cd0 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,8 @@
+2001-11-09  Oliver Kiddle  <opk@zsh.org>
+
+	* 16228: Src/builtin.c, Doc/Zsh/builtins.yo: allow widths
+	and precisions to work with printf's %b format specifier
+
 2001-11-06  Oliver Kiddle  <opk@zsh.org>
 
 	* unposted: Functions/Misc/mere: fix for IRIX
diff --git a/Doc/Zsh/builtins.yo b/Doc/Zsh/builtins.yo
index c312842c2..463bfcf53 100644
--- a/Doc/Zsh/builtins.yo
+++ b/Doc/Zsh/builtins.yo
@@ -745,9 +745,10 @@ with the normal style and the handling of such mixed styles may be subject
 to future change.
 
 If arguments remain unused after formatting, the format string is reused
-until all arguments have been consumed. If more arguments are required by
-the format than have been specified, the behaviour is as if zero or an
-empty string had been specified as the argument.
+until all arguments have been consumed. With the tt(print) builtin, this
+can be suppressed by using the tt(-r) option. If more arguments are
+required by the format than have been specified, the behaviour is as if
+zero or an empty string had been specified as the argument.
 )
 findex(pushd)
 pindex(PUSHD_TO_HOME, use of)
diff --git a/Src/builtin.c b/Src/builtin.c
index 1d8195835..0a399e068 100644
--- a/Src/builtin.c
+++ b/Src/builtin.c
@@ -2970,6 +2970,25 @@ bin_print(char *name, char **args, char *ops, int func)
 	}
     }
 
+    /* -o and -O -- sort the arguments */
+    if (ops['o']) {
+	if (fmt && !*args) return 0;
+	if (ops['i'])
+	    qsort(args, arrlen(args), sizeof(char *), cstrpcmp);
+	else
+	    qsort(args, arrlen(args), sizeof(char *), strpcmp);
+    } else if (ops['O']) {
+	if (fmt && !*args) return 0;
+	if (ops['i'])
+	    qsort(args, arrlen(args), sizeof(char *), invcstrpcmp);
+	else
+	    qsort(args, arrlen(args), sizeof(char *), invstrpcmp);
+    }
+    /* after sorting arguments, recalculate lengths */
+    if(ops['o'] || ops['O'])
+	for(n = 0; n < argc; n++)
+	    len[n] = strlen(args[n]);
+
     /* -z option -- push the arguments onto the editing buffer stack */
     if (ops['z']) {
 	queue_signals();
@@ -3028,25 +3047,6 @@ bin_print(char *name, char **args, char *ops, int func)
 	}
     }
 
-    /* -o and -O -- sort the arguments */
-    if (ops['o']) {
-	if (fmt && !*args) return 0;
-	if (ops['i'])
-	    qsort(args, arrlen(args), sizeof(char *), cstrpcmp);
-	else
-	    qsort(args, arrlen(args), sizeof(char *), strpcmp);
-    } else if (ops['O']) {
-	if (fmt && !*args) return 0;
-	if (ops['i'])
-	    qsort(args, arrlen(args), sizeof(char *), invcstrpcmp);
-	else
-	    qsort(args, arrlen(args), sizeof(char *), invstrpcmp);
-    }
-    /* after sorting arguments, recalculate lengths */
-    if(ops['o'] || ops['O'])
-	for(n = 0; n < argc; n++)
-	    len[n] = strlen(args[n]);
-
     /* -c -- output in columns */
     if (ops['c']) {
 	int l, nc, nr, sc, n, t, i;
@@ -3230,7 +3230,15 @@ bin_print(char *name, char **args, char *ops, int func)
 		if (curarg) {
 		    int l;
 		    char *b = getkeystring(curarg, &l, ops['b'] ? 2 : 0, &nnl);
+		    /* handle width/precision here and use fwrite so that
+		     * nul characters can be output */
+		    if (prec >= 0 && prec < l) l = prec;
+		    if (width > 0 && flags[2]) width = -width;
+		    if (width > 0 && l < width)
+		    	printf("%*c", width - l, ' ');
 		    fwrite(b, l, 1, fout);
+		    if (width < 0 && l < -width)
+		    	printf("%*c", -width - l, ' ');
 		    count += l;
 		}
 		break;