Stop plink losing data at start of session
[u/mdw/putty] / mkres.c
1 /*
2 *
3 * Commands ...
4 *
5 * INIT(...) : Set configs. (rowstep, totwidth, stdheight, stdwidth)
6 * SPOS(V,H) : Set current position.
7 *
8 * SCOL : Standard column, for a single column, increment position
9 * NEXT(V,H) : increment postion by standard + (V,H)
10 * COL(K,N) : X,Y position for col K of N (default 1of [same as last])
11 * SS : Standard size of last COL (using number of cols).
12 * ADJ(V,H) : Adjust next COL or SCOL by (V,H)
13 *
14 * CURX(H) : Current Xpos+H
15 * CURY(V) : Current Ypos+V
16 *
17 */
18
19 #include <stdio.h>
20
21 FILE * ifd;
22 FILE * ofd;
23
24 char wordbuf[256];
25
26 #define T_INIT 100 /* Init the style of the values */
27 #define T_SPOS 101 /* Set the current position */
28 #define T_SCOL 102 /* Standard column COL(1,1), SS NEXT */
29 #define T_NEXT 103 /* Next line */
30 #define T_COL 104 /* Multi-column */
31 #define T_SS 105 /* Standard Size */
32 #define T_ADJ 106 /* Adjust next COL/SCOL */
33 #define T_GRID 107 /* */
34 #define T_GAP 108 /* */
35
36 #define T_CURX 120 /* Current X + offset */
37 #define T_CURY 121 /* Current Y + offset */
38
39 #define T_SAVEPOSN 122 /* Save current status */
40 #define T_RESTOREPOSN 123 /* Restore current status */
41
42
43 struct keys {
44 char * name;
45 int token;
46 } keywords[] = {
47 {"INIT", T_INIT, },
48 {"SPOS", T_SPOS, },
49 {"SCOL", T_SCOL, },
50 {"NEXT", T_NEXT, },
51 {"COL", T_COL, },
52 {"SS", T_SS, },
53 {"ADJ", T_ADJ, },
54 {"GRID", T_GRID, },
55 {"GAP", T_GAP, },
56 {"CURX", T_CURX, },
57 {"CURY", T_CURY, },
58 {"SAVEPOSN", T_SAVEPOSN, },
59 {"RESTOREPOSN", T_RESTOREPOSN, },
60 {0,0}
61 };
62
63 struct statbuf {
64 int token;
65
66 int curx;
67 int cury;
68 int cols;
69
70 int con_width;
71 int con_height;
72 int row_step;
73 int tot_width;
74
75 int gutter;
76
77 int vadjust;
78 int hadjust;
79 }
80 status, saved_status;
81
82 int ar_count, ar_val[10];
83
84 main(argc, argv)
85 int argc;
86 char ** argv;
87 {
88 int ch;
89
90 ifd = stdin; ofd = stdout;
91
92 while(!feof(ifd))
93 {
94 if (ferror(ifd))
95 {
96 fprintf(stderr, "Error reading input file\n");
97 exit(1);
98 }
99
100 if (readword() < 0) break;
101
102 if (check_keys() < 0)
103 {
104 fprintf(ofd, "%s", wordbuf);
105 continue;
106 }
107
108 /* To get here we have found one of our keywords, some words will
109 * be followed by an argument.
110 */
111
112 ar_count = 0;
113
114 while((ch = getc(ifd)) != EOF && isspace(ch) && ch != '\n')
115 putc(ch, ofd);
116
117 if (ch == '(' )
118 {
119 for(;;)
120 {
121 ar_val[ar_count++] = get_number();
122
123 while((ch=getc(ifd)) != EOF && isspace(ch)) ;
124 if (ch != ',') break;
125 }
126 if (ch == EOF) break;
127 }
128 else
129 ungetc(ch, ifd);
130
131 /* Ok got args, now doit */
132 execute_command();
133 }
134 exit(0);
135 }
136
137 /* This is the lexer - not using lex(1) because this will have to
138 * compile under windows.
139 */
140 int readword()
141 {
142 int ch;
143 char *wp;
144
145 try_again:; /* This is for "too big" words and strings. */
146
147 wp=wordbuf;
148
149 /* Find a word ... */
150 while((ch=getc(ifd)) != EOF && !isalpha(ch) && ch != '"')
151 putc(ch, ofd);
152
153 if (ch == '"')
154 {
155 putc(ch, ofd);
156
157 while((ch=getc(ifd)) != EOF && ch != '"')
158 putc(ch, ofd);
159 if (ch != EOF)
160 putc(ch, ofd);
161
162 goto try_again;
163 }
164
165 if (ch == EOF) return -1;
166
167 do
168 {
169 if (wp>=wordbuf+sizeof(wordbuf)-2)
170 {
171 *wp = 0;
172 fprintf(ofd, "%s", wordbuf);
173
174 while(ch!=EOF && isalpha(ch))
175 {
176 putc(ch, ofd);
177 ch=getc(ifd);
178 }
179 ungetc(ch, ifd);
180
181 goto try_again;
182 }
183 *wp++ = ch;
184 ch = getc(ifd);
185 }
186 while(ch != EOF && (isalnum(ch) || ch == '_'));
187 *wp = 0;
188
189 ungetc(ch, ifd);
190 return wp-wordbuf;
191 }
192
193 int
194 get_number()
195 {
196 int ch;
197 int sign = 0;
198 int value = 0;
199
200 while((ch=getc(ifd)) != EOF && isspace(ch)) ;
201
202 if( ch == '+' ) { sign=1; ch=getc(ifd); }
203 else if( ch == '-' ) { sign=-1; ch=getc(ifd); }
204
205 while(ch>='0' && ch<='9')
206 {
207 value = value * 10 + ch - '0';
208 ch = getc(ifd);
209 }
210
211 ungetc(ch, ifd);
212 if (sign < 0) value = -value;
213
214 return value;
215 }
216
217 check_keys()
218 {
219 struct keys *p;
220
221 for(p=keywords; p->name; p++)
222 {
223 if (strcmp(wordbuf, p->name) == 0 )
224 {
225 status.token = p->token;
226 return p->token;
227 }
228 }
229 return -1;
230 }
231
232 execute_command()
233 {
234 if (status.cols < 1) status.cols = 1;
235
236 switch(status.token)
237 {
238 case T_INIT:
239 if (ar_count > 0) status.row_step = ar_val[0];
240 if (ar_count > 1) status.tot_width = ar_val[1];
241 if (ar_count > 2) status.con_height = ar_val[2];
242 else status.con_height = status.row_step;
243 if (ar_count > 3) status.con_width = ar_val[3];
244 else status.con_width = status.tot_width;
245
246 status.gutter = ( status.tot_width - status.con_width ) /2;
247 break;
248
249 case T_SPOS:
250 status.cury = status.curx = 0;
251 if (ar_count > 0) status.cury = ar_val[0];
252 if (ar_count > 1) status.curx = ar_val[1];
253 break;
254
255 case T_SCOL:
256 fprintf(ofd, "%d, %d", status.curx + status.hadjust,
257 status.cury + status.vadjust);
258 status.hadjust = status.vadjust = 0;
259
260 fprintf(ofd, ", %d, %d", status.con_width, status.con_height);
261
262 status.cury += status.row_step;
263
264 if (ar_count > 0) status.cury += ar_val[0];
265 if (ar_count > 1) status.curx += ar_val[1];
266 break;
267
268 case T_NEXT:
269 status.cury += status.row_step;
270 if (ar_count > 0) status.cury += ar_val[0];
271 if (ar_count > 1) status.curx += ar_val[1];
272 break;
273
274 case T_COL:
275 {
276 int curcol;
277 int col_pos;
278
279 if (ar_count > 0) curcol = ar_val[0]; else curcol = 1;
280 if (ar_count > 1) status.cols = ar_val[1];
281
282 col_pos = (status.con_width+status.gutter) *(curcol-1) /status.cols;
283
284 fprintf(ofd, "%d, %d",
285 status.curx + status.hadjust + col_pos,
286 status.cury + status.vadjust);
287 status.hadjust = status.vadjust = 0;
288 }
289 break;
290
291 case T_SS:
292 {
293 int wm = 1, hm=1;
294 int width;
295 if (ar_count > 0) wm = ar_val[0];
296 if (ar_count > 1) hm = ar_val[1];
297
298 width = (status.con_width+status.gutter) / status.cols;
299 width *= wm;
300 width -= status.gutter;
301
302 fprintf(ofd, "%d, %d", width, hm*status.con_height);
303 }
304 break;
305
306 case T_ADJ:
307 if (ar_count > 0) status.vadjust = ar_val[0];
308 if (ar_count > 1) status.hadjust = ar_val[0];
309 break;
310
311 case T_GRID:
312 if (ar_count > 0) status.cols = ar_val[0];
313 else status.cols = 1;
314 if (ar_count > 1) status.con_height = ar_val[1];
315 if (ar_count > 2) status.row_step = ar_val[2];
316 break;
317
318 case T_GAP:
319 if (ar_count > 0) status.cury += ar_val[0];
320 else status.cury += 2;
321 break;
322
323 case T_CURX:
324 if (ar_count>0)
325 fprintf(ofd, "%d", status.curx+ar_val[0]);
326 else
327 fprintf(ofd, "%d", status.curx);
328 break;
329 case T_CURY:
330 if (ar_count>0)
331 fprintf(ofd, "%d", status.cury+ar_val[0]);
332 else
333 fprintf(ofd, "%d", status.cury);
334 break;
335
336 case T_SAVEPOSN:
337 saved_status = status;
338 break;
339 case T_RESTOREPOSN:
340 status = saved_status;
341 break;
342 }
343 }