blob: 860032f6eeab9a1e6646bea42b88ac2fac553e77 [file] [log] [blame]
MG Mud User88f12472016-06-24 23:31:02 +02001/* This sefun is to provide a replacement for the efun debug_info().
2 * Feel free to add it to your mudlibs, if you have much code relying on that.
3 */
4
5#if ! __EFUN_DEFINED__(debug_info)
6
7#include <driver_info.h>
8#include <debug_info.h>
9
10mixed debug_info(int what, varargs mixed* args)
11{
12 if (sizeof(args) > 2)
13 raise_error("Too many arguments to debug_info\n");
14
15 switch(what)
16 {
17 default:
18 raise_error(sprintf("Illegal value %d for debug_info().\n", what));
19
20 case DINFO_OBJECT:
21 {
22 object ob;
23
24 if (sizeof(args) != 1)
25 raise_error("bad number of arguments to debug_info\n");
26 if (!objectp(args[0]))
27 raise_error("bag arg 2 to debug_info().\n");
28
29 ob = args[0];
30 printf("O_HEART_BEAT : %s\n", efun::object_info(ob, OC_HEART_BEAT) ? "TRUE" : "FALSE");
31 printf("O_ENABLE_COMMANDS : %s\n", efun::object_info(ob, OC_COMMANDS_ENABLED) ? "TRUE" : "FALSE");
32 printf("O_CLONE : %s\n", efun::clonep(ob) ? "TRUE" : "FALSE");
33 printf("O_DESTRUCTED : FALSE\n");
34 printf("O_SWAPPED : %s\n", efun::object_info(ob, OI_SWAPPED) ? "TRUE" : "FALSE");
35 printf("O_ONCE_INTERACTIVE: %s\n", efun::object_info(ob, OI_ONCE_INTERACTIVE) ? "TRUE" : "FALSE");
36 printf("O_RESET_STATE : %s\n", efun::object_info(ob, OI_RESET_STATE) ? "TRUE" : "FALSE");
37 printf("O_WILL_CLEAN_UP : %s\n", efun::object_info(ob, OI_WILL_CLEAN_UP) ? "TRUE" : "FALSE");
38 printf("O_REPLACED : %s\n", efun::object_info(ob, OI_REPLACED) ? "TRUE" : "FALSE");
39 printf("time_reset : %d\n", efun::object_info(ob, OI_NEXT_RESET_TIME));
40 printf("time_of_ref : %d\n", efun::object_info(ob, OI_LAST_REF_TIME));
41 printf("ref : %d\n", efun::object_info(ob, OI_OBJECT_REFS));
42
43 int gticks = efun::object_info(ob, OI_GIGATICKS);
44 if(gticks)
45 printf("evalcost : %d%09d\n", gticks, efun::object_info(ob, OI_TICKS));
46 else
47 printf("evalcost : %d\n", efun::object_info(ob, OI_TICKS));
48
49 printf("swap_num : %d\n", efun::object_info(ob, OI_SWAP_NUM));
50 printf("name : '%s'\n", efun::object_name(ob));
51 printf("load_name : '%s'\n", efun::load_name(ob));
52
53 object next_ob = efun::object_info(ob, OI_OBJECT_NEXT);
54 if (next_ob)
55 printf("next_all : OBJ(%s)\n", efun::object_name(next_ob));
56
57 object prev_ob = efun::object_info(ob, OI_OBJECT_PREV);
58 if (prev_ob)
59 printf("Previous object in object list: OBJ(%s)\n", efun::object_name(prev_ob));
60 else
61 printf("This object is the head of the object list.\n");
62 break;
63 }
64
65 case DINFO_MEMORY:
66 {
67 object ob;
68
69 if (sizeof(args) != 1)
70 raise_error("bad number of arguments to debug_info\n");
71 if (!objectp(args[0]))
72 raise_error("bag arg 2 to debug_info().\n");
73
74 ob = args[0];
75
76 printf("program ref's %3d\n", efun::object_info(ob, OI_PROG_REFS));
77 printf("Name: '%s'\n", efun::program_name(ob));
78 printf("program size %6d\n", efun::object_info(ob, OI_PROG_SIZE));
79 printf("num func's: %3d (%4d)\n",
80 efun::object_info(ob, OI_NUM_FUNCTIONS),
81 efun::object_info(ob, OI_SIZE_FUNCTIONS));
82 printf("num vars: %3d (%4d)\n",
83 efun::object_info(ob, OI_NUM_VARIABLES),
84 efun::object_info(ob, OI_SIZE_VARIABLES));
85
86 printf("num strings: %3d (%4d) : overhead %d + data %d (%d)\n",
87 efun::object_info(ob, OI_NUM_STRINGS),
88 efun::object_info(ob, OI_SIZE_STRINGS) + efun::object_info(ob, OI_SIZE_STRINGS_DATA),
89 efun::object_info(ob, OI_SIZE_STRINGS),
90 efun::object_info(ob, OI_SIZE_STRINGS_DATA),
91 efun::object_info(ob, OI_SIZE_STRINGS_DATA_TOTAL));
92
93 printf("num inherits %3d (%4d)\n",
94 efun::object_info(ob, OI_NUM_INHERITED),
95 efun::object_info(ob, OI_SIZE_INHERITED));
96
97 printf("total size %6d\n", efun::object_info(ob, OI_PROG_SIZE_TOTAL));
98
99 printf("data size %6d (%6d\n",
100 efun::object_info(ob, OI_DATA_SIZE),
101 efun::object_info(ob, OI_DATA_SIZE_TOTAL));
102 break;
103 }
104
105 case DINFO_OBJLIST:
106 {
107 if (sizeof(args) == 0)
108 raise_error("bad number of arguments to debug_info\n");
109
110 if (sizeof(args) == 1)
111 {
112 object * obs = efun::objects(args[0], 1);
113 return obs[0];
114 }
115 else
116 return efun::objects(args[0], args[1]);
MG Mud User88f12472016-06-24 23:31:02 +0200117 }
118
119 case DINFO_MALLOC:
120 write(debug_info(DINFO_STATUS, "malloc"));
121 break;
122
123 case DINFO_STATUS:
124 {
125 string which;
126 int opt;
127
128 if (sizeof(args) > 1)
129 raise_error("bad number of arguments to debug_info\n");
130
131 if (!sizeof(args) || !args[0])
132 which = "";
133 else if(stringp(args[0]))
134 which = args[0];
135 else
136 raise_error("bag arg 2 to debug_info().\n");
137
138 switch(which)
139 {
140 case "":
141 opt = DI_STATUS_TEXT_MEMORY;
142 break;
143
144 case "tables":
145 opt = DI_STATUS_TEXT_TABLES;
146 break;
147
148 case "swap":
149 opt = DI_STATUS_TEXT_SWAP;
150 break;
151
152 case "malloc":
153 opt = DI_STATUS_TEXT_MALLOC;
154 break;
155
156 case "malloc extstats":
157 opt = DI_STATUS_TEXT_MALLOC_EXTENDED;
158 break;
159
160 default:
161 return 0;
162 }
163
164 return efun::driver_info(opt);
165 }
166
167 case DINFO_DUMP:
168 {
169 int opt;
170
171 if (!sizeof(args))
172 raise_error("bad number of arguments to debug_info\n");
173
174 if(!stringp(args[0]))
175 raise_error("bag arg 2 to debug_info().\n");
176
177 switch(args[0])
178 {
179 case "objects":
180 opt = DDI_OBJECTS;
181 break;
182
183 case "destructed":
184 opt = DDI_OBJECTS_DESTRUCTED;
185 break;
186
187 case "opcodes":
188 opt = DDI_OPCODES;
189 break;
190
191 case "memory":
192 opt = DDI_MEMORY;
193 break;
194
195 default:
196 raise_error(sprintf("Bad argument '%s' to debug_info(DINFO_DUMP).\n", args[0]));
MG Mud User88f12472016-06-24 23:31:02 +0200197 }
Zesstra250a96b2021-04-02 00:14:30 +0200198 // set object for valid_write() master apply...
199 set_this_object(previous_object());
MG Mud User88f12472016-06-24 23:31:02 +0200200 return efun::dump_driver_info(opt, args[1..1]...);
201 }
202
203 case DINFO_DATA:
204 {
205 mixed * result;
206
207 if (!sizeof(args))
208 raise_error("bad number of arguments to debug_info\n");
209
210 if (!intp(args[0]))
211 raise_error("bag arg 2 to debug_info().\n");
212
213 if (sizeof(args) == 2 && !intp(args[1]))
214 raise_error("bag arg 3 to debug_info().\n");
215
216 switch(args[0])
217 {
218 case DID_STATUS:
219 result = allocate(DID_STATUS_MAX);
220
221 result[DID_ST_ACTIONS] = efun::driver_info(DI_NUM_ACTIONS);
222 result[DID_ST_ACTIONS_SIZE] = efun::driver_info(DI_SIZE_ACTIONS);
223 result[DID_ST_SHADOWS] = efun::driver_info(DI_NUM_SHADOWS);
224 result[DID_ST_SHADOWS_SIZE] = efun::driver_info(DI_SIZE_SHADOWS);
225
226 result[DID_ST_OBJECTS] = efun::driver_info(DI_NUM_OBJECTS);
227 result[DID_ST_OBJECTS_SIZE] = efun::driver_info(DI_SIZE_OBJECTS);
228 result[DID_ST_OBJECTS_SWAPPED] = efun::driver_info(DI_NUM_OBJECTS_SWAPPED);
229 result[DID_ST_OBJECTS_SWAP_SIZE] = efun::driver_info(DI_SIZE_OBJECTS_SWAPPED);
230 result[DID_ST_OBJECTS_LIST] = efun::driver_info(DI_NUM_OBJECTS_IN_LIST);
231 result[DID_ST_OBJECTS_NEWLY_DEST] = efun::driver_info(DI_NUM_OBJECTS_NEWLY_DESTRUCTED);
232 result[DID_ST_OBJECTS_DESTRUCTED] = efun::driver_info(DI_NUM_OBJECTS_DESTRUCTED);
233 result[DID_ST_OBJECTS_PROCESSED] = efun::driver_info(DI_NUM_OBJECTS_LAST_PROCESSED);
234 result[DID_ST_OBJECTS_AVG_PROC] = efun::driver_info(DI_LOAD_AVERAGE_PROCESSED_OBJECTS_RELATIVE);
235
236 result[DID_ST_OTABLE] = efun::driver_info(DI_NUM_OBJECTS_IN_TABLE);
237 result[DID_ST_OTABLE_SLOTS] = efun::driver_info(DI_NUM_OBJECT_TABLE_SLOTS);
238 result[DID_ST_OTABLE_SIZE] = efun::driver_info(DI_SIZE_OBJECT_TABLE);
239
240 result[DID_ST_HBEAT_OBJS] = efun::driver_info(DI_NUM_HEARTBEATS);
241 result[DID_ST_HBEAT_CALLS] = efun::driver_info(DI_NUM_HEARTBEAT_ACTIVE_CYCLES);
242 result[DID_ST_HBEAT_CALLS_TOTAL] = efun::driver_info(DI_NUM_HEARTBEAT_TOTAL_CYCLES);
243 result[DID_ST_HBEAT_SLOTS] = efun::driver_info(DI_NUM_HEARTBEATS);
244 result[DID_ST_HBEAT_SIZE] = efun::driver_info(DI_SIZE_HEARTBEATS);
245 result[DID_ST_HBEAT_PROCESSED] = efun::driver_info(DI_NUM_HEARTBEATS_LAST_PROCESSED);
246 result[DID_ST_HBEAT_AVG_PROC] = efun::driver_info(DI_LOAD_AVERAGE_PROCESSED_HEARTBEATS_RELATIVE);
247
248 result[DID_ST_CALLOUTS] = efun::driver_info(DI_NUM_CALLOUTS);
249 result[DID_ST_CALLOUT_SIZE] = efun::driver_info(DI_SIZE_CALLOUTS);
250
251 result[DID_ST_ARRAYS] = efun::driver_info(DI_NUM_ARRAYS);
252 result[DID_ST_ARRAYS_SIZE] = efun::driver_info(DI_SIZE_ARRAYS);
253
254 result[DID_ST_MAPPINGS] = efun::driver_info(DI_NUM_MAPPINGS);
255 result[DID_ST_MAPPINGS_SIZE] = efun::driver_info(DI_SIZE_MAPPINGS);
256 result[DID_ST_HYBRID_MAPPINGS] = efun::driver_info(DI_NUM_MAPPINGS_HYBRID);
257 result[DID_ST_HASH_MAPPINGS] = efun::driver_info(DI_NUM_MAPPINGS_HASH);
258
259 result[DID_ST_STRUCTS] = efun::driver_info(DI_NUM_STRUCTS);
260 result[DID_ST_STRUCTS_SIZE] = efun::driver_info(DI_SIZE_STRUCTS);
261 result[DID_ST_STRUCT_TYPES] = efun::driver_info(DI_NUM_STRUCT_TYPES);
262 result[DID_ST_STRUCT_TYPES_SIZE] = efun::driver_info(DI_SIZE_STRUCT_TYPES);
263
264 result[DID_ST_PROGS] = efun::driver_info(DI_NUM_PROGS);
265 result[DID_ST_PROGS_SIZE] = efun::driver_info(DI_SIZE_PROGS);
266
267 result[DID_ST_PROGS_SWAPPED] = efun::driver_info(DI_NUM_PROGS_SWAPPED);
268 result[DID_ST_PROGS_SWAP_SIZE] = efun::driver_info(DI_SIZE_PROGS_SWAPPED);
269
270 result[DID_ST_USER_RESERVE] = efun::driver_info(DI_MEMORY_RESERVE_USER);
271 result[DID_ST_MASTER_RESERVE] = efun::driver_info(DI_MEMORY_RESERVE_MASTER);
272 result[DID_ST_SYSTEM_RESERVE] = efun::driver_info(DI_MEMORY_RESERVE_SYSTEM);
273
274 result[DID_ST_ADD_MESSAGE] = efun::driver_info(DI_NUM_MESSAGES_OUT);
275 result[DID_ST_PACKETS] = efun::driver_info(DI_NUM_PACKETS_OUT);
276 result[DID_ST_PACKET_SIZE] = efun::driver_info(DI_SIZE_PACKETS_OUT);
277 result[DID_ST_PACKETS_IN] = efun::driver_info(DI_NUM_PACKETS_IN);
278 result[DID_ST_PACKET_SIZE_IN] = efun::driver_info(DI_SIZE_PACKETS_IN);
279
280 result[DID_ST_APPLY] = efun::driver_info(DI_NUM_FUNCTION_NAME_CALLS);
281 result[DID_ST_APPLY_HITS] = efun::driver_info(DI_NUM_FUNCTION_NAME_CALL_HITS);
282
283 result[DID_ST_STRINGS] = efun::driver_info(DI_NUM_VIRTUAL_STRINGS);
284 result[DID_ST_STRING_SIZE] = efun::driver_info(DI_SIZE_STRINGS);
285 result[DID_ST_STR_TABLE_SIZE] = efun::driver_info(DI_SIZE_STRING_TABLE);
286 result[DID_ST_STR_OVERHEAD] = efun::driver_info(DI_SIZE_STRING_OVERHEAD);
287 result[DID_ST_UNTABLED] = efun::driver_info(DI_NUM_STRINGS_UNTABLED);
288 result[DID_ST_UNTABLED_SIZE] = efun::driver_info(DI_SIZE_STRINGS_UNTABLED);
289 result[DID_ST_TABLED] = efun::driver_info(DI_NUM_STRINGS_TABLED);
290 result[DID_ST_TABLED_SIZE] = efun::driver_info(DI_SIZE_STRINGS_TABLED);
291 result[DID_ST_STR_SEARCHES] = efun::driver_info(DI_NUM_STRING_TABLE_LOOKUPS_BY_INDEX);
292 result[DID_ST_STR_SEARCHLEN] = efun::driver_info(DI_NUM_STRING_TABLE_LOOKUP_STEPS_BY_INDEX);
293 result[DID_ST_STR_SEARCHES_BYVALUE] = efun::driver_info(DI_NUM_STRING_TABLE_LOOKUPS_BY_VALUE);
294 result[DID_ST_STR_SEARCHLEN_BYVALUE] = efun::driver_info(DI_NUM_STRING_TABLE_LOOKUP_STEPS_BY_VALUE);
295 result[DID_ST_STR_CHAINS] = efun::driver_info(DI_NUM_STRING_TABLE_SLOTS_USED);
296 result[DID_ST_STR_ADDED] = efun::driver_info(DI_NUM_STRING_TABLE_STRINGS_ADDED);
297 result[DID_ST_STR_DELETED] = efun::driver_info(DI_NUM_STRING_TABLE_STRINGS_REMOVED);
298 result[DID_ST_STR_COLLISIONS] = efun::driver_info(DI_NUM_STRING_TABLE_COLLISIONS);
299 result[DID_ST_STR_FOUND] = efun::driver_info(DI_NUM_STRING_TABLE_HITS_BY_INDEX);
300 result[DID_ST_STR_FOUND_BYVALUE] = efun::driver_info(DI_NUM_STRING_TABLE_HITS_BY_VALUE);
301
302 result[DID_ST_RX_CACHED] = efun::driver_info(DI_NUM_REGEX);
303 result[DID_ST_RX_TABLE] = efun::driver_info(DI_NUM_REGEX_TABLE_SLOTS);
304 result[DID_ST_RX_TABLE_SIZE] = efun::driver_info(DI_SIZE_REGEX);
305 result[DID_ST_RX_REQUESTS] = efun::driver_info(DI_NUM_REGEX_LOOKUPS);
306 result[DID_ST_RX_REQ_FOUND] = efun::driver_info(DI_NUM_REGEX_LOOKUP_HITS);
307 result[DID_ST_RX_REQ_COLL] = efun::driver_info(DI_NUM_REGEX_LOOKUP_COLLISIONS);
308
309 result[DID_ST_MB_FILE] = efun::driver_info(DI_SIZE_BUFFER_FILE);
310 result[DID_ST_MB_SWAP] = efun::driver_info(DI_SIZE_BUFFER_SWAP);
311
312 result[DID_ST_BOOT_TIME] = efun::driver_info(DI_BOOT_TIME);
313 break;
314
315 case DID_SWAP:
316 result = allocate(DID_SWAP_MAX);
317
318 result[DID_SW_PROGS] = efun::driver_info(DI_NUM_PROGS_SWAPPED);
319 result[DID_SW_PROG_SIZE] = efun::driver_info(DI_SIZE_PROGS_SWAPPED);
320 result[DID_SW_PROG_UNSWAPPED] = efun::driver_info(DI_NUM_PROGS_UNSWAPPED);
321 result[DID_SW_PROG_U_SIZE] = efun::driver_info(DI_SIZE_PROGS_UNSWAPPED);
322 result[DID_SW_VARS] = efun::driver_info(DI_NUM_OBJECTS_SWAPPED);
323 result[DID_SW_VAR_SIZE] = efun::driver_info(DI_SIZE_OBJECTS_SWAPPED);
324 result[DID_SW_FREE] = efun::driver_info(DI_NUM_SWAP_BLOCKS_FREE);
325 result[DID_SW_FREE_SIZE] = efun::driver_info(DI_SIZE_SWAP_BLOCKS_FREE);
326 result[DID_SW_FILE_SIZE] = efun::driver_info(DI_SIZE_SWAP_BLOCKS);
327 result[DID_SW_REUSED] = efun::driver_info(DI_SIZE_SWAP_BLOCKS_REUSED);
328 result[DID_SW_SEARCHES] = efun::driver_info(DI_NUM_SWAP_BLOCKS_REUSE_LOOKUPS);
329 result[DID_SW_SEARCH_LEN] = efun::driver_info(DI_NUM_SWAP_BLOCKS_REUSE_LOOKUP_STEPS);
330 result[DID_SW_F_SEARCHES] = efun::driver_info(DI_NUM_SWAP_BLOCKS_FREE_LOOKUPS);
331 result[DID_SW_F_SEARCH_LEN] = efun::driver_info(DI_NUM_SWAP_BLOCKS_FREE_LOOKUP_STEPS);
332 result[DID_SW_COMPACT] = efun::driver_info(DC_SWAP_COMPACT_MODE);
333 result[DID_SW_RECYCLE_FREE] = efun::driver_info(DI_SWAP_RECYCLE_PHASE);
334 break;
335
336 case DID_MEMORY:
337 result = allocate(DID_MEMORY_MAX);
338
339 result[DID_MEM_NAME] = efun::driver_info(DI_MEMORY_ALLOCATOR_NAME);
340 result[DID_MEM_SBRK] = efun::driver_info(DI_NUM_SYS_ALLOCATED_BLOCKS);
341 result[DID_MEM_SBRK_SIZE] = efun::driver_info(DI_SIZE_SYS_ALLOCATED_BLOCKS);
342 result[DID_MEM_LARGE] = efun::driver_info(DI_NUM_LARGE_BLOCKS_ALLOCATED);
343 result[DID_MEM_LARGE_SIZE] = efun::driver_info(DI_SIZE_LARGE_BLOCKS_ALLOCATED);
344 result[DID_MEM_LFREE] = efun::driver_info(DI_NUM_LARGE_BLOCKS_FREE);
345 result[DID_MEM_LFREE_SIZE] = efun::driver_info(DI_SIZE_LARGE_BLOCKS_FREE);
346 result[DID_MEM_LWASTED] = efun::driver_info(DI_NUM_LARGE_BLOCKS_WASTE);
347 result[DID_MEM_LWASTED_SIZE] = efun::driver_info(DI_SIZE_LARGE_BLOCKS_WASTE);
348 result[DID_MEM_CHUNK] = efun::driver_info(DI_NUM_SMALL_BLOCK_CHUNKS);
349 result[DID_MEM_CHUNK_SIZE] = efun::driver_info(DI_SIZE_SMALL_BLOCK_CHUNKS);
350 result[DID_MEM_SMALL] = efun::driver_info(DI_NUM_SMALL_BLOCKS_ALLOCATED);
351 result[DID_MEM_SMALL_SIZE] = efun::driver_info(DI_SIZE_SMALL_BLOCKS_ALLOCATED);
352 result[DID_MEM_SFREE] = efun::driver_info(DI_NUM_SMALL_BLOCKS_FREE);
353 result[DID_MEM_SFREE_SIZE] = efun::driver_info(DI_SIZE_SMALL_BLOCKS_FREE);
354 result[DID_MEM_SWASTED] = efun::driver_info(DI_NUM_SMALL_BLOCKS_WASTE);
355 result[DID_MEM_SWASTED_SIZE] = efun::driver_info(DI_SIZE_SMALL_BLOCKS_WASTE);
356 result[DID_MEM_MINC_CALLS] = efun::driver_info(DI_NUM_INCREMENT_SIZE_CALLS);
357 result[DID_MEM_MINC_SUCCESS] = efun::driver_info(DI_NUM_INCREMENT_SIZE_CALL_SUCCESSES);
358 result[DID_MEM_MINC_SIZE] = efun::driver_info(DI_SIZE_INCREMENT_SIZE_CALL_DIFFS);
359 result[DID_MEM_PERM] = efun::driver_info(DI_NUM_UNMANAGED_BLOCKS);
360 result[DID_MEM_PERM_SIZE] = efun::driver_info(DI_SIZE_UNMANAGED_BLOCKS);
361 result[DID_MEM_CLIB] = efun::driver_info(DI_NUM_REPLACEMENT_MALLOC_CALLS);
362 result[DID_MEM_CLIB_SIZE] = efun::driver_info(DI_SIZE_REPLACEMENT_MALLOC_CALLS);
363 result[DID_MEM_OVERHEAD] = efun::driver_info(DI_SIZE_SMALL_BLOCK_OVERHEAD);
364 result[DID_MEM_ALLOCATED] = efun::driver_info(DI_SIZE_MEMORY_USED) + efun::driver_info(DI_SIZE_MEMORY_OVERHEAD);
365 result[DID_MEM_USED] = efun::driver_info(DI_SIZE_MEMORY_USED);
366 result[DID_MEM_TOTAL_UNUSED] = efun::driver_info(DI_SIZE_MEMORY_UNUSED);
367 result[DID_MEM_DEFRAG_CALLS] = efun::driver_info(DI_NUM_MEMORY_DEFRAGMENTATION_CALLS_FULL) + efun::driver_info(DI_NUM_MEMORY_DEFRAGMENTATION_CALLS_TARGETED);
368 result[DID_MEM_DEFRAG_CALLS_REQ] = efun::driver_info(DI_NUM_MEMORY_DEFRAGMENTATION_CALLS_TARGETED);
369 result[DID_MEM_DEFRAG_REQ_SUCCESS] = efun::driver_info(DI_NUM_MEMORY_DEFRAGMENTATION_CALL_TARGET_HITS);
370 result[DID_MEM_DEFRAG_BLOCKS_INSPECTED] = efun::driver_info(DI_NUM_MEMORY_DEFRAGMENTATION_BLOCKS_INSPECTED);
371 result[DID_MEM_DEFRAG_BLOCKS_MERGED] = efun::driver_info(DI_NUM_MEMORY_DEFRAGMENTATION_BLOCKS_MERGED);
372 result[DID_MEM_DEFRAG_BLOCKS_RESULT] = efun::driver_info(DI_NUM_MEMORY_DEFRAGMENTATION_BLOCKS_RESULTING);
373 result[DID_MEM_AVL_NODES] = efun::driver_info(DI_NUM_FREE_BLOCKS_AVL_NODES);
374 result[DID_MEM_EXT_STATISTICS] = efun::driver_info(DI_MEMORY_EXTENDED_STATISTICS);
375 break;
376 }
377
378 if (sizeof(args) == 2)
379 {
380 int idx = args[0];
381 if (idx < 0 || idx >= sizeof(result))
382 raise_error(sprintf("Illegal index for debug_info(): %d, expected 0..%d\n",
383 idx, sizeof(result)-1));
384
385 return result[idx];
386 }
387 else
388 return result;
389 }
390
391 case DINFO_TRACE:
392 {
393 int which = DIT_CURRENT;
394
395 if (sizeof(args) > 1)
396 raise_error("bad number of arguments to debug_info\n");
397 if (sizeof(args))
398 {
399 if (!intp(args[0]))
400 raise_error("bag arg 2 to debug_info().\n");
401 which = args[0];
402 }
403
404 switch (which)
405 {
406 case DIT_CURRENT:
407 return efun::driver_info(DI_TRACE_CURRENT);
408
409 case DIT_ERROR:
410 return efun::driver_info(DI_TRACE_LAST_ERROR) || ({ "No trace." });
411
412 case DIT_UNCAUGHT_ERROR:
413 return efun::driver_info(DI_TRACE_LAST_UNCAUGHT_ERROR) || ({ "No trace." });
414
415 case DIT_STR_CURRENT:
416 return efun::driver_info(DI_TRACE_CURRENT_AS_STRING);
417
418 case DIT_CURRENT_DEPTH:
419 return efun::driver_info(DI_TRACE_CURRENT_DEPTH);
420
421 default:
422 raise_error("bad arg 2 to debug_info().\n");
423 }
424
425 }
426
427 case DINFO_EVAL_NUMBER:
428 return efun::driver_info(DI_EVAL_NUMBER);
429 }
430 return 0;
431}
432
433#endif