about summary refs log tree commit diff
path: root/Src
diff options
context:
space:
mode:
authorPaul Ackersviller <packersv@users.sourceforge.net>2007-05-08 03:40:00 +0000
committerPaul Ackersviller <packersv@users.sourceforge.net>2007-05-08 03:40:00 +0000
commit7bbd96eb48a07e2e5013f1a4d8dcaf941f10d754 (patch)
tree747dbcb7ad662d3d9994539aa7f03e6696fbff8e /Src
parent7e0230709af3ecb75b30ecd1905300f160dc0e92 (diff)
downloadzsh-7bbd96eb48a07e2e5013f1a4d8dcaf941f10d754.tar.gz
zsh-7bbd96eb48a07e2e5013f1a4d8dcaf941f10d754.tar.xz
zsh-7bbd96eb48a07e2e5013f1a4d8dcaf941f10d754.zip
Merge of workers/{21518,21552,21579,21581}.
Diffstat (limited to 'Src')
-rw-r--r--Src/builtin.c122
1 files changed, 76 insertions, 46 deletions
diff --git a/Src/builtin.c b/Src/builtin.c
index cf0a1da85..c0ad11170 100644
--- a/Src/builtin.c
+++ b/Src/builtin.c
@@ -57,7 +57,7 @@ static struct builtin builtins[] =
     BUILTIN("dirs", 0, bin_dirs, 0, -1, 0, "clpv", NULL),
     BUILTIN("disable", 0, bin_enable, 0, -1, BIN_DISABLE, "afmrs", NULL),
     BUILTIN("disown", 0, bin_fg, 0, -1, BIN_DISOWN, NULL, NULL),
-    BUILTIN("echo", BINF_PRINTOPTS | BINF_SKIPINVALID, bin_print, 0, -1, BIN_ECHO, "neE", "-"),
+    BUILTIN("echo", BINF_SKIPINVALID, bin_print, 0, -1, BIN_ECHO, "neE", "-"),
     BUILTIN("emulate", 0, bin_emulate, 1, 1, 0, "LR", NULL),
     BUILTIN("enable", 0, bin_enable, 0, -1, BIN_ENABLE, "afmrs", NULL),
     BUILTIN("eval", BINF_PSPECIAL, bin_eval, 0, -1, BIN_EVAL, NULL, NULL),
@@ -102,7 +102,7 @@ static struct builtin builtins[] =
     BUILTIN("print", BINF_PRINTOPTS, bin_print, 0, -1, BIN_PRINT, "abcC:Df:ilmnNoOpPrRsu:z-", NULL),
     BUILTIN("printf", 0, bin_print, 1, -1, BIN_PRINTF, NULL, NULL),
     BUILTIN("pushd", BINF_SKIPINVALID | BINF_SKIPDASH | BINF_DASHDASHVALID, bin_cd, 0, 2, BIN_PUSHD, "sPL", NULL),
-    BUILTIN("pushln", BINF_PRINTOPTS, bin_print, 0, -1, BIN_PRINT, NULL, "-nz"),
+    BUILTIN("pushln", 0, bin_print, 0, -1, BIN_PRINT, NULL, "-nz"),
     BUILTIN("pwd", 0, bin_pwd, 0, 0, 0, "rLP", NULL),
     BUILTIN("r", 0, bin_fc, 0, -1, BIN_R, "nrl", NULL),
     BUILTIN("read", 0, bin_read, 0, -1, 0, "cd:ek:%lnpqrst:%zu:AE", NULL),
@@ -3285,11 +3285,11 @@ mod_export LinkList bufstack;
 int
 bin_print(char *name, char **args, Options ops, int func)
 {
-    int flen, width, prec, type, argc, n, narg;
-    int nnl = 0, ret = 0, maxarg = 0;
+    int flen, width, prec, type, argc, n, narg, curlen = 0;
+    int nnl = 0, fmttrunc = 0, ret = 0, maxarg = 0;
     int flags[5], *len;
     char *start, *endptr, *c, *d, *flag, *buf, spec[13], *fmt = NULL;
-    char **first, *curarg, *flagch = "0+- #", save = '\0', nullstr = '\0';
+    char **first, **argp, *curarg, *flagch = "0+- #", save = '\0', nullstr = '\0';
     size_t rcount, count = 0;
 #ifdef HAVE_OPEN_MEMSTREAM
     size_t mcount;
@@ -3315,7 +3315,7 @@ bin_print(char *name, char **args, Options ops, int func)
     else if (OPT_HASARG(ops,'f'))
 	fmt = OPT_ARG(ops,'f');
     if (fmt)
-	fmt = getkeystring(fmt, &flen, OPT_ISSET(ops,'b') ? 2 : 0, &nnl);
+	fmt = getkeystring(fmt, &flen, OPT_ISSET(ops,'b') ? 2 : 0, &fmttrunc);
 
     first = args;
     
@@ -3332,7 +3332,7 @@ bin_print(char *name, char **args, Options ops, int func)
 	tokenize(*args);
 	if (!(pprog = patcompile(*args, PAT_STATIC, NULL))) {
 	    untokenize(*args);
-	    zwarnnam(name, "bad pattern : %s", *args, 0);
+	    zwarnnam(name, "bad pattern: %s", *args, 0);
 	    return 1;
 	}
 	for (t = p = ++args; *p; p++)
@@ -3351,10 +3351,16 @@ bin_print(char *name, char **args, Options ops, int func)
 	    (!OPT_ISSET(ops,'e') && 
 	     (OPT_ISSET(ops,'R') || OPT_ISSET(ops,'r') || OPT_ISSET(ops,'E'))))
 	    unmetafy(args[n], &len[n]);
