|
|
1.1 ! root 1: #include "../h/rt.h" ! 2: ! 3: /* ! 4: * deref - dereference a descriptor. ! 5: */ ! 6: deref(d) ! 7: struct descrip *d; ! 8: { ! 9: register int i, j; ! 10: register union block *bp; ! 11: struct descrip v, tbl, tref; ! 12: char sbuf[MAXSTRING]; ! 13: extern char *alcstr(); ! 14: ! 15: if (!QUAL(*d) && VAR(*d)) { ! 16: /* ! 17: * *d is a variable and must be dereferenced. ! 18: */ ! 19: if (TVAR(*d)) { ! 20: switch (TYPE(*d)) { ! 21: case T_TVSUBS: ! 22: /* ! 23: * A substring trapped variable is being dereferenced. Point ! 24: * bp at the trapped variable block and v at the substrung ! 25: * string. ! 26: */ ! 27: bp = TVARLOC(*d); ! 28: v = bp->tvsubs.ssvar; ! 29: /* ! 30: * Convert v into a string. ! 31: */ ! 32: switch (cvstr(&v, sbuf)) { ! 33: case NULL: ! 34: runerr(103,&v); ! 35: case 1: ! 36: /* ! 37: * A conversion to string was made. Allocate the ! 38: * converted string and fall through to common code ! 39: * for allocated strings. Note that bp is reassigned ! 40: * in case the sneed caused a garbage collection. ! 41: */ ! 42: sneed(STRLEN(v)); ! 43: STRLOC(v) = alcstr(STRLOC(v), STRLEN(v)); ! 44: bp = TVARLOC(*d); ! 45: case 2: ! 46: /* ! 47: * The substrung string is an allocated string. Be sure ! 48: * that the position is in range. ! 49: */ ! 50: if (bp->tvsubs.sspos + bp->tvsubs.sslen - 1 > STRLEN(v)) ! 51: runerr(205,NULL); ! 52: /* ! 53: * Make a descriptor for the substring by getting the ! 54: * length and pointing into the substrung string. ! 55: */ ! 56: STRLEN(*d) = bp->tvsubs.sslen; ! 57: STRLOC(*d) = STRLOC(v) + bp->tvsubs.sspos - 1; ! 58: } ! 59: break; ! 60: ! 61: case T_TVTBL: ! 62: /* ! 63: * A table element trapped variable is being dereferenced. ! 64: * Point tbl at the table header block, ! 65: * tref at the subscripting value, ! 66: * bp at the appropriate element chain. Make d a ! 67: * descriptor for the default value in case the value ! 68: * referenced by the subscript isn't in the table. ! 69: */ ! 70: if (BLKLOC(*d)->tvtbl.type == T_TELEM) { ! 71: /* ! 72: * the tvtbl has been converted to a telem and is in the table ! 73: * just replace d with the value of the element ! 74: */ ! 75: *d = BLKLOC(*d)->telem.tval; ! 76: break; ! 77: } ! 78: tbl = BLKLOC(*d)->tvtbl.tvtable; ! 79: tref = BLKLOC(*d)->tvtbl.tvtref; ! 80: i = BLKLOC(*d)->tvtbl.hashnum; ! 81: *d = BLKLOC(tbl)->table.defvalue; ! 82: bp = BLKLOC(BLKLOC(tbl)->table.buckets[i % NBUCKETS]); ! 83: /* ! 84: * Look down the element chain for the subscript value. ! 85: * If found, replace d with the value of the element. ! 86: */ ! 87: while (bp != NULL) { ! 88: if (bp->telem.hashnum > i) ! 89: break; ! 90: if ((bp->telem.hashnum == i) && ! 91: (equiv(&bp->telem.tref, &tref))) { ! 92: *d = bp->telem.tval; ! 93: break; ! 94: } ! 95: bp = BLKLOC(bp->telem.blink); ! 96: } ! 97: break; ! 98: ! 99: case T_TVPOS: ! 100: /* ! 101: * &pos is being dereferenced, make a descriptor for the ! 102: * appropriate integer value. ! 103: */ ! 104: d->type = D_INTEGER; ! 105: INTVAL(*d) = k_pos; ! 106: break; ! 107: ! 108: case T_TVRAND: ! 109: /* ! 110: * &random is being dereferenced, use mkint to make a ! 111: * an integer descriptor from the value of k_random. ! 112: */ ! 113: mkint(k_random, d); ! 114: break; ! 115: ! 116: case T_TVTRACE: ! 117: /* ! 118: * &trace is being dereferenced, make a descriptor for the ! 119: * appropriate integer value. ! 120: */ ! 121: d->type = D_INTEGER; ! 122: INTVAL(*d) = k_trace; ! 123: break; ! 124: ! 125: default: ! 126: syserr("deref: illegal trapped variable"); ! 127: } ! 128: } ! 129: else ! 130: /* ! 131: * An ordinary variable is being dereferenced, just replace *d ! 132: * with the the descriptor *d is pointing to. ! 133: */ ! 134: *d = *VARLOC(*d); ! 135: } ! 136: #ifdef DEBUG ! 137: if (!QUAL(*d) && VAR(*d)) ! 138: syserr("deref: didn't get dereferenced"); ! 139: #endif DEBUG ! 140: return (1); ! 141: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.