1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278#include <assert.h>
279#include <ctype.h>
280#include <errno.h>
281#include <limits.h>
282#include <stdio.h>
283#include <stdlib.h>
284#include <string.h>
285
286#ifndef LONG_BIT
287#define LONG_BIT (CHAR_BIT * sizeof (long))
288#endif
289
290#define MAXfunction 32
291#define MAXBITS LONG_BIT
292typedef unsigned long bits;
293enum type {T_ERROR, T_UNKNOWN, T_INTEGER, T_STRING};
294const char *const typename[] = {"error", "unknown", "integer", "string"};
295enum walkstringop {COUNTARRAYS, DECLAREARRAYS, COMPILEARRAYS};
296char *bitstype = "unsigned long";
297
298int maxfunctionname, maxargwidth;
299char *progname = "makedis";
300char **global_argv;
301char *filename;
302char *headerfilename;
303FILE *headerfile;
304int lineno;
305int indentation;
306int debug, dump, warnings;
307
308
309
310
311bits componentbits;
312
313
314struct entry;
315struct arg;
316struct string;
317struct functioncall;
318struct array;
319struct bits;
320struct bitsplice;
321
322
323int main(int argc, char **argv);
324int makedis(FILE *f, char *fname);
325struct function *findfunction(char *function);
326int parseextern(struct function *fp, FILE *f);
327struct function *makefunction(char *function);
328int parsebits(struct function *fp, char *bitstring, int nbits);
329int parseentrybits(struct entry *ep, char *bitstring, int nbits, int issplice);
330int parsecontrol(char *name, char *value);
331int parseargs(struct function *fp, FILE *f, int *cp);
332int parsestring(struct function *fp, char *str);
333enum type makestring(struct function *fp, struct string **stringlink,
334 char **stringp, char *magic, enum type targettype);
335int parsedollar(struct function *fp, char **stringp, struct string *sp);
336int parsebitsplice(struct function *fp, char *bitstring, int nbits,
337 struct string *sp);
338int findvariable(struct function *fp, int name, struct string *sp);
339int parsefunctioncall(struct function *fp, char *start, char **stringp,
340 struct string *sp);
341int parsearray(struct function *fp, char **stringp, struct string *sp,
342 enum type t);
343void dumpfunctions(void);
344void dumpfunction(struct function *fp);
345void showentry(FILE *f, struct function *fp, struct entry *ep, bits highlight);
346void showbits(FILE *f, struct entry *ep, int nbits, bits highlight);
347void showargs(FILE *f, struct arg *ap, int fieldwidth);
348void showstring(FILE *f, struct string *sp);
349void showstringelement(FILE *f, struct string *sp);
350void showfunctioncall(FILE *f, struct functioncall *fcp);
351void showarray(FILE *f, struct array *ap);
352int outputfunctions(void);
353void outputidentity(FILE *f);
354int outputdeclarations(void);
355void outputconcats(void);
356void outputconcat(int n);
357void outputconcatheader(FILE *f, int n);
358void findarrays(void);
359int checkfixedlength(struct array *ap);
360int outputfunction(struct function *fp);
361void functionarray(struct function *fp);
362void functionheader(FILE *f, struct function *fp);
363int simplearray(struct array *ap);
364void compiletype(FILE *f, enum type *tp);
365int functionswitch(struct function *fp, bits mask, bits value);
366int compilestring(int assignto, struct string *sp, enum type type);
367int compilecheckedstring(int assignto, struct string *sp, enum type type);
368void compileassign(int assignto);
369void compiletemp(int tempno);
370void compiletext(char *s);
371int compileconcat(struct string *sp, enum type type);
372int compilenull(enum type type);
373int compilesimple(struct string *sp, enum type type);
374int compilearrayref(struct array *ap);
375int compilefunctioncall(struct string *sp);
376int walkstring(struct string *sp, enum walkstringop op, int tempno);
377int compilearray(struct array *ap);
378void compilesimplearray(enum type *tp, char *name, int num, struct array *ap);
379void declarearray(struct array *ap);
380void compilebitstring(struct bits *bp);
381void compilebitsplice(struct bitsplice *splicep);
382int bitcount(bits x);
383bits allbitsset(int nbits);
384void findent(FILE *f);
385void indent(void);
386void *xrealloc(char *oldp, size_t size);
387void *xmalloc(size_t size);
388void *xstrdup(char *s);
389int prematureeof(void);
390
391
392int main(int argc, char **argv) {
393 int i;
394 FILE *f;
395
396 global_argv = argv;
397 if (argc > 0)
398 progname = argv[0];
399 for (i = 1; i < argc && argv[i][0] == '-'; i++) {
400 switch (argv[i][1]) {
401 case 'h':
402 if (++i >= argc)
403 goto Usage;
404 headerfilename = argv[i]; break;
405 case 'd':
406 debug = 1; break;
407 case 'D':
408 dump = 1; break;
409 case 'w':
410 warnings = 1; break;
411 default:
412Usage:
413 fprintf(stderr, "Usage: %s [file]\n", progname);
414 return 1;
415 }
416 }
417 if (i == argc)
418 return makedis(stdin, "<stdin>");
419 if (i + 1 != argc)
420 goto Usage;
421 if ((f = fopen(argv[i], "r")) == NULL) {
422 fprintf(stderr, "%s: %s: %s\n", progname, argv[i], strerror(errno));
423 return 1;
424 }
425 return makedis(f, argv[i]);
426}
427
428
429int makedis(FILE *f, char *fname) {
430 int c, i;
431 char function[MAXfunction], bitstring[MAXBITS];
432 static char *string = NULL;
433 int stringlen = 0;
434 struct function *fp;
435
436 filename = fname;
437 lineno = 1;
438
439 while (1) {
440
441 while (isspace(c = getc(f)))
442 if (c == '\n')
443 lineno++;
444 if (c == EOF)
445 break;
446
447
448 if (c == '#') {
449 while ((c = getc(f)) != '\n')
450 if (c == EOF)
451 return prematureeof();
452 lineno++;
453 continue;
454 }
455
456
457 for (i = 0; i < sizeof function && !isspace(c); i++, c = getc(f)) {
458 if (c == EOF)
459 return prematureeof();
460 function[i] = c;
461 }
462 if (i >= sizeof function) {
463 fprintf(stderr, "%s: %s(%d): function name is too long: %.*s\n",
464 progname, filename, lineno, i, function);
465 return 1;
466 }
467 function[i] = '\0';
468
469
470 while (isspace(c) && c != '\n')
471 c = getc(f);
472
473
474 if (function[0] == ':')
475 fp = 0;
476 else {
477 fp = makefunction(function);
478 if (fp == NULL)
479 return 1;
480
481
482 for (i = 0; i < sizeof bitstring && isalnum(c); i++, c = getc(f)) {
483 if (c == EOF)
484 return prematureeof();
485 bitstring[i] = c;
486 }
487 if (isalnum(c)) {
488 fprintf(stderr, "%s: %s(%d): bit string is too long: %.*s\n",
489 progname, filename, lineno, i, bitstring);
490 return 1;
491 }
492 if (parsebits(fp, bitstring, i) != 0)
493 return 1;
494
495
496 if (parseargs(fp, f, &c) != 0)
497 return 1;
498
499
500 while (isspace(c) && c != '\n')
501 c = getc(f);
502
503
504 if (c == ':') {
505 if (parseextern(fp, f) != 0)
506 return 1;
507 continue;
508 }
509 }
510
511
512 i = 0;
513 while (1) {
514 for ( ; c != '\n'; i++, c = getc(f)) {
515 if (c == EOF)
516 return prematureeof();
517 if (i >= stringlen) {
518 stringlen = stringlen * 2 + 16;
519 string = xrealloc(string, stringlen);
520 }
521 string[i] = c;
522 }
523 lineno++;
524 if (i > 0) {
525 switch (string[i - 1]) {
526 case '\\':
527 i--;
528
529 case '|':
530 while (isspace(c = getc(f)) && c != '\n') ;
531 continue;
532 }
533 }
534 break;
535 }
536 if (i >= stringlen) {
537 stringlen = stringlen * 2 + 16;
538 string = xrealloc(string, stringlen);
539 }
540 string[i] = '\0';
541
542
543 if (function[0] == ':') {
544 if (parsecontrol(function + 1, string) != 0)
545 return 1;
546 } else {
547 if (parsestring(fp, string) != 0)
548 return 1;
549 }
550 }
551 if (dump)
552 dumpfunctions();
553 return outputfunctions();
554}
555
556
557
558
559struct function {
560 struct function *next;
561 char *name;
562 enum type type;
563 int nbits;
564 int nargs;
565 char isarray;
566 int fixedlength;
567 struct entry *first, *last;
568
569 struct arg *args;
570};
571struct function *functions;
572
573
574
575
576struct function *findfunction(char *name) {
577 struct function *fp;
578
579 for (fp = functions; fp != NULL; fp = fp->next) {
580 if (strcmp(fp->name, name) == 0)
581 return fp;
582 }
583 if (strlen(name) > maxfunctionname)
584 maxfunctionname = strlen(name);
585 fp = xmalloc(sizeof *fp);
586 fp->next = functions;
587 functions = fp;
588 fp->name = xstrdup(name);
589 fp->type = T_UNKNOWN;
590 fp->nbits = fp->nargs = -1;
591 fp->isarray = 0;
592 fp->first = fp->last = NULL;
593 return fp;
594}
595
596
597
598
599
600
601int parseextern(struct function *fp, FILE *f) {
602 int c;
603
604 if ((c = getc(f)) != '\n') {
605 fprintf(stderr,
606 "%s: %s(%d): extern declaration should be a lone `:'\n",
607 progname, filename, lineno);
608 return 1;
609 }
610 if (fp->nbits != 0) {
611 fprintf(stderr,
612 "%s: %s(%d): extern functions should not have bitstrings\n",
613 progname, filename, lineno);
614 return 1;
615 }
616 free(fp->first);
617 fp->first = fp->last = NULL;
618 return 0;
619}
620
621
622
623
624
625
626
627
628struct entry {
629 struct entry *next;
630 bits mask, value;
631 struct bits *bits;
632 struct string *string;
633 char done;
634};
635
636
637
638
639
640struct function *makefunction(char *name) {
641 struct function *fp;
642 struct entry *ep = xmalloc(sizeof *ep);
643 enum type type;
644
645 if (name[0] == '%') {
646 name++;
647 type = T_INTEGER;
648 } else
649 type = T_STRING;
650 fp = findfunction(name);
651 if (fp->type == T_UNKNOWN)
652 fp->type = type;
653 else if (fp->type != type) {
654 fprintf(stderr, "%s: %s(%d): function %s previously declared as %s, "
655 "here as %s\n", progname, filename, lineno, name,
656 typename[fp->type], typename[type]);
657 return NULL;
658 }
659 ep->next = NULL;
660 ep->bits = NULL;
661 ep->done = 0;
662 if (fp->first != NULL)
663 fp->last->next = ep;
664 else
665 fp->first = ep;
666 fp->last = ep;
667 return fp;
668}
669
670
671
672
673
674struct bits {
675 struct bits *next;
676 int shift;
677 bits mask;
678 char name;
679};
680
681
682
683
684int parsebits(struct function *fp, char *bitstring, int nbits) {
685 if (fp->nbits < 0)
686 fp->nbits = nbits;
687 else if (fp->nbits != nbits) {
688 fprintf(stderr, "%s: %s(%d): bit string of length %d;\n",
689 progname, filename, lineno, nbits);
690 fprintf(stderr, " function %s has bit strings of length %d\n",
691 fp->name, fp->nbits);
692 return 1;
693 }
694 return parseentrybits(fp->last, bitstring, nbits, 0);
695}
696
697
698
699
700int parseentrybits(struct entry *ep, char *bitstring, int nbits, int issplice) {
701 int i, j;
702 char bit;
703 bits mask, value, entrymask;
704 struct bits *bp;
705
706 mask = value = 0;
707 for (i = 0; i < nbits; i++) {
708 bit = bitstring[nbits - 1 - i];
709 switch (bit) {
710 case '1':
711 value |= 1 << i;
712
713 case '0':
714 mask |= 1 << i;
715 continue;
716 }
717 if (!isalpha(bit)) {
718 fprintf(stderr, "%s: %s(%d): invalid character in bitstring: %c\n",
719 progname, filename, lineno, bit);
720 return 1;
721 }
722 if (!issplice) {
723 for (bp = ep->bits; bp != NULL; bp = bp->next) {
724 if (bp->name == bit) {
725 fprintf(stderr,
726 "%s: %s(%d): bitstring name %c used twice\n",
727 progname, filename, lineno, bit);
728 return 1;
729 }
730 }
731 }
732 entrymask = 1 << i;
733 for (j = i + 1; j < nbits && bitstring[nbits - 1 - j] == bit; j++)
734 entrymask |= 1 << j;
735 bp = xmalloc(sizeof *bp);
736 bp->shift = i;
737 bp->mask = entrymask;
738 bp->name = bit;
739 bp->next = ep->bits;
740 ep->bits = bp;
741 i = j - 1;
742 }
743 ep->mask = mask;
744 ep->value = value;
745 return 0;
746}
747
748
749
750
751
752
753int parsecontrol(char *name, char *value) {
754 if (strcmp(name, "bitstype") == 0)
755 bitstype = xstrdup(value);
756 else {
757 fprintf(stderr, "%s: %s(%d): unrecognised control keyword %s\n",
758 progname, filename, lineno, name);
759 return 1;
760 }
761 return 0;
762}
763
764
765
766
767struct arg {
768 struct arg *next;
769 enum type type;
770 char name;
771};
772
773
774
775
776
777
778
779
780
781int parseargs(struct function *fp, FILE *f, int *cp) {
782 struct arg **arglink, *ap;
783 struct bits *bp;
784 int nargs, width;
785 char name;
786 enum type t;
787
788 arglink = &fp->args;
789 width = nargs = 0;
790 if (*cp == '(') {
791 *cp = getc(f);
792 if (*cp != ')') {
793 width = 1;
794 while (1) {
795 nargs++;
796 width += 2;
797 if (fp->nargs >= 0 && nargs > fp->nargs) {
798 fprintf(stderr,
799 "%s: %s(%d): %d arg(s) instead of %d for %s\n",
800 progname, filename, lineno, nargs, fp->nargs,
801 fp->name);
802 return 1;
803 }
804 t = T_STRING;
805 if (*cp == '%') {
806 width++;
807 t = T_INTEGER;
808 *cp = getc(f);
809 }
810 name = *cp;
811 if (!isalpha(name)) {
812 fprintf(stderr,
813 "%s: %s(%d): argument should be letter: %c\n",
814 progname, filename, lineno, name);
815 return 1;
816 }
817 for (bp = fp->last->bits; bp != NULL; bp = bp->next) {
818 if (bp->name == name) {
819 fprintf(stderr,
820 "%s: %s(%d): %c is a bitstring and an arg\n",
821 progname, filename, lineno, name);
822 return 1;
823 }
824 }
825 if (fp->nargs >= 0) {
826 if ((*arglink)->name != name) {
827 fprintf(stderr,
828 "%s: %s(%d): arg %d of %s is %c not %c\n",
829 progname, filename, lineno, nargs, fp->name,
830 (*arglink)->name, name);
831 return 1;
832 }
833 if ((*arglink)->type != t) {
834 fprintf(stderr,
835 "%s: %s(%d): arg %c of %s: inconsistent type\n",
836 progname, filename, lineno, name, fp->name);
837 return 1;
838 }
839 } else {
840 for (ap = fp->args; ap != *arglink; ap = ap->next) {
841 if (ap->name == name) {
842 fprintf(stderr,
843 "%s: %s(%d): argument name %c used twice\n",
844 progname, filename, lineno, name);
845 return 1;
846 }
847 }
848 *arglink = xmalloc(sizeof **arglink);
849 (*arglink)->name = name;
850 (*arglink)->type = t;
851 }
852 arglink = &(*arglink)->next;
853 *cp = getc(f);
854 if (*cp == ')')
855 break;
856 if (*cp != ',') {
857 fprintf(stderr,
858 "%s: %s(%d): bad character in argument list: %c\n"
859 " (arguments must be single letters)\n",
860 progname, filename, lineno, *cp);
861 return 1;
862 }
863 *cp = getc(f);
864 }
865 }
866 *cp = getc(f);
867 }
868 if (fp->nargs < 0) {
869 fp->nargs = nargs;
870 width += fp->nbits;
871 if (width > maxargwidth)
872 maxargwidth = width;
873 } else if (fp->nargs != nargs) {
874 fprintf(stderr, "%s: %s(%d): argument list of length %d;\n",
875 progname, filename, lineno, nargs);
876 fprintf(stderr, " function %s has argument lists of length %d\n",
877 fp->name, fp->nargs);
878 return 1;
879 }
880 *arglink = NULL;
881 return 0;
882}
883
884
885
886
887int parsestring(struct function *fp, char *str) {
888 enum type t;
889
890 t = makestring(fp, &fp->last->string, &str, NULL, fp->type);
891 if (t == T_ERROR)
892 return 1;
893 if (fp->type != t && t != T_UNKNOWN) {
894 fprintf(stderr, "%s: %s(%d): function %s has inconsistent types\n",
895 progname, filename, lineno, fp->name);
896 return 1;
897 }
898 return 0;
899}
900
901
902
903
904
905struct string {
906 struct string *next;
907 enum elementtype {
908 S_TEXT, S_BITSTRING, S_BITSPLICE, S_PARAMETER, S_FUNCTIONCALL, S_ARRAY
909 } type;
910 union value {
911 char *text;
912 struct bits *bits;
913 struct bitsplice *bitsplice;
914 struct arg *parameter;
915 struct functioncall *functioncall;
916 struct array *array;
917 } value;
918};
919
920
921
922struct functioncall {
923 struct function *function;
924 struct stringlist *args;
925};
926
927
928
929
930struct array {
931 struct string *index;
932 struct stringlist *elements;
933 enum type type;
934 int tempno;
935};
936
937
938
939struct stringlist {
940 struct stringlist *next;
941 enum type type;
942 struct string *string;
943};
944
945
946
947
948
949#define MAKESTRING_MAGIC "${"
950
951
952
953
954
955
956
957
958
959enum type makestring(struct function *fp, struct string **stringlink,
960 char **stringp, char *magic, enum type targettype) {
961 char *p, *q;
962 struct string *sp, **firststringlink;
963 int n, components;
964 int parenlevel = 0;
965 enum type t = targettype, newt;
966
967 if (magic == NULL)
968 magic = MAKESTRING_MAGIC;
969 p = *stringp;
970 firststringlink = stringlink;
971 components = 0;
972 while (*p != '\0') {
973 sp = xmalloc(sizeof *sp);
974 q = p;
975 n = 0;
976 do {
977 if (strchr(magic, *q) != NULL) {
978 if (*q != ')' || parenlevel == 0)
979 break;
980 }
981 switch (*q) {
982 case '(':
983 parenlevel++; break;
984 case ')':
985 parenlevel--; break;
986 case '\\':
987 if (q[1] != '\0')
988 q++;
989 break;
990 }
991 n++;
992 } while (*++q != '\0');
993 if (n > 0) {
994 sp->type = S_TEXT;
995 sp->value.text = q = xmalloc(n + 1);
996 do {
997 if (*p == '\\')
998 p++;
999 *q++ = *p++;
1000 } while (--n > 0);
1001 *q = '\0';
1002 newt = t;
1003 } else if (*p == '$') {
1004 if (parsedollar(fp, &p, sp) != 0)
1005 return T_ERROR;
1006 switch (sp->type) {
1007 case S_BITSTRING:
1008 case S_BITSPLICE:
1009 newt = T_INTEGER;
1010 break;
1011 case S_PARAMETER:
1012 newt = sp->value.parameter->type;
1013 break;
1014 case S_FUNCTIONCALL:
1015 newt = sp->value.functioncall->function->type;
1016 break;
1017 default:
1018 fprintf(stderr, "makestring type %d\n", sp->type);
1019 abort();
1020 }
1021 } else if (*p == '{') {
1022 if (parsearray(fp, &p, sp, t) != 0)
1023 return T_ERROR;
1024 newt = sp->value.array->type;
1025 } else {
1026 free(sp);
1027 break;
1028 }
1029 if (t == T_UNKNOWN)
1030 t = newt;
1031 else if (newt != T_UNKNOWN && t != newt) {
1032 if (stringlink == firststringlink) {
1033 fprintf(stderr, "%s: %s(%d): expected %s type:\n", progname,
1034 filename, lineno, typename[t]);
1035 showstringelement(stderr, sp);
1036 return T_ERROR;
1037 }
1038 *stringlink = NULL;
1039 fprintf(stderr, "%s: %s(%d): mixed types in string:\n",
1040 progname, filename, lineno);
1041 showstring(stderr, *firststringlink);
1042 fprintf(stderr, " -- %s\n", typename[t]);
1043 showstringelement(stderr, sp);
1044 fprintf(stderr, " -- %s\n", typename[newt]);
1045 return T_ERROR;
1046 }
1047 *stringlink = sp;
1048 stringlink = &sp->next;
1049 components++;
1050 }
1051 *stringlink = NULL;
1052 *stringp = p;
1053 if (components >= MAXBITS) {
1054 fprintf(stderr, "%s: %s(%d): excessively complicated string\n",
1055 progname, filename, lineno);
1056 return T_ERROR;
1057 }
1058 componentbits |= 1 << components;
1059 return t;
1060}
1061
1062
1063
1064
1065
1066int parsedollar(struct function *fp, char **stringp, struct string *sp) {
1067 char *p, *start;
1068
1069 p = *stringp;
1070 assert(*p == '$');
1071 start = ++p;
1072 if (*p == '[')
1073 p++;
1074 while (isalnum(*p) || *p == '_')
1075 p++;
1076 if (*start == '[') {
1077 if (*p != ']') {
1078 fprintf(stderr, "%s: %s(%d): missing ] or bad character in $[\n",
1079 progname, filename, lineno);
1080 return 1;
1081 }
1082 *stringp = p + 1;
1083 return parsebitsplice(fp, start + 1, p - start - 1, sp);
1084 }
1085 if (p == start) {
1086 fprintf(stderr, "%s: %s(%d): missing identifier after $\n", progname,
1087 filename, lineno);
1088 return 1;
1089 }
1090 if (p == start + 1) {
1091 if (findvariable(fp, *start, sp) != 0)
1092 return 1;
1093 } else {
1094 if (parsefunctioncall(fp, start, &p, sp) != 0)
1095 return 1;
1096 }
1097 *stringp = p;
1098 return 0;
1099}
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128struct bitsplice {
1129 struct entry entry;
1130 int nbits;
1131 struct bitsplicebits *splice;
1132};
1133struct bitsplicebits {
1134 struct bitsplicebits *next;
1135 int shift;
1136 enum elementtype type;
1137 union {
1138 struct arg *arg;
1139 bits mask;
1140 } value;
1141};
1142
1143
1144int parsebitsplice(struct function *fp, char *bitstring, int nbits,
1145 struct string *sp) {
1146 struct bitsplice *splicep;
1147 struct bitsplicebits *bsp, *lastbsp, **bspp;
1148 struct bits *bp;
1149 int shift, nfrombits, ntobits;
1150 bits allbits, b;
1151
1152 splicep = xmalloc(sizeof *splicep);
1153 splicep->nbits = nbits;
1154 if (parseentrybits(&splicep->entry, bitstring, nbits, 1) != 0)
1155 return 1;
1156 bspp = &splicep->splice;
1157 lastbsp = NULL;
1158 for (bp = splicep->entry.bits; bp != NULL; bp = bp->next) {
1159 if (findvariable(fp, bp->name, sp) != 0)
1160 return 1;
1161 shift = bp->shift;
1162 if (sp->type == S_BITSTRING) {
1163 nfrombits = bitcount(sp->value.bits->mask);
1164 ntobits = bitcount(bp->mask);
1165 if (warnings) {
1166 if (nfrombits != ntobits) {
1167 fprintf(stderr, "%s: %s(%d): warning: "
1168 "bitstring $%c %ser than its place "
1169 "in bitsplice\n",
1170 progname, filename, lineno, bp->name,
1171 (nfrombits > ntobits) ? "bigg" : "small");
1172 }
1173 }
1174 shift -= sp->value.bits->shift;
1175
1176
1177
1178 if (lastbsp != NULL && lastbsp->type == S_BITSTRING
1179 && lastbsp->shift == shift) {
1180 lastbsp->value.mask |= sp->value.bits->mask;
1181 continue;
1182 }
1183 } else {
1184 assert(sp->type == S_PARAMETER);
1185 if (sp->value.parameter->type != T_INTEGER) {
1186 fprintf(stderr,
1187 "%s: %s(%d): variable %c in $[...] should be integer\n",
1188 progname, filename, lineno, sp->value.parameter->name);
1189 return 1;
1190 }
1191 }
1192 *bspp = bsp = xmalloc(sizeof *bsp);
1193 bsp->type = sp->type;
1194 bsp->shift = shift;
1195 if (sp->type == S_PARAMETER)
1196 bsp->value.arg = sp->value.parameter;
1197 else
1198 bsp->value.mask = sp->value.bits->mask;
1199 bspp = &bsp->next;
1200 lastbsp = bsp;
1201 }
1202 *bspp = NULL;
1203
1204
1205
1206 allbits = allbitsset(fp->nbits);
1207 for (bsp = splicep->splice; bsp != NULL; bsp = bsp->next) {
1208 if (bsp->type == S_BITSTRING) {
1209 for (b = bsp->value.mask; b != 0 && !(b & 1); b >>= 1) ;
1210 if (b == allbits)
1211 bsp->value.mask = 0;
1212 }
1213 }
1214 sp->type = S_BITSPLICE;
1215 sp->value.bitsplice = splicep;
1216 return 0;
1217}
1218
1219
1220int findvariable(struct function *fp, int name, struct string *sp) {
1221 struct bits *bp;
1222 struct arg *ap;
1223
1224 for (bp = fp->last->bits; bp != NULL; bp = bp->next) {
1225 if (bp->name == name) {
1226 sp->type = S_BITSTRING;
1227 sp->value.bits = bp;
1228 return 0;
1229 }
1230 }
1231 for (ap = fp->args; ap != NULL; ap = ap->next) {
1232 if (ap->name == name) {
1233 sp->type = S_PARAMETER;
1234 sp->value.parameter = ap;
1235 return 0;
1236 }
1237 }
1238 fprintf(stderr, "%s: %s(%d): undefined parameter %c\n", progname, filename,
1239 lineno, name);
1240 return 1;
1241}
1242
1243
1244int parsefunctioncall(struct function *fp, char *start, char **stringp,
1245 struct string *sp) {
1246 char *p;
1247 struct functioncall *fcp;
1248 struct stringlist **arglink, *arg;
1249 enum type t;
1250
1251 p = *stringp;
1252 if (*p != '(') {
1253 fprintf(stderr, "%s: %s(%d): missing ( after function %.*s\n", progname,
1254 filename, lineno, p - start, start);
1255 return 1;
1256 }
1257 sp->type = S_FUNCTIONCALL;
1258 sp->value.functioncall = fcp = xmalloc(sizeof *fcp);
1259 *p = '\0';
1260 fcp->function = findfunction(start);
1261 *p = '(';
1262 arglink = &fcp->args;
1263 if (*++p != ')') {
1264 while (1) {
1265 arg = xmalloc(sizeof *arg);
1266 t = makestring(fp, &arg->string, &p, MAKESTRING_MAGIC ",)",
1267 T_UNKNOWN);
1268 if (t == T_ERROR)
1269 return 1;
1270 arg->type = t;
1271 *arglink = arg;
1272 arglink = &arg->next;
1273 if (*p == ')')
1274 break;
1275 assert(*p == ',');
1276 p++;
1277 }
1278 }
1279 *arglink = NULL;
1280 assert(*p == ')');
1281 *stringp = p + 1;
1282 return 0;
1283}
1284
1285
1286int parsearray(struct function *fp, char **stringp, struct string *sp,
1287 enum type t) {
1288 char *p;
1289 struct array *ap;
1290 struct stringlist **elementlink, *element;
1291
1292 p = *stringp;
1293 assert(*p == '{');
1294 sp->type = S_ARRAY;
1295 sp->value.array = ap = xmalloc(sizeof *ap);
1296 ap->tempno = -1;
1297 elementlink = &ap->elements;
1298 ap->type = t;
1299 if (*++p != '}') {
1300 while (1) {
1301 element = xmalloc(sizeof *element);
1302 t = makestring(fp, &element->string, &p,
1303 MAKESTRING_MAGIC "|}", t);
1304 if (t == T_ERROR)
1305 return 1;
1306 element->type = t;
1307 if (ap->type == T_UNKNOWN)
1308 ap->type = t;
1309 else if (t != T_UNKNOWN && ap->type != t) {
1310 fprintf(stderr, "%s: %s(%d): mixed types in array:\n",
1311 progname, filename, lineno);
1312 showstring(stderr, ap->elements->string);
1313 fprintf(stderr, " -- %s\n", typename[ap->type]);
1314 showstring(stderr, element->string);
1315 fprintf(stderr, " -- %s\n", typename[t]);
1316 return 1;
1317 }
1318 *elementlink = element;
1319 elementlink = &element->next;
1320 if (*p == '}')
1321 break;
1322 assert(*p == '|');
1323 p++;
1324 }
1325 }
1326 *elementlink = NULL;
1327 assert(*p == '}');
1328 if (*++p != '[') {
1329 fprintf(stderr, "%s: %s(%d): missing [index] after array\n",
1330 progname, filename, lineno);
1331 return 1;
1332 }
1333 ++p;
1334 t = makestring(fp, &ap->index, &p, MAKESTRING_MAGIC "]", T_INTEGER);
1335 if (t == T_ERROR)
1336 return 1;
1337 if (t == T_STRING) {
1338 fprintf(stderr, "%s: %s(%d): array index cannot be string:\n",
1339 progname, filename, lineno);
1340 showstring(stderr, ap->index);
1341 return 1;
1342 }
1343 if (*p != ']') {
1344 fprintf(stderr, "%s: %s(%d): [ without ]\n", progname, filename,
1345 lineno);
1346 return 1;
1347 }
1348 *stringp = p + 1;
1349 return 0;
1350}
1351
1352
1353void dumpfunctions() {
1354 struct function *fp;
1355
1356 for (fp = functions; fp != NULL; fp = fp->next)
1357 dumpfunction(fp);
1358}
1359
1360
1361void dumpfunction(struct function *fp) {
1362 struct entry *ep;
1363
1364 for (ep = fp->first; ep != NULL; ep = ep->next)
1365 showentry(stderr, fp, ep, 0);
1366}
1367
1368
1369
1370
1371
1372
1373
1374void showentry(FILE *f, struct function *fp, struct entry *ep, bits highlight) {
1375 if (fp->type == T_INTEGER)
1376 putc('%', f);
1377 fprintf(f, "%-*s ", maxfunctionname + 1, fp->name);
1378 if (fp->nbits == 0 && fp->nargs == 0)
1379 fprintf(f, "%-*s", maxargwidth, "()");
1380 else {
1381 showbits(f, ep, fp->nbits, 0);
1382 showargs(f, fp->args, maxargwidth - fp->nbits);
1383 }
1384 putc(' ', f);
1385 showstring(f, ep->string);
1386 putc('\n', f);
1387 if (highlight != 0) {
1388 fprintf(f, "%-*s ", maxfunctionname + 1, "");
1389 showbits(f, ep, fp->nbits, highlight);
1390 putc('\n', f);
1391 }
1392}
1393
1394
1395void showbits(FILE *f, struct entry *ep, int nbits, bits highlight) {
1396 struct bits *bp;
1397 bits i, value;
1398 char zero, one;
1399
1400 if (nbits == 0)
1401 return;
1402 i = 1 << (nbits - 1);
1403 bp = ep->bits;
1404 if (highlight) {
1405 value = highlight;
1406 zero = ' ';
1407 one = '^';
1408 } else {
1409 value = ep->value;
1410 zero = '0';
1411 one = '1';
1412 }
1413 do {
1414 if (highlight != 0 || (ep->mask & i)) {
1415 putc((value & i) ? one : zero, f);
1416 i >>= 1;
1417 } else {
1418 assert(bp != NULL && (bp->mask & i));
1419 do {
1420 putc(bp->name, f);
1421 i >>= 1;
1422 } while (bp->mask & i);
1423 bp = bp->next;
1424 }
1425 } while (i != 0);
1426}
1427
1428
1429void showargs(FILE *f, struct arg *ap, int fieldwidth) {
1430 int width;
1431 int lastc;
1432 int isint;
1433
1434 if (ap == NULL)
1435 width = 0;
1436 else {
1437 width = 1;
1438 lastc = '(';
1439 do {
1440 isint = (ap->type == T_INTEGER);
1441 fprintf(f, "%c%s%c", lastc, isint ? "%" : "", ap->name);
1442 width += 2 + isint;
1443 ap = ap->next;
1444 lastc = ',';
1445 } while (ap != NULL);
1446 putc(')', f);
1447 }
1448 fprintf(f, "%-*s", fieldwidth - width, "");
1449}
1450
1451
1452void showstring(FILE *f, struct string *sp) {
1453 for ( ; sp != NULL; sp = sp->next)
1454 showstringelement(f, sp);
1455}
1456
1457
1458void showstringelement(FILE *f, struct string *sp) {
1459 struct bitsplice *bsp;
1460
1461 switch (sp->type) {
1462 case S_TEXT:
1463 fputs(sp->value.text, f);
1464 break;
1465 case S_BITSTRING:
1466 fprintf(f, "$%c", sp->value.bits->name);
1467 break;
1468 case S_BITSPLICE:
1469 fprintf(f, "$[");
1470 bsp = sp->value.bitsplice;
1471 showbits(f, &bsp->entry, bsp->nbits, 0);
1472 fprintf(f, "]");
1473 break;
1474 case S_PARAMETER:
1475 fprintf(f, "$%c", sp->value.parameter->name);
1476 break;
1477 case S_FUNCTIONCALL:
1478 showfunctioncall(f, sp->value.functioncall);
1479 break;
1480 case S_ARRAY:
1481 showarray(f, sp->value.array);
1482 break;
1483 default:
1484 fprintf(stderr, "showstring case %d\n", sp->type);
1485 abort();
1486 }
1487}
1488
1489
1490void showfunctioncall(FILE *f, struct functioncall *fcp) {
1491 struct stringlist *sp;
1492 char *last;
1493
1494 fprintf(f, "$%s(", fcp->function->name);
1495 last = "";
1496 for (sp = fcp->args; sp != NULL; sp = sp->next) {
1497 fputs(last, f);
1498 last = ",";
1499 showstring(f, sp->string);
1500 }
1501 putc(')', f);
1502}
1503
1504
1505void showarray(FILE *f, struct array *ap) {
1506 struct stringlist *sp;
1507 char *last;
1508
1509 putc('{', f);
1510 last = "";
1511 for (sp = ap->elements; sp != NULL; sp = sp->next) {
1512 fputs(last, f);
1513 last = "|";
1514 showstring(f, sp->string);
1515 }
1516 fputs("}[", f);
1517 showstring(f, ap->index);
1518 putc(']', f);
1519}
1520
1521
1522const char commonpreamble[] = "\
1523typedef %s bits;\n\
1524\n\
1525";
1526
1527const char concatpreamble[] = "\
1528static char *dis_buf;\n\
1529static int dis_bufindex, dis_buflen;\n\
1530\n\
1531void *dis_alloc(size_t size)\n\
1532{\n\
1533 void *p;\n\
1534 int newindex = dis_bufindex + size;\n\
1535 if (newindex > dis_buflen) {\n\
1536 dis_buflen = newindex * 4;\n\
1537 dis_buf = malloc(dis_buflen);\n\
1538
1539
1540\n\
1541 if (dis_buf == 0) {\n\
1542 perror(\"malloc\");\n\
1543 exit(1);\n\
1544 }\n\
1545 dis_bufindex = 0;\n\
1546 }\n\
1547 p = dis_buf + dis_bufindex;\n\
1548 dis_bufindex = newindex;\n\
1549 return p;\n\
1550}\n\
1551\n\
1552void dis_done()\n\
1553{\n\
1554 dis_bufindex = 0;\n\
1555}\n\
1556\n\
1557";
1558
1559const char concatdeclarations[] = "\
1560#include <string.h>\n\
1561#include <stdlib.h>\n\
1562#include <errno.h>\n\
1563\n\
1564extern void *dis_realloc(void *p, size_t size); \n\
1565void *dis_alloc(size_t size);\n\
1566void dis_done(void);\n\
1567";
1568
1569const char nonconcatpreamble[] = "\
1570void dis_done() {}\n\
1571";
1572
1573
1574int outputfunctions() {
1575 struct function *fp;
1576
1577 outputidentity(stdout);
1578 if (headerfilename != NULL) {
1579 if ((headerfile = fopen(headerfilename, "w")) == NULL) {
1580 fprintf(stderr, "%s: create %s: %s\n", progname, headerfilename,
1581 strerror(errno));
1582 return 1;
1583 }
1584 outputidentity(headerfile);
1585 fprintf(headerfile, commonpreamble, bitstype);
1586 printf("\n#include \"%s\"\n", headerfilename);
1587 } else
1588 printf(commonpreamble, bitstype);
1589 findarrays();
1590 if (outputdeclarations() != 0)
1591 return 1;
1592 outputconcats();
1593 for (fp = functions; fp != NULL; fp = fp->next) {
1594 if (fp->isarray)
1595 functionarray(fp);
1596 }
1597 for (fp = functions; fp != NULL; fp = fp->next) {
1598 if (fp->first != NULL && !fp->isarray) {
1599 if (outputfunction(fp) != 0)
1600 return 1;
1601 }
1602 }
1603 return 0;
1604}
1605
1606
1607void outputidentity(FILE *f) {
1608 char **p;
1609
1610 fprintf(f, "/*\n * This file was generated by:\n *");
1611 for (p = global_argv; *p != NULL; p++)
1612 fprintf(f, " %s", *p);
1613 fprintf(f, "\n */\n\n");
1614}
1615
1616
1617int outputdeclarations() {
1618 FILE *f = headerfile ? headerfile : stdout;
1619 struct function *fp;
1620
1621 for (fp = functions; fp != NULL; fp = fp->next) {
1622 if (fp->type != T_UNKNOWN) {
1623 if (fp->isarray) {
1624 fprintf(f, "extern ");
1625 if (fp->fixedlength > 0)
1626 fprintf(f, "char %s[][%d]", fp->name, fp->fixedlength);
1627 else {
1628 compiletype(f, &fp->type);
1629 fprintf(f, "%s[]", fp->name);
1630 }
1631 } else
1632 functionheader(f, fp);
1633 fprintf(f, ";\n");
1634 }
1635 }
1636 return 0;
1637}
1638
1639
1640void outputconcats() {
1641 int i;
1642
1643 if (componentbits & ~3) {
1644 fputs(concatdeclarations, headerfile ? headerfile : stdout);
1645 fputs(concatpreamble, stdout);
1646 } else
1647 fputs(nonconcatpreamble, stdout);
1648 for (i = 2; i < MAXBITS; i++) {
1649 if (componentbits & (1 << i))
1650 outputconcat(i);
1651 }
1652}
1653
1654
1655void outputconcat(int n) {
1656 int i;
1657 char *last;
1658
1659 assert(n > 1);
1660 if (headerfile) {
1661 outputconcatheader(headerfile, n);
1662 fprintf(headerfile, ";\n");
1663 }
1664 outputconcatheader(stdout, n);
1665 printf("\n{\n void *p;\n int len = ");
1666 last = "";
1667 for (i = 0; i < n; i++) {
1668 printf("%sstrlen(p%d)", last, i);
1669 last = " + ";
1670 }
1671 printf(";\n p = dis_alloc(len + 1);\n return ");
1672 for (i = 1; i < n; i++)
1673 printf("strcat(");
1674 printf("strcpy(p, p0)");
1675 for (i = 1; i < n; i++)
1676 printf(", p%d)", i);
1677 printf(";\n}\n\n");
1678}
1679
1680
1681void outputconcatheader(FILE *f, int n) {
1682 int i;
1683 char *last = "";
1684
1685 fprintf(f, "char *dis_concat%d(", n);
1686 for (i = 0; i < n; i++) {
1687 fprintf(f, "%schar *p%d", last, i);
1688 last = ", ";
1689 }
1690 fprintf(f, ")");
1691}
1692
1693
1694void findarrays() {
1695 struct function *fp;
1696 struct entry *ep;
1697 struct string *estr, *indexstr;
1698 struct bits *bp;
1699
1700 for (fp = functions; fp != NULL; fp = fp->next) {
1701 if (fp->nbits > 0 && fp->nargs > 0)
1702 continue;
1703 if (fp->nargs > 1)
1704 continue;
1705 ep = fp->first;
1706 if (ep == NULL || ep->next != NULL)
1707 continue;
1708 estr = ep->string;
1709 if (estr == NULL || estr->next != NULL || estr->type != S_ARRAY)
1710 continue;
1711 indexstr = estr->value.array->index;
1712 if (indexstr->next != NULL)
1713 continue;
1714 if (fp->nbits > 0) {
1715 bp = ep->bits;
1716 if (bp == NULL || bp->next != NULL || bp->shift != 0)
1717 continue;
1718 if (bp->mask != allbitsset(fp->nbits))
1719 continue;
1720 if (indexstr->type != S_BITSTRING || indexstr->value.bits != bp)
1721 continue;
1722 } else {
1723 if (indexstr->type != S_PARAMETER
1724 || indexstr->value.parameter != fp->args)
1725 continue;
1726 }
1727 if (!simplearray(estr->value.array))
1728 continue;
1729 fp->isarray = 1;
1730 fp->fixedlength =
1731 (fp->type == T_INTEGER) ? 0 : checkfixedlength(estr->value.array);
1732 }
1733}
1734
1735
1736int checkfixedlength(struct array *ap) {
1737 int len, maxlen, wasted, n;
1738 struct stringlist *lp;
1739
1740 maxlen = 0;
1741 for (lp = ap->elements; lp != NULL; lp = lp->next) {
1742 if (lp->string == NULL)
1743 continue;
1744 assert(lp->string->type == S_TEXT);
1745 len = strlen(lp->string->value.text);
1746 if (len > maxlen)
1747 maxlen = len;
1748 }
1749 for (wasted = n = 0, lp = ap->elements; lp != NULL; n++, lp = lp->next) {
1750 if (lp->string == NULL)
1751 continue;
1752 wasted += maxlen - strlen(lp->string->value.text);
1753 }
1754 if (wasted < n * sizeof(char *))
1755 return maxlen + 1;
1756 return 0;
1757}
1758
1759
1760int outputfunction(struct function *fp) {
1761 printf("\n");
1762 functionheader(stdout, fp);
1763 printf("\n{\n");
1764 switch (functionswitch(fp, 0, 0)) {
1765 case -1:
1766 return 1;
1767 case 0:
1768 if (warnings) {
1769 fprintf(stderr, "%s: warning: not all cases of %s covered\n",
1770 progname, fp->name);
1771 }
1772 }
1773 printf("}\n");
1774 return 0;
1775}
1776
1777
1778void functionarray(struct function *fp) {
1779 struct array *ap;
1780
1781 ap = fp->first->string->value.array;
1782 printf("\n");
1783 compilesimplearray(&fp->type, fp->name, 0, ap);
1784}
1785
1786
1787void functionheader(FILE *f, struct function *fp) {
1788 char *last;
1789 struct arg *ap;
1790
1791 compiletype(f, &fp->type);
1792 fprintf(f, "%s(", fp->name);
1793 last = "";
1794 if (fp->nbits > 0) {
1795 fprintf(f, "bits code");
1796 last = ", ";
1797 }
1798 for (ap = fp->args; ap != NULL; ap = ap->next) {
1799 fprintf(f, last);
1800 compiletype(f, &ap->type);
1801 putc(ap->name, f);
1802 last = ", ";
1803 }
1804 if (*last == '\0')
1805 fprintf(f, "void");
1806 putc(')', f);
1807}
1808
1809
1810int simplearray(struct array *ap) {
1811 struct stringlist *lp;
1812
1813 for (lp = ap->elements; lp != NULL; lp = lp->next) {
1814 if (lp->string != NULL
1815 && (lp->string->next != NULL || lp->string->type != S_TEXT))
1816 break;
1817 }
1818 return (lp == NULL);
1819}
1820
1821
1822void compiletype(FILE *f, enum type *tp) {
1823 switch (*tp) {
1824 case T_UNKNOWN:
1825 *tp = T_STRING;
1826
1827 case T_STRING:
1828 fprintf(f, "char *");
1829 break;
1830 case T_INTEGER:
1831 fprintf(f, "bits ");
1832 break;
1833 default:
1834 fprintf(stderr, "compiletype type %d\n", *tp);
1835 abort();
1836 }
1837}
1838
1839
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856int functionswitch(struct function *fp, bits mask, bits value) {
1857 struct entry *ep, *defaultcase;
1858 bits allbits, constbits, missingcases;
1859 int nhits, ncases, nconstbits, alwaysreturns;
1860
1861 indentation++;
1862 allbits = allbitsset(fp->nbits);
1863 constbits = allbits & ~mask;
1864 if (debug) {
1865 findent(stderr);
1866 fprintf(stderr,
1867 "functionswitch(%s): (x & 0x%lx) == 0x%lx; const == 0x%lx\n",
1868 fp->name, mask, value, constbits);
1869 }
1870 defaultcase = NULL;
1871 ncases = nhits = 0;
1872 alwaysreturns = 1;
1873 for (ep = fp->first; ep != NULL; ep = ep->next) {
1874
1875 if (ep->done
1876 || (ep->mask & mask) != mask || (ep->value & mask) != value)
1877 continue;
1878 if (debug) {
1879 findent(stderr);
1880 showentry(stderr, fp, ep, 0);
1881 }
1882
1883
1884 if ((constbits & ep->mask) == 0) {
1885 if (defaultcase != NULL) {
1886 fprintf(stderr,
1887 "%s: function %s: unable to distinguish between:\n",
1888 progname, fp->name);
1889 showentry(stderr, fp, defaultcase, 0);
1890 showentry(stderr, fp, ep, 0);
1891 return -1;
1892 }
1893 defaultcase = ep;
1894 if (debug) {
1895 findent(stderr);
1896 fprintf(stderr, "^^ default case\n");
1897 }
1898 } else {
1899 if (debug && (constbits & ~ep->mask)) {
1900 findent(stderr);
1901 fprintf(stderr, "const now 0x%lx\n", constbits & ep->mask);
1902 }
1903 constbits &= ep->mask;
1904 nhits++;
1905 }
1906 }
1907 if (nhits > 0) {
1908 indent();
1909 if (constbits == allbits)
1910 printf("switch (code) {\n");
1911 else
1912 printf("switch (code & 0x%lx) {\n", constbits);
1913 for (ep = fp->first; ep != NULL; ep = ep->next) {
1914
1915 if ((ep->mask & mask) != mask || (ep->value & mask) != value)
1916 continue;
1917 if (ep->done || ep == defaultcase)
1918 continue;
1919 ncases++;
1920 indent();
1921 printf("case 0x%lx:\n", ep->value & constbits);
1922 switch (functionswitch(fp, mask | constbits,
1923 value | (ep->value & constbits))) {
1924 case -1:
1925 return -1;
1926 case 0:
1927 alwaysreturns = 0;
1928 indentation++; indent(); indentation--;
1929 printf("break;\n");
1930 }
1931 }
1932 indent();
1933 printf("}\n");
1934 }
1935 nconstbits = bitcount(constbits);
1936 missingcases = ((nconstbits == MAXBITS) ? 0 : 1 << nconstbits) - ncases;
1937 if (alwaysreturns) {
1938 switch (missingcases) {
1939 case 0:
1940 if (defaultcase != NULL) {
1941 fprintf(stderr, "%s: warning: redundant entry:\n", progname);
1942 showentry(stderr, fp, defaultcase, 0);
1943 defaultcase = NULL;
1944 }
1945 break;
1946 case 1:
1947 if (defaultcase != NULL && nconstbits != 0) {
1948 fprintf(stderr,
1949 "%s: warning: variable bit(s) could be constant:\n",
1950 progname);
1951 showentry(stderr, fp, defaultcase, constbits);
1952 break;
1953 }
1954
1955 default:
1956 alwaysreturns = 0;
1957 }
1958 }
1959 if (defaultcase != NULL) {
1960
1961
1962 if ((defaultcase->mask & ~mask) == 0) {
1963 alwaysreturns = 1;
1964 if (compilestring(-1, defaultcase->string, fp->type) != 0)
1965 return -1;
1966 defaultcase->done = 1;
1967 } else {
1968 indentation--;
1969 alwaysreturns = functionswitch(fp, mask, value);
1970 indentation++;
1971 }
1972 }
1973 indentation--;
1974 return alwaysreturns;
1975}
1976
1977
1978int compilestring(int assignto, struct string *sp, enum type type) {
1979 int tempno;
1980
1981 tempno = walkstring(sp, COUNTARRAYS, assignto);
1982 if (tempno > assignto) {
1983 indent();
1984 printf("{\n");
1985 indentation++;
1986 (void) walkstring(sp, DECLAREARRAYS, assignto);
1987 if (walkstring(sp, COMPILEARRAYS, assignto) < 0)
1988 return 1;
1989 }
1990 if (compilecheckedstring(assignto, sp, type) != 0)
1991 return 1;
1992 if (tempno > assignto) {
1993 indentation--;
1994 indent();
1995 printf("}\n");
1996 }
1997 return 0;
1998}
1999
2000
2001int compilecheckedstring(int assignto, struct string *sp, enum type type) {
2002 compileassign(assignto);
2003 if (compileconcat(sp, type) != 0)
2004 return 1;
2005 printf(";\n");
2006 return 0;
2007}
2008
2009
2010void compileassign(int assignto) {
2011 indent();
2012 if (assignto < 0)
2013 printf("return ");
2014 else {
2015 compiletemp(assignto);
2016 printf(" = ");
2017 }
2018}
2019
2020
2021void compiletemp(int tempno) {
2022 printf("t__%d", tempno);
2023}
2024
2025
2026void compiletext(char *s) {
2027 putchar('"');
2028 if (s != NULL) {
2029 for ( ; *s != '\0'; s++) {
2030 switch (*s) {
2031 case '"':
2032 case '\\':
2033 putchar('\\');
2034 }
2035 putchar(*s);
2036 }
2037 }
2038 putchar('"');
2039}
2040
2041
2042int compileconcat(struct string *sp, enum type type) {
2043 int elements;
2044 struct string *sp1;
2045 char *last;
2046
2047 if (sp == NULL)
2048 return compilenull(type);
2049 if (sp->next == NULL)
2050 return compilesimple(sp, type);
2051 if (type != T_INTEGER) {
2052 for (elements = 0, sp1 = sp; sp1 != NULL; elements++, sp1 = sp1->next) ;
2053 printf("dis_concat%d(", elements);
2054 }
2055 last = "";
2056 for (sp1 = sp; sp1 != NULL; sp1 = sp1->next) {
2057 printf(last);
2058 if (type != T_INTEGER)
2059 last = ", ";
2060 if (sp1->type == S_ARRAY)
2061 compilearrayref(sp1->value.array);
2062 else
2063 if (compilesimple(sp1, type) != 0)
2064 return 1;
2065 }
2066 if (type != T_INTEGER)
2067 printf(")");
2068 return 0;
2069}
2070
2071
2072int compilenull(enum type type) {
2073 if (type == T_INTEGER) {
2074 fprintf(stderr, "%s: empty integer expression\n", progname);
2075 return 1;
2076 }
2077 printf("\"\"");
2078 return 0;
2079}
2080
2081
2082int compilesimple(struct string *sp, enum type type) {
2083 if (sp == NULL)
2084 return compilenull(type);
2085 switch (sp->type) {
2086 case S_TEXT:
2087 if (type == T_INTEGER)
2088 printf("%s", sp->value.text);
2089 else
2090 compiletext(sp->value.text);
2091 break;
2092 case S_BITSTRING:
2093 compilebitstring(sp->value.bits);
2094 break;
2095 case S_BITSPLICE:
2096 compilebitsplice(sp->value.bitsplice);
2097 break;
2098 case S_PARAMETER:
2099 putchar(sp->value.parameter->name);
2100 break;
2101 case S_FUNCTIONCALL:
2102 return compilefunctioncall(sp);
2103 case S_ARRAY:
2104 if (compilearrayref(sp->value.array) != 0)
2105 return 1;
2106 break;
2107 default:
2108 fprintf(stderr, "compilesimple case %d", sp->type);
2109 abort();
2110 }
2111 return 0;
2112}
2113
2114
2115int compilearrayref(struct array *ap) {
2116 compiletemp(ap->tempno);
2117 if (simplearray(ap)) {
2118 printf("[");
2119 if (compileconcat(ap->index, T_INTEGER) != 0)
2120 return 1;
2121 printf("]");
2122 }
2123 return 0;
2124}
2125
2126
2127int compilefunctioncall(struct string *sp) {
2128 struct function *fp;
2129 struct stringlist *actualp;
2130 struct arg *formalp;
2131 char *last;
2132 int nbits;
2133 enum type formaltype;
2134
2135 assert(sp->type == S_FUNCTIONCALL);
2136 fp = sp->value.functioncall->function;
2137 printf("%s%c", fp->name, fp->isarray ? '[' : '(');
2138 last = "";
2139 nbits = fp->nbits;
2140 formalp = fp->args;
2141 actualp = sp->value.functioncall->args;
2142 while (actualp != NULL) {
2143 if (nbits > 0) {
2144 nbits = 0;
2145 formaltype = T_INTEGER;
2146 } else {
2147 if (formalp == NULL) {
2148 fprintf(stderr, "%s: too many arguments to %s:\n", progname,
2149 fp->name);
2150 showstring(stderr, sp);
2151 putc('\n', stderr);
2152 return 1;
2153 }
2154 formaltype = formalp->type;
2155 formalp = formalp->next;
2156 }
2157 if (actualp->type != T_UNKNOWN && actualp->type != formaltype) {
2158 fprintf(stderr, "%s: argument to %s has the wrong type:\n",
2159 progname, fp->name);
2160 showstring(stderr, actualp->string);
2161 putc('\n', stderr);
2162 return 1;
2163 }
2164 printf(last);
2165 last = ", ";
2166 if (compileconcat(actualp->string, formaltype) != 0)
2167 return 1;
2168 actualp = actualp->next;
2169 }
2170 putchar(fp->isarray ? ']' : ')');
2171 return 0;
2172}
2173
2174
2175int walkstring(struct string *sp, enum walkstringop op, int tempno) {
2176 struct stringlist *lp;
2177 struct array *ap;
2178
2179 for ( ; sp != NULL; sp = sp->next) {
2180 switch (sp->type) {
2181 case S_ARRAY:
2182 ap = sp->value.array;
2183 for (lp = ap->elements; lp != NULL; lp = lp->next)
2184 tempno = walkstring(lp->string, op, tempno);
2185 tempno = walkstring(ap->index, op, tempno);
2186 ap->tempno = ++tempno;
2187 switch (op) {
2188 case DECLAREARRAYS:
2189 if (simplearray(ap)) {
2190 indent();
2191 printf("static ");
2192 compilesimplearray(&ap->type, NULL, tempno, ap);
2193 } else
2194 declarearray(ap);
2195 break;
2196 case COMPILEARRAYS:
2197 if (!simplearray(ap))
2198 if (compilearray(ap) != 0)
2199 return -1;
2200 break;
2201 default:
2202 break;
2203 }
2204 break;
2205 case S_FUNCTIONCALL:
2206 for (lp = sp->value.functioncall->args; lp != NULL; lp = lp->next)
2207 tempno = walkstring(lp->string, op, tempno);
2208 break;
2209 default:
2210 break;
2211 }
2212 }
2213 return tempno;
2214}
2215
2216
2217int compilearray(struct array *ap) {
2218 struct stringlist *ep;
2219 int i;
2220
2221 indent();
2222 printf("switch (");
2223 if (compileconcat(ap->index, T_INTEGER) != 0)
2224 return 1;
2225 printf(") {\n");
2226 for (i = 0, ep = ap->elements; ep != NULL; i++, ep = ep->next) {
2227 indent();
2228 printf("case %d:\n", i);
2229 indentation++;
2230 if (compilecheckedstring(ap->tempno, ep->string, ap->type) != 0)
2231 return 1;
2232 indent();
2233 printf("break;\n");
2234 indentation--;
2235 }
2236 indent();
2237 printf("}\n");
2238 return 0;
2239}
2240
2241
2242void compilesimplearray(enum type *tp, char *name, int num, struct array *ap) {
2243 struct stringlist *lp;
2244 int fixedlength;
2245
2246 fixedlength = (*tp == T_INTEGER) ? 0 : checkfixedlength(ap);
2247 if (fixedlength > 0)
2248 printf("char ");
2249 else
2250 compiletype(stdout, tp);
2251 if (name != NULL)
2252 printf(name);
2253 else
2254 compiletemp(num);
2255 printf("[]");
2256 if (fixedlength > 0)
2257 printf("[%d]", fixedlength);
2258 printf(" = {\n");
2259 indentation++;
2260 for (lp = ap->elements; lp != NULL; lp = lp->next) {
2261 indent();
2262 compilesimple(lp->string, lp->type);
2263 printf(",\n");
2264 }
2265 indentation--;
2266 indent();
2267 printf("};\n");
2268}
2269
2270
2271void declarearray(struct array *ap) {
2272 indent();
2273 compiletype(stdout, &ap->type);
2274 compiletemp(ap->tempno);
2275 printf(";\n");
2276}
2277
2278
2279void compilebitstring(struct bits *bp) {
2280 printf("(");
2281 if (bp->shift != 0)
2282 printf("(");
2283 printf("code & 0x%lx", bp->mask);
2284 if (bp->shift != 0)
2285 printf(") >> %d", bp->shift);
2286 printf(")");
2287}
2288
2289
2290void compilebitsplice(struct bitsplice *splicep) {
2291 struct bitsplicebits *bsp;
2292 char *last = "";
2293
2294 printf("(");
2295 for (bsp = splicep->splice; bsp != NULL; bsp = bsp->next) {
2296 printf(last);
2297 last = " | ";
2298 if (bsp->type == S_PARAMETER)
2299 putchar(bsp->value.arg->name);
2300 else {
2301 assert(bsp->type == S_BITSTRING);
2302 if (bsp->value.mask == 0)
2303 printf("code");
2304 else
2305 printf("(code & 0x%lx)", bsp->value.mask);
2306 }
2307 if (bsp->shift > 0)
2308 printf(" << %d", bsp->shift);
2309 else if (bsp->shift < 0)
2310 printf(" >> %d", -bsp->shift);
2311 }
2312 if (splicep->entry.value != 0)
2313 printf("%s0x%lx", last, splicep->entry.value);
2314 printf(")");
2315}
2316
2317
2318int bitcount(bits x) {
2319 int nbits;
2320
2321 for (nbits = 0; x != 0; x >>= 1) {
2322 if (x & 1)
2323 nbits++;
2324 }
2325 return nbits;
2326}
2327
2328
2329bits allbitsset(int nbits) {
2330 return (nbits == MAXBITS) ? ~0 : (1 << nbits) - 1;
2331}
2332
2333
2334void findent(FILE *f) {
2335 int i;
2336
2337 for (i = 1; i < indentation; i += 2)
2338 putc('\t', f);
2339 if (i == indentation)
2340 fputs(" ", f);
2341}
2342
2343
2344void indent() {
2345 findent(stdout);
2346}
2347
2348
2349void *xrealloc(char *oldp, size_t size) {
2350 void *p;
2351
2352 if (oldp == NULL)
2353 p = malloc(size);
2354 else
2355 p = realloc(oldp, size);
2356 if (p == NULL) {
2357 fprintf(stderr, "%s: allocate of %d bytes failed: %s\n", progname,
2358 (int) size, strerror(errno));
2359 exit(1);
2360 }
2361 return p;
2362}
2363
2364
2365void *xmalloc(size_t size) {
2366 return xrealloc(NULL, size);
2367}
2368
2369
2370void *xstrdup(char *s) {
2371 char *p;
2372
2373 p = xmalloc(strlen(s) + 1);
2374 strcpy(p, s);
2375 return p;
2376}
2377
2378
2379int prematureeof() {
2380 fprintf(stderr, "%s: %s(%d): premature end of file\n", progname, filename,
2381 lineno);
2382 return 1;
2383}
2384