From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 6997 invoked from network); 30 Oct 2002 21:19:30 -0000 Received: from sunsite.dk (130.225.247.90) by ns1.primenet.com.au with SMTP; 30 Oct 2002 21:19:30 -0000 Received: (qmail 12009 invoked by alias); 30 Oct 2002 21:18:59 -0000 Mailing-List: contact zsh-workers-help@sunsite.dk; run by ezmlm Precedence: bulk X-No-Archive: yes X-Seq: 17881 Received: (qmail 11971 invoked from network); 30 Oct 2002 21:18:53 -0000 Date: Wed, 30 Oct 2002 13:17:51 -0800 From: Wayne Davison To: Peter Stephenson Cc: Zsh hackers list Subject: PATCH: my "SECONDS can be floating point" tweaks Message-ID: <20021030211750.GA6296@scuzzy.blorf.net> References: <22634.1035831352@csr.com> Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <22634.1035831352@csr.com> User-Agent: Mutt/1.3.28i 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---