/*-------------------------------------------------------------------------*/ static vector_t * single_struct_info (struct_type_t * st, Bool include_base) /* Create the struct_info() result array for a single struct and return it. * If <include_base> is TRUE, all members defined in a possible base * struct are included as if they were top-level members. */ { vector_t * rc; size_t offset; size_t i; offset = 0; if (!include_base && st->base != NULL) offset = struct_t_size(st->base); rc = allocate_array(struct_t_size(st) - offset + SI_MAX); put_ref_string(&rc->item[SI_NAME], struct_t_name(st)); put_ref_string(&rc->item[SI_PROG_NAME], struct_t_pname(st)); put_number(&rc->item[SI_PROG_ID], st->prog_id); for (i = offset; i < struct_t_size(st); i++) { vector_t * member; struct_member_t * pMember; pMember = &st->member[i]; member = allocate_array(SIM_MAX); put_array(&rc->item[SI_MEMBER+i-offset], member); put_ref_string(&member->item[SIM_NAME], pMember->name); put_number(&member->item[SIM_TYPE], 0); /* TODO: Convert pMember->type to int */ if (pMember->type->t_class == TCLASS_STRUCT) put_ref_string(&member->item[SIM_EXTRA] , pMember->type->t_struct.name->name ); } return rc; } /* single_struct_info() */
/*-------------------------------------------------------------------------*/ svalue_t * f_get_error_file (svalue_t *sp) /* EFUN get_error_file() * * mixed * get_error_file(string name, int set_forget_flag) * * Return information about the last error which occured for * <name> (where <name> is a valid name from the wiz list). * * Result is an array of four elements: the filename of the * program where the error occured, the linenumber in the * program, the error message (runtime error messages usually * start with a '*'), and a numerical flag (the 'forget flag') if * the error information has been queried already. * * If there is no error stored for the given <name>, 0 is * returned. * * If <set_forget_flag> is non-zero, the 'forget' flag is set * for the error message after it has been returned. */ { string_t *name; int forget; wiz_list_t *wl; vector_t *vec; svalue_t *v; # define FORGET_FLAG 0x4000000 /* 0x80...0 would be the sign! */ /* Get the function arguments */ name = sp[-1].u.str; forget = sp->u.number; wl = find_wiz(name); sp--; free_string_svalue(sp); /* The error_message is used as a flag if there has been any error. */ if (!wl || !wl->error_message) { put_number(sp, 0); return sp; } vec = allocate_array(4); v = vec->item; put_ref_string(v, wl->file_name); put_number(v+1, wl->line_number & ~0x40000000); put_ref_string(v+2, wl->error_message); put_number(v+3, (wl->line_number & 0x40000000) != 0); if (forget) wl->line_number |= 0x40000000; put_array(sp, vec); return sp; # undef FORGET_FLAG } /* f_get_error_file() */
/*-------------------------------------------------------------------------*/ 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() */
/*-------------------------------------------------------------------------*/ svalue_t * f_struct_info (svalue_t *sp) /* EFUN struct_info() * * mixed * struct_info(struct s, int type) * * Return an array with information about the struct <s>. The * type of information returned is determined by <type>. */ { struct_type_t *st; int rtype; svalue_t result; /* Get the arguments from the stack */ st = sp[-1].u.strct->type; rtype = sp[0].u.number; /* Get the basic result information */ put_array(&result, single_struct_info(st, rtype != SINFO_NESTED)); if (st->base != NULL) { /* Depending on the <rtype> argument, determine the how to handle * the base structs (if any). */ switch(rtype) { case SINFO_FLAT: put_ref_string(&result.u.vec->item[SI_BASE], struct_t_name(st->base)); break; case SINFO_NESTED: { svalue_t *rc; for ( rc = &result.u.vec->item[SI_BASE], st = st->base ; st != NULL ; st = st->base, rc = &rc->u.vec->item[SI_BASE] ) { put_array(rc, single_struct_info(st, MY_FALSE)); } break; } default: free_svalue(&result); errorf("Bad arg 2 to struct_info(): illegal value %"PRIdPINT"\n" , sp->u.number); /* NOTREACHED */ return sp; } } free_svalue(sp); sp--; /* type */ free_svalue(sp); /* struct */ /* Assign the result */ transfer_svalue_no_free(sp, &result); return sp; } /* f_struct_info() */