-	else
+	else {
 	    args[n] = getkeystring(args[n], &len[n], OPT_ISSET(ops,'b') ? 2 :
 				   (func != BIN_ECHO && !OPT_ISSET(ops,'e')),
 				   &nnl);
+	    if (nnl) {
+		/* If there was a \c escape, make this the last arg. */
+		argc = n + 1;
+		args[argc] = NULL;
+	    }
+	}
 	/* -P option -- interpret as a prompt sequence */
 	if(OPT_ISSET(ops,'P')) {
 	    /*
@@ -3436,7 +3442,7 @@ bin_print(char *name, char **args, Options ops, int func)
 	    len[n] = strlen(args[n]);
 
     /* -c -- output in columns */
-    if (OPT_ISSET(ops,'c') || OPT_ISSET(ops,'C')) {
+    if (!fmt && (OPT_ISSET(ops,'c') || OPT_ISSET(ops,'C'))) {
 	int l, nc, nr, sc, n, t, i;
 	char **ap;
 
@@ -3524,7 +3530,7 @@ bin_print(char *name, char **args, Options ops, int func)
 		    l = strlen(*ap);
 		    fprintf(fout, "%s", *ap);
 		    for (t = nr; t && *ap; t--, ap++);
-		    if(*ap)
+		    if (*ap)
 			for (; l < sc; l++)
 			    fputc(' ', fout);
 		} while (*ap);
@@ -3609,7 +3615,8 @@ bin_print(char *name, char **args, Options ops, int func)
     } 
     
     /* printf style output */
-    *spec='%';
+    *spec = '%';
+    argp = args;
     do {
     	rcount = count;
     	if (maxarg) {
@@ -3617,7 +3624,7 @@ bin_print(char *name, char **args, Options ops, int func)
 	    argc -= maxarg;
     	    maxarg = 0;
 	}
-	for (c = fmt;c-fmt < flen;c++) {
+	for (c = fmt; c-fmt < flen; c++) {
 	    if (*c != '%') {
 		putc(*c, fout);
 		++count;
@@ -3626,7 +3633,7 @@ bin_print(char *name, char **args, Options ops, int func)
 
 	    start = c++;
 	    if (*c == '%') {
-		putchar('%');
+		putc('%', fout);
 		++count;
 		continue;
 	    }
@@ -3644,14 +3651,16 @@ bin_print(char *name, char **args, Options ops, int func)
 		    if (narg > argc) {
 		    	zwarnnam(name, "%d: argument specifier out of range",
 				 0, narg);
+			if (fout != stdout)
+			    fclose(fout);
 			return 1;
 		    } else {
 		    	if (narg > maxarg) maxarg = narg;
 		    	curarg = *(first + narg - 1);
+			curlen = len[first - args + narg - 1];
 		    }
 		}
 	    }
-		    
 	    
 	    /* copy only one of each flag as spec has finite size */
 	    memset(flags, 0, sizeof(flags));
@@ -3675,15 +3684,17 @@ bin_print(char *name, char **args, Options ops, int func)
 		    	    zwarnnam(name,
 				     "%d: argument specifier out of range",
 				     0, narg);
+			    if (fout != stdout)
+				fclose(fout);
 			    return 1;
 			} else {
 		    	    if (narg > maxarg) maxarg = narg;
-		    	    args = first + narg - 1;
+		    	    argp = first + narg - 1;
 			}
 		    }
 		}
-		if (*args) {
-		    width = (int)mathevali(*args++);
+		if (*argp) {
+		    width = (int)mathevali(*argp++);
 		    if (errflag) {
 			errflag = 0;
 			ret = 1;
@@ -3702,16 +3713,18 @@ bin_print(char *name, char **args, Options ops, int func)
 		    		zwarnnam(name,
 					 "%d: argument specifier out of range",
 					 0, narg);
+				if (fout != stdout)
+				    fclose(fout);
 				return 1;
 			    } else {
 		    		if (narg > maxarg) maxarg = narg;
-		    		args = first + narg - 1;
+		    		argp = first + narg - 1;
 			    }
 			}
 		    }
 		    
