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)
Defined functions
Xcopy
defined in line
8;
never used