xref: /csrg-svn/old/dbx/c.c (revision 9659)
1*9659Slinton /* Copyright (c) 1982 Regents of the University of California */
2*9659Slinton 
3*9659Slinton static char sccsid[] = "@(#)@(#)c.c 1.1 12/15/82";
4*9659Slinton 
5*9659Slinton /*
6*9659Slinton  * C-dependent symbol routines.
7*9659Slinton  */
8*9659Slinton 
9*9659Slinton #include "defs.h"
10*9659Slinton #include "symbols.h"
11*9659Slinton #include "printsym.h"
12*9659Slinton #include "languages.h"
13*9659Slinton #include "c.h"
14*9659Slinton #include "tree.h"
15*9659Slinton #include "eval.h"
16*9659Slinton #include "operators.h"
17*9659Slinton #include "mappings.h"
18*9659Slinton #include "process.h"
19*9659Slinton #include "runtime.h"
20*9659Slinton #include "machine.h"
21*9659Slinton 
22*9659Slinton #define isdouble(range) ( \
23*9659Slinton     range->symvalue.rangev.upper == 0 and range->symvalue.rangev.lower > 0 \
24*9659Slinton )
25*9659Slinton 
26*9659Slinton #define isrange(t, name) (t->class == RANGE and istypename(t->type, name))
27*9659Slinton 
28*9659Slinton /*
29*9659Slinton  * Initialize C language information.
30*9659Slinton  */
31*9659Slinton 
32*9659Slinton public c_init()
33*9659Slinton {
34*9659Slinton     Language lang;
35*9659Slinton 
36*9659Slinton     lang = language_define("c", ".c");
37*9659Slinton     language_setop(lang, L_PRINTDECL, c_printdecl);
38*9659Slinton     language_setop(lang, L_PRINTVAL, c_printval);
39*9659Slinton     language_setop(lang, L_TYPEMATCH, c_typematch);
40*9659Slinton }
41*9659Slinton 
42*9659Slinton /*
43*9659Slinton  * Test if two types are compatible.
44*9659Slinton  *
45*9659Slinton  * Integers and reals are not compatible since they cannot always be mixed.
46*9659Slinton  */
47*9659Slinton 
48*9659Slinton public Boolean c_typematch(type1, type2)
49*9659Slinton Symbol type1, type2;
50*9659Slinton {
51*9659Slinton     Boolean b;
52*9659Slinton     register Symbol t1, t2, tmp;
53*9659Slinton 
54*9659Slinton     t1 = type1;
55*9659Slinton     t2 = type2;
56*9659Slinton     if (t1 == t2) {
57*9659Slinton 	b = true;
58*9659Slinton     } else {
59*9659Slinton 	t1 = rtype(t1);
60*9659Slinton 	t2 = rtype(t2);
61*9659Slinton 	if (t1->type == t_int or t1->type == t_char) {
62*9659Slinton 	    tmp = t1;
63*9659Slinton 	    t1 = t2;
64*9659Slinton 	    t2 = tmp;
65*9659Slinton 	}
66*9659Slinton 	b = (Boolean) (
67*9659Slinton 	    (
68*9659Slinton 		isrange(t1, "int") and
69*9659Slinton 		(t2->type == t_int or t2->type == t_char)
70*9659Slinton 	    ) or (
71*9659Slinton 		isrange(t1, "char") and
72*9659Slinton 		(t2->type == t_char or t2->type == t_int)
73*9659Slinton 	    ) or (
74*9659Slinton 		t1->type == t2->type and (
75*9659Slinton 		    (t1->class == t2->class) or
76*9659Slinton 		    (t1->class == SCAL and t2->class == CONST) or
77*9659Slinton 		    (t1->class == CONST and t2->class == SCAL)
78*9659Slinton 		)
79*9659Slinton 	    )
80*9659Slinton 	);
81*9659Slinton     }
82*9659Slinton     return b;
83*9659Slinton }
84*9659Slinton 
85*9659Slinton /*
86*9659Slinton  * Decide if a field is a bit field.
87*9659Slinton  */
88*9659Slinton 
89*9659Slinton private Boolean isbitfield(s)
90*9659Slinton register Symbol s;
91*9659Slinton {
92*9659Slinton     Boolean b;
93*9659Slinton     register Integer off, len;
94*9659Slinton     register Symbol t;
95*9659Slinton 
96*9659Slinton     off = s->symvalue.field.offset;
97*9659Slinton     len = s->symvalue.field.length;
98*9659Slinton     if ((off mod BITSPERBYTE) != 0 or (len mod BITSPERBYTE) != 0) {
99*9659Slinton 	b = true;
100*9659Slinton     } else {
101*9659Slinton 	t = rtype(s->type);
102*9659Slinton 	b = (Boolean)
103*9659Slinton 	    (t->class == SCAL and len != (sizeof(int)*BITSPERBYTE) or
104*9659Slinton 	    len != (size(t)*BITSPERBYTE)
105*9659Slinton 	);
106*9659Slinton     }
107*9659Slinton     return b;
108*9659Slinton }
109*9659Slinton 
110*9659Slinton /*
111*9659Slinton  * Print out the declaration of a C variable.
112*9659Slinton  */
113*9659Slinton 
114*9659Slinton public c_printdecl(s)
115*9659Slinton Symbol s;
116*9659Slinton {
117*9659Slinton     printdecl(s, 0);
118*9659Slinton }
119*9659Slinton 
120*9659Slinton private printdecl(s, indent)
121*9659Slinton register Symbol s;
122*9659Slinton Integer indent;
123*9659Slinton {
124*9659Slinton     register Symbol t;
125*9659Slinton     Boolean semicolon, newline;
126*9659Slinton 
127*9659Slinton     semicolon = true;
128*9659Slinton     newline = true;
129*9659Slinton     if (indent > 0) {
130*9659Slinton 	printf("%*c", indent, ' ');
131*9659Slinton     }
132*9659Slinton     if (s->class == TYPE) {
133*9659Slinton 	printf("typedef ");
134*9659Slinton     }
135*9659Slinton     switch (s->class) {
136*9659Slinton 	case CONST:
137*9659Slinton 	    if (s->type->class == SCAL) {
138*9659Slinton 		printf("(enumeration constant, ord %ld)",
139*9659Slinton 		    s->symvalue.iconval);
140*9659Slinton 	    } else {
141*9659Slinton 		printf("const %s = ", symname(s));
142*9659Slinton 		printval(s);
143*9659Slinton 	    }
144*9659Slinton 	    break;
145*9659Slinton 
146*9659Slinton 	case TYPE:
147*9659Slinton 	case VAR:
148*9659Slinton 	    if (s->class != TYPE) {
149*9659Slinton 		if (s->level == 2) {
150*9659Slinton 		    printf("static ");
151*9659Slinton 		} else if (s->level < 0) {
152*9659Slinton 		    printf("register ");
153*9659Slinton 		}
154*9659Slinton 	    }
155*9659Slinton 	    if (s->type->class == ARRAY) {
156*9659Slinton 		printtype(s->type, s->type->type, indent);
157*9659Slinton 		t = rtype(s->type->chain);
158*9659Slinton 		assert(t->class == RANGE);
159*9659Slinton 		printf(" %s[%d]", symname(s), t->symvalue.rangev.upper + 1);
160*9659Slinton 	    } else {
161*9659Slinton 		printtype(s, s->type, indent);
162*9659Slinton 		if (s->type->class != PTR) {
163*9659Slinton 		    printf(" ");
164*9659Slinton 		}
165*9659Slinton 		printf("%s", symname(s));
166*9659Slinton 	    }
167*9659Slinton 	    break;
168*9659Slinton 
169*9659Slinton 	case FIELD:
170*9659Slinton 	    if (s->type->class == ARRAY) {
171*9659Slinton 		printtype(s->type, s->type->type, indent);
172*9659Slinton 		t = rtype(s->type->chain);
173*9659Slinton 		assert(t->class == RANGE);
174*9659Slinton 		printf(" %s[%d]", symname(s), t->symvalue.rangev.upper + 1);
175*9659Slinton 	    } else {
176*9659Slinton 		printtype(s, s->type, indent);
177*9659Slinton 		if (s->type->class != PTR) {
178*9659Slinton 		    printf(" ");
179*9659Slinton 		}
180*9659Slinton 		printf("%s", symname(s));
181*9659Slinton 	    }
182*9659Slinton 	    if (isbitfield(s)) {
183*9659Slinton 		printf(" : %d", s->symvalue.field.length);
184*9659Slinton 	    }
185*9659Slinton 	    break;
186*9659Slinton 
187*9659Slinton 	case TAG:
188*9659Slinton 	    if (s->type == nil) {
189*9659Slinton 		findtype(s);
190*9659Slinton 		if (s->type == nil) {
191*9659Slinton 		    error("unexpected missing type information");
192*9659Slinton 		}
193*9659Slinton 	    }
194*9659Slinton 	    printtype(s, s->type, indent);
195*9659Slinton 	    break;
196*9659Slinton 
197*9659Slinton 	case RANGE:
198*9659Slinton 	case ARRAY:
199*9659Slinton 	case RECORD:
200*9659Slinton 	case VARNT:
201*9659Slinton 	case PTR:
202*9659Slinton 	    semicolon = false;
203*9659Slinton 	    printtype(s, s, indent);
204*9659Slinton 	    break;
205*9659Slinton 
206*9659Slinton 	case PROC:
207*9659Slinton 	    semicolon = false;
208*9659Slinton 	    printf("%s", symname(s));
209*9659Slinton 	    c_listparams(s);
210*9659Slinton 	    newline = false;
211*9659Slinton 	    break;
212*9659Slinton 
213*9659Slinton 	case FUNC:
214*9659Slinton 	    semicolon = false;
215*9659Slinton 	    if (not istypename(s->type, "void")) {
216*9659Slinton 		printtype(s, s->type, indent);
217*9659Slinton 		printf(" ");
218*9659Slinton 	    }
219*9659Slinton 	    printf("%s", symname(s));
220*9659Slinton 	    c_listparams(s);
221*9659Slinton 	    newline = false;
222*9659Slinton 	    break;
223*9659Slinton 
224*9659Slinton 	case MODULE:
225*9659Slinton 	    semicolon = false;
226*9659Slinton 	    printf("source file \"%s.c\"", symname(s));
227*9659Slinton 	    break;
228*9659Slinton 
229*9659Slinton 	case PROG:
230*9659Slinton 	    semicolon = false;
231*9659Slinton 	    printf("executable file \"%s\"", symname(s));
232*9659Slinton 	    break;
233*9659Slinton 
234*9659Slinton 	default:
235*9659Slinton 	    error("class %s in c_printdecl", classname(s));
236*9659Slinton     }
237*9659Slinton     if (semicolon) {
238*9659Slinton 	putchar(';');
239*9659Slinton     }
240*9659Slinton     if (newline) {
241*9659Slinton 	putchar('\n');
242*9659Slinton     }
243*9659Slinton }
244*9659Slinton 
245*9659Slinton /*
246*9659Slinton  * Recursive whiz-bang procedure to print the type portion
247*9659Slinton  * of a declaration.
248*9659Slinton  *
249*9659Slinton  * The symbol associated with the type is passed to allow
250*9659Slinton  * searching for type names without getting "type blah = blah".
251*9659Slinton  */
252*9659Slinton 
253*9659Slinton private printtype(s, t, indent)
254*9659Slinton Symbol s;
255*9659Slinton Symbol t;
256*9659Slinton Integer indent;
257*9659Slinton {
258*9659Slinton     register Symbol i;
259*9659Slinton     long r0, r1;
260*9659Slinton     register String p;
261*9659Slinton 
262*9659Slinton     checkref(s);
263*9659Slinton     checkref(t);
264*9659Slinton     switch (t->class) {
265*9659Slinton 	case VAR:
266*9659Slinton 	case CONST:
267*9659Slinton 	case PROC:
268*9659Slinton 	    panic("printtype: class %s", classname(t));
269*9659Slinton 	    break;
270*9659Slinton 
271*9659Slinton 	case ARRAY:
272*9659Slinton 	    printf("array[");
273*9659Slinton 	    i = t->chain;
274*9659Slinton 	    if (i != nil) {
275*9659Slinton 		for (;;) {
276*9659Slinton 		    printtype(i, i, indent);
277*9659Slinton 		    i = i->chain;
278*9659Slinton 		    if (i == nil) {
279*9659Slinton 			break;
280*9659Slinton 		    }
281*9659Slinton 		    printf(", ");
282*9659Slinton 		}
283*9659Slinton 	    }
284*9659Slinton 	    printf("] of ");
285*9659Slinton 	    printtype(t, t->type, indent);
286*9659Slinton 	    break;
287*9659Slinton 
288*9659Slinton 	case RECORD:
289*9659Slinton 	case VARNT:
290*9659Slinton 	    printf("%s ", c_classname(t));
291*9659Slinton 	    if (s->name != nil and s->class == TAG) {
292*9659Slinton 		p = symname(s);
293*9659Slinton 		if (p[0] == '$' and p[1] == '$') {
294*9659Slinton 		    printf("%s ", &p[2]);
295*9659Slinton 		} else {
296*9659Slinton 		    printf("%s ", p);
297*9659Slinton 		}
298*9659Slinton 	    }
299*9659Slinton 	    printf("{\n", t->class == RECORD ? "struct" : "union");
300*9659Slinton 	    for (i = t->chain; i != nil; i = i->chain) {
301*9659Slinton 		assert(i->class == FIELD);
302*9659Slinton 		printdecl(i, indent+4);
303*9659Slinton 	    }
304*9659Slinton 	    if (indent > 0) {
305*9659Slinton 		printf("%*c", indent, ' ');
306*9659Slinton 	    }
307*9659Slinton 	    printf("}");
308*9659Slinton 	    break;
309*9659Slinton 
310*9659Slinton 	case RANGE:
311*9659Slinton 	    r0 = t->symvalue.rangev.lower;
312*9659Slinton 	    r1 = t->symvalue.rangev.upper;
313*9659Slinton 	    if (istypename(t->type, "char")) {
314*9659Slinton 		if (r0 < 0x20 or r0 > 0x7e) {
315*9659Slinton 		    printf("%ld..", r0);
316*9659Slinton 		} else {
317*9659Slinton 		    printf("'%c'..", (char) r0);
318*9659Slinton 		}
319*9659Slinton 		if (r1 < 0x20 or r1 > 0x7e) {
320*9659Slinton 		    printf("\\%lo", r1);
321*9659Slinton 		} else {
322*9659Slinton 		    printf("'%c'", (char) r1);
323*9659Slinton 		}
324*9659Slinton 	    } else if (r0 > 0 and r1 == 0) {
325*9659Slinton 		printf("%ld byte real", r0);
326*9659Slinton 	    } else if (r0 >= 0) {
327*9659Slinton 		printf("%lu..%lu", r0, r1);
328*9659Slinton 	    } else {
329*9659Slinton 		printf("%ld..%ld", r0, r1);
330*9659Slinton 	    }
331*9659Slinton 	    break;
332*9659Slinton 
333*9659Slinton 	case PTR:
334*9659Slinton 	    printtype(t, t->type, indent);
335*9659Slinton 	    if (t->type->class != PTR) {
336*9659Slinton 		printf(" ");
337*9659Slinton 	    }
338*9659Slinton 	    printf("*");
339*9659Slinton 	    break;
340*9659Slinton 
341*9659Slinton 	case FUNC:
342*9659Slinton 	    printtype(t, t->type, indent);
343*9659Slinton 	    printf("()");
344*9659Slinton 	    break;
345*9659Slinton 
346*9659Slinton 	case TYPE:
347*9659Slinton 	    if (t->name != nil) {
348*9659Slinton 		printname(stdout, t);
349*9659Slinton 	    } else {
350*9659Slinton 		printtype(t, t->type, indent);
351*9659Slinton 	    }
352*9659Slinton 	    break;
353*9659Slinton 
354*9659Slinton 	case TYPEREF:
355*9659Slinton 	    printf("@%s", symname(t));
356*9659Slinton 	    break;
357*9659Slinton 
358*9659Slinton 	case SCAL:
359*9659Slinton 	    printf("enum ");
360*9659Slinton 	    if (s->name != nil and s->class == TAG) {
361*9659Slinton 		printf("%s ", symname(s));
362*9659Slinton 	    }
363*9659Slinton 	    printf("{ ");
364*9659Slinton 	    i = t->chain;
365*9659Slinton 	    if (i != nil) {
366*9659Slinton 		for (;;) {
367*9659Slinton 		    printf("%s", symname(i));
368*9659Slinton 		    i = i->chain;
369*9659Slinton 		if (i == nil) break;
370*9659Slinton 		    printf(", ");
371*9659Slinton 		}
372*9659Slinton 	    }
373*9659Slinton 	    printf(" }");
374*9659Slinton 	    break;
375*9659Slinton 
376*9659Slinton 	case TAG:
377*9659Slinton 	    if (t->type == nil) {
378*9659Slinton 		printf("unresolved tag %s", symname(t));
379*9659Slinton 	    } else {
380*9659Slinton 		i = rtype(t->type);
381*9659Slinton 		printf("%s %s", c_classname(i), symname(t));
382*9659Slinton 	    }
383*9659Slinton 	    break;
384*9659Slinton 
385*9659Slinton 	default:
386*9659Slinton 	    printf("(class %d)", t->class);
387*9659Slinton 	    break;
388*9659Slinton     }
389*9659Slinton }
390*9659Slinton 
391*9659Slinton /*
392*9659Slinton  * List the parameters of a procedure or function.
393*9659Slinton  * No attempt is made to combine like types.
394*9659Slinton  */
395*9659Slinton 
396*9659Slinton public c_listparams(s)
397*9659Slinton Symbol s;
398*9659Slinton {
399*9659Slinton     register Symbol t;
400*9659Slinton 
401*9659Slinton     putchar('(');
402*9659Slinton     for (t = s->chain; t != nil; t = t->chain) {
403*9659Slinton 	printf("%s", symname(t));
404*9659Slinton 	if (t->chain != nil) {
405*9659Slinton 	    printf(", ");
406*9659Slinton 	}
407*9659Slinton     }
408*9659Slinton     putchar(')');
409*9659Slinton     if (s->chain != nil) {
410*9659Slinton 	printf("\n");
411*9659Slinton 	for (t = s->chain; t != nil; t = t->chain) {
412*9659Slinton 	    if (t->class != VAR) {
413*9659Slinton 		panic("unexpected class %d for parameter", t->class);
414*9659Slinton 	    }
415*9659Slinton 	    printdecl(t, 0);
416*9659Slinton 	}
417*9659Slinton     } else {
418*9659Slinton 	putchar('\n');
419*9659Slinton     }
420*9659Slinton }
421*9659Slinton 
422*9659Slinton /*
423*9659Slinton  * Print out the value on the top of the expression stack
424*9659Slinton  * in the format for the type of the given symbol.
425*9659Slinton  */
426*9659Slinton 
427*9659Slinton public c_printval(s)
428*9659Slinton Symbol s;
429*9659Slinton {
430*9659Slinton     register Symbol t;
431*9659Slinton     register Address a;
432*9659Slinton     register int i, len;
433*9659Slinton 
434*9659Slinton     switch (s->class) {
435*9659Slinton 	case CONST:
436*9659Slinton 	case TYPE:
437*9659Slinton 	case VAR:
438*9659Slinton 	case REF:
439*9659Slinton 	case FVAR:
440*9659Slinton 	case TAG:
441*9659Slinton 	    c_printval(s->type);
442*9659Slinton 	    break;
443*9659Slinton 
444*9659Slinton 	case FIELD:
445*9659Slinton 	    if (isbitfield(s)) {
446*9659Slinton 		len = s->symvalue.field.length;
447*9659Slinton 		if (len <= BITSPERBYTE) {
448*9659Slinton 		    i = pop(char);
449*9659Slinton 		} else if (len <= sizeof(short)*BITSPERBYTE) {
450*9659Slinton 		    i = pop(short);
451*9659Slinton 		} else {
452*9659Slinton 		    i = pop(long);
453*9659Slinton 		}
454*9659Slinton 		i >>= (s->symvalue.field.offset mod BITSPERBYTE);
455*9659Slinton 		i &= ((1 << len) - 1);
456*9659Slinton 		t = rtype(s->type);
457*9659Slinton 		if (t->class == SCAL) {
458*9659Slinton 		    printenum(i, t);
459*9659Slinton 		} else {
460*9659Slinton 		    printrange(i, t);
461*9659Slinton 		}
462*9659Slinton 	    } else {
463*9659Slinton 		c_printval(s->type);
464*9659Slinton 	    }
465*9659Slinton 	    break;
466*9659Slinton 
467*9659Slinton 	case ARRAY:
468*9659Slinton 	    t = rtype(s->type);
469*9659Slinton 	    if (t->class == RANGE and istypename(t->type, "char")) {
470*9659Slinton 		len = size(s);
471*9659Slinton 		sp -= len;
472*9659Slinton 		printf("\"%.*s\"", len, sp);
473*9659Slinton 	    } else {
474*9659Slinton 		printarray(s);
475*9659Slinton 	    }
476*9659Slinton 	    break;
477*9659Slinton 
478*9659Slinton 	case RECORD:
479*9659Slinton 	case VARNT:
480*9659Slinton 	    c_printstruct(s);
481*9659Slinton 	    break;
482*9659Slinton 
483*9659Slinton 	case RANGE:
484*9659Slinton 	    if (istypename(s->type, "boolean")) {
485*9659Slinton 		printrange(popsmall(s), s);
486*9659Slinton 	    } else if (istypename(s->type, "char")) {
487*9659Slinton 		printrange(pop(char), s);
488*9659Slinton 	    } else if (isdouble(s)) {
489*9659Slinton 		switch (s->symvalue.rangev.lower) {
490*9659Slinton 		    case sizeof(float):
491*9659Slinton 			prtreal(pop(float));
492*9659Slinton 			break;
493*9659Slinton 
494*9659Slinton 		    case sizeof(double):
495*9659Slinton 			prtreal(pop(double));
496*9659Slinton 			break;
497*9659Slinton 
498*9659Slinton 		    default:
499*9659Slinton 			panic("bad real size %d", t->symvalue.rangev.lower);
500*9659Slinton 			break;
501*9659Slinton 		}
502*9659Slinton 	    } else {
503*9659Slinton 		printrange(popsmall(s), s);
504*9659Slinton 	    }
505*9659Slinton 	    break;
506*9659Slinton 
507*9659Slinton 	case PTR:
508*9659Slinton 	    t = rtype(s->type);
509*9659Slinton 	    a = pop(Address);
510*9659Slinton 	    if (a == 0) {
511*9659Slinton 		printf("(nil)");
512*9659Slinton 	    } else if (t->class == RANGE and istypename(t->type, "char")) {
513*9659Slinton 		printstring(a);
514*9659Slinton 	    } else {
515*9659Slinton 		printf("0x%x", a);
516*9659Slinton 	    }
517*9659Slinton 	    break;
518*9659Slinton 
519*9659Slinton 	case SCAL:
520*9659Slinton 	    i = pop(Integer);
521*9659Slinton 	    printenum(i, s);
522*9659Slinton 	    break;
523*9659Slinton 
524*9659Slinton 	default:
525*9659Slinton 	    if (ord(s->class) > ord(TYPEREF)) {
526*9659Slinton 		panic("printval: bad class %d", ord(s->class));
527*9659Slinton 	    }
528*9659Slinton 	    error("don't know how to print a %s", c_classname(s));
529*9659Slinton 	    /* NOTREACHED */
530*9659Slinton     }
531*9659Slinton }
532*9659Slinton 
533*9659Slinton /*
534*9659Slinton  * Print out a C structure.
535*9659Slinton  */
536*9659Slinton 
537*9659Slinton private c_printstruct(s)
538*9659Slinton Symbol s;
539*9659Slinton {
540*9659Slinton     register Symbol f;
541*9659Slinton     register Stack *savesp;
542*9659Slinton     register Integer n, off, len;
543*9659Slinton 
544*9659Slinton     sp -= size(s);
545*9659Slinton     savesp = sp;
546*9659Slinton     printf("(");
547*9659Slinton     f = s->chain;
548*9659Slinton     for (;;) {
549*9659Slinton 	off = f->symvalue.field.offset;
550*9659Slinton 	len = f->symvalue.field.length;
551*9659Slinton 	n = (off + len + 7) div BITSPERBYTE;
552*9659Slinton 	sp += n;
553*9659Slinton 	printf("%s = ", symname(f));
554*9659Slinton 	c_printval(f);
555*9659Slinton 	sp = savesp;
556*9659Slinton 	f = f->chain;
557*9659Slinton     if (f == nil) break;
558*9659Slinton 	printf(", ");
559*9659Slinton     }
560*9659Slinton     printf(")");
561*9659Slinton }
562*9659Slinton 
563*9659Slinton /*
564*9659Slinton  * Print out a range type (integer, char, or boolean).
565*9659Slinton  */
566*9659Slinton 
567*9659Slinton private printrange(i, t)
568*9659Slinton Integer i;
569*9659Slinton register Symbol t;
570*9659Slinton {
571*9659Slinton     if (istypename(t->type, "boolean")) {
572*9659Slinton 	printf(((Boolean) i) == true ? "true" : "false");
573*9659Slinton     } else if (istypename(t->type, "char")) {
574*9659Slinton 	putchar('\'');
575*9659Slinton 	printchar(i);
576*9659Slinton 	putchar('\'');
577*9659Slinton     } else if (t->symvalue.rangev.lower >= 0) {
578*9659Slinton 	printf("%lu", i);
579*9659Slinton     } else {
580*9659Slinton 	printf("%ld", i);
581*9659Slinton     }
582*9659Slinton }
583*9659Slinton 
584*9659Slinton /*
585*9659Slinton  * Print out a null-terminated string (pointer to char)
586*9659Slinton  * starting at the given address.
587*9659Slinton  */
588*9659Slinton 
589*9659Slinton private printstring(addr)
590*9659Slinton Address addr;
591*9659Slinton {
592*9659Slinton     register Address a;
593*9659Slinton     register Integer i, len;
594*9659Slinton     register Boolean endofstring;
595*9659Slinton     union {
596*9659Slinton 	char ch[sizeof(Word)];
597*9659Slinton 	int word;
598*9659Slinton     } u;
599*9659Slinton 
600*9659Slinton     putchar('"');
601*9659Slinton     a = addr;
602*9659Slinton     endofstring = false;
603*9659Slinton     while (not endofstring) {
604*9659Slinton 	dread(&u, a, sizeof(u));
605*9659Slinton 	i = 0;
606*9659Slinton 	do {
607*9659Slinton 	    if (u.ch[i] == '\0') {
608*9659Slinton 		endofstring = true;
609*9659Slinton 	    } else {
610*9659Slinton 		printchar(u.ch[i]);
611*9659Slinton 	    }
612*9659Slinton 	    ++i;
613*9659Slinton 	} while (i < sizeof(Word) and not endofstring);
614*9659Slinton 	a += sizeof(Word);
615*9659Slinton     }
616*9659Slinton     putchar('"');
617*9659Slinton }
618*9659Slinton 
619*9659Slinton /*
620*9659Slinton  * Print out an enumerated value by finding the corresponding
621*9659Slinton  * name in the enumeration list.
622*9659Slinton  */
623*9659Slinton 
624*9659Slinton private printenum(i, t)
625*9659Slinton Integer i;
626*9659Slinton Symbol t;
627*9659Slinton {
628*9659Slinton     register Symbol e;
629*9659Slinton 
630*9659Slinton     e = t->chain;
631*9659Slinton     while (e != nil and e->symvalue.iconval != i) {
632*9659Slinton 	e = e->chain;
633*9659Slinton     }
634*9659Slinton     if (e != nil) {
635*9659Slinton 	printf("%s", symname(e));
636*9659Slinton     } else {
637*9659Slinton 	printf("%d", i);
638*9659Slinton     }
639*9659Slinton }
640*9659Slinton 
641*9659Slinton /*
642*9659Slinton  * Return the C name for the particular class of a symbol.
643*9659Slinton  */
644*9659Slinton 
645*9659Slinton public String c_classname(s)
646*9659Slinton Symbol s;
647*9659Slinton {
648*9659Slinton     String str;
649*9659Slinton 
650*9659Slinton     switch (s->class) {
651*9659Slinton 	case RECORD:
652*9659Slinton 	    str = "struct";
653*9659Slinton 	    break;
654*9659Slinton 
655*9659Slinton 	case VARNT:
656*9659Slinton 	    str = "union";
657*9659Slinton 	    break;
658*9659Slinton 
659*9659Slinton 	case SCAL:
660*9659Slinton 	    str = "enum";
661*9659Slinton 	    break;
662*9659Slinton 
663*9659Slinton 	default:
664*9659Slinton 	    str = classname(s);
665*9659Slinton     }
666*9659Slinton     return str;
667*9659Slinton }
668