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: }
Defined functions
deref
defined in line
6;
never used