xref: /illumos-gate/usr/src/cmd/eqn/io.c (revision afab0816ecb604f0099a09ad8ee398f0d7b77b1c)
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 
20 char in[MAXLINE+1];	/* input buffer */
21 int noeqn;
22 
23 void error(int, char *, char *);
24 
25 static void do_inline(void);
26 int eqn(int, char *[]);
27 static int getaline(char *);
28 static void init(void);
29 void nrwid(int, int, int);
30 int oalloc(void);
31 void ofree(int);
32 static void setfile(int, char *[]);
33 void setps(int);
34 
35 int
36 main(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 
46 int
47 eqn(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 
95 static int
96 getaline(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 
112 static void
113 do_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 
138 void
139 putout(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 
175 int
176 max(int i, int j)
177 {
178 	return (i > j ? i : j);
179 }
180 
181 int
182 oalloc(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 
195 void
196 ofree(int n)
197 {
198 	used[n] = 0;
199 }
200 
201 void
202 setps(int p)
203 {
204 	printf(".ps %d\n", EFFPS(p));
205 }
206 
207 void
208 nrwid(int n1, int p, int n2)
209 {
210 	printf(".nr %d \\w'\\s%d\\*(%d'\n", n1, EFFPS(p), n2);
211 }
212 
213 static void
214 setfile(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 	}
234 endargs:
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 
245 void
246 yyerror(void)
247 {
248 }
249 
250 static void
251 init(void)
252 {
253 	ct = 0;
254 	ps = gsize;
255 	ft = gfont;
256 	setps(ps);
257 	printf(".ft %c\n", ft);
258 }
259 
260 void
261 error(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