xref: /csrg-svn/old/dbx/check.c (revision 14444)
19660Slinton /* Copyright (c) 1982 Regents of the University of California */
29660Slinton 
3*14444Slinton static char sccsid[] = "@(#)check.c 1.5 08/10/83";
49660Slinton 
59660Slinton /*
69660Slinton  * Check a tree for semantic correctness.
79660Slinton  */
89660Slinton 
99660Slinton #include "defs.h"
109660Slinton #include "tree.h"
119660Slinton #include "operators.h"
129660Slinton #include "events.h"
139660Slinton #include "symbols.h"
149660Slinton #include "scanner.h"
159660Slinton #include "source.h"
169660Slinton #include "object.h"
179660Slinton #include "mappings.h"
189660Slinton #include "process.h"
199660Slinton 
209660Slinton #ifndef public
219660Slinton #endif
229660Slinton 
239660Slinton /*
249660Slinton  * Check that the nodes in a tree have the correct arguments
259660Slinton  * in order to be evaluated.  Basically the error checking here
269660Slinton  * frees the evaluation routines from worrying about anything
279660Slinton  * except dynamic errors, e.g. subscript out of range.
289660Slinton  */
299660Slinton 
309660Slinton public check(p)
319660Slinton register Node p;
329660Slinton {
339660Slinton     Address addr;
349660Slinton     Symbol f;
359660Slinton 
369660Slinton     checkref(p);
379660Slinton     switch (p->op) {
389660Slinton 	case O_LIST:
399660Slinton 	    if (p->value.arg[0]->op == O_SYM) {
409660Slinton 		f = p->value.arg[0]->value.sym;
419660Slinton 		if (not isblock(f) or ismodule(f)) {
429660Slinton 		    error("\"%s\" is not a procedure or function", symname(f));
439660Slinton 		}
449660Slinton 		addr = firstline(f);
459660Slinton 		if (addr == NOADDR) {
469660Slinton 		    error("\"%s\" is empty", symname(f));
479660Slinton 		}
489660Slinton 	    }
499660Slinton 	    break;
509660Slinton 
519660Slinton 	case O_TRACE:
529660Slinton 	case O_TRACEI:
539660Slinton 	    chktrace(p);
549660Slinton 	    break;
559660Slinton 
569660Slinton 	case O_STOP:
579660Slinton 	case O_STOPI:
589660Slinton 	    chkstop(p);
599660Slinton 	    break;
609660Slinton 
619660Slinton 	default:
629660Slinton 	    break;
639660Slinton     }
649660Slinton }
659660Slinton 
669660Slinton /*
679660Slinton  * Check arguments to a trace command.
689660Slinton  */
699660Slinton 
709660Slinton private chktrace(p)
719660Slinton Node p;
729660Slinton {
739660Slinton     Node exp, place, cond;
749660Slinton 
759660Slinton     exp = p->value.arg[0];
769660Slinton     place = p->value.arg[1];
779660Slinton     cond = p->value.arg[2];
789660Slinton     if (exp == nil) {
799660Slinton 	chkblock(place);
809660Slinton     } else if (exp->op == O_LCON or exp->op == O_QLINE) {
819660Slinton 	if (place != nil) {
829660Slinton 	    error("unexpected \"at\" or \"in\"");
839660Slinton 	}
849660Slinton 	if (p->op == O_TRACE) {
859660Slinton 	    chkline(exp);
869660Slinton 	} else {
879660Slinton 	    chkaddr(exp);
889660Slinton 	}
899660Slinton     } else if (place != nil and (place->op == O_QLINE or place->op == O_LCON)) {
909660Slinton 	if (p->op == O_TRACE) {
919660Slinton 	    chkline(place);
929660Slinton 	} else {
939660Slinton 	    chkaddr(place);
949660Slinton 	}
959660Slinton     } else {
969861Slinton 	if (exp->op != O_RVAL and exp->op != O_SYM and exp->op != O_CALL) {
979660Slinton 	    error("can't trace expressions");
989660Slinton 	}
999660Slinton 	chkblock(place);
1009660Slinton     }
1019660Slinton }
1029660Slinton 
1039660Slinton /*
1049660Slinton  * Check arguments to a stop command.
1059660Slinton  */
1069660Slinton 
1079660Slinton private chkstop(p)
1089660Slinton Node p;
1099660Slinton {
1109660Slinton     Node exp, place, cond;
1119660Slinton 
1129660Slinton     exp = p->value.arg[0];
1139660Slinton     place = p->value.arg[1];
1149660Slinton     cond = p->value.arg[2];
1159660Slinton     if (exp != nil) {
116*14444Slinton 	if (exp->op != O_RVAL and exp->op != O_SYM and exp->op != O_LCON) {
1179660Slinton 	    beginerrmsg();
1189660Slinton 	    fprintf(stderr, "expected variable, found ");
1199660Slinton 	    prtree(stderr, exp);
1209660Slinton 	    enderrmsg();
1219660Slinton 	}
1229660Slinton 	chkblock(place);
1239660Slinton     } else if (place->op == O_SYM) {
1249660Slinton 	chkblock(place);
1259660Slinton     } else {
1269660Slinton 	if (p->op == O_STOP) {
1279660Slinton 	    chkline(place);
1289660Slinton 	} else {
1299660Slinton 	    chkaddr(place);
1309660Slinton 	}
1319660Slinton     }
1329660Slinton }
1339660Slinton 
1349660Slinton /*
1359660Slinton  * Check to see that the given node specifies some subprogram.
1369660Slinton  * Nil is ok since that means the entire program.
1379660Slinton  */
1389660Slinton 
1399660Slinton private chkblock(b)
1409660Slinton Node b;
1419660Slinton {
1429660Slinton     if (b != nil) {
1439660Slinton 	if (b->op != O_SYM) {
1449660Slinton 	    beginerrmsg();
1459660Slinton 	    fprintf(stderr, "expected subprogram, found ");
1469660Slinton 	    prtree(stderr, b);
1479660Slinton 	    enderrmsg();
1489660Slinton 	} else if (not isblock(b->value.sym) or ismodule(b->value.sym)) {
1499660Slinton 	    error("\"%s\" is not a subprogram", symname(b->value.sym));
1509660Slinton 	}
1519660Slinton     }
1529660Slinton }
1539660Slinton 
1549660Slinton /*
1559660Slinton  * Check to make sure a node corresponds to a source line.
1569660Slinton  */
1579660Slinton 
1589660Slinton private chkline(p)
1599660Slinton Node p;
1609660Slinton {
1619660Slinton     if (p == nil) {
1629660Slinton 	error("missing line");
1639660Slinton     } else if (p->op != O_QLINE and p->op != O_LCON) {
1649660Slinton 	error("expected source line number, found \"%t\"", p);
1659660Slinton     }
1669660Slinton }
1679660Slinton 
1689660Slinton /*
1699660Slinton  * Check to make sure a node corresponds to an address.
1709660Slinton  */
1719660Slinton 
1729660Slinton private chkaddr(p)
1739660Slinton Node p;
1749660Slinton {
1759660Slinton     if (p == nil) {
1769660Slinton 	error("missing address");
1779660Slinton     } else if (p->op != O_LCON and p->op != O_QLINE) {
1789660Slinton 	beginerrmsg();
1799660Slinton 	fprintf(stderr, "expected address, found \"");
1809660Slinton 	prtree(stderr, p);
1819660Slinton 	fprintf(stderr, "\"");
1829660Slinton 	enderrmsg();
1839660Slinton     }
1849660Slinton }
185