#define DEBERROR(x) debug_message(x); return 0; /* * In dieser Datei stehen diverse Routinen die beim Programmieren des * base-Debuggers nuetlich sind. */ void printflags( char *buffer, uint32 flags ) { // *** Schreibt die Flags in den Buffer. buffer[0] = 0x00; strcat(buffer,"["); #define APPEND_WS { strcat(buffer," "); } if (flags & NAME_INHERITED) { strcat(buffer,"i"); } else APPEND_WS; if (flags & TYPE_MOD_STATIC) { strcat(buffer,"S"); } else APPEND_WS; if (flags & TYPE_MOD_NO_MASK) { strcat(buffer,"N"); } else APPEND_WS; if (flags & TYPE_MOD_PRIVATE) // *** Pirivate und public schliessen sich aus { strcat(buffer,"P"); } else if (flags & TYPE_MOD_PUBLIC) { strcat(buffer,"p"); } else APPEND_WS; if (flags & TYPE_MOD_VARARGS) { strcat(buffer,"V"); } else APPEND_WS; if (flags & TYPE_MOD_VIRTUAL) { strcat(buffer,"v"); } else APPEND_WS; if (flags & TYPE_MOD_PROTECTED) { strcat(buffer,"p"); } else APPEND_WS; strcat(buffer,"]"); } struct function *locate_function( char *name, struct program *prog ) { // *** Sucht die Funktion mit dem Namen name im programm prog. int lauf1; int lauf2; struct function *temp; if (name == 0) { debug_message("*** DebugError: locate_function.name == 0 !\n"); return 0; } if (prog->funktionsdaten == 0) { debug_message("*** DebugError: locate_funtion.prog->funktionsdaten == 0 !\n"); return 0; } for (lauf1 = 0; lauf1 < prog->num_functions ; lauf1++) { if (prog->funktionsdaten[lauf1].name == 0) { debug_message("*** DebugError: locate_funtion.prog->funktionsdaten[lauf1].name == 0"); return 0; } if (strcmp(prog->funktionsdaten[lauf1].name,name) == 0) { // *** Die Funktion hat den richtigen Namen ! if (prog->funktionsdaten[lauf1].flags & NAME_INHERITED) { // *** MIST. Das Dings is inherited. Nun die Inherits durchsuchen. for (lauf2 = 0; lauf2 < prog->num_inherited; lauf2++) { temp = locate_function(name,prog->inherit[lauf2].prog); // *** Solange suchen, bis wir die richtige Funktion erwischen. if (temp != 0) { return temp; } } } else { // *** Da ham wir die Funktion. Zurueckspringen. return &(prog->funktionsdaten[lauf1]); } } } return 0; } struct svalue *get_global_variable_pointer( char *name ) { // *** Gibt den zeiger auf die Svalue einer Objektglobalen Variablen // *** zurueck. Wenn eine Solche Variable nicht exisitert, wird 0 // *** zurueckgegeben. int lauf1; if ( name == 0 ) { DEBERROR("*** DebugError: name == 0 !\n"); } for (lauf1 = 0; lauf1 < current_object->prog->num_variables; lauf1++) { if (current_object->prog->variable_names[lauf1].name == 0) { debug_message("*** DebugError: get_global_variable_pointer.c_o->p->v_n[l1].name == 0\n"); return 0; } if (strcmp(current_object->prog->variable_names[lauf1].name,name) == 0) { // *** Gefunden ! // return &(current_variables[lauf1]); // return &(csp->current_variables[lauf1]); return &(current_object->variables[lauf1]); // *** Gewagt, muesste aber funtkionieren ! } } return 0; } struct svalue *get_local_variable_pointer( char *name ) { // *** Gibt den Zeiger auf die Svalue der lokalen Variable zurueck, // *** oder 0, wenn keine entsprechende lokale Variable gefunden werden konnte. // *** Dazu holen wir uns die aktuelle Funktion. struct function *tempzeiger; int lauf1; int lauf2; tempzeiger = locate_function( (char *) (*( (char **) (&csp->funstart[-5]) )),current_object->prog); if (tempzeiger == 0) return 0; // *** d.h. Funktion konnte nicht gefunden werden ! if (tempzeiger->variable_names == 0) return 0; // *** So ein Aerger. Die Funktion hat garkeine lokalen Variablen. lauf1 = -1; lauf2 = -1; do { lauf1++; if (strcmp(tempzeiger->variable_names[lauf1].name,name) == 0) { lauf2 = lauf1; } } while (tempzeiger->variable_names[lauf1].flags != 0xff); // *** Lauf2 -> Variable, lauf1 -> annzahl an Zeugs // *** lauf2 == -1 -> Variable nicht gefunden. if (lauf2 == -1) { return 0; } if (strcmp(tempzeiger->variable_names[lauf2].name,name) != 0) return 0; // *** So, das Dingsbums ist eine lokale Variable. return &(inter_fp[lauf1-lauf2]); // *** Gewagt, aber es muesste funktionieren ! } void get_variable_data_for_svalue( char *buffer, struct svalue *variable ) { int lauf1; char buf2[10000]; struct hash_mapping *temphash; struct map_chain *temp_map_chain; // buffer[0] = 0x00; // *** Ganz langsam und ausfuehrlich ! // *** Damit man es auch leicht verstehen kann, anders als den Rest des Drivers :( #define ADDBUFFER(x) strcat(buffer,x) strcat(buffer," Variablentyp : "); if (variable->type == T_INVALID) { ADDBUFFER(" Invalid (ups, wie kommt das hierher !?)"); } else if (variable->type == T_LVALUE) { ADDBUFFER(" LValue (ups, wie kommt das hierher !?)"); } else if (variable->type == T_NUMBER) { ADDBUFFER(" Number"); } else if (variable->type == T_STRING) { ADDBUFFER(" String"); } else if (variable->type == T_POINTER) { ADDBUFFER(" Pointer (d.h. ein Array)"); } else if (variable->type == T_OBJECT) { ADDBUFFER(" Objekt"); } else if (variable->type == T_MAPPING) { ADDBUFFER(" Mapping"); } else if (variable->type == T_FLOAT) { ADDBUFFER(" Float"); } else if (variable->type == T_CLOSURE) { ADDBUFFER(" Closure"); } else if (variable->type == T_SYMBOL) { ADDBUFFER(" Symbol"); } else if (variable->type == T_QUOTED_ARRAY) { ADDBUFFER(" Q-Array"); } ADDBUFFER("\n"); if (variable->type == T_NUMBER) { sprintf(buf2," Wert : %d\n",variable->u.number); ADDBUFFER(buf2); if (variable->u.number == 0) { ADDBUFFER("Achtung !\nDieser Wert entspricht auch der \"uninitialisiert\" bzw. \"leer\"-Notation !\n"); } } else if (variable->type == T_STRING) { sprintf(buf2," Wert : %s\n",variable->u.string); ADDBUFFER(buf2); } else if (variable->type == T_FLOAT) { sprintf(buf2," Wert : %g\n",READ_DOUBLE(variable)); ADDBUFFER(buf2); } else if (variable->type == T_POINTER) { sprintf(buf2," Anzahl der Elemente : %d\n",VEC_SIZE(variable->u.vec)); ADDBUFFER(buf2); sprintf(buf2,"Dump der Variablen : \n"); ADDBUFFER(buf2); for (lauf1 = 0; lauf1 < VEC_SIZE(variable->u.vec) ; lauf1++) { sprintf(buf2,"Dump von Element %d der Variablen :\n",lauf1); ADDBUFFER(buf2); get_variable_data_for_svalue(buffer,&(variable->u.vec->item[lauf1])); } } else if (variable->type == T_MAPPING) { // *** Anm. Mappingausgabe is noch nicht so doll und sehr evtl. fehlerhaft ! */ sprintf(buf2," Reference-Count : %d\n",variable->u.map->ref); ADDBUFFER(buf2); temphash = variable->u.map->hash; // *** Nun die einzelnen Hash-Tabellen durchgehen. for (lauf1 = 0; lauf1 < temphash->used; lauf1++) { temp_map_chain = temphash->chains[lauf1]; // *** Tempmapchain zeigt jetzt auf das erste Element der jeweiligen // *** hashkette. while (temp_map_chain != 0) { sprintf(buf2," Mapping-Key : \n"); ADDBUFFER(buf2); get_variable_data_for_svalue(buffer,&(temp_map_chain->key)); ADDBUFFER("\n"); sprintf(buf2," Mapping-Wert : \n"); ADDBUFFER(buf2); get_variable_data_for_svalue(buffer,&(temp_map_chain->data)); temp_map_chain = temp_map_chain->next; ADDBUFFER("\n\n"); } } } else if (variable->type == T_OBJECT) { if (variable->u.ob == 0) { ADDBUFFER("Interner Fehler - Objektreferenz ungueltig !\n"); return; } if (variable->u.ob->name == 0) { ADDBUFFER("Interner Fehler - Kein referenzierter Objektname !\n"); return; } sprintf(buf2," referenziertes Objekt : %s\n",variable->u.ob->name); ADDBUFFER(buf2); ADDBUFFER(" Flags : "); /* Das per Hand machen, wird sonst nirgends benoetigt. */ if (variable->u.ob->flags & O_HEART_BEAT) ADDBUFFER("[Heartbeat]"); if (variable->u.ob->flags & O_IS_WIZARD ) ADDBUFFER("[Wizard]"); if (variable->u.ob->flags & O_ENABLE_COMMANDS ) ADDBUFFER("[Enable Commands]"); if (variable->u.ob->flags & O_CLONE) ADDBUFFER("[Clone]"); if (variable->u.ob->flags & O_SHADOW) ADDBUFFER("[Shadow]"); ADDBUFFER("\n"); sprintf(buf2," Licht : %d\n",variable->u.ob->total_light); ADDBUFFER(buf2); sprintf(buf2," naechster Reset : %d\n",variable->u.ob->next_reset); ADDBUFFER(buf2); ADDBUFFER(" Enthaelt : "); if (variable->u.ob->contains != 0) { ADDBUFFER(variable->u.ob->contains->name); } else { ADDBUFFER("Nix, null, nada !"); } ADDBUFFER("\n"); ADDBUFFER(" Umgebung : "); if (variable->u.ob->super != 0) { ADDBUFFER(variable->u.ob->super->name); } else { ADDBUFFER("Nix, null, nada !"); } ADDBUFFER("\n"); if (variable->u.ob->user != 0) { sprintf(buf2," Programmierer : %s\n",variable->u.ob->user->name); ADDBUFFER(buf2); } else ADDBUFFER(" Programmierer : Keiner, Niemand, anonym !\n"); if (variable->u.ob->eff_user != 0) { sprintf(buf2," Effektive UID : %s\n",variable->u.ob->eff_user->name); ADDBUFFER(buf2); } else ADDBUFFER(" Effektive UID : Keine, nix, leer, nada !\n"); } else { ADDBUFFER("Tut mir leid. Dieser Variablentyp kann noch nicht dargestellt werden !\nErinnere Sunblade mal, das es das nit vergisst !\n"); } } struct breakpoint *breakpoint_exists( int curr_line, char *curr_file ) { // *** Diese Funtkion ueberpreuft, ob ein Breakpoint existiert, // *** der an der Zeile curr_line in der Datei curr_file gesetzt ist. struct breakpoint *tempbreak; tempbreak = first_breakpoint; while (tempbreak != 0) { if ((curr_line == tempbreak->line) && (strcmp(curr_file,tempbreak->in_file) == 0)) { // *** Da ist ein Breakpoint gefunden worden ! return tempbreak; } tempbreak = tempbreak->next; } return 0; }