Uprating of the passphrase pixie.
[u/mdw/catacomb] / mptext.c
index fcdac51..9cca8a8 100644 (file)
--- a/mptext.c
+++ b/mptext.c
@@ -1,6 +1,6 @@
 /* -*-c-*-
  *
- * $Id: mptext.c,v 1.16 2002/10/15 22:57:43 mdw Exp $
+ * $Id$
  *
  * Textual representation of multiprecision numbers
  *
  * MA 02111-1307, USA.
  */
 
-/*----- Revision history --------------------------------------------------* 
- *
- * $Log: mptext.c,v $
- * Revision 1.16  2002/10/15 22:57:43  mdw
- * Bug fix: prevent negative zero.
- *
- * Revision 1.15  2002/10/15 19:18:15  mdw
- * Fix fencepost bugs in binary radix writing.
- *
- * Revision 1.14  2002/10/09 00:33:44  mdw
- * Allow `0o' and `0b' prefixes for octal and binary (from Haskell)
- *
- * Revision 1.13  2002/10/09 00:21:06  mdw
- * Allow user-specified `r_xx' bases to be up to 62.
- *
- * Revision 1.12  2002/01/13 19:51:18  mdw
- * Extend the textual format to bases up to 62 by distinguishing case.
- *
- * Revision 1.11  2001/06/16 23:42:17  mdw
- * Typesetting fixes.
- *
- * Revision 1.10  2001/06/16 13:22:39  mdw
- * Added fast-track code for binary output bases, and tests.
- *
- * Revision 1.9  2001/02/03 16:05:17  mdw
- * Make flags be unsigned.  Improve the write algorithm: recurse until the
- * parts are one word long and use single-precision arithmetic from there.
- * Fix off-by-one bug when breaking the number apart.
- *
- * Revision 1.8  2000/12/06 20:32:42  mdw
- * Reduce binary bytes (to allow marker bits to be ignored).  Fix error
- * message string a bit.  Allow leading `+' signs.
- *
- * Revision 1.7  2000/07/15 10:01:08  mdw
- * Bug fix in binary input.
- *
- * Revision 1.6  2000/06/25 12:58:23  mdw
- * Fix the derivation of `depth' commentary.
- *
- * Revision 1.5  2000/06/17 11:46:19  mdw
- * New and much faster stack-based algorithm for reading integers.  Support
- * reading and writing binary integers in bases between 2 and 256.
- *
- * Revision 1.4  1999/12/22 15:56:56  mdw
- * Use clever recursive algorithm for writing numbers out.
- *
- * Revision 1.3  1999/12/10 23:23:26  mdw
- * Allocate slightly less memory.
- *
- * Revision 1.2  1999/11/20 22:24:15  mdw
- * Use function versions of MPX_UMULN and MPX_UADDN.
- *
- * Revision 1.1  1999/11/17 18:02:16  mdw
- * New multiprecision integer arithmetic suite.
- *
- */
-
 /*----- Header files ------------------------------------------------------*/
 
 #include <ctype.h>
@@ -212,7 +155,7 @@ mp *mp_read(mp *m, int radix, const mptext_ops *ops, void *p)
     r = -1;
   } else if (radix < 0) {
     rd = -radix;
-    assert(((void)"binary radix must fit in a byte", rd < UCHAR_MAX));
+    assert(((void)"binary radix must fit in a byte", rd <= UCHAR_MAX));
     r = -1;
   } else if (ch != '0') {
     rd = 10;
@@ -348,6 +291,7 @@ restart:
       m->f &= ~MP_UNDEF;
       m = mp_lsr(m, m, (unsigned long)n * MPW_BITS + b);
     }
+    ops->unget(ch, p);
     goto done;
   }}
 
@@ -598,7 +542,7 @@ static int complicated(mp *m, int radix, mp **pr, unsigned i, unsigned z,
 
   assert(i);
   mp_div(&q, &m, m, pr[i]);
-  if (!MP_LEN(q))
+  if (MP_ZEROP(q))
     d = z;
   else {
     if (z > d)
@@ -725,13 +669,13 @@ int mp_write(mp *m, int radix, const mptext_ops *ops, void *p)
   if (radix > 0)
     assert(((void)"ascii radix must be <= 62", radix <= 62));
   else if (radix < 0)
-    assert(((void)"binary radix must fit in a byte", -radix < UCHAR_MAX));
+    assert(((void)"binary radix must fit in a byte", -radix <= UCHAR_MAX));
   else
     assert(((void)"radix can't be zero in mp_write", 0));
 
   /* --- If the number is negative, sort that out --- */
 
-  if (m->f & MP_NEG) {
+  if (MP_NEGP(m)) {
     if (ops->put("-", 1, p))
       return (EOF);
     m->f &= ~MP_NEG;
@@ -808,7 +752,8 @@ static int verify(dstr *v)
   int ok = 1;
   int ib = *(int *)v[0].buf, ob = *(int *)v[2].buf;
   dstr d = DSTR_INIT;
-  mp *m = mp_readdstr(MP_NEW, &v[1], 0, ib);
+  size_t off = 0;
+  mp *m = mp_readdstr(MP_NEW, &v[1], &off, ib);
   if (m) {
     if (!ob) {
       fprintf(stderr, "*** unexpected successful parse\n"
@@ -847,12 +792,12 @@ static int verify(dstr *v)
   } else {
     if (ob) {
       fprintf(stderr, "*** unexpected parse failure\n"
-                     "*** input [%i]    = ", ib);
+                     "*** input [%2i]    = ", ib);
       if (ib < 0)
        type_hex.dump(&v[1], stderr);
       else
        fputs(v[1].buf, stderr);
-      fprintf(stderr, "\n*** expected [%i]   = ", ob);
+      fprintf(stderr, "\n*** expected [%2i]   = ", ob);
       if (ob < 0)
        type_hex.dump(&v[3], stderr);
       else
@@ -862,6 +807,20 @@ static int verify(dstr *v)
     }
   }
 
+  if (v[1].len - off != v[4].len ||
+      memcmp(v[1].buf + off, v[4].buf, v[4].len) != 0) {
+    fprintf(stderr, "*** leftovers incorrect\n"
+                   "*** input [%2i]    = ", ib);
+    if (ib < 0)
+      type_hex.dump(&v[1], stderr);
+    else
+      fputs(v[1].buf, stderr);
+    fprintf(stderr, "\n*** expected `%s'\n"
+                   "*** found `%s'\n",
+           v[4].buf, v[1].buf + off);
+    ok = 0;
+  }
+           
   dstr_destroy(&d);
   assert(mparena_count(MPARENA_GLOBAL) == 0);
   return (ok);
@@ -869,11 +828,11 @@ static int verify(dstr *v)
 
 static test_chunk tests[] = {
   { "mptext-ascii", verify,
-    { &type_int, &type_string, &type_int, &type_string, 0 } },
+    { &type_int, &type_string, &type_int, &type_string, &type_string, 0 } },
   { "mptext-bin-in", verify,
-    { &type_int, &type_hex, &type_int, &type_string, 0 } },
+    { &type_int, &type_hex, &type_int, &type_string, &type_string, 0 } },
   { "mptext-bin-out", verify,
-    { &type_int, &type_string, &type_int, &type_hex, 0 } },
+    { &type_int, &type_string, &type_int, &type_hex, &type_string, 0 } },
   { 0, 0, { 0 } }
 };