/* * There is an error in a specific file. Ask the MudOS driver to log the * message somewhere. */ void smart_log (const char * error_file, int line, const char * what, int flag) { char *buff; svalue_t *mret; extern int pragmas; buff = (char *) DMALLOC(strlen(error_file) + strlen(what) + ((pragmas & PRAGMA_ERROR_CONTEXT) ? 100 : 40), TAG_TEMPORARY, "smart_log: 1"); if (flag) sprintf(buff, "/%s line %d: Warning: %s", error_file, line, what); else sprintf(buff, "/%s line %d: %s", error_file, line, what); if (pragmas & PRAGMA_ERROR_CONTEXT) { char *ls = strrchr(buff, '\n'); unsigned char *tmp; if (ls) { tmp = (unsigned char *)ls + 1; while (*tmp && isspace(*tmp)) tmp++; if (!*tmp) *ls = 0; } strcat(buff, show_error_context()); } else strcat(buff, "\n"); push_malloced_string(add_slash(error_file)); copy_and_push_string(buff); mret = safe_apply_master_ob(APPLY_LOG_ERROR, 2); if (!mret || mret == (svalue_t *)-1) { debug_message("%s", buff); } FREE(buff); } /* smart_log() */
/* * Converts any LPC datatype into an arbitrary string format * and returns a pointer to this string. * Scary number of parameters for a recursive function. */ void svalue_to_string (svalue_t * obj, outbuffer_t * outbuf, int indent, int trailing, int indent2) { int i; /* prevent an infinite recursion on self-referential structures */ if (indent > 20) { outbuf_add(outbuf, "..."); return; } if (!indent2) add_space(outbuf, indent); switch ((obj->type & ~T_FREED)) { case T_INVALID: outbuf_add(outbuf, "T_INVALID"); break; case T_LVALUE: outbuf_add(outbuf, "lvalue: "); svalue_to_string(obj->u.lvalue, outbuf, indent + 2, trailing, 0); break; case T_REF: if(!obj->u.ref->lvalue) kill_ref(obj->u.ref); else { outbuf_add(outbuf, "ref: "); svalue_to_string(obj->u.ref->lvalue, outbuf, indent + 2, trailing, 0); } break; case T_NUMBER: numadd(outbuf, obj->u.number); break; case T_REAL: outbuf_addv(outbuf, "%f", obj->u.real); break; case T_STRING: outbuf_add(outbuf, "\""); outbuf_add(outbuf, obj->u.string); outbuf_add(outbuf, "\""); break; case T_CLASS: { int n = obj->u.arr->size; outbuf_add(outbuf, "CLASS( "); numadd(outbuf, n); outbuf_add(outbuf, n == 1 ? " element\n" : " elements\n"); for (i = 0; i < (obj->u.arr->size) - 1; i++) svalue_to_string(&(obj->u.arr->item[i]), outbuf, indent + 2, 1, 0); if(obj->u.arr->size) svalue_to_string(&(obj->u.arr->item[i]), outbuf, indent + 2, 0, 0); outbuf_add(outbuf, "\n"); add_space(outbuf, indent); outbuf_add(outbuf, " )"); break; } case T_ARRAY: if (!(obj->u.arr->size)) { outbuf_add(outbuf, "({ })"); } else { outbuf_add(outbuf, "({ /* sizeof() == "); numadd(outbuf, obj->u.arr->size); outbuf_add(outbuf, " */\n"); for (i = 0; i < (obj->u.arr->size) - 1; i++) svalue_to_string(&(obj->u.arr->item[i]), outbuf, indent + 2, 1, 0); svalue_to_string(&(obj->u.arr->item[i]), outbuf, indent + 2, 0, 0); outbuf_add(outbuf, "\n"); add_space(outbuf, indent); outbuf_add(outbuf, "})"); } break; #ifndef NO_BUFFER_TYPE case T_BUFFER: outbuf_add(outbuf, "<buffer>"); break; #endif case T_FUNCTION: { svalue_t tmp; object_t *ob; tmp.type = T_ARRAY; outbuf_add(outbuf, "(: "); switch (obj->u.fp->hdr.type) { case FP_LOCAL | FP_NOT_BINDABLE: ob = obj->u.fp->hdr.owner; if (!ob || ob->flags & O_DESTRUCTED) { outbuf_add(outbuf, "0"); break; } outbuf_add(outbuf, function_name(ob->prog, obj->u.fp->f.local.index)); break; case FP_SIMUL: outbuf_add(outbuf, simuls[obj->u.fp->f.simul.index].func->funcname); break; case FP_FUNCTIONAL: case FP_FUNCTIONAL | FP_NOT_BINDABLE: { char buf[10]; int n = obj->u.fp->f.functional.num_arg; outbuf_add(outbuf, "<code>("); for (i=1; i < n; i++) { sprintf(buf, "$%i, ", i); outbuf_add(outbuf, buf); } if (n) { sprintf(buf, "$%i", n); outbuf_add(outbuf, buf); } outbuf_add(outbuf, ")"); break; } case FP_EFUN: { int i; i = obj->u.fp->f.efun.index; outbuf_add(outbuf, query_instr_name(i)); break; } } if (obj->u.fp->hdr.args) { for (i=0; i<obj->u.fp->hdr.args->size; i++) { outbuf_add(outbuf, ", "); svalue_to_string(&(obj->u.fp->hdr.args->item[i]), outbuf, indent, 0, 0); } } } outbuf_add(outbuf, " :)"); break; case T_MAPPING: if (!(obj->u.map->count)) { outbuf_add(outbuf, "([ ])"); } else { outbuf_add(outbuf, "([ /* sizeof() == "); numadd(outbuf, obj->u.map->count); outbuf_add(outbuf, " */\n"); for (i = 0; i <= obj->u.map->table_size; i++) { mapping_node_t *elm; for (elm = obj->u.map->table[i]; elm; elm = elm->next) { svalue_to_string(&(elm->values[0]), outbuf, indent + 2, 0, 0); outbuf_add(outbuf, " : "); svalue_to_string(&(elm->values[1]), outbuf, indent + 4, 1, 1); } } add_space(outbuf, indent); outbuf_add(outbuf, "])"); } break; case T_OBJECT: { svalue_t *temp; if (obj->u.ob->flags & O_DESTRUCTED) { numadd(outbuf, 0); break; } outbuf_addchar(outbuf, '/'); outbuf_add(outbuf, obj->u.ob->obname); if (!max_eval_error && !too_deep_error) { push_object(obj->u.ob); temp = safe_apply_master_ob(APPLY_OBJECT_NAME, 1); if (temp && temp != (svalue_t *) -1 && (temp->type == T_STRING)) { outbuf_add(outbuf, " (\""); outbuf_add(outbuf, temp->u.string); outbuf_add(outbuf, "\")"); } } break; } default: outbuf_addv(outbuf, "!ERROR: GARBAGE SVALUE: %x!", obj->type); } /* end of switch (obj->type) */ if (trailing) outbuf_add(outbuf, ",\n"); } /* end of svalue_to_string() */