made minimum granularity of vertical movement a parameter read from DESC file
[unix-history] / usr / src / old / dbx / check.c
CommitLineData
b329a001
ML
1/* Copyright (c) 1982 Regents of the University of California */
2
e1f4dbca 3static char sccsid[] = "@(#)check.c 1.6 (Berkeley) %G%";
b329a001
ML
4
5/*
6 * Check a tree for semantic correctness.
7 */
8
9#include "defs.h"
10#include "tree.h"
11#include "operators.h"
12#include "events.h"
13#include "symbols.h"
14#include "scanner.h"
15#include "source.h"
16#include "object.h"
17#include "mappings.h"
18#include "process.h"
19
20#ifndef public
21#endif
22
23/*
24 * Check that the nodes in a tree have the correct arguments
25 * in order to be evaluated. Basically the error checking here
26 * frees the evaluation routines from worrying about anything
27 * except dynamic errors, e.g. subscript out of range.
28 */
29
30public check(p)
31register Node p;
32{
33 Address addr;
34 Symbol f;
35
36 checkref(p);
37 switch (p->op) {
38 case O_LIST:
39 if (p->value.arg[0]->op == O_SYM) {
40 f = p->value.arg[0]->value.sym;
41 if (not isblock(f) or ismodule(f)) {
42 error("\"%s\" is not a procedure or function", symname(f));
43 }
44 addr = firstline(f);
45 if (addr == NOADDR) {
46 error("\"%s\" is empty", symname(f));
47 }
48 }
49 break;
50
51 case O_TRACE:
52 case O_TRACEI:
53 chktrace(p);
54 break;
55
56 case O_STOP:
57 case O_STOPI:
58 chkstop(p);
59 break;
60
2fd0f574
SL
61 case O_CALL:
62 if (not isroutine(p->value.arg[0]->nodetype)) {
63 beginerrmsg();
64 fprintf(stderr, "\"");
65 prtree(stderr, p->value.arg[0]);
66 fprintf(stderr, "\" not call-able");
67 enderrmsg();
68 }
69 break;
70
b329a001
ML
71 default:
72 break;
73 }
74}
75
76/*
77 * Check arguments to a trace command.
78 */
79
80private chktrace(p)
81Node p;
82{
83 Node exp, place, cond;
84
85 exp = p->value.arg[0];
86 place = p->value.arg[1];
87 cond = p->value.arg[2];
88 if (exp == nil) {
89 chkblock(place);
90 } else if (exp->op == O_LCON or exp->op == O_QLINE) {
91 if (place != nil) {
92 error("unexpected \"at\" or \"in\"");
93 }
94 if (p->op == O_TRACE) {
95 chkline(exp);
96 } else {
97 chkaddr(exp);
98 }
99 } else if (place != nil and (place->op == O_QLINE or place->op == O_LCON)) {
100 if (p->op == O_TRACE) {
101 chkline(place);
102 } else {
103 chkaddr(place);
104 }
105 } else {
7bf092d9 106 if (exp->op != O_RVAL and exp->op != O_SYM and exp->op != O_CALL) {
b329a001
ML
107 error("can't trace expressions");
108 }
109 chkblock(place);
110 }
111}
112
113/*
114 * Check arguments to a stop command.
115 */
116
117private chkstop(p)
118Node p;
119{
120 Node exp, place, cond;
121
122 exp = p->value.arg[0];
123 place = p->value.arg[1];
124 cond = p->value.arg[2];
125 if (exp != nil) {
7cc22d81 126 if (exp->op != O_RVAL and exp->op != O_SYM and exp->op != O_LCON) {
b329a001
ML
127 beginerrmsg();
128 fprintf(stderr, "expected variable, found ");
129 prtree(stderr, exp);
130 enderrmsg();
131 }
132 chkblock(place);
2fd0f574
SL
133 } else if (place != nil) {
134 if (place->op == O_SYM) {
135 chkblock(place);
b329a001 136 } else {
2fd0f574
SL
137 if (p->op == O_STOP) {
138 chkline(place);
139 } else {
140 chkaddr(place);
141 }
b329a001
ML
142 }
143 }
144}
145
146/*
147 * Check to see that the given node specifies some subprogram.
148 * Nil is ok since that means the entire program.
149 */
150
151private chkblock(b)
152Node b;
153{
2fd0f574
SL
154 Symbol p, outer;
155
b329a001
ML
156 if (b != nil) {
157 if (b->op != O_SYM) {
158 beginerrmsg();
159 fprintf(stderr, "expected subprogram, found ");
160 prtree(stderr, b);
161 enderrmsg();
2fd0f574
SL
162 } else if (ismodule(b->value.sym)) {
163 outer = b->value.sym;
164 while (outer != nil) {
165 find(p, outer->name) where p->block == outer endfind(p);
166 if (p == nil) {
167 outer = nil;
168 error("\"%s\" is not a subprogram", symname(b->value.sym));
169 } else if (ismodule(p)) {
170 outer = p;
171 } else {
172 outer = nil;
173 b->value.sym = p;
174 }
175 }
176 } else if (not isblock(b->value.sym)) {
b329a001
ML
177 error("\"%s\" is not a subprogram", symname(b->value.sym));
178 }
179 }
180}
181
182/*
183 * Check to make sure a node corresponds to a source line.
184 */
185
186private chkline(p)
187Node p;
188{
189 if (p == nil) {
190 error("missing line");
191 } else if (p->op != O_QLINE and p->op != O_LCON) {
192 error("expected source line number, found \"%t\"", p);
193 }
194}
195
196/*
197 * Check to make sure a node corresponds to an address.
198 */
199
200private chkaddr(p)
201Node p;
202{
203 if (p == nil) {
204 error("missing address");
205 } else if (p->op != O_LCON and p->op != O_QLINE) {
206 beginerrmsg();
207 fprintf(stderr, "expected address, found \"");
208 prtree(stderr, p);
209 fprintf(stderr, "\"");
210 enderrmsg();
211 }
212}