Make prime generation work when function pointers are equal. Get random
authormdw <mdw>
Mon, 22 Nov 2004 01:54:52 +0000 (01:54 +0000)
committermdw <mdw>
Mon, 22 Nov 2004 01:54:52 +0000 (01:54 +0000)
noise from network device packet counts.  And fix a really stupid bug
from the beginning of time in mp_cmp().

mp-arith.c
noise.c
pgen.c

index 0172981..941b8df 100644 (file)
@@ -229,9 +229,12 @@ int mp_eq(const mp *a, const mp *b) { return (MP_EQ(a, b)); }
 
 int mp_cmp(const mp *a, const mp *b)
 {
-  if (!((a->f ^ b->f) & MP_NEG))
-    return (mpx_ucmp(a->v, a->vl, b->v, b->vl));
-  else if (a->f & MP_NEG)
+  if (!((a->f ^ b->f) & MP_NEG)) {
+    if (a->f & MP_NEG)
+      return (-mpx_ucmp(a->v, a->vl, b->v, b->vl));
+    else
+      return (mpx_ucmp(a->v, a->vl, b->v, b->vl));
+  } else if (a->f & MP_NEG)
     return (-1);
   else
     return (+1);
diff --git a/noise.c b/noise.c
index 0244869..9088930 100644 (file)
--- a/noise.c
+++ b/noise.c
@@ -1,6 +1,6 @@
 /* -*-c-*-
  *
- * $Id: noise.c,v 1.8 2004/04/08 01:36:15 mdw Exp $
+ * $Id$
  *
  * Acquisition of environmental noise (Unix-specific)
  *
@@ -423,6 +423,7 @@ int noise_enquire(rand_pool *r)
   } tab[] = {
     { "ps alxww || ps -elf",   16 },
     { "netstat -n",             6 },
+    { "ifconfig -a",            8 },
     { "df",                    20 },
     { "w",                      6 },
     { "ls -align /tmp/.",      10 },
diff --git a/pgen.c b/pgen.c
index 439cbde..e569647 100644 (file)
--- a/pgen.c
+++ b/pgen.c
@@ -174,6 +174,9 @@ mp *pgen(const char *name, mp *d, mp *m, pgen_proc *event, void *ectx,
   int rq, rc;
   pgen_proc *proc;
   void *ctx;
+  int p;
+
+  enum { P_STEP, P_TEST };
 
   /* --- Set up the initial event block --- */
 
@@ -188,67 +191,67 @@ mp *pgen(const char *name, mp *d, mp *m, pgen_proc *event, void *ectx,
 
   /* --- Tell the event handler we're under way --- */
 
-  if (event && event(PGEN_BEGIN, &ev, ectx) == PGEN_ABORT)
+  if (event && event(PGEN_BEGIN, &ev, ectx) == PGEN_ABORT) {
+    ev.r->ops->destroy(ev.r);
     return (0);
+  }
 
   /* --- Set up for the initial call --- */
 
-  proc = step; ctx = sctx; rq = PGEN_BEGIN;
+  proc = step; ctx = sctx; p = P_STEP; rq = PGEN_BEGIN;
 
   /* --- Enter the great maelstrom of state transitions --- */
 
   for (;;) {
     unsigned act = 0;
 
-    enum {
-      A_STEP = 1u,
-      A_TEST = 2u,
-      A_EVENT = 4u,
-      A_ENDTEST = 8u,
-      A_ENDSTEP = 16u,
-      A_DONE = 32u
-    };
+#define A_STEP 1u
+#define A_TEST 2u
+#define A_EVENT 4u
+#define A_ENDTEST 8u
+#define A_ENDSTEP 16u
+#define A_DONE 32u
 
     /* --- Call the procedure and decide what to do next --- */
 
     rc = proc(rq, &ev, ctx);
     switch (rc) {
       case PGEN_TRY:
-       if (proc == test)
+       if (p == P_TEST)
          rq = PGEN_TRY;
        else {
          act |= A_EVENT;
-         proc = test; ctx = tctx;
+         proc = test; ctx = tctx; p = P_TEST;
          rq = PGEN_BEGIN;
        }
        break;
       case PGEN_PASS:
        act |= A_TEST | A_EVENT;
-       if (proc == test)
+       if (p == P_TEST)
          rq = PGEN_TRY;
        else {
-         proc = test; ctx = tctx;
+         proc = test; ctx = tctx; p = P_TEST;
          rq = PGEN_BEGIN;
        }
        break;
       case PGEN_FAIL:
        act |= A_STEP;
-       if (proc == test) {
+       if (p == P_TEST) {
          act |= A_ENDTEST | A_EVENT;
-         proc = step; ctx = sctx;
+         proc = step; ctx = sctx; p = P_STEP;
        }
        rq = PGEN_TRY;
        break;
       case PGEN_DONE:
        act |= A_EVENT | A_DONE | A_ENDSTEP;
-       if (proc == test)
+       if (p == P_TEST)
          act |= A_ENDTEST;
        break;
       case PGEN_ABORT:
        act |= A_EVENT | A_DONE;
-       if (proc == test || rq == PGEN_TRY)
+       if (p == P_TEST || rq == PGEN_TRY)
          act |= A_ENDSTEP;
-       if (proc == test && rq == PGEN_BEGIN)
+       if (p == P_TEST && rq != PGEN_BEGIN)
          act |= A_ENDTEST;
        break;
       default:
@@ -281,7 +284,7 @@ mp *pgen(const char *name, mp *d, mp *m, pgen_proc *event, void *ectx,
       rc = PGEN_ABORT;
       if (!(act & A_DONE)) {
        act |= A_ENDSTEP | A_DONE;
-       if (proc == test)
+       if (p == P_TEST)
          act |= A_ENDTEST;
       }
     }  
@@ -321,7 +324,7 @@ mp *pgen(const char *name, mp *d, mp *m, pgen_proc *event, void *ectx,
 
 int pgen_primep(mp *p, grand *gr)
 {
-  int i = rabin_iters(mp_bits(p));
+  int i;
   rabin r;
   mp *x = MP_NEW;
 
@@ -331,11 +334,10 @@ int pgen_primep(mp *p, grand *gr)
     case PGEN_FAIL: return (0);
   }
   rabin_create(&r, p);
-  while (i) {
+  for (i = 32; i; i--) {
     x = mprand_range(x, p, gr, 0);
     if (rabin_rtest(&r, x) == PGEN_FAIL)
       break;
-    i--;
   }
   MP_DROP(x);
   rabin_destroy(&r);