From f40278ec0b45c31211782c3fcd6eff9515de7f63 Mon Sep 17 00:00:00 2001 From: Oliver Kiddle Date: Tue, 19 Mar 2002 14:34:01 +0000 Subject: 16862: allow print's -s and -z options to be used with -f --- ChangeLog | 5 ++ Src/builtin.c | 158 ++++++++++++++++++++++++++++++++++++---------------------- zshconfig.ac | 2 +- 3 files changed, 105 insertions(+), 60 deletions(-) diff --git a/ChangeLog b/ChangeLog index 3facb207b..e6f41a169 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2002-03-19 Oliver Kiddle + + * 16862: zshconfig.ac, Src/builtin.c: allow print's -s and -z + options to be used with -f + 2002-03-17 Clint Adams * 16850: Completion/Unix/Command/_rsync: remote file completion via diff --git a/Src/builtin.c b/Src/builtin.c index b2815c155..372dcf8f4 100644 --- a/Src/builtin.c +++ b/Src/builtin.c @@ -27,6 +27,9 @@ * */ +/* this is defined so we get the prototype for open_memstream */ +#define _GNU_SOURCE 1 + #include "zsh.mdh" #include "builtin.pro" @@ -2909,10 +2912,11 @@ bin_print(char *name, char **args, char *ops, int func) int flen, width, prec, type, argc, n, narg; int nnl = 0, ret = 0, maxarg = 0; int flags[5], *len; - char *start, *endptr, *c, *d, *flag, spec[11], *fmt = NULL; + char *start, *endptr, *c, *d, *flag, *buf, *tmpf, spec[11], *fmt = NULL; char **first, *curarg, *flagch = "0+- #", save = '\0', nullstr = '\0'; - zlong count; + size_t rcount, mcount, count = 0; FILE *fout = stdout; + Histent ent; mnumber mnumval; double doubleval; @@ -2984,61 +2988,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]); - - /* -z option -- push the arguments onto the editing buffer stack */ - if (ops['z']) { - queue_signals(); - zpushnode(bufstack, sepjoin(args, NULL, 0)); - unqueue_signals(); - return 0; - } - /* -s option -- add the arguments to the history list */ - if (ops['s']) { - int nwords = 0, nlen, iwords; - char **pargs = args; - Histent ent; - - queue_signals(); - ent = prepnexthistent(); - while (*pargs++) - nwords++; - if ((ent->nwords = nwords)) { - ent->words = (short *)zalloc(nwords*2*sizeof(short)); - nlen = iwords = 0; - for (pargs = args; *pargs; pargs++) { - ent->words[iwords++] = nlen; - nlen += strlen(*pargs); - ent->words[iwords++] = nlen; - nlen++; - } - } else - ent->words = (short *)NULL; - ent->text = zjoin(args, ' ', 0); - ent->stim = ent->ftim = time(NULL); - ent->flags = 0; - addhistnode(histtab, ent->text, ent); - unqueue_signals(); - return 0; - } - /* -u and -p -- output to other than standard output */ if (ops['u'] || ops['p']) { int fd; @@ -3061,6 +3010,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]); + /* -c -- output in columns */ if (ops['c']) { int l, nc, nr, sc, n, t, i; @@ -3099,6 +3067,41 @@ bin_print(char *name, char **args, char *ops, int func) /* normal output */ if (!fmt) { + /* -z option -- push the arguments onto the editing buffer stack */ + if (ops['z']) { + queue_signals(); + zpushnode(bufstack, sepjoin(args, NULL, 0)); + unqueue_signals(); + return 0; + } + /* -s option -- add the arguments to the history list */ + if (ops['s']) { + int nwords = 0, nlen, iwords; + char **pargs = args; + + queue_signals(); + ent = prepnexthistent(); + while (*pargs++) + nwords++; + if ((ent->nwords = nwords)) { + ent->words = (short *)zalloc(nwords*2*sizeof(short)); + nlen = iwords = 0; + for (pargs = args; *pargs; pargs++) { + ent->words[iwords++] = nlen; + nlen += strlen(*pargs); + ent->words[iwords++] = nlen; + nlen++; + } + } else + ent->words = (short *)NULL; + ent->text = zjoin(args, ' ', 0); + ent->stim = ent->ftim = time(NULL); + ent->flags = 0; + addhistnode(histtab, ent->text, ent); + unqueue_signals(); + return 0; + } + for (; *args; args++, len++) { fwrite(*args, *len, 1, fout); if (args[1]) @@ -3115,10 +3118,22 @@ bin_print(char *name, char **args, char *ops, int func) return ret; } + if (ops['z'] || ops['s']) { +#ifdef HAVE_OPEN_MEMSTREAM + if ((fout = open_memstream(&buf, &mcount)) == NULL) + zwarnnam(name, "open_memstream failed", NULL, 0); +#else + tmpf = gettempname(); + if ((fout = fopen(tmpf, "w+")) == NULL) + zwarnnam(name, "can't open temp file: %e", NULL, errno); + unlink(tmpf); +#endif + } + /* printf style output */ *spec='%'; do { - count = 0; + rcount = count; if (maxarg) { first += maxarg; argc -= maxarg; @@ -3287,7 +3302,7 @@ bin_print(char *name, char **args, char *ops, int func) type=3; break; case 'n': - if (curarg) setiparam(curarg, count); + if (curarg) setiparam(curarg, count - rcount); break; default: if (*c) { @@ -3364,6 +3379,31 @@ bin_print(char *name, char **args, char *ops, int func) /* if there are remaining args, reuse format string */ } while (*args && args != first && !ops['r']); + if (ops['z'] || ops['s']) { +#ifdef HAVE_OPEN_MEMSTREAM + putc(0, fout); + fflush(fout); + count = mcount; +#else + rewind(fout); + buf = (char *)zalloc(count + 1); + fread(buf, count, 1, fout); + buf[count] = '\0'; +#endif + queue_signals(); + if (ops['z']) { + zpushnode(bufstack, buf); + } else { + ent = prepnexthistent(); + ent->text = buf; + ent->stim = ent->ftim = time(NULL); + ent->flags = 0; + ent->words = (short *)NULL; + addhistnode(histtab, ent->text, ent); + } + unqueue_signals(); + } + /* Testing EBADF special-cases >&- redirections */ if ((fout != stdout) ? (fclose(fout) != 0) : (fflush(fout) != 0 && errno != EBADF)) { diff --git a/zshconfig.ac b/zshconfig.ac index 86540a893..902981547 100644 --- a/zshconfig.ac +++ b/zshconfig.ac @@ -951,7 +951,7 @@ AC_CHECK_FUNCS(strftime difftime gettimeofday \ tgetent tigetflag tigetnum tigetstr setupterm \ pcre_compile pcre_study pcre_exec \ nl_langinfo \ - erand48) + erand48 open_memstream) AC_FUNC_STRCOLL dnl Check if tgetent accepts NULL (and will allocate its own termcap buffer) -- cgit 1.4.1