1 /*************************************************************************
2  *
3  * @(#)parse.c	1.2 (CWI) 87/07/10
4  *
5  * Code to parse the ditroff output language and take the appropriate
6  * action.
7  *
8  * For a description of the ditroff language, see the comment in main.c.
9  *
10  ************************************************************************/
11 
12 #include "the.h"
13 
14 /* from dev.c  */
15 extern int	output;		/* do we output at all? */
16 extern int	hpos, vpos;	/* current position	*/
17 extern int	virtRES;	/* resolution of input		*/
18 
19 /* from main.c */
20 extern int	debug, dbg;
21 extern char	*devname;
22 
23 
24 conv(fp)
25 register FILE *fp;
26 {
27 	register int c, k;
28 	int m, n, n1, m1;
29 	char str[100], buf[300];
30 
31 	while ((c = getc(fp)) != EOF) {
32 		switch (c) {
33 		case '\n':	/* when input is text */
34 		case 0:		/* occasional noise creeps in */
35 		case '\t':
36 		case ' ':
37 			break;
38 		case '{':	/* push down current environment */
39 			t_push();
40 			break;
41 		case '}':
42 			t_pop();
43 			break;
44 		case '0': case '1': case '2': case '3': case '4':
45 		case '5': case '6': case '7': case '8': case '9':
46 			/* two motion digits plus a character */
47 			k = (c-'0')*10 + getc(fp)-'0';
48 			hmot(k);
49 			put1(getc(fp));
50 			break;
51 		case 'c':	/* single ascii character */
52 			put1(getc(fp));
53 			break;
54 		case 'C':
55 			fscanf(fp, "%s", str);
56 			put1s(str);
57 			break;
58 		case 't':	/* straight text */
59 			if (fgets(buf, sizeof(buf), fp) == NULL)
60 			    error(FATAL, "unexpected end of input");
61 			t_text(buf);
62 			break;
63 		case 'D':	/* draw function */
64 			if (fgets(buf, sizeof(buf), fp) == NULL)
65 			    error(FATAL, "unexpected end of input");
66 			switch (buf[0]) {
67 			case 'l':	/* draw a line */
68 			    sscanf(buf+1, "%d %d", &n, &m);
69 			    drawline(n, m);
70 			    break;
71 			case 'c':	/* circle */
72 			    sscanf(buf+1, "%d", &n);
73 			    drawcirc(n);
74 			    break;
75 			case 'e':	/* ellipse */
76 			    sscanf(buf+1, "%d %d", &m, &n);
77 			    drawellip(m, n);
78 			    break;
79 			case 'a':	/* arc */
80 			    sscanf(buf+1, "%d %d %d %d", &n, &m, &n1, &m1);
81 			    drawarc(n, m, n1, m1);
82 			    break;
83 
84 			case '~':	/* wiggly line */
85 			    drawwig(buf+1, fp, buf[0] == '~');
86 			    break;
87 			default:
88 			    error(FATAL, "unknown drawing function %s", buf);
89 			    break;
90 			}
91 			break;
92 		case 's':
93 			fscanf(fp, "%d", &n);
94 			setsize(t_size(n));
95 			break;
96 		case 'f':
97 			fscanf(fp, "%s", str);
98 			setfont(t_font(str));
99 			break;
100 		case 'H':	/* absolute horizontal motion */
101 			while ((c = getc(fp)) == ' ')
102 				;
103 			k = 0;
104 			do {
105 				k = 10 * k + c - '0';
106 			} while (isdigit(c = getc(fp)));
107 			ungetc(c, fp);
108 			hgoto(k);
109 			break;
110 		case 'h':	/* relative horizontal motion */
111 			while ((c = getc(fp)) == ' ')
112 				;
113 			k = 0;
114 			do {
115 				k = 10 * k + c - '0';
116 			} while (isdigit(c = getc(fp)));
117 			ungetc(c, fp);
118 			hmot(k);
119 			break;
120 		case 'w':	/* word space */
121 			break;
122 		case 'V':
123 			fscanf(fp, "%d", &n);
124 			vgoto(n);
125 			break;
126 		case 'v':
127 			fscanf(fp, "%d", &n);
128 			vmot(n);
129 			break;
130 		case 'P':	/* new spread */
131 
132 			DBGPRINT(0, ("output = %d\n", output));
133 
134 			if (output) outband(OVERBAND);
135 			break;
136 		case 'p':	/* new page */
137 			fscanf(fp, "%d", &n);
138 			t_page(n);
139 			break;
140 		case 'n':	/* end of line */
141 			t_newline();
142 
143 		case '#':	/* comment */
144 			do
145 				c = getc(fp);
146 			while (c != '\n' && c != EOF);
147 			break;
148 		case 'x':	/* device control */
149 			if (devcntrl(fp)) return;
150 			break;
151 		default:
152 			error(FATAL, "unknown input character %o %c", c, c);
153 		}
154 	}
155 }
156 
157 int
158 devcntrl(fp)		/* interpret device control functions */
159 FILE *fp;		/* returns -1 apon recieving "stop" command */
160 {
161         char str[20], str1[50], buf[50];
162 	int c, n;
163 
164 	fscanf(fp, "%s", str);
165 	switch (str[0]) {	/* crude for now */
166 	case 'i':			/* initialize */
167 		fileinit();
168 		t_init();
169 		break;
170 	case 't':			/* trailer */
171 		break;
172 	case 'p':			/* pause -- can restart */
173 		t_reset('p');
174 		break;
175 	case 's':			/* stop */
176 		t_reset('s');
177 		return -1;
178 	case 'r':			/* resolution assumed when prepared */
179 		fscanf(fp, "%d", &virtRES);
180 		initgraph(virtRES);		/* graph needs to know about this */
181 		break;
182 	case 'f':			/* font used */
183 		fscanf(fp, "%d %s", &n, str);
184 		(void) fgets(buf, sizeof buf, fp);   /* in case of filename */
185 		ungetc('\n', fp);		/* fgets goes too far */
186 		str1[0] = 0;			/* in case nothing comes in */
187 		sscanf(buf, "%s", str1);
188 		loadfont(n, str, str1);
189 		break;
190 	case 'H':			/* char height */
191 		fscanf(fp, "%d", &n);
192 		t_charht(n);
193 		break;
194 	case 'S':			/* slant */
195 		fscanf(fp, "%d", &n);
196 		t_slant(n);
197 		break;
198 	case 'T':			/* device name */
199 		fscanf(fp, "%s", str);
200 		if (strcmp(str,devname) != 0)
201 			exit(-1);	/* tell lpd to abort this file */
202 		break;
203 
204 	}
205 	while ((c = getc(fp)) != '\n')	/* skip rest of input line */
206 		if (c == EOF)
207 			return -1;
208 	return 0;
209 }
210