Annotation of 43BSDReno/pgrm/dbx/check.c, revision 1.1.1.1

1.1       root        1: /*
                      2:  * Copyright (c) 1983 The Regents of the University of California.
                      3:  * All rights reserved.
                      4:  *
                      5:  * Redistribution and use in source and binary forms are permitted
                      6:  * provided that: (1) source distributions retain this entire copyright
                      7:  * notice and comment, and (2) distributions including binaries display
                      8:  * the following acknowledgement:  ``This product includes software
                      9:  * developed by the University of California, Berkeley and its contributors''
                     10:  * in the documentation or other materials provided with the distribution
                     11:  * and in all advertising materials mentioning features or use of this
                     12:  * software. Neither the name of the University nor the names of its
                     13:  * contributors may be used to endorse or promote products derived
                     14:  * from this software without specific prior written permission.
                     15:  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
                     16:  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
                     17:  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
                     18:  */
                     19: 
                     20: #ifndef lint
                     21: static char sccsid[] = "@(#)check.c    5.4 (Berkeley) 6/1/90";
                     22: #endif /* not lint */
                     23: 
                     24: /*
                     25:  * Check a tree for semantic correctness.
                     26:  */
                     27: 
                     28: #include "defs.h"
                     29: #include "tree.h"
                     30: #include "operators.h"
                     31: #include "events.h"
                     32: #include "symbols.h"
                     33: #include "scanner.h"
                     34: #include "source.h"
                     35: #include "object.h"
                     36: #include "mappings.h"
                     37: #include "process.h"
                     38: #include <signal.h>
                     39: 
                     40: #ifndef public
                     41: #endif
                     42: 
                     43: /*
                     44:  * Check that the nodes in a tree have the correct arguments
                     45:  * in order to be evaluated.  Basically the error checking here
                     46:  * frees the evaluation routines from worrying about anything
                     47:  * except dynamic errors, e.g. subscript out of range.
                     48:  */
                     49: 
                     50: public check(p)
                     51: register Node p;
                     52: {
                     53:     Node p1, p2;
                     54:     Address addr;
                     55:     Symbol f;
                     56: 
                     57:     checkref(p);
                     58:     switch (p->op) {
                     59:        case O_ASSIGN:
                     60:            p1 = p->value.arg[0];
                     61:            p2 = p->value.arg[1];
                     62:            if (varIsSet("$unsafeassign")) {
                     63:                if (size(p1->nodetype) != size(p2->nodetype)) {
                     64:                    error("incompatible sizes");
                     65:                }
                     66:            } else if (not compatible(p1->nodetype, p2->nodetype)) {
                     67:                error("incompatible types");
                     68:            }
                     69:            break;
                     70: 
                     71:        case O_CATCH:
                     72:        case O_IGNORE:
                     73:            if (p->value.lcon < 0 or p->value.lcon > NSIG) {
                     74:                error("invalid signal number");
                     75:            }
                     76:            break;
                     77: 
                     78:        case O_CONT:
                     79:            if (p->value.lcon != DEFSIG and (
                     80:                p->value.lcon < 0 or p->value.lcon > NSIG)
                     81:            ) {
                     82:                error("invalid signal number");
                     83:            }
                     84:            break;
                     85: 
                     86:        case O_DUMP:
                     87:            if (p->value.arg[0] != nil) {
                     88:                if (p->value.arg[0]->op == O_SYM) {
                     89:                    f = p->value.arg[0]->value.sym;
                     90:                    if (not isblock(f)) {
                     91:                        error("\"%s\" is not a block", symname(f));
                     92:                    }
                     93:                } else {
                     94:                    beginerrmsg();
                     95:                    fprintf(stderr, "expected a symbol, found \"");
                     96:                    prtree(stderr, p->value.arg[0]);
                     97:                    fprintf(stderr, "\"");
                     98:                    enderrmsg();
                     99:                }
                    100:            }
                    101:            break;
                    102: 
                    103:        case O_LIST:
                    104:            if (p->value.arg[0]->op == O_SYM) {
                    105:                f = p->value.arg[0]->value.sym;
                    106:                if (not isblock(f) or ismodule(f)) {
                    107:                    error("\"%s\" is not a procedure or function", symname(f));
                    108:                }
                    109:                addr = firstline(f);
                    110:                if (addr == NOADDR) {
                    111:                    error("\"%s\" is empty", symname(f));
                    112:                }
                    113:            }
                    114:            break;
                    115: 
                    116:        case O_TRACE:
                    117:        case O_TRACEI:
                    118:            chktrace(p);
                    119:            break;
                    120: 
                    121:        case O_STOP:
                    122:        case O_STOPI:
                    123:            chkstop(p);
                    124:            break;
                    125: 
                    126:        case O_CALLPROC:
                    127:        case O_CALL:
                    128:            if (not isroutine(p->value.arg[0]->nodetype)) {
                    129:                beginerrmsg();
                    130:                fprintf(stderr, "\"");
                    131:                prtree(stderr, p->value.arg[0]);
                    132:                fprintf(stderr, "\" not call-able");
                    133:                enderrmsg();
                    134:            }
                    135:            break;
                    136: 
                    137:        case O_WHEREIS:
                    138:            if (p->value.arg[0]->op == O_SYM and
                    139:              p->value.arg[0]->value.sym == nil) {
                    140:                error("symbol not defined");
                    141:            }
                    142:            break;
                    143: 
                    144:        default:
                    145:            break;
                    146:     }
                    147: }
                    148: 
                    149: /*
                    150:  * Check arguments to a trace command.
                    151:  */
                    152: 
                    153: private chktrace(p)
                    154: Node p;
                    155: {
                    156:     Node exp, place, cond;
                    157: 
                    158:     exp = p->value.arg[0];
                    159:     place = p->value.arg[1];
                    160:     cond = p->value.arg[2];
                    161:     if (exp == nil) {
                    162:        chkblock(place);
                    163:     } else if (exp->op == O_LCON or exp->op == O_QLINE) {
                    164:        if (place != nil) {
                    165:            error("unexpected \"at\" or \"in\"");
                    166:        }
                    167:        if (p->op == O_TRACE) {
                    168:            chkline(exp);
                    169:        } else {
                    170:            chkaddr(exp);
                    171:        }
                    172:     } else if (place != nil and (place->op == O_QLINE or place->op == O_LCON)) {
                    173:        if (p->op == O_TRACE) {
                    174:            chkline(place);
                    175:        } else {
                    176:            chkaddr(place);
                    177:        }
                    178:     } else {
                    179:        if (exp->op != O_RVAL and exp->op != O_SYM and exp->op != O_CALL) {
                    180:            error("can't trace expressions");
                    181:        }
                    182:        chkblock(place);
                    183:     }
                    184: }
                    185: 
                    186: /*
                    187:  * Check arguments to a stop command.
                    188:  */
                    189: 
                    190: private chkstop(p)
                    191: Node p;
                    192: {
                    193:     Node exp, place, cond;
                    194: 
                    195:     exp = p->value.arg[0];
                    196:     place = p->value.arg[1];
                    197:     cond = p->value.arg[2];
                    198:     if (exp != nil) {
                    199:        if (exp->op != O_RVAL and exp->op != O_SYM and exp->op != O_LCON) {
                    200:            beginerrmsg();
                    201:            fprintf(stderr, "expected variable, found ");
                    202:            prtree(stderr, exp);
                    203:            enderrmsg();
                    204:        }
                    205:        chkblock(place);
                    206:     } else if (place != nil) {
                    207:        if (place->op == O_SYM) {
                    208:            chkblock(place);
                    209:        } else {
                    210:            if (p->op == O_STOP) {
                    211:                chkline(place);
                    212:            } else {
                    213:                chkaddr(place);
                    214:            }
                    215:        }
                    216:     }
                    217: }
                    218: 
                    219: /*
                    220:  * Check to see that the given node specifies some subprogram.
                    221:  * Nil is ok since that means the entire program.
                    222:  */
                    223: 
                    224: private chkblock(b)
                    225: Node b;
                    226: {
                    227:     Symbol p, outer;
                    228: 
                    229:     if (b != nil) {
                    230:        if (b->op != O_SYM) {
                    231:            beginerrmsg();
                    232:            fprintf(stderr, "expected subprogram, found ");
                    233:            prtree(stderr, b);
                    234:            enderrmsg();
                    235:        } else if (ismodule(b->value.sym)) {
                    236:            outer = b->value.sym;
                    237:            while (outer != nil) {
                    238:                find(p, outer->name) where p->block == outer endfind(p);
                    239:                if (p == nil) {
                    240:                    outer = nil;
                    241:                    error("\"%s\" is not a subprogram", symname(b->value.sym));
                    242:                } else if (ismodule(p)) {
                    243:                    outer = p;
                    244:                } else {
                    245:                    outer = nil;
                    246:                    b->value.sym = p;
                    247:                }
                    248:            }
                    249:        } else if (
                    250:            b->value.sym->class == VAR and
                    251:            b->value.sym->name == b->value.sym->block->name and
                    252:            b->value.sym->block->class == FUNC
                    253:        ) {
                    254:            b->value.sym = b->value.sym->block;
                    255:        } else if (not isblock(b->value.sym)) {
                    256:            error("\"%s\" is not a subprogram", symname(b->value.sym));
                    257:        }
                    258:     }
                    259: }
                    260: 
                    261: /*
                    262:  * Check to make sure a node corresponds to a source line.
                    263:  */
                    264: 
                    265: private chkline(p)
                    266: Node p;
                    267: {
                    268:     if (p == nil) {
                    269:        error("missing line");
                    270:     } else if (p->op != O_QLINE and p->op != O_LCON) {
                    271:        error("expected source line number, found \"%t\"", p);
                    272:     }
                    273: }
                    274: 
                    275: /*
                    276:  * Check to make sure a node corresponds to an address.
                    277:  */
                    278: 
                    279: private chkaddr(p)
                    280: Node p;
                    281: {
                    282:     if (p == nil) {
                    283:        error("missing address");
                    284:     } else if (p->op != O_LCON and p->op != O_QLINE) {
                    285:        beginerrmsg();
                    286:        fprintf(stderr, "expected address, found \"");
                    287:        prtree(stderr, p);
                    288:        fprintf(stderr, "\"");
                    289:        enderrmsg();
                    290:     }
                    291: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.