xref: /illumos-gate/usr/src/lib/libmp/common/mout.c (revision 981fe1b1)
17c478bd9Sstevel@tonic-gate /*	Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T	*/
27c478bd9Sstevel@tonic-gate /*	  All Rights Reserved  	*/
37c478bd9Sstevel@tonic-gate 
47c478bd9Sstevel@tonic-gate 
57c478bd9Sstevel@tonic-gate /*
67c478bd9Sstevel@tonic-gate  * Copyright (c) 1980 Regents of the University of California.
77c478bd9Sstevel@tonic-gate  * All rights reserved.  The Berkeley software License Agreement
87c478bd9Sstevel@tonic-gate  * specifies the terms and conditions for redistribution.
97c478bd9Sstevel@tonic-gate  */
107c478bd9Sstevel@tonic-gate /* 	Portions Copyright(c) 1988, Sun Microsystems Inc.	*/
117c478bd9Sstevel@tonic-gate /*	All Rights Reserved					*/
127c478bd9Sstevel@tonic-gate 
137c478bd9Sstevel@tonic-gate /*
147c478bd9Sstevel@tonic-gate  * Copyright (c) 1997, by Sun Microsystems, Inc.
157c478bd9Sstevel@tonic-gate  * All rights reserved.
167c478bd9Sstevel@tonic-gate  */
177c478bd9Sstevel@tonic-gate 
18*981fe1b1SJohn Levon /*
19*981fe1b1SJohn Levon  * Copyright (c) 2018, Joyent, Inc.
20*981fe1b1SJohn Levon  */
217c478bd9Sstevel@tonic-gate 
227c478bd9Sstevel@tonic-gate /* LINTLIBRARY */
237c478bd9Sstevel@tonic-gate 
247c478bd9Sstevel@tonic-gate #include <stdio.h>
257c478bd9Sstevel@tonic-gate #include <mp.h>
267c478bd9Sstevel@tonic-gate #include <sys/types.h>
277c478bd9Sstevel@tonic-gate #include "libmp.h"
287c478bd9Sstevel@tonic-gate #include <stdlib.h>
297c478bd9Sstevel@tonic-gate 
307c478bd9Sstevel@tonic-gate static int
m_in(MINT * a,short b,FILE * f)317c478bd9Sstevel@tonic-gate m_in(MINT *a, short b, FILE *f)
327c478bd9Sstevel@tonic-gate {
337c478bd9Sstevel@tonic-gate 	MINT x, y, ten;
347c478bd9Sstevel@tonic-gate 	int sign, c;
357c478bd9Sstevel@tonic-gate 	short qten, qy;
367c478bd9Sstevel@tonic-gate 
377c478bd9Sstevel@tonic-gate 	_mp_xfree(a);
387c478bd9Sstevel@tonic-gate 	sign = 1;
397c478bd9Sstevel@tonic-gate 	ten.len = 1;
407c478bd9Sstevel@tonic-gate 	ten.val = &qten;
417c478bd9Sstevel@tonic-gate 	qten = b;
427c478bd9Sstevel@tonic-gate 	x.len = 0;
437c478bd9Sstevel@tonic-gate 	y.len = 1;
447c478bd9Sstevel@tonic-gate 	y.val = &qy;
45*981fe1b1SJohn Levon 	while ((c = getc(f)) != EOF) {
46*981fe1b1SJohn Levon 		switch (c) {
477c478bd9Sstevel@tonic-gate 
48*981fe1b1SJohn Levon 		case '\\':
49*981fe1b1SJohn Levon 			(void) getc(f);
507c478bd9Sstevel@tonic-gate 			continue;
51*981fe1b1SJohn Levon 		case '\t':
52*981fe1b1SJohn Levon 		case '\n':
537c478bd9Sstevel@tonic-gate 			a->len *= sign;
54*981fe1b1SJohn Levon 			_mp_xfree(&x);
557c478bd9Sstevel@tonic-gate 			return (0);
56*981fe1b1SJohn Levon 		case ' ':
57*981fe1b1SJohn Levon 			continue;
58*981fe1b1SJohn Levon 		case '-':
59*981fe1b1SJohn Levon 			sign = -sign;
60*981fe1b1SJohn Levon 			continue;
61*981fe1b1SJohn Levon 		default:
62*981fe1b1SJohn Levon 			if (c >= '0' && c <= '9') {
63*981fe1b1SJohn Levon 				qy = c - '0';
64*981fe1b1SJohn Levon 				mp_mult(&x, &ten, a);
65*981fe1b1SJohn Levon 				mp_madd(a, &y, a);
66*981fe1b1SJohn Levon 				_mp_move(a, &x);
67*981fe1b1SJohn Levon 				continue;
68*981fe1b1SJohn Levon 			} else {
69*981fe1b1SJohn Levon 				(void) ungetc(c, stdin);
70*981fe1b1SJohn Levon 				a->len *= sign;
71*981fe1b1SJohn Levon 				return (0);
72*981fe1b1SJohn Levon 			}
737c478bd9Sstevel@tonic-gate 		}
747c478bd9Sstevel@tonic-gate 	}
75*981fe1b1SJohn Levon 
767c478bd9Sstevel@tonic-gate 	return (EOF);
777c478bd9Sstevel@tonic-gate }
787c478bd9Sstevel@tonic-gate 
797c478bd9Sstevel@tonic-gate static void
m_out(MINT * a,short b,FILE * f)807c478bd9Sstevel@tonic-gate m_out(MINT *a, short b, FILE *f)
817c478bd9Sstevel@tonic-gate {
827c478bd9Sstevel@tonic-gate 	int sign, xlen, i;
837c478bd9Sstevel@tonic-gate 	short r;
847c478bd9Sstevel@tonic-gate 	MINT x;
857c478bd9Sstevel@tonic-gate 
867c478bd9Sstevel@tonic-gate 	char *obuf;
877c478bd9Sstevel@tonic-gate 	char *bp;
887c478bd9Sstevel@tonic-gate 
897c478bd9Sstevel@tonic-gate 	if (a == NULL)
907c478bd9Sstevel@tonic-gate 		return;
917c478bd9Sstevel@tonic-gate 	sign = 1;
927c478bd9Sstevel@tonic-gate 	xlen = a->len;
937c478bd9Sstevel@tonic-gate 	if (xlen < 0) {
947c478bd9Sstevel@tonic-gate 		xlen = -xlen;
957c478bd9Sstevel@tonic-gate 		sign = -1;
967c478bd9Sstevel@tonic-gate 	}
977c478bd9Sstevel@tonic-gate 	if (xlen == 0) {
987c478bd9Sstevel@tonic-gate 		(void) fprintf(f, "0\n");
997c478bd9Sstevel@tonic-gate 		return;
1007c478bd9Sstevel@tonic-gate 	}
1017c478bd9Sstevel@tonic-gate 	x.len = xlen;
1027c478bd9Sstevel@tonic-gate 	x.val = _mp_xalloc(xlen, "m_out");
1037c478bd9Sstevel@tonic-gate 	for (i = 0; i < xlen; i++)
1047c478bd9Sstevel@tonic-gate 		x.val[i] = a->val[i];
1057c478bd9Sstevel@tonic-gate 	obuf = malloc(7 * (size_t)xlen);
1067c478bd9Sstevel@tonic-gate 	bp = obuf + 7 * xlen - 1;
1077c478bd9Sstevel@tonic-gate 	*bp-- = 0;
1087c478bd9Sstevel@tonic-gate 	while (x.len > 0) {
1097c478bd9Sstevel@tonic-gate 		for (i = 0; i < 10 && x.len > 0; i++) {
1107c478bd9Sstevel@tonic-gate 			mp_sdiv(&x, b, &x, &r);
1117c478bd9Sstevel@tonic-gate 			*bp-- = (char)(r + '0');
1127c478bd9Sstevel@tonic-gate 		}
1137c478bd9Sstevel@tonic-gate 		if (x.len > 0)
1147c478bd9Sstevel@tonic-gate 			*bp-- = ' ';
1157c478bd9Sstevel@tonic-gate 	}
1167c478bd9Sstevel@tonic-gate 	if (sign == -1)
1177c478bd9Sstevel@tonic-gate 		*bp-- = '-';
1187c478bd9Sstevel@tonic-gate 	(void) fprintf(f, "%s\n", bp + 1);
1197c478bd9Sstevel@tonic-gate 	free(obuf);
1207c478bd9Sstevel@tonic-gate 	_mp_xfree(&x);
1217c478bd9Sstevel@tonic-gate }
1227c478bd9Sstevel@tonic-gate 
1237c478bd9Sstevel@tonic-gate static void s_div(MINT *, short, MINT *, short *);
1247c478bd9Sstevel@tonic-gate 
1257c478bd9Sstevel@tonic-gate void
mp_sdiv(MINT * a,short n,MINT * q,short * r)1267c478bd9Sstevel@tonic-gate mp_sdiv(MINT *a, short n, MINT *q, short *r)
1277c478bd9Sstevel@tonic-gate {
1287c478bd9Sstevel@tonic-gate 	MINT x, y;
1297c478bd9Sstevel@tonic-gate 	short sign;
1307c478bd9Sstevel@tonic-gate 
1317c478bd9Sstevel@tonic-gate 	sign = 1;
1327c478bd9Sstevel@tonic-gate 	x.len = a->len;
1337c478bd9Sstevel@tonic-gate 	x.val = a->val;
1347c478bd9Sstevel@tonic-gate 	if (n < 0) {
1357c478bd9Sstevel@tonic-gate 		sign = -sign;
1367c478bd9Sstevel@tonic-gate 		n = -n;
1377c478bd9Sstevel@tonic-gate 	}
1387c478bd9Sstevel@tonic-gate 	if (x.len < 0) {
1397c478bd9Sstevel@tonic-gate 		sign = -sign;
1407c478bd9Sstevel@tonic-gate 		x.len = -x.len;
1417c478bd9Sstevel@tonic-gate 	}
1427c478bd9Sstevel@tonic-gate 	s_div(&x, n, &y, r);
1437c478bd9Sstevel@tonic-gate 	_mp_xfree(q);
1447c478bd9Sstevel@tonic-gate 	q->val = y.val;
1457c478bd9Sstevel@tonic-gate 	q->len = sign * y.len;
1467c478bd9Sstevel@tonic-gate 	*r = *r * sign;
1477c478bd9Sstevel@tonic-gate }
1487c478bd9Sstevel@tonic-gate 
1497c478bd9Sstevel@tonic-gate static void
s_div(MINT * a,short n,MINT * q,short * r)1507c478bd9Sstevel@tonic-gate s_div(MINT *a, short n, MINT *q, short *r)
1517c478bd9Sstevel@tonic-gate {
1527c478bd9Sstevel@tonic-gate 	int qlen;
1537c478bd9Sstevel@tonic-gate 	int i;
1547c478bd9Sstevel@tonic-gate 	int x;
1557c478bd9Sstevel@tonic-gate 	short *qval;
1567c478bd9Sstevel@tonic-gate 	short *aval;
1577c478bd9Sstevel@tonic-gate 
1587c478bd9Sstevel@tonic-gate 	x = 0;
1597c478bd9Sstevel@tonic-gate 	qlen = a->len;
1607c478bd9Sstevel@tonic-gate 	q->val = _mp_xalloc(qlen, "s_div");
1617c478bd9Sstevel@tonic-gate 	aval = a->val + qlen;
1627c478bd9Sstevel@tonic-gate 	qval = q->val + qlen;
1637c478bd9Sstevel@tonic-gate 	for (i = qlen - 1; i >= 0; i--) {
1647c478bd9Sstevel@tonic-gate 		x = x * 0100000 + *--aval;
1657c478bd9Sstevel@tonic-gate 		*--qval = (short)(x / n);
1667c478bd9Sstevel@tonic-gate 		x = x % n;
1677c478bd9Sstevel@tonic-gate 	}
1687c478bd9Sstevel@tonic-gate 	*r = (short)x;
1697c478bd9Sstevel@tonic-gate 	if (qlen && q->val[qlen-1] == 0)
1707c478bd9Sstevel@tonic-gate 		qlen--;
1717c478bd9Sstevel@tonic-gate 	q->len = qlen;
1727c478bd9Sstevel@tonic-gate 	if (qlen == 0)
1737c478bd9Sstevel@tonic-gate 		free(q->val);
1747c478bd9Sstevel@tonic-gate }
1757c478bd9Sstevel@tonic-gate 
1767c478bd9Sstevel@tonic-gate int
mp_min(MINT * a)1777c478bd9Sstevel@tonic-gate mp_min(MINT *a)
1787c478bd9Sstevel@tonic-gate {
1797c478bd9Sstevel@tonic-gate 	return (m_in(a, 10, stdin));
1807c478bd9Sstevel@tonic-gate }
1817c478bd9Sstevel@tonic-gate 
1827c478bd9Sstevel@tonic-gate int
mp_omin(MINT * a)1837c478bd9Sstevel@tonic-gate mp_omin(MINT *a)
1847c478bd9Sstevel@tonic-gate {
1857c478bd9Sstevel@tonic-gate 	return (m_in(a, 8, stdin));
1867c478bd9Sstevel@tonic-gate }
1877c478bd9Sstevel@tonic-gate 
1887c478bd9Sstevel@tonic-gate void
mp_mout(MINT * a)1897c478bd9Sstevel@tonic-gate mp_mout(MINT *a)
1907c478bd9Sstevel@tonic-gate {
1917c478bd9Sstevel@tonic-gate 	m_out(a, 10, stdout);
1927c478bd9Sstevel@tonic-gate }
1937c478bd9Sstevel@tonic-gate 
1947c478bd9Sstevel@tonic-gate void
mp_omout(MINT * a)1957c478bd9Sstevel@tonic-gate mp_omout(MINT *a)
1967c478bd9Sstevel@tonic-gate {
1977c478bd9Sstevel@tonic-gate 	m_out(a, 8, stdout);
1987c478bd9Sstevel@tonic-gate }
1997c478bd9Sstevel@tonic-gate 
2007c478bd9Sstevel@tonic-gate void
mp_fmout(MINT * a,FILE * f)2017c478bd9Sstevel@tonic-gate mp_fmout(MINT *a, FILE *f)
2027c478bd9Sstevel@tonic-gate {
2037c478bd9Sstevel@tonic-gate 	m_out(a, 10, f);
2047c478bd9Sstevel@tonic-gate }
2057c478bd9Sstevel@tonic-gate 
2067c478bd9Sstevel@tonic-gate int
mp_fmin(MINT * a,FILE * f)2077c478bd9Sstevel@tonic-gate mp_fmin(MINT *a, FILE *f)
2087c478bd9Sstevel@tonic-gate {
2097c478bd9Sstevel@tonic-gate 	return (m_in(a, 10, f));
2107c478bd9Sstevel@tonic-gate }
211