/** * Capture a regular expression from the user, one key at a time. * This modifies the global variables regex_cur and regex_last. * * \param sview * The source viewer. * * \return * 0 if user gave a regex, otherwise 1. */ static int status_bar_regex_input(struct sviewer *sview, int key) { int regex_icase = cgdbrc_get(CGDBRC_IGNORECASE)->variant.int_val; /* Flag to indicate we're done with regex mode, need to switch back */ int done = 0; /* Recieve a regex from the user. */ switch (key) { case '\r': case '\n': case CGDB_KEY_CTRL_M: /* Save for future searches via 'n' or 'N' */ if (regex_last != NULL) { ibuf_free(regex_last); } regex_last = ibuf_dup(regex_cur); regex_direction_last = regex_direction_cur; source_search_regex(sview, ibuf_get(regex_last), 2, regex_direction_last, regex_icase); if_draw(); done = 1; break; case 8: case 127: /* Backspace or DEL key */ if (ibuf_length(regex_cur) == 0) { done = 1; } else { ibuf_delchar(regex_cur); source_search_regex(sview, ibuf_get(regex_cur), 1, regex_direction_cur, regex_icase); if_draw(); update_status_win(); } break; default: if (kui_term_is_cgdb_key(key)) { const char *keycode = kui_term_get_keycode_from_cgdb_key(key); int length = strlen(keycode), i; for (i = 0; i < length; i++) ibuf_addchar(regex_cur, keycode[i]); } else { ibuf_addchar(regex_cur, key); } source_search_regex(sview, ibuf_get(regex_cur), 1, regex_direction_cur, regex_icase); if_draw(); update_status_win(); }; if (done) { ibuf_free(regex_cur); regex_cur = NULL; if_set_focus(CGDB); } return 0; }
static int status_bar_normal_input(int key) { /* Flag to indicate we're done with status mode, need to switch back */ int done = 0; /* The goal of this state is to recieve a command from the user. */ switch (key) { case '\r': case '\n': case CGDB_KEY_CTRL_M: /* Found a command */ if_run_command(src_win, cur_sbc); done = 1; break; case 8: case 127: /* Backspace or DEL key */ if (ibuf_length(cur_sbc) == 0) { done = 1; } else { ibuf_delchar(cur_sbc); update_status_win(); } break; default: if (kui_term_is_cgdb_key(key)) { const char *keycode = kui_term_get_keycode_from_cgdb_key(key); int length = strlen(keycode), i; for (i = 0; i < length; i++) ibuf_addchar(cur_sbc, keycode[i]); } else { ibuf_addchar(cur_sbc, key); } update_status_win(); break; }; if (done) { ibuf_free(cur_sbc); cur_sbc = NULL; if_set_focus(CGDB); } return 0; }
int command_focus_tty(int param) { if_set_focus(TTY); return 0; }
int internal_if_input(int key) { int regex_icase = cgdbrc_get(CGDBRC_IGNORECASE)->variant.int_val; /* Normally, CGDB_KEY_ESC, but can be configured by the user */ int cgdb_mode_key = cgdbrc_get(CGDBRC_CGDB_MODE_KEY)->variant.int_val; /* The cgdb mode key, puts the debugger into command mode */ if (focus != CGDB && key == cgdb_mode_key) { /* Depending on which cgdb was in, it can free some memory here that * it was previously using. */ if (focus == CGDB_STATUS_BAR && sbc_kind == SBC_NORMAL) { ibuf_free(cur_sbc); cur_sbc = NULL; } else if (focus == CGDB_STATUS_BAR && sbc_kind == SBC_REGEX) { ibuf_free(regex_cur); regex_cur = NULL; free(src_win->cur->buf.cur_line); src_win->cur->buf.cur_line = NULL; src_win->cur->sel_rline = orig_line_regex; src_win->cur->sel_line = orig_line_regex; } if_set_focus(CGDB); return 0; } /* If you are already in cgdb mode, the cgdb mode key does nothing */ else if (key == cgdb_mode_key) return 0; /* Check for global keystrokes */ switch (focus) { case CGDB: switch (key) { case 'i': if_set_focus(GDB); return 0; case 'I': if_set_focus(TTY); return 0; case ':': /* Set the type of the command the user is typing in the status bar */ sbc_kind = SBC_NORMAL; if_set_focus(CGDB_STATUS_BAR); /* Since the user is about to type in a command, allocate a buffer * in which this command can be stored. */ cur_sbc = ibuf_init(); return 0; case '/': case '?': if (src_win->cur != NULL) { regex_cur = ibuf_init(); regex_direction_cur = ('/' == key); orig_line_regex = src_win->cur->sel_line; sbc_kind = SBC_REGEX; if_set_focus(CGDB_STATUS_BAR); /* Capturing regular expressions */ source_search_regex_init(src_win); /* Initialize the function for finding a regex and tell user */ if_draw(); } return 0; case 'n': source_search_regex(src_win, ibuf_get(regex_last), 2, regex_direction_last, regex_icase); if_draw(); break; case 'N': source_search_regex(src_win, ibuf_get(regex_last), 2, !regex_direction_last, regex_icase); if_draw(); break; case 'T': if (tty_win_on) { tty_win_on = 0; focus = CGDB; } else { tty_win_on = 1; focus = TTY; } if_layout(); break; case CGDB_KEY_CTRL_T: if (tgdb_tty_new(tgdb) == -1) { /* Error */ } else { scr_free(tty_win); tty_win = NULL; if_layout(); } break; case CGDB_KEY_F1: if_display_help(); return 0; case CGDB_KEY_F5: /* Issue GDB run command */ { tgdb_request_ptr request_ptr; request_ptr = tgdb_request_run_debugger_command(tgdb, TGDB_RUN); handle_request(tgdb, request_ptr); } return 0; case CGDB_KEY_F6: /* Issue GDB continue command */ { tgdb_request_ptr request_ptr; request_ptr = tgdb_request_run_debugger_command(tgdb, TGDB_CONTINUE); handle_request(tgdb, request_ptr); } return 0; case CGDB_KEY_F7: /* Issue GDB finish command */ { tgdb_request_ptr request_ptr; request_ptr = tgdb_request_run_debugger_command(tgdb, TGDB_FINISH); handle_request(tgdb, request_ptr); } return 0; case CGDB_KEY_F8: /* Issue GDB next command */ { tgdb_request_ptr request_ptr; request_ptr = tgdb_request_run_debugger_command(tgdb, TGDB_NEXT); handle_request(tgdb, request_ptr); } return 0; case CGDB_KEY_F10: /* Issue GDB step command */ { tgdb_request_ptr request_ptr; request_ptr = tgdb_request_run_debugger_command(tgdb, TGDB_STEP); handle_request(tgdb, request_ptr); } return 0; case CGDB_KEY_CTRL_L: if_layout(); return 0; } source_input(src_win, key); return 0; break; case TTY: return tty_input(key); case GDB: return gdb_input(key); case FILE_DLG: { static char filedlg_file[MAX_LINE]; int ret = filedlg_recv_char(fd, key, filedlg_file); /* The user cancelled */ if (ret == -1) { if_set_focus(CGDB); return 0; /* Needs more data */ } else if (ret == 0) { return 0; /* The user picked a file */ } else if (ret == 1) { tgdb_request_ptr request_ptr; request_ptr = tgdb_request_filename_pair(tgdb, filedlg_file); handle_request(tgdb, request_ptr); if_set_focus(CGDB); return 0; } } return 0; case CGDB_STATUS_BAR: return status_bar_input(src_win, key); } /* Never gets here */ return 0; }
int command_focus_gdb(int param) { if_set_focus(GDB); return 0; }
static void process_commands(struct tgdb *tgdb) { struct tgdb_response *item; while ((item = tgdb_get_response(tgdb)) != NULL) { switch (item->header) { /* This updates all the breakpoints */ case TGDB_UPDATE_BREAKPOINTS: { struct sviewer *sview = if_get_sview(); char *file; struct tgdb_list *list = item->choice.update_breakpoints.breakpoint_list; tgdb_list_iterator *iterator; struct tgdb_breakpoint *tb; source_clear_breaks(if_get_sview()); iterator = tgdb_list_get_first(list); while (iterator) { /* For each breakpoint */ tb = (struct tgdb_breakpoint *) tgdb_list_get_item(iterator); file = tb->file; if (tb->enabled) source_enable_break(sview, file, tb->line); else source_disable_break(sview, file, tb->line); iterator = tgdb_list_next(iterator); } if_show_file(NULL, 0); break; } /* This means a source file or line number changed */ case TGDB_UPDATE_FILE_POSITION: { struct tgdb_file_position *tfp; tfp = item->choice.update_file_position.file_position; /* Update the file */ source_reload(if_get_sview(), tfp->absolute_path, 0); if_show_file(tfp->absolute_path, tfp->line_number); source_set_relative_path(if_get_sview(), tfp->absolute_path, tfp->relative_path); break; } /* This is a list of all the source files */ case TGDB_UPDATE_SOURCE_FILES: { struct tgdb_list *list = item->choice.update_source_files.source_files; tgdb_list_iterator *i = tgdb_list_get_first(list); char *s; if_clear_filedlg(); while (i) { s = tgdb_list_get_item(i); if_add_filedlg_choice(s); i = tgdb_list_next(i); } if_set_focus(FILE_DLG); kui_input_acceptable = 1; break; } /* The user is trying to get a list of source files that make up * the debugged program but libtgdb is claiming that gdb knows * none. */ case TGDB_SOURCES_DENIED: if_display_message("Error:", 0, " No sources available! Was the program compiled with debug?"); kui_input_acceptable = 1; break; /* This is the absolute path to the last file the user requested */ case TGDB_FILENAME_PAIR: { const char *apath = item->choice.filename_pair.absolute_path; const char *rpath = item->choice.filename_pair.relative_path; if_show_file((char *) apath, 1); source_set_relative_path(if_get_sview(), apath, rpath); break; } /* The source file requested does not exist */ case TGDB_ABSOLUTE_SOURCE_DENIED: { struct tgdb_source_file *file = item->choice.absolute_source_denied.source_file; if_show_file(NULL, 0); /* com can be NULL when tgdb orig requests main file */ if (file->absolute_path != NULL) if_display_message("No such file:", 0, " %s", file->absolute_path); break; } case TGDB_INFERIOR_EXITED: { /* * int *status = item->data; * This could eventually go here, but for now, the update breakpoint * display function makes the status bar go back to the name of the file. * * if_display_message ( "Program exited with value", 0, " %d", *status ); */ /* Clear the cache */ break; } case TGDB_UPDATE_COMPLETIONS: { struct tgdb_list *list = item->choice.update_completions.completion_list; do_tab_completion(list); break; } case TGDB_UPDATE_CONSOLE_PROMPT_VALUE: { const char *new_prompt = item->choice.update_console_prompt_value.prompt_value; change_prompt(new_prompt); break; } case TGDB_QUIT: cleanup(); exit(0); break; /* Default */ default: break; } } }
/** * Capture a regular expression from the user, one key at a time. * This modifies the global variables regex_cur and regex_last. * * \param sview * The source viewer. * * \return * 0 if user gave a regex, otherwise 1. */ static int gdb_input_regex_input(struct scroller *scr, int key) { int regex_icase = cgdbrc_get_int(CGDBRC_IGNORECASE); /* Flag to indicate we're done with regex mode, need to switch back */ int done = 0; /* Receive a regex from the user. */ switch (key) { case '\r': case '\n': case CGDB_KEY_CTRL_M: /* Save for future searches via 'n' or 'N' */ ibuf_free(regex_last); regex_last = ibuf_dup(regex_cur); regex_direction_last = regex_direction_cur; scr_search_regex(scr, ibuf_get(regex_last), 2, regex_direction_last, regex_icase); if_draw(); done = 1; break; case 8: case 127: /* Backspace or DEL key */ if (ibuf_length(regex_cur) == 0) { done = 1; scr_search_regex(scr, "", 2, regex_direction_cur, regex_icase); } else { ibuf_delchar(regex_cur); scr_search_regex(scr, ibuf_get(regex_cur), 1, regex_direction_cur, regex_icase); if_draw(); update_status_win(WIN_REFRESH); } break; default: if (kui_term_is_cgdb_key(key)) { const char *keycode = kui_term_get_keycode_from_cgdb_key(key); int length = strlen(keycode), i; for (i = 0; i < length; i++) ibuf_addchar(regex_cur, keycode[i]); } else { ibuf_addchar(regex_cur, key); } scr_search_regex(scr, ibuf_get(regex_cur), 1, regex_direction_cur, regex_icase); if_draw(); update_status_win(WIN_REFRESH); }; if (done) { gdb_scroller->in_search_mode = 0; ibuf_free(regex_cur); regex_cur = NULL; sbc_kind = SBC_NORMAL; if_set_focus(GDB); } return 0; }
int internal_if_input(int key, int *last_key) { /* Normally, CGDB_KEY_ESC, but can be configured by the user */ int cgdb_mode_key = cgdbrc_get_int(CGDBRC_CGDB_MODE_KEY); /* The cgdb mode key, puts the debugger into command mode */ if (focus != CGDB && key == cgdb_mode_key) { enum Focus new_focus = CGDB; /* Depending on which cgdb was in, it can free some memory here that * it was previously using. */ if (focus == CGDB_STATUS_BAR && sbc_kind == SBC_NORMAL) { ibuf_free(cur_sbc); cur_sbc = NULL; } else if (focus == CGDB_STATUS_BAR && sbc_kind == SBC_REGEX) { ibuf_free(regex_cur); regex_cur = NULL; hl_regex_free(&src_viewer->hlregex); src_viewer->cur->sel_rline = orig_line_regex; src_viewer->cur->sel_line = orig_line_regex; sbc_kind = SBC_NORMAL; } else if (focus == GDB && sbc_kind == SBC_REGEX) { ibuf_free(regex_cur); regex_cur = NULL; gdb_scroller->in_search_mode = 0; sbc_kind = SBC_NORMAL; new_focus = GDB; } if_set_focus(new_focus); return 0; } /* If you are already in cgdb mode, the cgdb mode key does nothing */ else if (key == cgdb_mode_key) return 0; /* Check for global keystrokes */ switch (focus) { case CGDB: return cgdb_input(key, last_key); case GDB: return gdb_input(key, last_key); case FILE_DLG: { char filedlg_file[MAX_LINE]; int ret = filedlg_recv_char(fd, key, filedlg_file, last_key_pressed); /* The user cancelled */ if (ret == -1) { if_set_focus(CGDB); return 0; /* Needs more data */ } else if (ret == 0) { return 0; /* The user picked a file */ } else if (ret == 1) { if_show_file(filedlg_file, 0, 0); if_set_focus(CGDB); return 0; } } return 0; case CGDB_STATUS_BAR: return status_bar_input(src_viewer, key); } /* Never gets here */ return 0; }
/** * Send input to the CGDB source window. * * @param key * The key to send to the CGDB source window. * * @param last_key * An output parameter. When set, that will tell cgdb to use the set value, * instead of the current key, as the "last_key_pressed" in the next * call to cgdb_input. This is useful to set mainly when the current input * has consumed more than one character, and the "last_key_pressed" should * be not set on the next call to cgdb_input. * * @return * Currently only returns 0. */ static int cgdb_input(int key, int *last_key) { int regex_icase = cgdbrc_get_int(CGDBRC_IGNORECASE); if (src_viewer && src_viewer->cur) { int ret = 0; /* Handle setting (mX) and going ('X) to source buffer marks */ if (last_key_pressed == 'm') ret = source_set_mark(src_viewer, key); else if (last_key_pressed == '\'') ret = source_goto_mark(src_viewer, key); if (ret) { /* When m[a-zA-Z] matches, don't let the marker char * be treated as the last key. That would allow the * chars mgg, to set the marker g, and then move to the top * of the file via gg. * CGDB should see those as mg (set a local mark g), and then * an individual g. */ *last_key = 0; if_draw(); return 0; } } switch (key) { case 's': gdb_scroller->in_scroll_mode = 1; if_set_focus(GDB); return 0; case 'i': if_set_focus(GDB); return 0; case ':': /* Set the type of the command the user is typing in the status bar */ sbc_kind = SBC_NORMAL; if_set_focus(CGDB_STATUS_BAR); /* Since the user is about to type in a command, allocate a buffer * in which this command can be stored. */ cur_sbc = ibuf_init(); return 0; case '/': case '?': if (src_viewer->cur) { regex_cur = ibuf_init(); regex_direction_cur = ('/' == key); orig_line_regex = src_viewer->cur->sel_line; sbc_kind = SBC_REGEX; if_set_focus(CGDB_STATUS_BAR); /* Capturing regular expressions */ source_search_regex_init(src_viewer); /* Initialize the function for finding a regex and tell user */ if_draw(); } return 0; case 'n': source_search_regex(src_viewer, ibuf_get(regex_last), 2, regex_direction_last, regex_icase); if_draw(); break; case 'N': source_search_regex(src_viewer, ibuf_get(regex_last), 2, !regex_direction_last, regex_icase); if_draw(); break; case CGDB_KEY_CTRL_T: if (tgdb_tty_new(tgdb) == -1) { /* Error */ } else { if_layout(); } break; case CGDB_KEY_CTRL_W: switch (cur_split_orientation) { case WSO_HORIZONTAL: cur_split_orientation = WSO_VERTICAL; break; case WSO_VERTICAL: cur_split_orientation = WSO_HORIZONTAL; break; } if_layout(); break; case CGDB_KEY_F1: if_display_help(); return 0; case CGDB_KEY_F5: /* Issue GDB run command */ tgdb_request_run_debugger_command(tgdb, TGDB_RUN); return 0; case CGDB_KEY_F6: /* Issue GDB continue command */ tgdb_request_run_debugger_command(tgdb, TGDB_CONTINUE); return 0; case CGDB_KEY_F7: /* Issue GDB finish command */ tgdb_request_run_debugger_command(tgdb, TGDB_FINISH); return 0; case CGDB_KEY_F8: /* Issue GDB next command */ tgdb_request_run_debugger_command(tgdb, TGDB_NEXT); case CGDB_KEY_F10: /* Issue GDB step command */ tgdb_request_run_debugger_command(tgdb, TGDB_STEP); return 0; case CGDB_KEY_CTRL_L: if_layout(); return 0; } source_input(src_viewer, key); return 0; }