1
0
Fork 0
mirror of git://git.code.sf.net/p/zsh/code synced 2025-10-30 17:50:58 +01:00

21552: Thorsten Dahlheimer: various fixes to print builtin

This commit is contained in:
Peter Stephenson 2005-08-01 10:00:38 +00:00
parent 8c095a5169
commit 1f3bd88afb
2 changed files with 43 additions and 31 deletions

View file

@ -1,5 +1,8 @@
2005-08-01 Peter Stephenson <pws@csr.com> 2005-08-01 Peter Stephenson <pws@csr.com>
* 21552: Thorsten Dahlheimer: Src/builtin.c: various fixes to the
print builtin.
* unposted: Completion/Unix/Command/_perforce: add the as yet * unposted: Completion/Unix/Command/_perforce: add the as yet
undocumented "attribute" command. undocumented "attribute" command.

View file

@ -57,7 +57,7 @@ static struct builtin builtins[] =
BUILTIN("dirs", 0, bin_dirs, 0, -1, 0, "clpv", NULL), BUILTIN("dirs", 0, bin_dirs, 0, -1, 0, "clpv", NULL),
BUILTIN("disable", 0, bin_enable, 0, -1, BIN_DISABLE, "afmrs", NULL), BUILTIN("disable", 0, bin_enable, 0, -1, BIN_DISABLE, "afmrs", NULL),
BUILTIN("disown", 0, bin_fg, 0, -1, BIN_DISOWN, NULL, 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("emulate", 0, bin_emulate, 1, 1, 0, "LR", NULL),
BUILTIN("enable", 0, bin_enable, 0, -1, BIN_ENABLE, "afmrs", NULL), BUILTIN("enable", 0, bin_enable, 0, -1, BIN_ENABLE, "afmrs", NULL),
BUILTIN("eval", BINF_PSPECIAL, bin_eval, 0, -1, BIN_EVAL, NULL, 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("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("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("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("pwd", 0, bin_pwd, 0, 0, 0, "rLP", NULL),
BUILTIN("r", 0, bin_fc, 0, -1, BIN_R, "nrl", 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), BUILTIN("read", 0, bin_read, 0, -1, 0, "cd:ek:%lnpqrst:%zu:AE", NULL),
@ -3283,11 +3283,11 @@ mod_export LinkList bufstack;
int int
bin_print(char *name, char **args, Options ops, int func) bin_print(char *name, char **args, Options ops, int func)
{ {
int flen, width, prec, type, argc, n, narg; int flen, width, prec, type, argc, n, narg, curlen;
int nnl = 0, fmttrunc = 0, ret = 0, maxarg = 0; int nnl = 0, fmttrunc = 0, ret = 0, maxarg = 0;
int flags[5], *len; int flags[5], *len;
char *start, *endptr, *c, *d, *flag, *buf, spec[13], *fmt = NULL; 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; size_t rcount, count = 0;
#ifdef HAVE_OPEN_MEMSTREAM #ifdef HAVE_OPEN_MEMSTREAM
size_t mcount; size_t mcount;
@ -3330,7 +3330,7 @@ bin_print(char *name, char **args, Options ops, int func)
tokenize(*args); tokenize(*args);
if (!(pprog = patcompile(*args, PAT_STATIC, NULL))) { if (!(pprog = patcompile(*args, PAT_STATIC, NULL))) {
untokenize(*args); untokenize(*args);
zwarnnam(name, "bad pattern : %s", *args, 0); zwarnnam(name, "bad pattern: %s", *args, 0);
return 1; return 1;
} }
for (t = p = ++args; *p; p++) for (t = p = ++args; *p; p++)
@ -3440,7 +3440,7 @@ bin_print(char *name, char **args, Options ops, int func)
len[n] = strlen(args[n]); len[n] = strlen(args[n]);
/* -c -- output in columns */ /* -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; int l, nc, nr, sc, n, t, i;
char **ap; char **ap;
@ -3528,7 +3528,7 @@ bin_print(char *name, char **args, Options ops, int func)
l = strlen(*ap); l = strlen(*ap);
fprintf(fout, "%s", *ap); fprintf(fout, "%s", *ap);
for (t = nr; t && *ap; t--, ap++); for (t = nr; t && *ap; t--, ap++);
if(*ap) if (*ap)
for (; l < sc; l++) for (; l < sc; l++)
fputc(' ', fout); fputc(' ', fout);
} while (*ap); } while (*ap);
@ -3613,7 +3613,8 @@ bin_print(char *name, char **args, Options ops, int func)
} }
/* printf style output */ /* printf style output */
*spec='%'; *spec = '%';
argp = args;
do { do {
rcount = count; rcount = count;
if (maxarg) { if (maxarg) {
@ -3621,7 +3622,7 @@ bin_print(char *name, char **args, Options ops, int func)
argc -= maxarg; argc -= maxarg;
maxarg = 0; maxarg = 0;
} }
for (c = fmt;c-fmt < flen;c++) { for (c = fmt; c-fmt < flen; c++) {
if (*c != '%') { if (*c != '%') {
putc(*c, fout); putc(*c, fout);
++count; ++count;
@ -3630,7 +3631,7 @@ bin_print(char *name, char **args, Options ops, int func)
start = c++; start = c++;
if (*c == '%') { if (*c == '%') {
putchar('%'); putc('%', fout);
++count; ++count;
continue; continue;
} }
@ -3648,14 +3649,16 @@ bin_print(char *name, char **args, Options ops, int func)
if (narg > argc) { if (narg > argc) {
zwarnnam(name, "%d: argument specifier out of range", zwarnnam(name, "%d: argument specifier out of range",
0, narg); 0, narg);
if (fout != stdout)
fclose(fout);
return 1; return 1;
} else { } else {
if (narg > maxarg) maxarg = narg; if (narg > maxarg) maxarg = narg;
curarg = *(first + narg - 1); curarg = *(first + narg - 1);
curlen = len[first - args + narg - 1];
} }
} }
} }
/* copy only one of each flag as spec has finite size */ /* copy only one of each flag as spec has finite size */
memset(flags, 0, sizeof(flags)); memset(flags, 0, sizeof(flags));
@ -3679,15 +3682,17 @@ bin_print(char *name, char **args, Options ops, int func)
zwarnnam(name, zwarnnam(name,
"%d: argument specifier out of range", "%d: argument specifier out of range",
0, narg); 0, narg);
if (fout != stdout)
fclose(fout);
return 1; return 1;
} else { } else {
if (narg > maxarg) maxarg = narg; if (narg > maxarg) maxarg = narg;
args = first + narg - 1; argp = first + narg - 1;
} }
} }
} }
if (*args) { if (*argp) {
width = (int)mathevali(*args++); width = (int)mathevali(*argp++);
if (errflag) { if (errflag) {
errflag = 0; errflag = 0;
ret = 1; ret = 1;
@ -3706,16 +3711,18 @@ bin_print(char *name, char **args, Options ops, int func)
zwarnnam(name, zwarnnam(name,
"%d: argument specifier out of range", "%d: argument specifier out of range",
0, narg); 0, narg);
if (fout != stdout)
fclose(fout);
return 1; return 1;
} else { } else {
if (narg > maxarg) maxarg = narg; if (narg > maxarg) maxarg = narg;
args = first + narg - 1; argp = first + narg - 1;
} }
} }
} }
if (*args) { if (*argp) {
prec = (int)mathevali(*args++); prec = (int)mathevali(*argp++);
if (errflag) { if (errflag) {
errflag = 0; errflag = 0;
ret = 1; ret = 1;
@ -3731,7 +3738,10 @@ bin_print(char *name, char **args, Options ops, int func)
/* ignore any size modifier */ /* ignore any size modifier */
if (*c == 'l' || *c == 'L' || *c == 'h') c++; 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'; d[1] = '\0';
switch (*d = *c) { switch (*d = *c) {
case 'c': case 'c':
@ -3748,24 +3758,24 @@ bin_print(char *name, char **args, Options ops, int func)
case 'b': case 'b':
if (curarg) { if (curarg) {
int l; int l;
char *b = getkeystring(curarg, &l, char *b = getkeystring(metafy(curarg, curlen, META_USEHEAP), &l,
OPT_ISSET(ops,'b') ? 2 : 0, &nnl); OPT_ISSET(ops,'b') ? 2 : 0, &nnl);
/* handle width/precision here and use fwrite so that /* handle width/precision here and use fwrite so that
* nul characters can be output */ * nul characters can be output */
if (prec >= 0 && prec < l) l = prec; if (prec >= 0 && prec < l) l = prec;
if (width > 0 && flags[2]) width = -width; if (width > 0 && flags[2]) width = -width;
if (width > 0 && l < width) if (width > 0 && l < width)
printf("%*c", width - l, ' '); count += fprintf(fout, "%*c", width - l, ' ');
fwrite(b, l, 1, fout); count += fwrite(b, 1, l, fout);
if (width < 0 && l < -width) if (width < 0 && l < -width)
printf("%*c", -width - l, ' '); count += fprintf(fout, "%*c", -width - l, ' ');
count += l;
if (nnl) { if (nnl) {
/* If the %b arg had a \c escape, truncate the fmt. */ /* If the %b arg had a \c escape, truncate the fmt. */
flen = c - fmt + 1; flen = c - fmt + 1;
fmttrunc = 1; fmttrunc = 1;
} }
} } else
count += fprintf(fout, "%*c", width, ' ');
break; break;
case 'q': case 'q':
stringval = curarg ? bslashquote(curarg, NULL, 0) : &nullstr; stringval = curarg ? bslashquote(curarg, NULL, 0) : &nullstr;
@ -3810,10 +3820,10 @@ bin_print(char *name, char **args, Options ops, int func)
if (type > 0) { if (type > 0) {
if (curarg && (*curarg == '\'' || *curarg == '"' )) { if (curarg && (*curarg == '\'' || *curarg == '"' )) {
if (type == 2) { if (type == 2) {
doubleval = (unsigned char)curarg[1]; doubleval = STOUC(curarg[1]);
print_val(doubleval); print_val(doubleval);
} else { } else {
intval = (unsigned char)curarg[1]; intval = STOUC(curarg[1]);
print_val(intval); print_val(intval);
} }
} else { } else {
@ -3859,19 +3869,18 @@ bin_print(char *name, char **args, Options ops, int func)
} }
} }
} }
if (maxarg && (args - first > maxarg)) if (maxarg && (argp - first > maxarg))
maxarg = args - first; maxarg = argp - first;
} }
if (maxarg) args = first + maxarg; if (maxarg) argp = first + maxarg;
/* if there are remaining args, reuse format string */ /* if there are remaining args, reuse format string */
} while (*args && args != first && !fmttrunc && !OPT_ISSET(ops,'r')); } while (*argp && argp != first && !fmttrunc && !OPT_ISSET(ops,'r'));
if (OPT_ISSET(ops,'z') || OPT_ISSET(ops,'s')) { if (OPT_ISSET(ops,'z') || OPT_ISSET(ops,'s')) {
#ifdef HAVE_OPEN_MEMSTREAM #ifdef HAVE_OPEN_MEMSTREAM
putc(0, fout); putc(0, fout);
fflush(fout); fflush(fout);
count = mcount;
#else #else
rewind(fout); rewind(fout);
buf = (char *)zalloc(count + 1); buf = (char *)zalloc(count + 1);