#if HAVE_CONFIG_H #include "config.h" #endif /* HAVE_CONFIG_H */ #if HAVE_STDIO_H #include #endif /* HAVE_STDLIB_H */ #if HAVE_STRING_H #include #endif /* HAVE_STRING_H */ #include "data.h" #include "commands.h" #include "globals.h" #include "io.h" #include "logger.h" #include "a2-tgdb.h" #include "sys_util.h" /** * The info stored for each data context. */ struct data { /** * The maximum size of the prompt. */ #define GDB_PROMPT_SIZE 1024 /** * the state of the data context */ enum internal_state data_state; /** * The debugger's prompt. */ char gdb_prompt[GDB_PROMPT_SIZE]; /** * The size of gdb_prompt. */ int gdb_prompt_size; /** * What the debugger's prompt was before. */ char gdb_prompt_last[GDB_PROMPT_SIZE]; }; struct data *data_initialize ( void ) { struct data *d = (struct data *)xmalloc ( sizeof ( struct data ) ); d->data_state = VOID; d->gdb_prompt_size = 0; d->gdb_prompt[0] = 0; d->gdb_prompt_last[0] = 0; return d; } void data_shutdown ( struct data *d ) { free ( d ); d = NULL; } enum internal_state data_get_state( struct data *d){ return d->data_state; } void data_set_state ( struct annotate_two *a2, enum internal_state state ) { /* if tgdb is at an internal command, than nothing changes that * state unless tgdb gets to the prompt annotation. This means that * the internal command is done */ if(a2->data->data_state == INTERNAL_COMMAND && state != USER_AT_PROMPT ) return; a2->data->data_state = state; switch(a2->data->data_state){ case VOID: break; case AT_PROMPT: a2->data->gdb_prompt_size = 0; break; case USER_AT_PROMPT: /* Null-Terminate the prompt */ a2->data->gdb_prompt[a2->data->gdb_prompt_size] = '\0'; if ( strcmp(a2->data->gdb_prompt, a2->data->gdb_prompt_last) != 0 ) { strcpy(a2->data->gdb_prompt_last, a2->data->gdb_prompt); /* Update the prompt */ if (a2->cur_response_list) { struct tgdb_response *response = (struct tgdb_response *) xmalloc (sizeof (struct tgdb_response)); response->header = TGDB_UPDATE_CONSOLE_PROMPT_VALUE; response->choice.update_console_prompt_value.prompt_value = xstrdup (a2->data->gdb_prompt_last); tgdb_list_append (a2->cur_response_list, response); } } a2->command_finished = 1; /* This is important, because it resets the commands state. * With this line not here, if the user hits 'o' from cgdb, * then the commands state gets set to INFO_SOURCES, then the * user hits ^c from the gdb window, the error occurs because * commands state is INFO_SOURCES instead of VOID. */ commands_set_state ( a2->c, VOID, NULL ); break; case POST_PROMPT: a2->data->data_state = VOID; break; case GUI_COMMAND: break; case INTERNAL_COMMAND: break; case USER_COMMAND: break; } /* end switch */ } void data_process ( struct annotate_two *a2, char a, char *buf, int *n, struct tgdb_list *list){ switch(a2->data->data_state){ case VOID: buf[(*n)++] = a; break; case AT_PROMPT: a2->data->gdb_prompt[a2->data->gdb_prompt_size++] = a; /* buf[(*n)++] = a;*/ break; case USER_AT_PROMPT: break; case GUI_COMMAND: case INTERNAL_COMMAND: if(a2->data->data_state == INTERNAL_COMMAND) commands_process(a2->c, a, list); else if(a2->data->data_state == GUI_COMMAND) buf[(*n)++] = a; break; /* do nothing */ case USER_COMMAND: break; case POST_PROMPT: break; } /* end switch */ }