|
|
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.