-		    if (*args) {
-			prec = (int)mathevali(*args++);
+		    if (*argp) {
+			prec = (int)mathevali(*argp++);
 			if (errflag) {
 			    errflag = 0;
 			    ret = 1;
@@ -3727,36 +3740,47 @@ bin_print(char *name, char **args, Options ops, int func)
 	    /* ignore any size modifier */
 	    if (*c == 'l' || *c == 'L' || *c == 'h') c++;
 
-	    if (!curarg && *args) curarg = *args++;
+	    if (!curarg && *argp) {
+		curarg = *argp;
+		curlen = len[argp++ - args];
+	    }
 	    d[1] = '\0';
 	    switch (*d = *c) {
 	    case 'c':
-		if (curarg) {
+		if (curarg)
 		    intval = *curarg;
-		} else
+		else
 		    intval = 0;
 		print_val(intval);
 		break;
 	    case 's':
-		stringval = curarg ? curarg : &nullstr;
-		print_val(stringval);
-		break;
 	    case 'b':
 		if (curarg) {
+		    char *b;
 		    int l;
-		    char *b = getkeystring(curarg, &l, 
-					   OPT_ISSET(ops,'b') ? 2 : 0, &nnl);
+		    if (*c == 'b') {
+			b = getkeystring(metafy(curarg, curlen, META_USEHEAP), &l,
+					 OPT_ISSET(ops,'b') ? 2 : 0, &nnl);
+		    } else {
+			b = curarg;
+			l = curlen;
+		    }
 		    /* 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);
+		    	count += fprintf(fout, "%*c", width - l, ' ');
+		    count += fwrite(b, 1, l, fout);
 		    if (width < 0 && l < -width)
-		    	printf("%*c", -width - l, ' ');
-		    count += l;
-		}
+		    	count += fprintf(fout, "%*c", -width - l, ' ');
+		    if (nnl) {
+			/* If the %b arg had a \c escape, truncate the fmt. */
+			flen = c - fmt + 1;
+			fmttrunc = 1;
+		    }
+		} else if (width)
+		    count += fprintf(fout, "%*c", width, ' ');
 		break;
 	    case 'q':
 		stringval = curarg ? bslashquote(curarg, NULL, 0) : &nullstr;
@@ -3801,10 +3825,10 @@ bin_print(char *name, char **args, Options ops, int func)
 	    if (type > 0) {
 		if (curarg && (*curarg == '\'' || *curarg == '"' )) {
 		    if (type == 2) {
-			doubleval = (unsigned char)curarg[1];
+			doubleval = STOUC(curarg[1]);
 			print_val(doubleval);
 		    } else {
-			intval = (unsigned char)curarg[1];
+			intval = STOUC(curarg[1]);
 			print_val(intval);
 		    }
 		} else {
@@ -3847,22 +3871,21 @@ bin_print(char *name, char **args, Options ops, int func)
 			    ret = 1;
 			}
 			print_val(zulongval)
-			    }
+		    }
 		}
 	    }
-	    if (maxarg && (args - first > maxarg))
-	    	maxarg = args - first;
+	    if (maxarg && (argp - first > maxarg))
+	    	maxarg = argp - first;
 	}
 
-    	if (maxarg) args = first + maxarg;
+    	if (maxarg) argp = first + maxarg;
 	/* if there are remaining args, reuse format string */
-    } while (*args && args != first && !OPT_ISSET(ops,'r'));
+    } while (*argp && argp != first && !fmttrunc && !OPT_ISSET(ops,'r'));
 
     if (OPT_ISSET(ops,'z') || OPT_ISSET(ops,'s')) {
 #ifdef HAVE_OPEN_MEMSTREAM
 	putc(0, fout);
 	fflush(fout);
-	count = mcount;
 #else
 	rewind(fout);
 	buf = (char *)zalloc(count + 1);
@@ -5002,13 +5025,20 @@ bin_trap(char *name, char **argv, UNUSED(Options ops), UNUSED(int func))
     /* If we have a signal number, unset the specified *
      * signals.  With only -, remove all traps.        */
     if ((getsignum(*argv) != -1) || (!strcmp(*argv, "-") && argv++)) {
-	if (!*argv)
+	if (!*argv) {
 	    for (sig = 0; sig < VSIGCOUNT; sig++)
 		unsettrap(sig);
-	else
-	    while (*argv)
-		unsettrap(getsignum(*argv++));
-	return 0;
+	} else {
+	    for (; *argv; argv++) {
+		sig = getsignum(*argv);
+		if (sig == -1) {
+		    zwarnnam(name, "undefined signal: %s", *argv, 0);
+		    break;
+		}
+		unsettrap(sig);
+	    }
+	}
+	return *argv != NULL;
     }
 
     /* Sort out the command to execute on trap */