date and time created 83/12/05 16:21:09 by ralph
[unix-history] / usr / src / old / dbx / check.c
CommitLineData
b329a001
ML
1/* Copyright (c) 1982 Regents of the University of California */
2
7cc22d81 3static char sccsid[] = "@(#)check.c 1.5 %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 {
7bf092d9 96 if (exp->op != O_RVAL and exp->op != O_SYM and exp->op != O_CALL) {
b329a001
ML
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) {
7cc22d81 116 if (exp->op != O_RVAL and exp->op != O_SYM and exp->op != O_LCON) {
b329a001
ML
117 beginerrmsg();
118 fprintf(stderr, "expected variable, found ");
119 prtree(stderr, exp);
120 enderrmsg();
121 }
122 chkblock(place);
b329a001
ML
123 } else if (place->op == O_SYM) {
124 chkblock(place);
125 } else {
126 if (p->op == O_STOP) {
127 chkline(place);
128 } else {
129 chkaddr(place);
130 }
131 }
132}
133
134/*
135 * Check to see that the given node specifies some subprogram.
136 * Nil is ok since that means the entire program.
137 */
138
139private chkblock(b)
140Node b;
141{
142 if (b != nil) {
143 if (b->op != O_SYM) {
144 beginerrmsg();
145 fprintf(stderr, "expected subprogram, found ");
146 prtree(stderr, b);
147 enderrmsg();
148 } else if (not isblock(b->value.sym) or ismodule(b->value.sym)) {
149 error("\"%s\" is not a subprogram", symname(b->value.sym));
150 }
151 }
152}
153
154/*
155 * Check to make sure a node corresponds to a source line.
156 */
157
158private chkline(p)
159Node p;
160{
161 if (p == nil) {
162 error("missing line");
163 } else if (p->op != O_QLINE and p->op != O_LCON) {
164 error("expected source line number, found \"%t\"", p);
165 }
166}
167
168/*
169 * Check to make sure a node corresponds to an address.
170 */
171
172private chkaddr(p)
173Node p;
174{
175 if (p == nil) {
176 error("missing address");
177 } else if (p->op != O_LCON and p->op != O_QLINE) {
178 beginerrmsg();
179 fprintf(stderr, "expected address, found \"");
180 prtree(stderr, p);
181 fprintf(stderr, "\"");
182 enderrmsg();
183 }
184}