1/*
2 * Copyright (c) 1990, 2010, Oracle and/or its affiliates. All rights reserved.
3 */
4
5/*	Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T	*/
6/*	  All Rights Reserved  	*/
7
8/*
9 * Copyright (c) 1980 Regents of the University of California.
10 * All rights reserved. The Berkeley software License Agreement
11 * specifies the terms and conditions for redistribution.
12 */
13
14#include "e.h"
15#include <stdlib.h>
16#include <locale.h>
17
18#define	MAXLINE	8192	/* maximum input line */
19
20char in[MAXLINE+1];	/* input buffer */
21int noeqn;
22
23void error(int, char *, char *);
24
25static void do_inline(void);
26int eqn(int, char *[]);
27static int getaline(char *);
28static void init(void);
29void nrwid(int, int, int);
30int oalloc(void);
31void ofree(int);
32static void setfile(int, char *[]);
33void setps(int);
34
35int
36main(int argc, char *argv[])
37{
38	(void) setlocale(LC_ALL, "");
39#if !defined(TEXT_DOMAIN)
40#define	TEXT_DOMAIN "SYS_TEST"
41#endif
42	(void) textdomain(TEXT_DOMAIN);
43	return (eqn(argc, argv));
44}
45
46int
47eqn(int argc, char *argv[])
48{
49	int i, type;
50
51	setfile(argc, argv);
52	init_tbl();	/* install keywords in tables */
53	while ((type = getaline(in)) != EOF) {
54		eqline = linect;
55		if (in[0] == '.' && in[1] == 'E' && in[2] == 'Q') {
56			for (i = 11; i < 100; used[i++] = 0)
57				;
58			printf("%s", in);
59			printf(".nr 99 \\n(.s\n.nr 98 \\n(.f\n");
60			markline = 0;
61			init();
62			yyparse();
63			if (eqnreg > 0) {
64				printf(".nr %d \\w'\\*(%d'\n", eqnreg, eqnreg);
65				/*
66				 * printf(".if \\n(%d>\\n(.l .tm too-long eqn,
67				 * file %s, between lines %d-%d\n",
68				 * eqnreg, svargv[ifile], eqline, linect);
69				 */
70
71				/* for -ms macros */
72				printf(".nr MK %d\n", markline);
73
74				printf(".if %d>\\n(.v .ne %du\n", eqnht, eqnht);
75				printf(".rn %d 10\n", eqnreg);
76				if (!noeqn) printf("\\*(10\n");
77			}
78			printf(".ps \\n(99\n.ft \\n(98\n");
79			printf(".EN");
80			if (lastchar == EOF) {
81				putchar('\n');
82				break;
83			}
84			if (putchar(lastchar) != '\n')
85				while (putchar(gtc()) != '\n')
86					;
87		} else if (type == lefteq)
88			do_inline();
89		else
90			printf("%s", in);
91	}
92	return (0);
93}
94
95static int
96getaline(char *s)
97{
98	int c;
99	while ((*s++ = c = gtc()) != '\n' && c != EOF && c != lefteq)
100		if (s >= in+MAXLINE) {
101			error(!FATAL, gettext(
102			    "input line too long: %.20s\n"), in);
103			in[MAXLINE] = '\0';
104			break;
105		}
106	if (c == lefteq)
107		s--;
108	*s++ = '\0';
109	return (c);
110}
111
112static void
113do_inline(void)
114{
115	int ds;
116
117	printf(".nr 99 \\n(.s\n.nr 98 \\n(.f\n");
118	ds = oalloc();
119	printf(".rm %d \n", ds);
120	do {
121		if (*in)
122			printf(".as %d \"%s\n", ds, in);
123		init();
124		yyparse();
125		if (eqnreg > 0) {
126			printf(".as %d \\*(%d\n", ds, eqnreg);
127			ofree(eqnreg);
128		}
129		printf(".ps \\n(99\n.ft \\n(98\n");
130	} while (getaline(in) == lefteq);
131	if (*in)
132		printf(".as %d \"%s", ds, in);
133	printf(".ps \\n(99\n.ft \\n(98\n");
134	printf("\\*(%d\n", ds);
135	ofree(ds);
136}
137
138void
139putout(int p1)
140{
141	extern int gsize, gfont;
142	int before, after;
143	if (dbg)
144		printf(".\tanswer <- S%d, h=%d,b=%d\n", p1, eht[p1], ebase[p1]);
145	eqnht = eht[p1];
146	printf(".ds %d \\x'0'", p1);
147	/* suppposed to leave room for a subscript or superscript */
148#ifndef NEQN
149	before = eht[p1] - ebase[p1] - VERT(EM(1.2, ps));
150#else	/* NEQN */
151	before = eht[p1] - ebase[p1] - VERT(3);	/* 3 = 1.5 lines */
152#endif	/* NEQN	*/
153	if (spaceval != NULL)
154		printf("\\x'0-%s'", spaceval);
155	else if (before > 0)
156		printf("\\x'0-%du'", before);
157	printf("\\f%c\\s%d\\*(%d%s\\s\\n(99\\f\\n(98",
158	    gfont, gsize, p1, rfont[p1] == ITAL ? "\\|" : "");
159#ifndef NEQN
160	after = ebase[p1] - VERT(EM(0.2, ps));
161#else	/* NEQN */
162	after = ebase[p1] - VERT(1);
163#endif	/* NEQN */
164	if (spaceval == NULL && after > 0)
165		printf("\\x'%du'", after);
166	putchar('\n');
167	eqnreg = p1;
168	if (spaceval != NULL) {
169		free(spaceval);
170		spaceval = NULL;
171	}
172
173}
174
175int
176max(int i, int j)
177{
178	return (i > j ? i : j);
179}
180
181int
182oalloc(void)
183{
184	int i;
185	char ebuf[3];
186
187	for (i = 11; i < 100; i++)
188		if (used[i]++ == 0)
189			return (i);
190	(void) snprintf(ebuf, sizeof (ebuf), "%d", i);
191	error(FATAL, gettext("no eqn strings left"), ebuf);
192	return (0);
193}
194
195void
196ofree(int n)
197{
198	used[n] = 0;
199}
200
201void
202setps(int p)
203{
204	printf(".ps %d\n", EFFPS(p));
205}
206
207void
208nrwid(int n1, int p, int n2)
209{
210	printf(".nr %d \\w'\\s%d\\*(%d'\n", n1, EFFPS(p), n2);
211}
212
213static void
214setfile(int argc, char *argv[])
215{
216	static char *nullstr = "-";
217
218	svargc = --argc;
219	svargv = argv;
220	while (svargc > 0 && svargv[1][0] == '-') {
221		switch (svargv[1][1]) {
222
223		case 'd': lefteq = svargv[1][2]; righteq = svargv[1][3]; break;
224		case 's': gsize = atoi(&svargv[1][2]); break;
225		case 'p': deltaps = atoi(&svargv[1][2]); break;
226		case 'f': gfont = svargv[1][2]; break;
227		case 'e': noeqn++; break;
228		case 0:	goto endargs;
229		default: dbg = 1;
230		}
231		svargc--;
232		svargv++;
233	}
234endargs:
235	ifile = 1;
236	linect = 1;
237	if (svargc <= 0) {
238		curfile = stdin;
239		svargv[1] = nullstr;
240	}
241	else
242		openinfile();	/* opens up the first input file */
243}
244
245void
246yyerror(void)
247{
248}
249
250static void
251init(void)
252{
253	ct = 0;
254	ps = gsize;
255	ft = gfont;
256	setps(ps);
257	printf(".ft %c\n", ft);
258}
259
260void
261error(int fatal, char *s1, char *s2)
262{
263	if (fatal > 0)
264		printf(gettext("eqn fatal error: "));
265	printf(s1, s2);
266	printf(gettext("\nfile %s, between lines %d and %d\n"),
267	    svargv[ifile], eqline, linect);
268	fprintf(stderr, gettext("eqn: "));
269	if (fatal > 0)
270		fprintf(stderr, gettext("fatal error: "));
271	fprintf(stderr, s1, s2);
272	fprintf(stderr, gettext("\nfile %s, between lines %d and %d\n"),
273	    svargv[ifile], eqline, linect);
274	if (fatal > 0)
275		exit(1);
276}
277