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
m_in(MINT * a,short b,FILE * f)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
m_out(MINT * a,short b,FILE * f)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
mp_sdiv(MINT * a,short n,MINT * q,short * r)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
s_div(MINT * a,short n,MINT * q,short * r)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
mp_min(MINT * a)177 mp_min(MINT *a)
178 {
179 return (m_in(a, 10, stdin));
180 }
181
182 int
mp_omin(MINT * a)183 mp_omin(MINT *a)
184 {
185 return (m_in(a, 8, stdin));
186 }
187
188 void
mp_mout(MINT * a)189 mp_mout(MINT *a)
190 {
191 m_out(a, 10, stdout);
192 }
193
194 void
mp_omout(MINT * a)195 mp_omout(MINT *a)
196 {
197 m_out(a, 8, stdout);
198 }
199
200 void
mp_fmout(MINT * a,FILE * f)201 mp_fmout(MINT *a, FILE *f)
202 {
203 m_out(a, 10, f);
204 }
205
206 int
mp_fmin(MINT * a,FILE * f)207 mp_fmin(MINT *a, FILE *f)
208 {
209 return (m_in(a, 10, f));
210 }
211