From: Peter Stephenson <p.stephenson@samsung.com>
To: Zsh Hackers' List <zsh-workers@zsh.org>
Subject: PATCH: ztrftime %. for fractions of a second in prompts
Date: Wed, 30 Jul 2014 11:46:51 +0100 [thread overview]
Message-ID: <20140730114651.5687f4df@pwslap01u.europe.root.pri> (raw)
I was trying to get some timings in prompts to better than a second ---
not particularly useful in a regular shell prompt, but very useful in
the prompts provided by e.g. the TCP functions.
I was shocked! shocked! to find this appears not to be possible.
I've used %. for this as it's definitely not POSIX and is very easy to
remember. You can specify 1 to 6 digits between the '%' and the '.'.
This doesn't appear to be useful in non-prompt calls to ztrftime() since
the fractions of a second aren't available.
pws
diff --git a/Doc/Zsh/prompt.yo b/Doc/Zsh/prompt.yo
index eab15d2..36f351b 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 34a5296..a2a3ad7 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 95a7d49..c16d781 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 cef2abe..aa978e6 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 5231579..8dea0b4 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 '%':
next reply other threads:[~2014-07-30 10:46 UTC|newest]
Thread overview: 5+ messages / expand[flat|nested] mbox.gz Atom feed top
2014-07-30 10:46 Peter Stephenson [this message]
2014-07-30 11:21 ` Peter Stephenson
2014-07-30 13:16 ` Vin Shelton
2014-07-30 13:24 ` Peter Stephenson
2014-07-30 13:56 ` Vin Shelton
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20140730114651.5687f4df@pwslap01u.europe.root.pri \
--to=p.stephenson@samsung.com \
--cc=zsh-workers@zsh.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
Code repositories for project(s) associated with this public inbox
https://git.vuxu.org/mirror/zsh/
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).