1 /*      Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T     */
   2 /*        All Rights Reserved   */
   3 
   4 
   5 /*
   6  * Copyright (c) 1980 Regents of the University of California.
   7  * All rights reserved.  The Berkeley software License Agreement
   8  * specifies the terms and conditions for redistribution.
   9  */
  10 /*      Portions Copyright(c) 1988, Sun Microsystems Inc.       */
  11 /*      All Rights Reserved                                     */
  12 
  13 /*
  14  * Copyright (c) 1997, by Sun Microsystems, Inc.
  15  * All rights reserved.
  16  */
  17 
  18 #ident  "%Z%%M% %I%     %E% SMI"        /* SVr4.0 1.1   */
  19 
  20 /* LINTLIBRARY */
  21 
  22 #include <stdio.h>
  23 #include <mp.h>
  24 #include <sys/types.h>
  25 #include "libmp.h"
  26 #include <stdlib.h>
  27 
  28 static int
  29 m_in(MINT *a, short b, FILE *f)
  30 {
  31         MINT x, y, ten;
  32         int sign, c;
  33         short qten, qy;
  34 
  35         _mp_xfree(a);
  36         sign = 1;
  37         ten.len = 1;
  38         ten.val = &qten;
  39         qten = b;
  40         x.len = 0;
  41         y.len = 1;
  42         y.val = &qy;
  43         while ((c = getc(f)) != EOF)
  44         switch (c) {
  45 
  46         case '\\':
  47                 (void) getc(f);
  48                 continue;
  49         case '\t':
  50         case '\n':
  51                 a->len *= sign;
  52                 _mp_xfree(&x);
  53                 return (0);
  54         case ' ':
  55                 continue;
  56         case '-':
  57                 sign = -sign;
  58                 continue;
  59         default:
  60                 if (c >= '0' && c <= '9') {
  61                         qy = c - '0';
  62                         mp_mult(&x, &ten, a);
  63                         mp_madd(a, &y, a);
  64                         _mp_move(a, &x);
  65                         continue;
  66                 } else {
  67                         (void) ungetc(c, stdin);
  68                         a->len *= sign;
  69                         return (0);
  70                 }
  71         }
  72         return (EOF);
  73 }
  74 
  75 static void
  76 m_out(MINT *a, short b, FILE *f)
  77 {
  78         int sign, xlen, i;
  79         short r;
  80         MINT x;
  81 
  82         char *obuf;
  83         char *bp;
  84 
  85         if (a == NULL)
  86                 return;
  87         sign = 1;
  88         xlen = a->len;
  89         if (xlen < 0) {
  90                 xlen = -xlen;
  91                 sign = -1;
  92         }
  93         if (xlen == 0) {
  94                 (void) fprintf(f, "0\n");
  95                 return;
  96         }
  97         x.len = xlen;
  98         x.val = _mp_xalloc(xlen, "m_out");
  99         for (i = 0; i < xlen; i++)
 100                 x.val[i] = a->val[i];
 101         obuf = malloc(7 * (size_t)xlen);
 102         bp = obuf + 7 * xlen - 1;
 103         *bp-- = 0;
 104         while (x.len > 0) {
 105                 for (i = 0; i < 10 && x.len > 0; i++) {
 106                         mp_sdiv(&x, b, &x, &r);
 107                         *bp-- = (char)(r + '0');
 108                 }
 109                 if (x.len > 0)
 110                         *bp-- = ' ';
 111         }
 112         if (sign == -1)
 113                 *bp-- = '-';
 114         (void) fprintf(f, "%s\n", bp + 1);
 115         free(obuf);
 116         _mp_xfree(&x);
 117 }
 118 
 119 static void s_div(MINT *, short, MINT *, short *);
 120 
 121 void
 122 mp_sdiv(MINT *a, short n, MINT *q, short *r)
 123 {
 124         MINT x, y;
 125         short sign;
 126 
 127         sign = 1;
 128         x.len = a->len;
 129         x.val = a->val;
 130         if (n < 0) {
 131                 sign = -sign;
 132                 n = -n;
 133         }
 134         if (x.len < 0) {
 135                 sign = -sign;
 136                 x.len = -x.len;
 137         }
 138         s_div(&x, n, &y, r);
 139         _mp_xfree(q);
 140         q->val = y.val;
 141         q->len = sign * y.len;
 142         *r = *r * sign;
 143 }
 144 
 145 static void
 146 s_div(MINT *a, short n, MINT *q, short *r)
 147 {
 148         int qlen;
 149         int i;
 150         int x;
 151         short *qval;
 152         short *aval;
 153 
 154         x = 0;
 155         qlen = a->len;
 156         q->val = _mp_xalloc(qlen, "s_div");
 157         aval = a->val + qlen;
 158         qval = q->val + qlen;
 159         for (i = qlen - 1; i >= 0; i--) {
 160                 x = x * 0100000 + *--aval;
 161                 *--qval = (short)(x / n);
 162                 x = x % n;
 163         }
 164         *r = (short)x;
 165         if (qlen && q->val[qlen-1] == 0)
 166                 qlen--;
 167         q->len = qlen;
 168         if (qlen == 0)
 169                 free(q->val);
 170 }
 171 
 172 int
 173 mp_min(MINT *a)
 174 {
 175         return (m_in(a, 10, stdin));
 176 }
 177 
 178 int
 179 mp_omin(MINT *a)
 180 {
 181         return (m_in(a, 8, stdin));
 182 }
 183 
 184 void
 185 mp_mout(MINT *a)
 186 {
 187         m_out(a, 10, stdout);
 188 }
 189 
 190 void
 191 mp_omout(MINT *a)
 192 {
 193         m_out(a, 8, stdout);
 194 }
 195 
 196 void
 197 mp_fmout(MINT *a, FILE *f)
 198 {
 199         m_out(a, 10, f);
 200 }
 201 
 202 int
 203 mp_fmin(MINT *a, FILE *f)
 204 {
 205         return (m_in(a, 10, f));
 206 }