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