/* * Copy an object value */ OBJECT * objcopy(OBJECT *op) { VALUE *v1, *v2; OBJECT *np; int i; i = op->o_actions->oa_count; if (i < USUAL_ELEMENTS) i = USUAL_ELEMENTS; if (i == USUAL_ELEMENTS) np = (OBJECT *) malloc(sizeof(OBJECT)); else np = (OBJECT *) malloc(objectsize(i)); if (np == NULL) { math_error("Cannot allocate object"); /*NOTREACHED*/ } np->o_actions = op->o_actions; v1 = op->o_table; v2 = np->o_table; for (i = op->o_actions->oa_count; i-- > 0; v1++, v2++) { copyvalue(v1, v2); } return np; }
/* * Copy an object value */ OBJECT * objcopy(OBJECT *op) { VALUE *v1, *v2; OBJECT *np; int i; i = op->o_actions->oa_count; if (i < USUAL_ELEMENTS) i = USUAL_ELEMENTS; if (i == USUAL_ELEMENTS) np = (OBJECT *) malloc(sizeof(OBJECT)); else np = (OBJECT *) malloc(objectsize(i)); if (np == NULL) { math_error("Cannot allocate object"); /*NOTREACHED*/ } np->o_actions = op->o_actions; v1 = op->o_table; v2 = np->o_table; for (i = op->o_actions->oa_count; i-- > 0; v1++, v2++) { if (v1->v_type == V_NUM) { v2->v_num = qlink(v1->v_num); v2->v_type = V_NUM; } else { copyvalue(v1, v2); } v2->v_subtype = V_NOSUBTYPE; } return np; }
static void copytypeinfo (struct rnntypeinfo *dst, struct rnntypeinfo *src, char *file) { int i; dst->name = src->name; dst->shr = src->shr; dst->min = src->min; dst->max = src->max; dst->align = src->align; for (i = 0; i < src->valsnum; i++) ADDARRAY(dst->vals, copyvalue(src->vals[i], file)); for (i = 0; i < src->bitfieldsnum; i++) ADDARRAY(dst->bitfields, copybitfield(src->bitfields[i], file)); }
RBNODE copy_rbnode_sub ( const RBNODE node, void * (*copykey)(const void *), void * (*copyvalue)(const void *) ){ assert(NULL!=node); assert(NULL!=copykey); RBNODE newnode = create_rbnode(black); newnode->colour = node->colour; newnode->key = copykey(node->key); newnode->value = (NULL!=copyvalue)?copyvalue(node->value):node->value; if (NULL!=node->left){ newnode->left = copy_rbnode_sub(node->left,copykey,copyvalue); newnode->left->parent = newnode; } if (NULL!=node->right){ newnode->right = copy_rbnode_sub(node->right,copykey,copyvalue); newnode->right->parent = newnode; } return newnode; }
/* * Call the appropriate user-defined routine to handle an object action. * Returns the value that the routine returned. */ VALUE objcall(int action, VALUE *v1, VALUE *v2, VALUE *v3) { FUNC *fp; /* function to call */ STATIC OBJECTACTIONS *oap; /* object to call for */ struct objectinfo *oip; /* information about action */ long index; /* index of function (negative if undefined) */ VALUE val; /* return value */ VALUE tmp; /* temp value */ char name[SYMBOLSIZE+1+1]; /* full name of user routine to call */ size_t namestr_len; /* length of the namestr() return string */ char *namestr_ret; /* namestr() return string */ size_t opi_name_len; /* length of the oip name */ /* initialize VALUEs */ val.v_subtype = V_NOSUBTYPE; tmp.v_subtype = V_NOSUBTYPE; if ((unsigned)action > OBJ_MAXFUNC) { math_error("Illegal action for object call"); /*NOTREACHED*/ } oip = &objectinfo[action]; if (v1->v_type == V_OBJ) { oap = v1->v_obj->o_actions; } else if (v2->v_type == V_OBJ) { oap = v2->v_obj->o_actions; } else { math_error("Object routine called with non-object"); /*NOTREACHED*/ } index = oap->oa_indices[action]; if (index < 0) { namestr_ret = namestr(&objectnames, oap->oa_index); if (namestr_ret == NULL) { math_error("namestr returned NULL!!!"); /*NOTREACHED*/ } namestr_len = strlen(namestr_ret); opi_name_len = strlen(oip->name); if (namestr_len > (size_t)SYMBOLSIZE-1-opi_name_len) { math_error("namestr returned a strong too long!!!"); /*NOTREACHED*/ } name[0] = '\0'; strncpy(name, namestr_ret, namestr_len+1); strcat(name, "_"); strncat(name, oip->name, opi_name_len+1); index = adduserfunc(name); oap->oa_indices[action] = index; } fp = NULL; if (index >= 0) fp = findfunc(index); if (fp == NULL) { switch (oip->error) { case ERR_PRINT: objprint(v1->v_obj); val.v_type = V_NULL; break; case ERR_CMP: val.v_type = V_INT; if (v1->v_type != v2->v_type) { val.v_int = 1; return val; } val.v_int = objcmp(v1->v_obj, v2->v_obj); break; case ERR_TEST: val.v_type = V_INT; val.v_int = objtest(v1->v_obj); break; case ERR_POW: if (v2->v_type != V_NUM) { math_error("Non-real power"); /*NOTREACHED*/ } val = objpowi(v1, v2->v_num); break; case ERR_ONE: val.v_type = V_NUM; val.v_num = qlink(&_qone_); break; case ERR_INC: tmp.v_type = V_NUM; tmp.v_num = &_qone_; val = objcall(OBJ_ADD, v1, &tmp, NULL_VALUE); break; case ERR_DEC: tmp.v_type = V_NUM; tmp.v_num = &_qone_; val = objcall(OBJ_SUB, v1, &tmp, NULL_VALUE); break; case ERR_SQUARE: val = objcall(OBJ_MUL, v1, v1, NULL_VALUE); break; case ERR_VALUE: copyvalue(v1, &val); break; case ERR_ASSIGN: copyvalue(v2, &tmp); tmp.v_subtype |= v1->v_subtype; freevalue(v1); *v1 = tmp; val.v_type = V_NULL; break; default: math_error("Function \"%s\" is undefined", namefunc(index)); /*NOTREACHED*/ } return val; } switch (oip->args) { case 0: break; case 1: ++stack; stack->v_addr = v1; stack->v_type = V_ADDR; break; case 2: ++stack; stack->v_addr = v1; stack->v_type = V_ADDR; ++stack; stack->v_addr = v2; stack->v_type = V_ADDR; break; case 3: ++stack; stack->v_addr = v1; stack->v_type = V_ADDR; ++stack; stack->v_addr = v2; stack->v_type = V_ADDR; ++stack; stack->v_addr = v3; stack->v_type = V_ADDR; break; default: math_error("Bad number of args to calculate"); /*NOTREACHED*/ } calculate(fp, oip->args); switch (oip->retval) { case A_VALUE: return *stack--; case A_UNDEF: freevalue(stack--); val.v_type = V_NULL; break; case A_INT: if ((stack->v_type != V_NUM) || qisfrac(stack->v_num)) { math_error("Integer return value required"); /*NOTREACHED*/ } index = qtoi(stack->v_num); qfree(stack->v_num); stack--; val.v_type = V_INT; val.v_int = index; break; default: math_error("Bad object return"); /*NOTREACHED*/ } return val; }
static void preptypeinfo(struct rnndb *db, struct rnntypeinfo *ti, char *prefix, struct rnnvarinfo *vi, int width, char *file) { int i; if (ti->name) { struct rnnenum *en = rnn_findenum (db, ti->name); struct rnnbitset *bs = rnn_findbitset (db, ti->name); struct rnnspectype *st = rnn_findspectype (db, ti->name); if (en) { if (en->isinline) { ti->type = RNN_TTYPE_INLINE_ENUM; int j; for (j = 0; j < en->valsnum; j++) ADDARRAY(ti->vals, copyvalue(en->vals[j], file)); } else { ti->type = RNN_TTYPE_ENUM; ti->eenum = en; } } else if (bs) { if (bs->isinline) { ti->type = RNN_TTYPE_INLINE_BITSET; int j; for (j = 0; j < bs->bitfieldsnum; j++) ADDARRAY(ti->bitfields, copybitfield(bs->bitfields[j], file)); } else { ti->type = RNN_TTYPE_BITSET; ti->ebitset = bs; } } else if (st) { ti->type = RNN_TTYPE_SPECTYPE; ti->spectype = st; } else if (!strcmp(ti->name, "hex")) { ti->type = RNN_TTYPE_HEX; } else if (!strcmp(ti->name, "float")) { ti->type = RNN_TTYPE_FLOAT; } else if (!strcmp(ti->name, "uint")) { ti->type = RNN_TTYPE_UINT; } else if (!strcmp(ti->name, "int")) { ti->type = RNN_TTYPE_INT; } else if (!strcmp(ti->name, "boolean")) { ti->type = RNN_TTYPE_BOOLEAN; } else if (!strcmp(ti->name, "bitfield")) { ti->type = RNN_TTYPE_INLINE_BITSET; } else if (!strcmp(ti->name, "enum")) { ti->type = RNN_TTYPE_INLINE_ENUM; } else if (!strcmp(ti->name, "fixed")) { ti->type = RNN_TTYPE_FIXED; } else if (!strcmp(ti->name, "ufixed")) { ti->type = RNN_TTYPE_UFIXED; } else { ti->type = RNN_TTYPE_HEX; fprintf (stderr, "%s: unknown type %s\n", prefix, ti->name); db->estatus = 1; } } else if (ti->bitfieldsnum) { ti->name = "bitfield"; ti->type = RNN_TTYPE_INLINE_BITSET; } else if (ti->valsnum) { ti->name = "enum"; ti->type = RNN_TTYPE_INLINE_ENUM; } else if (width == 1) { ti->name = "boolean"; ti->type = RNN_TTYPE_BOOLEAN; } else { ti->name = "hex"; ti->type = RNN_TTYPE_HEX; } for (i = 0; i < ti->bitfieldsnum; i++) prepbitfield(db, ti->bitfields[i], prefix, vi); for (i = 0; i < ti->valsnum; i++) prepvalue(db, ti->vals[i], prefix, vi); }