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

PATCH: my "SECONDS can be floating point" tweaks



On Mon, Oct 28, 2002 at 06:55:52PM +0000, Peter Stephenson wrote:
> This allows typeset to switch the SECONDS special parameter between
> integer and floating point

Here's a fairly simple patch that I think improves things a bit.

First, the intseconds{get,set}fn() functions are implemented by calling
the float* versions.  This makes the internal representation of the
value identical regardless of type (i.e. it ensures that shtimer.tv_usec
gets set relative to the current time, and that it is subtracted out on
get).

The second change may be more controversial.  I introduced two new
functions that allow us to get and set the "raw" (non-relative to now)
value of the SECONDS variable (though the value is returned as a
double).  I then added some code to builtin.c that saves this raw value
into the cached off u.dval, and changed the new code in params.c that
was adding local-elapsed time into the parent variable to just reload
the raw parent value.

A few other minor tweaks are also included, such as not testing the
newspecial enum against 0, enhancing the $SECONDS comment, and casting
the shtimer.* values to zlong instead of int (just in case int is too
small).

I won't commit this until I get some positive feedback about the
changes.

..wayne..

---8<------8<------8<------8<---cut here--->8------>8------>8------>8---
Index: Src/builtin.c
--- Src/builtin.c	29 Oct 2002 10:56:40 -0000	1.89
+++ Src/builtin.c	30 Oct 2002 21:08:28 -0000
@@ -1774,6 +1774,8 @@
 	    return NULL;
 	}
     }
+    else if (newspecial != NS_NONE && strcmp(pname, "SECONDS") == 0)
+	newspecial = NS_SECONDS;
 
     /*
      * A parameter will be local if
@@ -1913,8 +1915,12 @@
 	 * because we've checked for unpleasant surprises above.
 	 */
 	pm->flags = (PM_TYPE(pm->flags) | on | PM_SPECIAL) & ~off;
-	if (newspecial == NS_SECONDS)
+	if (newspecial == NS_SECONDS) {
+	    /* We save off the raw internal value of the SECONDS var */
+	    tpm->u.dval = getrawseconds();
 	    setsecondstype(pm, on, off);
+	}
+
 	/*
 	 * Final tweak: if we've turned on one of the flags with
 	 * numbers, we should use the appropriate integer.
@@ -1998,7 +2004,7 @@
 		  "BUG: parameter recreated with wrong flags");
 	    unsetparam_pm(ipm, 0, 1);
 	}
-    } else if (newspecial && !(pm->old->flags & PM_NORESTORE)) {
+    } else if (newspecial != NS_NONE && !(pm->old->flags & PM_NORESTORE)) {
 	/*
 	 * We need to use the special setting function to re-initialise
 	 * the special parameter to empty.
Index: Src/params.c
--- Src/params.c	29 Oct 2002 12:58:03 -0000	1.68
+++ Src/params.c	30 Oct 2002 21:08:29 -0000
@@ -97,7 +97,9 @@
 /**/
 unsigned char hatchar, hashchar;
  
-/* $SECONDS = time(NULL) - shtimer.tv_sec */
+/* $SECONDS = now.tv_sec - shtimer.tv_sec
+ *          + (now.tv_usec - shtimer.tv_usec) / 1000000.0
+ * (rounded to an integer if the parameter is not set to float) */
  
 /**/
 struct timeval shtimer;
@@ -2672,7 +2674,7 @@
 zlong
 intsecondsgetfn(Param pm)
 {
-    return time(NULL) - shtimer.tv_sec;
+    return (zlong)floatsecondsgetfn(pm);
 }
 
 /* Function to set value of special parameter `SECONDS' */
@@ -2681,8 +2683,7 @@
 void
 intsecondssetfn(Param pm, zlong x)
 {
-    shtimer.tv_sec = time(NULL) - x;
-    shtimer.tv_usec = 0;
+    floatsecondssetfn(pm, (double)x);
 }
 
 /**/
@@ -2706,8 +2707,23 @@
     struct timezone dummy_tz;
 
     gettimeofday(&now, &dummy_tz);
-    shtimer.tv_sec = now.tv_sec - (int)x;
-    shtimer.tv_usec = now.tv_usec - (int)((x - (double)(int)x) * 1000000.0);
+    shtimer.tv_sec = now.tv_sec - (zlong)x;
+    shtimer.tv_usec = now.tv_usec - (zlong)((x - (zlong)x) * 1000000.0);
+}
+
+/**/
+double
+getrawseconds(void)
+{
+    return (double)shtimer.tv_sec + (double)shtimer.tv_usec / 1000000.0;
+}
+
+/**/
+void
+setrawseconds(double x)
+{
+    shtimer.tv_sec = (zlong)x;
+    shtimer.tv_usec = (zlong)((x - (zlong)x) * 1000000.0);
 }
 
 /**/
@@ -3487,19 +3503,10 @@
 	    {
 		setsecondstype(pm, PM_TYPE(tpm->flags), PM_TYPE(pm->flags));
 		/*
-		 * We restore SECONDS by adding back in the elapsed
-		 * time (from the point we reset shtimer) rather
-		 * than restoring it completely, since SECONDS should
-		 * run in the calling function, too.
+		 * We restore SECONDS by restoring its raw internal value
+		 * that we cached off into tpm->u.dval.
 		 */
-		if (PM_TYPE(pm->flags) == PM_INTEGER)
-		{
-		    pm->sets.ifn(pm, pm->gets.ifn(pm) + tpm->u.val);
-		}
-		else
-		{
-		    pm->sets.ffn(pm, pm->gets.ffn(pm) + tpm->u.dval);
-		}
+		setrawseconds(tpm->u.dval);
 		tpm->flags |= PM_NORESTORE;
 	    }
 	    DPUTS(!tpm || PM_TYPE(pm->flags) != PM_TYPE(tpm->flags) ||
---8<------8<------8<------8<---cut here--->8------>8------>8------>8---



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