|
|
1.1 root 1: /*
2: * File: rdoasgn.c
3: * Contents: doasgn.c
4: */
5:
6: #include "../h/rt.h"
7:
8: /*
9: * doasgn - assign value of dp2 to variable dp1.
10: * Does the work for asgn, swap, rasgn, and rswap.
11: */
12:
13: /* >doasgn1 */
14: doasgn(dp1, dp2)
15: struct descrip *dp1, *dp2;
16: {
17: register word l1, l2;
18: register union block *bp;
19: register struct b_table *tp;
20: int (*putf) ();
21: union block *hook;
22: long l3;
23: char sbuf1[MaxCvtLen], sbuf2[MaxCvtLen];
24: extern struct descrip tended[];
25: extern struct b_lelem *alclstb();
26: extern char *alcstr();
27:
28: tended[1] = *dp1;
29: tended[2] = *dp2;
30: ntended = 2;
31:
32: assign:
33:
34: if (!Tvar(tended[1]))
35: *VarLoc(tended[1]) = tended[2];
36: else switch (Type(tended[1])) {
37: /* <doasgn1 */
38: /* >doasgn2 */
39: case T_Tvsubs:
40: /*
41: * An assignment is being made to a substring trapped
42: * variable. The tended descriptors are used as
43: * follows:
44: *
45: * tended[1] - the substring trapped variable
46: * tended[2] - the value to assign
47: * tended[3] - the string containing the substring
48: * tended[4] - the substring
49: * tended[5] - the result string
50: */
51:
52: /*
53: * Be sure that the value to be assigned is a string.
54: */
55: ntended = 5;
56: DeRef(tended[2]);
57: if (cvstr(&tended[2], sbuf1) == NULL)
58: runerr(103, &tended[2]);
59:
60: /*
61: * Be sure that the variable in the trapped variable points
62: * to a string.
63: */
64: tended[3] = BlkLoc(tended[1])->tvsubs.ssvar;
65: DeRef(tended[3]);
66: if (!Qual(tended[3]))
67: runerr(103, &tended[3]);
68: strreq(StrLen(tended[3]) + StrLen(tended[2]));
69:
70: /*
71: * Get a pointer to the tvsubs block and make l1 a C-style
72: * index to the character that begins the substring.
73: */
74: bp = BlkLoc(tended[1]);
75: l1 = bp->tvsubs.sspos - 1;
76:
77: /*
78: * Make tended[4] a descriptor for the substring.
79: */
80: StrLen(tended[4]) = bp->tvsubs.sslen;
81: StrLoc(tended[4]) = StrLoc(tended[3]) + l1;
82:
83: /*
84: * Make l2 a C-style index to the character after the
85: * substring. If l2 is greater than the length of the
86: * substring, it is an error because the string being
87: * assigned will not fit.
88: */
89: l2 = l1 + StrLen(tended[4]);
90: if (l2 > StrLen(tended[3]))
91: runerr(205, NULL);
92:
93: /*
94: * Form the result string. First, copy the portion of the
95: * substring string to the left of the substring into the
96: * string space.
97: */
98: StrLoc(tended[5]) = alcstr(StrLoc(tended[3]), l1);
99:
100: /*
101: * Copy the string to be assigned into the string space,
102: * effectively concatenating it.
103: */
104: alcstr(StrLoc(tended[2]), StrLen(tended[2]));
105:
106: /*
107: * Copy the portion of the substring to the right of
108: * the substring into the string space, completing the
109: * result.
110: */
111: alcstr(StrLoc(tended[3]) + l2, StrLen(tended[3]) - l2);
112:
113: /*
114: * Calculate the length of the new string.
115: */
116: StrLen(tended[5]) = StrLen(tended[3]) - StrLen(tended[4]) +
117: StrLen(tended[2]);
118: bp->tvsubs.sslen = StrLen(tended[2]);
119: tended[1] = bp->tvsubs.ssvar;
120: tended[2] = tended[5];
121:
122: /*
123: * Everything is set up for the actual assignment. Go
124: * back to the beginning of the routine to do it.
125: */
126: goto assign;
127: /* <doasgn2 */
128:
129: /* >doasgn3 */
130: case T_Tvtbl:
131: /*
132: *
133: * The tended descriptors are used as follows:
134: *
135: * tended[1] - the table element trapped variable
136: * tended[2] - the value to be assigned
137: * tended[3] - subscripting value
138: */
139:
140: /*
141: * Point bp to the trapped variable block; point tended[3]
142: * to the subscripting value; point tp to the table
143: * header block.
144: */
145: ntended = 3;
146: bp = BlkLoc(tended[1]);
147:
148: if (bp->tvtbl.title == T_Telem) {
149: /*
150: * The trapped variable block already has been converted
151: * to a table element block. Just assign to it and return.
152: */
153: bp->telem.tval = tended[2];
154: ntended = 0;
155: return 1;
156: }
157: tended[3] = bp->tvtbl.tref;
158: tp = (struct b_table *) BlkLoc(bp->tvtbl.clink);
159:
160: /*
161: * Get the hash number for the subscripting value and locate
162: * the chain that contains the element to which assignment is
163: * to be made.
164: */
165: l1 = bp->tvtbl.hashnum;
166: l2 = SlotNum(l1,TSlots);
167: bp = BlkLoc(tp->buckets[l2]);
168:
169: /*
170: * Traverse the chain to see if the value is already in the
171: * table. If it is there, assign to it and return.
172: */
173: hook = bp;
174: while (bp != NULL && bp->telem.hashnum <= l1) {
175: if (bp->telem.hashnum == l1 &&
176: equiv(&bp->telem.tref, &tended[3])) {
177: bp->telem.tval = tended[2];
178: ntended = 0;
179: return 1;
180: }
181: hook = bp;
182: bp = BlkLoc(bp->telem.clink);
183: }
184:
185: /*
186: * The value being assigned is new. Increment the table size,
187: * convert the tvtbl to a telem, and link it into the chain.
188: */
189: tp->size++;
190: if (hook == bp) { /* it goes at front of chain */
191: bp = BlkLoc(tended[1]);
192: bp->telem.clink = tp->buckets[l2];
193: BlkLoc(tp->buckets[l2]) = bp;
194: tp->buckets[l2].dword = D_Telem;
195: }
196:
197: else { /* it follows hook */
198: bp = BlkLoc(tended[1]);
199: bp->telem.clink = hook->telem.clink;
200: BlkLoc(hook->telem.clink) = bp;
201: hook->telem.clink.dword = D_Telem;
202: }
203:
204: bp->tvtbl.title = T_Telem;
205: bp->telem.tval = tended[2];
206: ntended = 0;
207: return 1;
208: /* <doasgn3 */
209:
210: /* >doasgn4 */
211: case T_Tvkywd:
212: ntended = 2;
213: putf = BlkLoc(tended[1])->tvkywd.putval;
214: if ((*putf)(&tended[2]) == NULL) {
215: ntended = 0;
216: return 0;
217: }
218: ntended = 0;
219: return 1;
220: /* <doasgn4 */
221:
222:
223: default:
224: syserr("doasgn: illegal trapped variable");
225: }
226:
227: ntended = 0;
228: return 1;
229: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.