4.3BSD beta release manual page
[unix-history] / usr / src / old / dbx / check.c
CommitLineData
b329a001
ML
1/* Copyright (c) 1982 Regents of the University of California */
2
0022c355
ML
3static char sccsid[] = "@(#)check.c 1.7 (Berkeley) %G%";
4
5static char rcsid[] = "$Header: check.c,v 1.5 84/12/26 10:38:35 linton Exp $";
b329a001
ML
6
7/*
8 * Check a tree for semantic correctness.
9 */
10
11#include "defs.h"
12#include "tree.h"
13#include "operators.h"
14#include "events.h"
15#include "symbols.h"
16#include "scanner.h"
17#include "source.h"
18#include "object.h"
19#include "mappings.h"
20#include "process.h"
0022c355 21#include <signal.h>
b329a001
ML
22
23#ifndef public
24#endif
25
26/*
27 * Check that the nodes in a tree have the correct arguments
28 * in order to be evaluated. Basically the error checking here
29 * frees the evaluation routines from worrying about anything
30 * except dynamic errors, e.g. subscript out of range.
31 */
32
33public check(p)
34register Node p;
35{
0022c355 36 Node p1, p2;
b329a001
ML
37 Address addr;
38 Symbol f;
39
40 checkref(p);
41 switch (p->op) {
0022c355
ML
42 case O_ASSIGN:
43 p1 = p->value.arg[0];
44 p2 = p->value.arg[1];
45 if (not compatible(p1->nodetype, p2->nodetype)) {
46 error("incompatible types");
47 }
48 break;
49
50 case O_CATCH:
51 case O_IGNORE:
52 if (p->value.lcon < 0 or p->value.lcon > NSIG) {
53 error("invalid signal number");
54 }
55 break;
56
57 case O_CONT:
58 if (p->value.lcon != DEFSIG and (
59 p->value.lcon < 0 or p->value.lcon > NSIG)
60 ) {
61 error("invalid signal number");
62 }
63 break;
64
65 case O_DUMP:
66 if (p->value.arg[0] != nil) {
67 if (p->value.arg[0]->op == O_SYM) {
68 f = p->value.arg[0]->value.sym;
69 if (not isblock(f)) {
70 error("\"%s\" is not a block", symname(f));
71 }
72 } else {
73 beginerrmsg();
74 fprintf(stderr, "expected a symbol, found \"");
75 prtree(stderr, p->value.arg[0]);
76 fprintf(stderr, "\"");
77 enderrmsg();
78 }
79 }
80 break;
81
b329a001
ML
82 case O_LIST:
83 if (p->value.arg[0]->op == O_SYM) {
84 f = p->value.arg[0]->value.sym;
85 if (not isblock(f) or ismodule(f)) {
86 error("\"%s\" is not a procedure or function", symname(f));
87 }
88 addr = firstline(f);
89 if (addr == NOADDR) {
90 error("\"%s\" is empty", symname(f));
91 }
92 }
93 break;
94
95 case O_TRACE:
96 case O_TRACEI:
97 chktrace(p);
98 break;
99
100 case O_STOP:
101 case O_STOPI:
102 chkstop(p);
103 break;
104
0022c355 105 case O_CALLPROC:
2fd0f574
SL
106 case O_CALL:
107 if (not isroutine(p->value.arg[0]->nodetype)) {
108 beginerrmsg();
109 fprintf(stderr, "\"");
110 prtree(stderr, p->value.arg[0]);
111 fprintf(stderr, "\" not call-able");
112 enderrmsg();
113 }
114 break;
115
0022c355
ML
116 case O_WHEREIS:
117 if (p->value.arg[0]->op == O_SYM and
118 p->value.arg[0]->value.sym == nil) {
119 error("symbol not defined");
120 }
121 break;
122
b329a001
ML
123 default:
124 break;
125 }
126}
127
128/*
129 * Check arguments to a trace command.
130 */
131
132private chktrace(p)
133Node p;
134{
135 Node exp, place, cond;
136
137 exp = p->value.arg[0];
138 place = p->value.arg[1];
139 cond = p->value.arg[2];
140 if (exp == nil) {
141 chkblock(place);
142 } else if (exp->op == O_LCON or exp->op == O_QLINE) {
143 if (place != nil) {
144 error("unexpected \"at\" or \"in\"");
145 }
146 if (p->op == O_TRACE) {
147 chkline(exp);
148 } else {
149 chkaddr(exp);
150 }
151 } else if (place != nil and (place->op == O_QLINE or place->op == O_LCON)) {
152 if (p->op == O_TRACE) {
153 chkline(place);
154 } else {
155 chkaddr(place);
156 }
157 } else {
7bf092d9 158 if (exp->op != O_RVAL and exp->op != O_SYM and exp->op != O_CALL) {
b329a001
ML
159 error("can't trace expressions");
160 }
161 chkblock(place);
162 }
163}
164
165/*
166 * Check arguments to a stop command.
167 */
168
169private chkstop(p)
170Node p;
171{
172 Node exp, place, cond;
173
174 exp = p->value.arg[0];
175 place = p->value.arg[1];
176 cond = p->value.arg[2];
177 if (exp != nil) {
7cc22d81 178 if (exp->op != O_RVAL and exp->op != O_SYM and exp->op != O_LCON) {
b329a001
ML
179 beginerrmsg();
180 fprintf(stderr, "expected variable, found ");
181 prtree(stderr, exp);
182 enderrmsg();
183 }
184 chkblock(place);
2fd0f574
SL
185 } else if (place != nil) {
186 if (place->op == O_SYM) {
187 chkblock(place);
b329a001 188 } else {
2fd0f574
SL
189 if (p->op == O_STOP) {
190 chkline(place);
191 } else {
192 chkaddr(place);
193 }
b329a001
ML
194 }
195 }
196}
197
198/*
199 * Check to see that the given node specifies some subprogram.
200 * Nil is ok since that means the entire program.
201 */
202
203private chkblock(b)
204Node b;
205{
2fd0f574
SL
206 Symbol p, outer;
207
b329a001
ML
208 if (b != nil) {
209 if (b->op != O_SYM) {
210 beginerrmsg();
211 fprintf(stderr, "expected subprogram, found ");
212 prtree(stderr, b);
213 enderrmsg();
2fd0f574
SL
214 } else if (ismodule(b->value.sym)) {
215 outer = b->value.sym;
216 while (outer != nil) {
217 find(p, outer->name) where p->block == outer endfind(p);
218 if (p == nil) {
219 outer = nil;
220 error("\"%s\" is not a subprogram", symname(b->value.sym));
221 } else if (ismodule(p)) {
222 outer = p;
223 } else {
224 outer = nil;
225 b->value.sym = p;
226 }
227 }
0022c355
ML
228 } else if (
229 b->value.sym->class == VAR and
230 b->value.sym->name == b->value.sym->block->name and
231 b->value.sym->block->class == FUNC
232 ) {
233 b->value.sym = b->value.sym->block;
2fd0f574 234 } else if (not isblock(b->value.sym)) {
b329a001
ML
235 error("\"%s\" is not a subprogram", symname(b->value.sym));
236 }
237 }
238}
239
240/*
241 * Check to make sure a node corresponds to a source line.
242 */
243
244private chkline(p)
245Node p;
246{
247 if (p == nil) {
248 error("missing line");
249 } else if (p->op != O_QLINE and p->op != O_LCON) {
250 error("expected source line number, found \"%t\"", p);
251 }
252}
253
254/*
255 * Check to make sure a node corresponds to an address.
256 */
257
258private chkaddr(p)
259Node p;
260{
261 if (p == nil) {
262 error("missing address");
263 } else if (p->op != O_LCON and p->op != O_QLINE) {
264 beginerrmsg();
265 fprintf(stderr, "expected address, found \"");
266 prtree(stderr, p);
267 fprintf(stderr, "\"");
268 enderrmsg();
269 }
270}