|
|
1.1 ! root 1: #include "../h/rt.h" ! 2: #include "../h/record.h" ! 3: ! 4: /* ! 5: * copy(x) - make a copy of object x. ! 6: */ ! 7: ! 8: Xcopy(nargs, arg1, arg0) ! 9: int nargs; ! 10: struct descrip arg1, arg0; ! 11: { ! 12: register int i; ! 13: struct descrip *d1, *d2; ! 14: union block *bp, *ep, **tp; ! 15: extern struct b_table *alctable(); ! 16: extern struct b_telem *alctelem(); ! 17: extern struct b_set *alcset(); ! 18: extern struct b_selem *alcselem(); ! 19: extern union block *allocate(); ! 20: ! 21: DeRef(arg1) ! 22: ! 23: if (NULLDESC(arg1) || QUAL(arg1)) ! 24: /* ! 25: * x is a string or &null, just copy its descriptor ! 26: * into arg0. ! 27: */ ! 28: arg0 = arg1; ! 29: else { ! 30: switch (TYPE(arg1)) { ! 31: case T_INTEGER: ! 32: #ifdef LONGS ! 33: case T_LONGINT: ! 34: #endif LONGS ! 35: case T_REAL: ! 36: case T_FILE: ! 37: case T_CSET: ! 38: case T_PROC: ! 39: case T_ESTACK: ! 40: /* ! 41: * Copy integers, long integers, reals, files, csets, procedures, ! 42: * and co-expressions by copying the descriptor. Note that for ! 43: * integers, this results in the assignment of a value, for the ! 44: * other types, a pointer is directed to a data block. ! 45: */ ! 46: arg0 = arg1; ! 47: break; ! 48: ! 49: case T_LIST: ! 50: /* ! 51: * Pass the buck to cplist to copy a list. ! 52: */ ! 53: cplist(&arg1, &arg0, 1, BLKLOC(arg1)->list.cursize + 1); ! 54: break; ! 55: ! 56: case T_TABLE: ! 57: /* ! 58: * Allocate space for table and elements and copy old table ! 59: * block into new. ! 60: */ ! 61: hneed((sizeof(struct b_table)) + ! 62: (sizeof(struct b_telem)) * BLKLOC(arg1)->table.cursize); ! 63: bp = (union block *) alctable(&nulldesc); ! 64: bp->table = BLKLOC(arg1)->table; ! 65: /* ! 66: * Work down the chain of table element blocks in each bucket ! 67: * and create identical chains in new table. ! 68: */ ! 69: for (i = 0; i < NBUCKETS; i++) { ! 70: tp = &(BLKLOC(bp->table.buckets[i])); ! 71: for (ep = *tp; ep != NULL; ep = *tp) { ! 72: *tp = (union block *) alctelem(); ! 73: (*tp)->telem = ep->telem; ! 74: tp = &(BLKLOC((*tp)->telem.blink)); ! 75: } ! 76: } ! 77: /* ! 78: * Return the copied table. ! 79: */ ! 80: arg0.type = D_TABLE; ! 81: BLKLOC(arg0) = bp; ! 82: break; ! 83: ! 84: #ifdef SETS ! 85: case T_SET: ! 86: /* ! 87: * Allocate space for set and elements and copy old set ! 88: * block into new. ! 89: */ ! 90: hneed((sizeof(struct b_set)) + ! 91: (sizeof(struct b_selem)) * BLKLOC(arg1)->set.setsize); ! 92: bp = (union block *) alcset(&nulldesc); ! 93: bp->set = BLKLOC(arg1)->set; ! 94: /* ! 95: * Work down the chain of set elements in each bucket ! 96: * and create identical chains in new set. ! 97: */ ! 98: for (i = 0; i < NBUCKETS; i++) { ! 99: tp = &(BLKLOC(bp->set.sbucks[i])); ! 100: for (ep = *tp; ep != NULL; ep = *tp) { ! 101: *tp = (union block *) alcselem(&nulldesc,0); ! 102: (*tp)->selem = ep->selem; ! 103: tp = &(BLKLOC((*tp)->selem.sblink)); ! 104: } ! 105: } ! 106: /* ! 107: * Return the copied set. ! 108: */ ! 109: arg0.type = D_SET; ! 110: BLKLOC(arg0) = bp; ! 111: break; ! 112: #endif SETS ! 113: ! 114: case T_RECORD: ! 115: /* ! 116: * Allocate space for the new record and copy the old ! 117: * one into it. ! 118: */ ! 119: i = BLKLOC(arg1)->record.size; ! 120: hneed(i); ! 121: bp = allocate(i); ! 122: bp->record = BLKLOC(arg1)->record; ! 123: /* ! 124: * The above assignment doesn't copy the fields, they are ! 125: * copied individually via a loop. ! 126: */ ! 127: i = bp->record.recptr->nfields; ! 128: d1 = bp->record.fields; ! 129: d2 = BLKLOC(arg1)->record.fields; ! 130: while (i--) ! 131: *d1++ = *d2++; ! 132: /* ! 133: * Return the copied record ! 134: */ ! 135: arg0.type = D_RECORD; ! 136: BLKLOC(arg0) = bp; ! 137: break; ! 138: ! 139: default: ! 140: syserr("copy: illegal datatype."); ! 141: } ! 142: } ! 143: } ! 144: ! 145: Procblock(copy,1)
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.