From 7bbd96eb48a07e2e5013f1a4d8dcaf941f10d754 Mon Sep 17 00:00:00 2001 From: Paul Ackersviller Date: Tue, 8 May 2007 03:40:00 +0000 Subject: Merge of workers/{21518,21552,21579,21581}. --- Src/builtin.c | 122 ++++++++++++++++++++++++++++++++++++---------------------- 1 file changed, 76 insertions(+), 46 deletions(-) (limited to 'Src') 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 */ -- cgit 1.4.1