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