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
Last modified: 1985-01-13
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 1151
Valid CSS Valid XHTML 1.0 Strict