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