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