From d3d091029367d7bf3c413330a2e93d720614d211 Mon Sep 17 00:00:00 2001 From: Peter Stephenson Date: Wed, 30 Jul 2014 12:10:15 +0100 Subject: 32918: add %. to ztrftime for use in prompts --- ChangeLog | 6 ++++++ Doc/Zsh/prompt.yo | 7 +++++++ Src/builtin.c | 2 +- Src/prompt.c | 8 +++++--- Src/utils.c | 28 +++++++++++++++++++++++++++- Src/watch.c | 2 +- 6 files changed, 47 insertions(+), 6 deletions(-) diff --git a/ChangeLog b/ChangeLog index 7e37dac37..f71458516 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2014-07-30 Peter Stephenson + + * 32918: Doc/Zsh/prompt.yo, Functions/TCP/tcp_output, + Src/builtin.c,Src/prompt.c, Src/utils.c, Src/watch.c: add + ability to display times with fractions of a second in prompts. + 2014-07-28 Barton E. Schaefer * 32593: Completion/Unix/Command/_qemu: update --vga option diff --git a/Doc/Zsh/prompt.yo b/Doc/Zsh/prompt.yo index eab15d29d..36f351b96 100644 --- a/Doc/Zsh/prompt.yo +++ b/Doc/Zsh/prompt.yo @@ -185,6 +185,13 @@ sitem(tt(%K))(the hour of the day on the 24-hour clock) sitem(tt(%L))(the hour of the day on the 12-hour clock) endsitem() +In addition, if the system supports the POSIX tt(gettimeofday) system +call, tt(%.) provides decimal fractions of a second since the epoch with +leading zeroes. By default three decimal places are provided, but a +number of digits up to 6 may be given following the tt(%); hence tt(%6.) +outputs microseconds. A typical example of this is the format +`tt(%D{%H:%M:%S.%.})'. + The GNU extension that a `tt(-)' between the tt(%) and the format character causes a leading zero or space to be stripped is handled directly by the shell for the format characters tt(d), tt(f), diff --git a/Src/builtin.c b/Src/builtin.c index 34a52962e..a2a3ad748 100644 --- a/Src/builtin.c +++ b/Src/builtin.c @@ -1731,7 +1731,7 @@ fclist(FILE *f, Options ops, zlong first, zlong last, if (tdfmt != NULL) { struct tm *ltm; ltm = localtime(&ent->stim); - if (ztrftime(timebuf, 256, tdfmt, ltm)) + if (ztrftime(timebuf, 256, tdfmt, ltm, 0L)) fprintf(f, "%s ", timebuf); } /* display the time taken by the command, if required */ diff --git a/Src/prompt.c b/Src/prompt.c index 95a7d4969..c16d78163 100644 --- a/Src/prompt.c +++ b/Src/prompt.c @@ -270,6 +270,8 @@ putpromptchar(int doprint, int endchar, unsigned int *txtchangep) char *ss, *hostnam; int t0, arg, test, sep, j, numjobs; struct tm *tm; + struct timezone dummy_tz; + struct timeval tv; time_t timet; Nameddir nd; @@ -636,8 +638,8 @@ putpromptchar(int doprint, int endchar, unsigned int *txtchangep) tmfmt = "%l:%M%p"; break; } - timet = time(NULL); - tm = localtime(&timet); + gettimeofday(&tv, &dummy_tz); + tm = localtime(&tv.tv_sec); /* * Hack because strftime won't say how * much space it actually needs. Try to add it @@ -647,7 +649,7 @@ putpromptchar(int doprint, int endchar, unsigned int *txtchangep) */ for(j = 0, t0 = strlen(tmfmt)*8; j < 3; j++, t0*=2) { addbufspc(t0); - if (ztrftime(bv->bp, t0, tmfmt, tm) >= 0) + if (ztrftime(bv->bp, t0, tmfmt, tm, tv.tv_usec) >= 0) break; } /* There is enough room for this because addbufspc(t0) diff --git a/Src/utils.c b/Src/utils.c index cef2abef8..aa978e6b9 100644 --- a/Src/utils.c +++ b/Src/utils.c @@ -2710,7 +2710,7 @@ ztrftimebuf(int *bufsizeptr, int decr) /**/ mod_export int -ztrftime(char *buf, int bufsize, char *fmt, struct tm *tm) +ztrftime(char *buf, int bufsize, char *fmt, struct tm *tm, long usec) { int hr12; #ifdef HAVE_STRFTIME @@ -2729,6 +2729,7 @@ ztrftime(char *buf, int bufsize, char *fmt, struct tm *tm) while (*fmt) if (*fmt == '%') { int strip; + int digs = 3; fmt++; if (*fmt == '-') { @@ -2736,6 +2737,17 @@ ztrftime(char *buf, int bufsize, char *fmt, struct tm *tm) fmt++; } else strip = 0; + if (idigit(*fmt)) { + /* Digit --- only useful with . */ + char *dstart = fmt; + char *dend = fmt+1; + while (idigit(*dend)) + dend++; + if (*dend == '.') { + fmt = dend; + digs = atoi(dstart); + } + } /* * Assume this format will take up at least two * characters. Not always true, but if that matters @@ -2745,6 +2757,20 @@ ztrftime(char *buf, int bufsize, char *fmt, struct tm *tm) if (ztrftimebuf(&bufsize, 2)) return -1; switch (*fmt++) { + case '.': + if (ztrftimebuf(&bufsize, digs)) + return -1; + if (digs > 6) + digs = 6; + if (digs < 6) { + int trunc; + for (trunc = 5 - digs; trunc; trunc--) + usec /= 10; + usec = (usec + 5) / 10; + } + sprintf(buf, "%0*ld", digs, usec); + buf += digs; + break; case 'd': if (tm->tm_mday > 9 || !strip) *buf++ = '0' + tm->tm_mday / 10; diff --git a/Src/watch.c b/Src/watch.c index 5231579f8..8dea0b495 100644 --- a/Src/watch.c +++ b/Src/watch.c @@ -330,7 +330,7 @@ watchlog2(int inout, WATCH_STRUCT_UTMP *u, char *fmt, int prnt, int fini) } timet = getlogtime(u, inout); tm = localtime(&timet); - ztrftime(buf, 40, fm2, tm); + ztrftime(buf, 40, fm2, tm, 0L); printf("%s", (*buf == ' ') ? buf + 1 : buf); break; case '%': -- cgit 1.4.1