/*-------------------------------------------------------------------------*/ static svalue_t * insert_alist (svalue_t *key, svalue_t * /* TODO: bool */ key_data, vector_t *list) /* Implementation of efun insert_alist() * * The function can be used in two ways: * * 1. Insert/replace a (new) <key>:<keydata> tuple into the alist <list>. * <key> and <key_data> have to point to an array of svalues. The first * element is the key value, the following values the associated * data values. The function will read as many elements from the * array as necessary to fill the alist <list>. * Result is a fresh copy of the modified alist. * * 2. Lookup a <key> in the alist <list> and return its index. If the key * is not found, return the position at which it would be inserted. * <key_data> must be NULL, <key> points to the svalue to be looked * up, and <list> points to an alist with at least the key vector. * * If <list> is no alist, the result can be wrong (case 2.) or not * an alist either (case 1.). * * If the <key> is a string, it is made shared. * * TODO: Make the hidden flag 'key_data' a real flag. */ { static svalue_t stmp; /* Result value */ mp_int i,j,ix; mp_int keynum, list_size; /* Number of keys, number of alist vectors */ int new_member; /* Flag if a new tuple is given */ /* If key is a string, make it shared */ if (key->type == T_STRING && !mstr_tabled(key->u.str)) { key->u.str = make_tabled(key->u.str); } keynum = (mp_int)VEC_SIZE(list->item[0].u.vec); /* Locate the key */ ix = lookup_key(key, list->item[0].u.vec); /* If its just a lookup: return the result. */ if (key_data == NULL) { put_number(&stmp, ix < 0 ? -ix-1 : ix); return &stmp; } /* Prepare the result alist vector */ put_array(&stmp, allocate_array(list_size = (mp_int)VEC_SIZE(list))); new_member = ix < 0; if (new_member) ix = -ix-1; /* Loop over all key/data vectors in <list>, insert/replace the * new value and put the new vector into <stmp>. */ for (i = 0; i < list_size; i++) { vector_t *vtmp; if (new_member) { svalue_t *pstmp = list->item[i].u.vec->item; vtmp = allocate_array(keynum+1); for (j=0; j < ix; j++) { assign_svalue_no_free(&vtmp->item[j], pstmp++); } assign_svalue_no_free(&vtmp->item[ix], i ? &key_data[i] : key ); for (j = ix+1; j <= keynum; j++) { assign_svalue_no_free(&vtmp->item[j], pstmp++); } } else { vtmp = slice_array(list->item[i].u.vec, 0, keynum-1); if (i) assign_svalue(&vtmp->item[ix], &key_data[i]); /* No need to assign the key value: it's already there. */ } stmp.u.vec->item[i].type=T_POINTER; stmp.u.vec->item[i].u.vec=vtmp; } /* Done */ return &stmp; } /* insert_alist() */
/*-------------------------------------------------------------------------*/ svalue_t * f_wizlist_info (svalue_t *sp) /* EFUN wizlist_info() * * mixed *wizlist_info() * * Returns an array with the interesting entries of the wizlist. * Raises a privilege_violation (wizlist_info, this_object(), 0). * * The result is an array with one entry for every wizard (uid). * Every entry is an array itself: * * string w[WL_NAME] = Name of the wizard. * int w[WL_COMMANDS] = Weighted number of commands execute by objects * of this wizard. * int w[WL_COST] and w[WL_GIGACOST] = Weighted sum of eval_costs. * int w[WL_TOTAL_COST] and w[WL_TOTAL_GIGACOST] = Total sum of * eval_costs. * int w[WL_HEART_BEATS] = Weighted count of heart_beats. * int w[WL_CALL_OUT] = Reserved for call_out() (unused yet). * int w[WL_ARRAY_TOTAL] = Total size of arrays in elements. * int w[WL_MAPPING_TOTAL] = Total size of mappings in elements. #ifdef USE_STRUCTS * int w[WL_STRUCT_TOTAL] = Total size of mappings in elements. #endif * mixed w[WL_EXTRA] = Extra wizlist-info if set. */ { vector_t *all, *entry; svalue_t *wsvp, *svp; wiz_list_t *w; if (!privilege_violation(STR_WIZLIST_INFO, &const0, sp)) { all = allocate_array(0); } else { all = allocate_array(number_of_wiz); wsvp = all->item; for (w = all_wiz; w; w = w->next) { entry = allocate_array(WL_SIZE); put_array(wsvp, entry); wsvp++; svp = entry->item; put_ref_string(&(svp[WL_NAME]), w->name); put_number(&(svp[WL_COMMANDS]), w->score); put_number(&(svp[WL_COST]), w->cost); put_number(&(svp[WL_GIGACOST]), w->gigacost); put_number(&(svp[WL_TOTAL_COST]), w->total_cost); put_number(&(svp[WL_TOTAL_GIGACOST]), w->total_gigacost); put_number(&(svp[WL_HEART_BEATS]), w->heart_beats); put_number(&(svp[WL_CALL_OUT]), 0); /* TODO: Implement me */ put_number(&(svp[WL_ARRAY_TOTAL]), w->size_array); put_number(&(svp[WL_MAPPING_TOTAL]), w->mapping_total); #ifdef USE_STRUCTS put_number(&(svp[WL_STRUCT_TOTAL]), w->struct_total); #else put_number(&(svp[WL_STRUCT_TOTAL]), 0); #endif /* USE_STRUCTS */ if (w->extra.type == T_POINTER) { vector_t *v = w->extra.u.vec; put_array(&(svp[WL_EXTRA]), slice_array(v, 0, VEC_SIZE(v) - 1)); } else assign_svalue_no_free(&(svp[WL_EXTRA]), &w->extra); } /* end for */ } /* end if */ push_array(sp, all); return sp; } /* f_wizlist_info() */
int main() { read_input(); slice_array(); return 0; }