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
conv(fp)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
devcntrl(fp)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