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:
parent
8c095a5169
commit
1f3bd88afb
2 changed files with 43 additions and 31 deletions
|
|
@ -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.
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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);
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue