Zsh Mailing List Archive
Messages sorted by: Reverse Date, Date, Thread, Author

Re: PATCH: support for nanosecond timestamps



Peter Stephenson wrote:
> %N seems reasonable, although I'm wondering if we might actually be
> better off with a specification for floating point seconds; we could
> then use the same thing in zsh/datetime where we only get microsecond
> resolution from gettimeofday().  Either way, it would probably be good
> to add this to ztrftime() and expand the interface to include a
> (possibly NULL) pointer to whatever gives the extra resolution.  Would
> it be too horrible to allow formats like "%.9s"?  We'd have to restrict
> it to %S and %s which are the only two where it makes sense, and we
> would have to decide what to do about E and O modifiers and glibc flag
> additions; simply passing them straight through and not allowing a
> fractional second in such cases would probably be good enough.

How about the following as an initial step? This only adds %N. I've
expanded the ztrftime interface with a long for nanoseconds. That seemed
as good as any pointer given that 0 is going to be the default value.
The only cases where I've not made it pass 0 is stat and prompt
expansion (where we have gettimeofday). So the datetime module is
unchanged.

Formats like %.9s make a certain amount of logical sense though you
might expect that to output the seconds too, e.g.: 23.562827621
It might be better to allow %6N and %3N given that %N is a non-standard
extension already.

The E and 0 modifiers don't seem to work for me, are they supposed to?

Oliver

Index: Src/prompt.c
===================================================================
RCS file: /cvsroot/zsh/zsh/Src/prompt.c,v
retrieving revision 1.43
diff -u -r1.43 prompt.c
--- Src/prompt.c	22 Oct 2007 10:22:19 -0000	1.43
+++ Src/prompt.c	5 Nov 2007 14:03:17 -0000
@@ -210,6 +210,8 @@
     char *ss, *hostnam;
     int t0, arg, test, sep, j, numjobs;
     struct tm *tm;
+    struct timeval timev;
+    struct timezone dummy;
     time_t timet;
     Nameddir nd;
 
@@ -529,8 +531,8 @@
 			tmfmt = "%l:%M%p";
 			break;
 		    }
-		    timet = time(NULL);
-		    tm = localtime(&timet);
+		    gettimeofday(&timev, &dummy);
+		    tm = localtime((const time_t*) &timev.tv_sec);
 		    /*
 		     * Hack because strftime won't say how
 		     * much space it actually needs.  Try to add it
@@ -540,7 +542,8 @@
 		     */
 		    for(j = 0, t0 = strlen(tmfmt)*8; j < 3; j++, t0*=2) {
 			addbufspc(t0);
-			if (ztrftime(bp, t0, tmfmt, tm) >= 0)
+			if (ztrftime(bp, t0, tmfmt, tm, 1000 * timev.tv_usec)
+                        	>= 0)
 			    break;
 		    }
 		    /* There is enough room for this because addbufspc(t0)
Index: Src/utils.c
===================================================================
RCS file: /cvsroot/zsh/zsh/Src/utils.c,v
retrieving revision 1.169
diff -u -r1.169 utils.c
--- Src/utils.c	31 Oct 2007 06:22:57 -0000	1.169
+++ Src/utils.c	5 Nov 2007 14:03:18 -0000
@@ -2357,7 +2357,7 @@
 
 /**/
 mod_export int
-ztrftime(char *buf, int bufsize, char *fmt, struct tm *tm)
+ztrftime(char *buf, int bufsize, char *fmt, struct tm *tm, long nsecs)
 {
     int hr12, decr;
 #ifndef HAVE_STRFTIME
@@ -2425,6 +2425,12 @@
 		*buf++ = '0' + tm->tm_min / 10;
 		*buf++ = '0' + tm->tm_min % 10;
 		break;
+            case 'N':
+		if (ztrftimebuf(&bufsize, 9))
+		    return 0;
+                sprintf(buf, "%09ld", nsecs);
+                buf += 9;
+		break;
 	    case 'S':
 		*buf++ = '0' + tm->tm_sec / 10;
 		*buf++ = '0' + tm->tm_sec % 10;
Index: Src/watch.c
===================================================================
RCS file: /cvsroot/zsh/zsh/Src/watch.c,v
retrieving revision 1.5
diff -u -r1.5 watch.c
--- Src/watch.c	4 Apr 2005 09:59:05 -0000	1.5
+++ Src/watch.c	5 Nov 2007 14:03:18 -0000
@@ -330,7 +330,7 @@
 		    }
 		    timet = getlogtime(u, inout);
 		    tm = localtime(&timet);
-		    ztrftime(buf, 40, fm2, tm);
+		    ztrftime(buf, 40, fm2, tm, 0);
 		    printf("%s", (*buf == ' ') ? buf + 1 : buf);
 		    break;
 		case '%':
Index: Src/Builtins/sched.c
===================================================================
RCS file: /cvsroot/zsh/zsh/Src/Builtins/sched.c,v
retrieving revision 1.13
diff -u -r1.13 sched.c
--- Src/Builtins/sched.c	6 Jul 2007 21:52:40 -0000	1.13
+++ Src/Builtins/sched.c	5 Nov 2007 14:03:18 -0000
@@ -211,7 +211,7 @@
 
 	    t = sch->time;
 	    tmp = localtime(&t);
-	    ztrftime(tbuf, 20, "%a %b %e %k:%M:%S", tmp);
+	    ztrftime(tbuf, 20, "%a %b %e %k:%M:%S", tmp, 0);
 	    if (sch->flags & SCHEDFLAG_TRASH_ZLE)
 		flagstr = "-o ";
 	    else
Index: Src/Modules/datetime.c
===================================================================
RCS file: /cvsroot/zsh/zsh/Src/Modules/datetime.c,v
retrieving revision 1.17
diff -u -r1.17 datetime.c
--- Src/Modules/datetime.c	6 Jul 2007 21:52:40 -0000	1.17
+++ Src/Modules/datetime.c	5 Nov 2007 14:03:18 -0000
@@ -125,7 +125,7 @@
     buffer = zalloc(bufsize);
 
     for (x=0; x < 4; x++) {
-        if (ztrftime(buffer, bufsize, argv[0], t) >= 0)
+        if (ztrftime(buffer, bufsize, argv[0], t, 0) >= 0)
 	    break;
 	buffer = zrealloc(buffer, bufsize *= 2);
     }
Index: Src/Modules/stat.c
===================================================================
RCS file: /cvsroot/zsh/zsh/Src/Modules/stat.c,v
retrieving revision 1.15
diff -u -r1.15 stat.c
--- Src/Modules/stat.c	6 Jul 2007 21:52:40 -0000	1.15
+++ Src/Modules/stat.c	5 Nov 2007 14:03:18 -0000
@@ -188,7 +188,7 @@
 
 /**/
 static void
-stattimeprint(time_t tim, char *outbuf, int flags)
+stattimeprint(time_t tim, long nsecs, char *outbuf, int flags)
 {
     if (flags & STF_RAW) {
 	sprintf(outbuf, "%ld", (unsigned long)tim);
@@ -198,7 +198,7 @@
     if (flags & STF_STRING) {
 	char *oend = outbuf + strlen(outbuf);
 	ztrftime(oend, 40, timefmt, (flags & STF_GMT) ? gmtime(&tim) :
-		 localtime(&tim));
+		 localtime(&tim), nsecs);
 	if (flags & STF_RAW)
 	    strcat(oend, ")");
     }
@@ -288,15 +288,27 @@
 	break;
 
     case ST_ATIM:
-	stattimeprint(sbuf->st_atime, optr, flags);
+#ifdef GET_ST_ATIME_NSEC
+	stattimeprint(sbuf->st_atime, GET_ST_ATIME_NSEC(*sbuf), optr, flags);
+#else
+	stattimeprint(sbuf->st_atime, 0, optr, flags);
+#endif
 	break;
 
     case ST_MTIM:
-	stattimeprint(sbuf->st_mtime, optr, flags);
+#ifdef GET_ST_ATIME_NSEC
+	stattimeprint(sbuf->st_atime, GET_ST_MTIME_NSEC(*sbuf), optr, flags);
+#else
+	stattimeprint(sbuf->st_mtime, 0, optr, flags);
+#endif
 	break;
 
     case ST_CTIM:
-	stattimeprint(sbuf->st_ctime, optr, flags);
+#ifdef GET_ST_ATIME_NSEC
+	stattimeprint(sbuf->st_atime, GET_ST_CTIME_NSEC(*sbuf), optr, flags);
+#else
+	stattimeprint(sbuf->st_ctime, 0, optr, flags);
+#endif
 	break;
 
     case ST_BLKSIZE:



Messages sorted by: Reverse Date, Date, Thread, Author