Add tests, fixes for tests, reinstate and type-convert stuff marked "bitrot"
[ccom.git] / cvopt.c
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <unistd.h>
4
5 int     tabflg;
6 int     labno   = 1;
7 int opno;
8 FILE    *curbuf;
9 FILE    *obuf;
10 FILE    *oobuf;
11 char  oname[]="/tmp/cvoptaXXXXXX";
12 char ooname[]="/tmp/cvoptbXXXXXX";
13 char lbuf[BUFSIZ];
14 char *lbufp = lbuf;
15
16 #ifndef __P
17 #ifdef __STDC__
18 #define __P(args) args
19 #else
20 #define __P(args) ()
21 #endif
22 #endif
23
24 int main __P((int argc, char **argv));
25 int flag __P((void));
26 void put __P((int c));
27 void comment __P((int c));
28
29 int main(argc, argv) int argc; char **argv; {
30 /*
31         A1 -> A
32         A2    B
33         A     O
34         B1    C
35         B2    D
36         BE    L
37         BF    P
38         C1    E
39         C2    F
40         F     G
41         H     H
42         R     I
43         R1    J
44         S     K
45         I     M
46         M     N
47
48                 *       +1
49                 S       +2
50                 C       +4
51                 1       +8
52
53         z  -> 4
54         c     10
55         a     14
56         e     20
57         n     63
58         *       +0100
59 */
60
61         int c, snlflg, nlflg, t, smode, m, ssmode, peekc, side;
62 #ifndef pdp11
63         int fd;
64 #endif
65
66         smode = nlflg = snlflg = ssmode = 0;
67         if (argc>1)
68                 if (freopen(argv[1], "r", stdin) == NULL) {
69                         fprintf(stderr, "%s?\n", argv[1]);
70                         return(1);
71                 }
72         if (argc>2) 
73                 if (freopen(argv[2], "w", stdout) == NULL) {
74                         fprintf(stderr, "%s?\n", argv[2]);
75                         return(1);
76                 }
77 #ifdef pdp11
78         mktemp(oname);
79         if ((obuf = fopen(oname, "w")) == NULL) {
80                 fprintf(stderr, "%s?\n", oname);
81                 exit(1);
82         }
83         mktemp(ooname);
84         if ((oobuf = fopen(ooname, "w")) == NULL) {
85                 fprintf(stderr, "%s?\n", ooname);
86                 exit(1);
87         }
88 #else
89         fd = mkstemp(oname);
90         if (fd < 0 || (obuf = fdopen(fd, "w")) == NULL) {
91                 fprintf(stderr, "%s?\n", oname);
92                 exit(1);
93         }
94         fd = mkstemp(ooname);
95         if (fd < 0 || (oobuf = fdopen(fd, "w")) == NULL) {
96                 fprintf(stderr, "%s?\n", ooname);
97                 exit(1);
98         }
99 #endif
100         printf("#include \"c1.h\"");
101         curbuf = obuf;
102 loop:
103         c = getchar();
104         if (c!='\n' && c!='\t')
105                 nlflg = 0;
106         if (ssmode!=0 && c!='%') {
107                 ssmode = 0;
108                 curbuf = stdout;
109                 fprintf(curbuf, "\nstatic char L%d[]=\"", labno++);
110         }
111         switch(c) {
112
113         case EOF:
114                 fprintf(obuf, "\t{0},\n};\n");
115                 fclose(obuf);
116                 if (freopen(oname, "r", stdin) == NULL) {
117                         fprintf(stderr, "%s?\n",oname);
118                         exit(1);
119                 }
120                 while ((c = getchar()) != EOF)
121                         putchar(c);
122                 unlink(oname);
123                 fclose(oobuf);
124                 if (freopen(ooname, "r", stdin) == NULL) {
125                         fprintf(stderr, "%s?\n",ooname);
126                         exit(1);
127                 }
128                 while ((c = getchar()) != EOF)
129                         putchar(c);
130                 unlink(ooname);
131                 return(0);
132
133         case 'A':
134                 if ((c=getchar())=='1' || c=='2') {
135                         put(c+'A'-'1');
136                         goto loop;
137                 }
138                 put('O');
139                 ungetc(c, stdin);
140                 goto loop;
141
142         case 'B':
143                 switch (getchar()) {
144
145                 case '1':
146                         put('C');
147                         goto loop;
148
149                 case '2':
150                         put('D');
151                         goto loop;
152
153                 case 'E':
154                         put('L');
155                         goto loop;
156
157                 case 'F':
158                         put('P');
159                         goto loop;
160                 }
161                 put('?');
162                 goto loop;
163
164         case 'C':
165                 put(getchar()+'E'-'1');
166                 goto loop;
167
168         case 'F':
169                 put('G');
170                 goto subtre;
171
172         case 'R':
173                 if ((c=getchar()) == '1')
174                 put('J'); else {
175                         put('I');
176                         ungetc(c, stdin);
177                 }
178                 goto loop;
179
180         case 'H':
181                 put('H');
182                 goto subtre;
183
184         case 'I':
185                 put('M');
186                 goto loop;
187
188         case 'S':
189                 put('K');
190 subtre:
191                 snlflg = 1;
192                 t = 'A';
193 l1:
194                 switch (c=getchar()) {
195
196                 case '*':
197                         t++;
198                         goto l1;
199
200                 case 'S':
201                         t += 2;
202                         goto l1;
203
204                 case 'C':
205                         t += 4;
206                         goto l1;
207
208                 case '1':
209                         t += 8;
210                         goto l1;
211
212                 case '2':
213                         t += 16;
214                         goto l1;
215                 }
216                 ungetc(c, stdin);
217                 put(t);
218                 goto loop;
219
220         case '#':
221                 if(getchar()=='1')
222                         put('#'); else
223                         put('"');
224                 goto loop;
225
226         case '%':
227                 if (smode)
228                         curbuf = obuf;
229                 if (ssmode==0) {
230                         if ((peekc=getchar())=='[') {
231                                 printf("\n#define ");
232                                 while((c=getchar())!=']' && c!=':')
233                                         putchar(c);
234                                 printf(" L%d\n",labno);
235                                 if (c==':') getchar();
236                                 getchar();
237                                 curbuf = obuf;
238                                 goto loop;
239                         }
240                         ungetc(peekc, stdin);
241                 }
242                 side=0;
243 loop1:
244                 switch (c=getchar()) {
245
246                 case ' ':
247                 case '\t':
248                         goto loop1;
249                 case 'a':
250                         m = 16;
251                         t = flag();
252                         goto pf;
253
254                 case ',':
255                         side=1;
256                         goto loop1;
257
258                 case 'i':
259                         m = 12;
260                         t = flag();
261                         goto pf;
262                 case 'z':
263                         m = 4;
264                         t = flag();
265                         goto pf;
266
267                 case 'r':
268                         m = 9;
269                         t = flag();
270                         goto pf;
271
272                 case '1':
273                         m = 5;
274                         t = flag();
275                         goto pf;
276
277                 case 'c':
278                         t = 0;
279                         m = 8;
280                         goto pf;
281
282                 case 'e':
283                         t = flag();
284                         m = 20;
285                         goto pf;
286
287                 case 'n':
288                         t = flag();
289                         m = 63;
290 pf:
291                         if ((c=getchar())=='*')
292                                 m += 0100; else
293                                 ungetc(c, stdin);
294                         if (side==0) {
295                                 if (opno==0) fprintf(curbuf,"\nstruct optab optab[]={\n");
296                                 fprintf(curbuf,"\t{");
297                         }
298                         fprintf(curbuf, "%d,%d,", m, t);
299                         goto loop1;
300                 case '[':
301                         printf("\n#define L%d ", labno++);
302                         while ((c=getchar())!=']')
303                                 putchar(c);
304                         printf("\n");
305                         ssmode = 0;
306                         smode = 0;
307                         goto loop;
308
309                 case '{':
310                 for(;;) {
311                         while ((c=getchar())!='%') putc(c,oobuf);
312                         if ((c=getchar())=='}') goto loop;
313                         else {putc('%',oobuf); putc(c,oobuf);}
314                 }
315                         
316                 case '\n':
317                         fprintf(curbuf, "L%d},  /* %d */\n", labno,opno);
318                         ++opno;
319                         ssmode = 1;
320                         nlflg = 1;
321                         smode = 1;
322                         goto loop;
323
324                 case '/':
325                         comment(c); goto loop1;
326
327                 }
328                 put(c);
329                 goto loop1;
330
331         case '\t':
332                 if (nlflg) {
333                         nlflg = 0;
334                         goto loop;
335                 }
336                 if (smode) {
337                         tabflg++;
338                         goto loop;
339                 }
340                 put('\t');
341                 goto loop;
342
343         case '\n':
344                 lbufp=lbuf;
345                 if (!smode)  {
346                         put('\n');
347                         goto loop;
348                 }
349                 if (nlflg) {
350                         nlflg = 0;
351                         fprintf(curbuf, "\";");
352                         curbuf = obuf;
353                         smode = 0;
354                         goto loop;
355                 }
356                 if (!snlflg)
357                         fprintf(curbuf, "\\n");
358                 snlflg = 0;
359                 nlflg = 1;
360                 goto loop;
361
362         case '/':
363                 comment(c); goto loop;
364
365         case 'X':
366         case 'Y':
367         case 'T':
368                 snlflg++;
369                 break;
370
371         case ':':
372                 fseek(curbuf,(long)(lbuf-lbufp),2);
373                 *lbufp='\0';
374                 if (opno!=0) {fprintf(curbuf,"\t{0},\n"); ++opno;}
375                 printf("\n#define %s &optab[%d]\n",lbuf,opno);
376                 fprintf(curbuf,"/* %s */",lbuf);
377                 lbufp=lbuf;
378                 goto loop;
379
380         }
381         *lbufp++=c;
382         put(c);
383         goto loop;
384 }
385
386 int flag() {
387         register int c, f;
388
389         f = 0;
390 l1:
391         switch(c=getchar()) {
392
393         case 'w':
394                 f = 1;
395                 goto l1;
396
397         case 'i':
398                 f = 2;
399                 goto l1;
400
401         case 'b':
402                 if (f==9)               /* unsigned word/int seen yet? */
403                         f = 10;         /*  yes - it is unsigned byte */
404                 else
405                         f = 3;          /*  no - it is regular (signed) byte */
406                 goto l1;
407
408         case 'f':
409                 f = 4;
410                 goto l1;
411
412         case 'd':
413                 f = 5;
414                 goto l1;
415
416         case 'u':
417                 if (f==3)               /* regular (signed) byte seen ? */
418                         f = 10;         /*  yes - unsigned byte now */
419                 else if (f == 8)        /* regular (signed) long seen? */
420                         f = 11;         /*  yes - it is unsigned long now */
421                 else
422                         f = 9;          /* otherwise we have unsigned word */
423                 goto l1;
424
425         case 's':
426                 f = 6;
427                 goto l1;
428
429         case 'l':
430                 if (f == 9)             /* seen unsigned yet? */
431                         f = 11;         /*  yes - it is unsigned long now */
432                 else
433                         f = 8;          /*  no - it is unsigned word now */
434                 goto l1;
435
436         case 'p':
437                 f += 16;
438                 goto l1;
439         }
440         ungetc(c, stdin);
441         return(f);
442 }
443
444 void put(c) int c; {
445         if (tabflg) {
446                 tabflg = 0;
447                 fprintf(curbuf, "\\%o", c+0200);
448         } else {
449                 if (c=='"') putc('\\',curbuf);
450                 putc(c, curbuf);
451         }
452 }
453
454 void comment(c) int c; {
455         putc(c,curbuf);
456         if ((c=getchar())=='*') for (;;) {
457                 do putc(c,curbuf); while ((c=getchar())!='*');
458                 putc(c,curbuf);
459                 if ((c=getchar())=='/') {putc(c,curbuf); break;}
460         } else ungetc(c,stdin);
461 }