forgot to purge this stuff somehow
[unix-history] / usr / src / old / dbx / check.c
CommitLineData
b329a001
ML
1/* Copyright (c) 1982 Regents of the University of California */
2
550fe947 3static char sccsid[] = "@(#)check.c 1.2 %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
61 default:
62 break;
63 }
64}
65
66/*
67 * Check arguments to a trace command.
68 */
69
70private chktrace(p)
71Node p;
72{
73 Node exp, place, cond;
74
75 exp = p->value.arg[0];
76 place = p->value.arg[1];
77 cond = p->value.arg[2];
78 if (exp == nil) {
79 chkblock(place);
80 } else if (exp->op == O_LCON or exp->op == O_QLINE) {
81 if (place != nil) {
82 error("unexpected \"at\" or \"in\"");
83 }
84 if (p->op == O_TRACE) {
85 chkline(exp);
86 } else {
87 chkaddr(exp);
88 }
89 } else if (place != nil and (place->op == O_QLINE or place->op == O_LCON)) {
90 if (p->op == O_TRACE) {
91 chkline(place);
92 } else {
93 chkaddr(place);
94 }
95 } else {
96 if (exp->op != O_RVAL and exp->op != O_SYM) {
97 error("can't trace expressions");
98 }
99 chkblock(place);
100 }
101}
102
103/*
104 * Check arguments to a stop command.
105 */
106
107private chkstop(p)
108Node p;
109{
110 Node exp, place, cond;
111
112 exp = p->value.arg[0];
113 place = p->value.arg[1];
114 cond = p->value.arg[2];
115 if (exp != nil) {
116 if (exp->op != O_RVAL and exp->op != O_SYM) {
117 beginerrmsg();
118 fprintf(stderr, "expected variable, found ");
119 prtree(stderr, exp);
120 enderrmsg();
121 }
122 chkblock(place);
123 } else if (cond != nil) {
124 chkblock(place);
125 } else if (place->op == O_SYM) {
126 chkblock(place);
127 } else {
128 if (p->op == O_STOP) {
129 chkline(place);
130 } else {
131 chkaddr(place);
132 }
133 }
134}
135
136/*
137 * Check to see that the given node specifies some subprogram.
138 * Nil is ok since that means the entire program.
139 */
140
141private chkblock(b)
142Node b;
143{
144 if (b != nil) {
145 if (b->op != O_SYM) {
146 beginerrmsg();
147 fprintf(stderr, "expected subprogram, found ");
148 prtree(stderr, b);
149 enderrmsg();
150 } else if (not isblock(b->value.sym) or ismodule(b->value.sym)) {
151 error("\"%s\" is not a subprogram", symname(b->value.sym));
152 }
153 }
154}
155
156/*
157 * Check to make sure a node corresponds to a source line.
158 */
159
160private chkline(p)
161Node p;
162{
163 if (p == nil) {
164 error("missing line");
165 } else if (p->op != O_QLINE and p->op != O_LCON) {
166 error("expected source line number, found \"%t\"", p);
167 }
168}
169
170/*
171 * Check to make sure a node corresponds to an address.
172 */
173
174private chkaddr(p)
175Node p;
176{
177 if (p == nil) {
178 error("missing address");
179 } else if (p->op != O_LCON and p->op != O_QLINE) {
180 beginerrmsg();
181 fprintf(stderr, "expected address, found \"");
182 prtree(stderr, p);
183 fprintf(stderr, "\"");
184 enderrmsg();
185 }
186}