[genius] Wed Jun 26 14:33:09 2013 Jiri (George) Lebl <jirka 5z com>



commit dd7e657473cde158ef07b099f1307dbb6ab80b48
Author: Jiri (George) Lebl <jirka 5z com>
Date:   Wed Jun 26 14:34:10 2013 -0500

    Wed Jun 26 14:33:09 2013  Jiri (George) Lebl <jirka 5z com>
    
        * src/funclib.c, src/funclibhelper.cP: implement subsecond precision
          in wait (approx 10ms) by simply passing in a noninteger number.

 ChangeLog            |    5 +++
 src/funclib.c        |   69 +++++++++++++++++++++----------------------------
 src/funclibhelper.cP |   12 ++++++++
 3 files changed, 47 insertions(+), 39 deletions(-)
---
diff --git a/ChangeLog b/ChangeLog
index 8b69854..80c17d5 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,8 @@
+Wed Jun 26 14:33:09 2013  Jiri (George) Lebl <jirka 5z com>
+
+       * src/funclib.c, src/funclibhelper.cP: implement subsecond precision
+         in wait (approx 10ms) by simply passing in a noninteger number.
+
 Tue Jun 25 16:11:28 2013  Jiri (George) Lebl <jirka 5z com>
 
        * help/C/genius.xml: A few updates, clarify how escapes in strings
diff --git a/src/funclib.c b/src/funclib.c
index 4ee6cba..e56a48e 100644
--- a/src/funclib.c
+++ b/src/funclib.c
@@ -429,54 +429,45 @@ error_op(GelCtx *ctx, GelETree * * a, gboolean *exception)
 static GelETree *
 wait_op(GelCtx *ctx, GelETree * * a, gboolean *exception)
 {
-       int secs;
+       double dsecs;
+       long msecs;
+       struct timeval tv;
+       struct timeval tv2;
 
-       if G_UNLIKELY ( ! check_argument_nonnegative_integer (a, 0, "wait"))
+       if G_UNLIKELY ( ! check_argument_nonnegative_number (a, 0, "wait"))
                return NULL;
 
-       secs = gel_get_nonnegative_integer (a[0]->val.value, "wait");
-       if G_UNLIKELY (secs < 0)
+       dsecs = mpw_get_double (a[0]->val.value);
+       if G_UNLIKELY (gel_error_num != 0) {
+               gel_error_num = 0;
                return NULL;
-       if (secs == 0) {
+       }
+
+       msecs = (long)(dsecs * 1000);
+       gettimeofday (&tv, NULL);
+       for (;;) {
                if (gel_evalnode_hook != NULL)
                        (*gel_evalnode_hook)();
-
-               if G_UNLIKELY (gel_interrupted)
-                       return NULL;
-               else
-                       return gel_makenum_null ();
-       } else {
-               if (gel_evalnode_hook != NULL) {
-                       struct timeval tv;
-                       struct timeval tv2;
-                       gettimeofday (&tv, NULL);
-                       for (;;) {
-                               (*gel_evalnode_hook)();
-                               if G_UNLIKELY (gel_interrupted) {
-                                       break;
-                               }
-                               gettimeofday (&tv2, NULL);
-                               if (tv.tv_sec + secs < tv2.tv_sec ||
-                                   (tv.tv_sec + secs == tv2.tv_sec &&
-                                    tv.tv_usec <= tv2.tv_usec))
-                                       break;
-                               /* sleep 10ms, this is a HORRIBLE HACK! */
-                               /* FIXME: do some mainloop thingie over here */
-                               usleep (10000);
-                       }
-               } else {
-                       int i;
-                       /* kind of hacky, but I don't want to risk long sleep not
-                          being interrupted on some systems */
-                       for (i = 0; i < secs && ! gel_interrupted; i++)
-                               sleep (1);
+               if G_UNLIKELY (gel_interrupted) {
+                       break;
                }
+               gettimeofday (&tv2, NULL);
 
-               if G_UNLIKELY (gel_interrupted)
-                       return NULL;
-               else
-                       return gel_makenum_null ();
+               if ( ((tv2.tv_sec - tv.tv_sec) * 1000
+                     - (tv.tv_usec / 1000)
+                     + (tv2.tv_usec / 1000))
+                    >= msecs)
+                       break;
+
+               /* sleep 10ms, this is a HORRIBLE HACK! */
+               /* FIXME: do some mainloop thingie over here */
+               usleep (10000);
        }
+
+       if G_UNLIKELY (gel_interrupted)
+               return NULL;
+       else
+               return gel_makenum_null ();
 }
 
 /*print function*/
diff --git a/src/funclibhelper.cP b/src/funclibhelper.cP
index 941c40f..f271431 100644
--- a/src/funclibhelper.cP
+++ b/src/funclibhelper.cP
@@ -92,6 +92,18 @@ check_argument_nonnegative_integer (GelETree **a, int argnum, const char *funcna
        return TRUE;
 }
 
+static inline gboolean
+check_argument_nonnegative_number (GelETree **a, int argnum, const char *funcname)
+{
+       if G_UNLIKELY (a[argnum]->type != GEL_VALUE_NODE ||
+                      mpw_is_complex(a[argnum]->val.value) ||
+                      mpw_sgn (a[argnum]->val.value) < 0) {
+               gel_errorout (_("%s: argument number %d not a nonnegative number"), funcname, argnum+1);
+               return FALSE;
+       }
+       return TRUE;
+}
+
 
 static inline gboolean
 check_argument_positive_integer (GelETree **a, int argnum, const char *funcname)


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]