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 }