int command_parse_syntax(int param) { /* This is something like: :syntax :syntax on :syntax off */ int rv = 1; switch ((rv = yylex())) { case EOL:{ /* TODO: Print out syntax info (like vim?) */ } break; case BOOLEAN: case IDENTIFIER:{ extern int sources_syntax_on; const char *value = get_token(); if (strcasecmp(value, "on") == 0 || strcasecmp(value, "yes") == 0) sources_syntax_on = 1; else if (strcasecmp(value, "no") == 0 || strcasecmp(value, "off") == 0) sources_syntax_on = 0; if_draw(); } break; default: break; } return 0; }
int command_parse_string( const char *buffer ) { typedef struct yy_buffer_state* YY_BUFFER_STATE; extern YY_BUFFER_STATE yy_scan_string( const char *yy_str ); extern void yy_delete_buffer( YY_BUFFER_STATE state ); int rv = 1; YY_BUFFER_STATE state = yy_scan_string( (char*)buffer ); switch ( yylex() ) { case SET: /* get the next token */ rv = command_parse_set(); break; case UNSET: case BIND: case MACRO: /* ignore this stuff for now. */ rv = 1; break; case NUMBER: { const char *number = get_token(); if ( number[0] == '+' ) { source_vscroll( if_get_sview(), atoi( number+1 )); rv = 0; } else if ( number[0] == '-' ) { source_vscroll( if_get_sview(), -atoi( number+1 )); rv = 0; } else { source_set_sel_line(if_get_sview(), atoi( number )); rv = 0; } if_draw(); } break; case IDENTIFIER: { COMMANDS *command = get_command( get_token() ); if ( command ) { command->action(command->param); rv = 0; } else { rv = 1; } } break; case EOL: /* basically just an empty line, don't do nothin. */ rv = 0; break; default: rv = 1; break; } yy_delete_buffer( state ); return rv; }
/* gdb_input: Handles user input to the GDB window. * ---------- * * key: Keystroke received. * * Return Value: 0 if internal key was used, * 1 if input to gdb or ... * -1 : Error resizing terminal -- terminal too small */ static int gdb_input(int key) { /* Handle special keys */ switch (key) { case CGDB_KEY_PPAGE: scr_up(gdb_win, get_gdb_height() - 1); break; case CGDB_KEY_NPAGE: scr_down(gdb_win, get_gdb_height() - 1); break; case CGDB_KEY_F11: scr_home(gdb_win); break; case CGDB_KEY_F12: scr_end(gdb_win); break; #if 0 /* I would like to add better support for control-l in the GDB * window, but this patch didn't make me happy enough to release it. * The problem is, when it clears the screen, it adds a lot of * whitespace in the buffer. If you hit page-up to look back in * the buffer, it's visible. This is really unacceptable. * * The approach I believe I would like to take with this, is to * have the GDB window behave more like the terminal. That is, * have GDB start at the top line, and move down as input * becomes available. Then, when you hit ctrl-l, you just move * the prompt to the top line. */ case CGDB_KEY_CTRL_L: { int height = get_gdb_height(), i; /* Allocate and print enough newlines to clear the gdb buffer. */ char *buf = (char *) cgdb_malloc(sizeof (char *) * height); for (i = 0; i < height - 1; ++i) { buf[i] = '\n'; } buf[i] = '\0'; if_print(buf); free(buf); /* Sneaky return 1 here. Basically, this allows tricks readline to think * that gdb did not handle the Ctrl-l. That way readline will also handle * it. Because readline uses TERM=dumb, that means that it will clear a * single line and put out the prompt. */ return 1; break; } #endif default: return 1; } if_draw(); return 0; }
/* if_layout: Update the layout of the screen based on current terminal size. * ---------- * * Return Value: Zero on success, non-zero on failure. */ static int if_layout() { /* Verify the window size is reasonable */ validate_window_sizes(); /* Initialize the GDB I/O window */ if (gdb_win == NULL) { gdb_win = scr_new(get_gdb_row(), get_gdb_col(), get_gdb_height(), get_gdb_width()); if (gdb_win == NULL) return 2; } else { /* Resize the GDB I/O window */ if (get_gdb_height() > 0) scr_move(gdb_win, get_gdb_row(), get_gdb_col(), get_gdb_height(), get_gdb_width()); } /* Initialize TTY I/O window */ if (tty_win == NULL) { tty_win = scr_new(get_tty_row(), get_tty_col(), get_tty_height(), get_tty_width()); if (tty_win == NULL) return 2; } else { /* Resize the GDB I/O window */ if (get_tty_height() > 0) scr_move(tty_win, get_tty_row(), get_tty_col(), get_tty_height(), get_tty_width()); } /* Initialize the source viewer window */ if (src_win == NULL) { src_win = source_new(get_src_row(), get_src_col(), get_src_height(), get_src_width()); if (src_win == NULL) return 3; } else { /* Resize the source viewer window */ if (get_src_height() > 0) source_move(src_win, get_src_row(), get_src_col(), get_src_height(), get_src_width()); } /* Initialize the status bar window */ status_win = newwin(get_src_status_height(), get_src_status_width(), get_src_status_row(), get_src_status_col()); /* Initialize the tty status bar window */ if (tty_win_on) tty_status_win = newwin(get_tty_status_height(), get_tty_status_width(), get_tty_status_row(), get_tty_status_col()); if_draw(); return 0; }
void if_highlight_sviewer(enum tokenizer_language_support l) { /* src_win->cur is NULL when reading cgdbrc */ if (src_win->cur) { src_win->cur->language = l; highlight(src_win->cur); if_draw(); } }
static void if_run_command(struct sviewer *sview, struct ibuf *ibuf_command) { char *command = ibuf_get(ibuf_command); /* refresh and return if the user entered no data */ if (ibuf_length(ibuf_command) == 0) { if_draw(); return; } if (command_parse_string(command)) { if_display_message("Unknown command: ", 0, "%s", command); } else { update_status_win(); } if_draw(); }
void if_highlight_sviewer(enum tokenizer_language_support l) { /* src_viewer->cur is NULL when reading cgdbrc */ if (src_viewer && src_viewer->cur) { if ( l == TOKENIZER_LANGUAGE_UNKNOWN ) l = tokenizer_get_default_file_type(strrchr(src_viewer->cur->path, '.')); src_viewer->cur->language = l; source_highlight(src_viewer->cur); if_draw(); } }
void if_display_help(void) { char cgdb_help_file[MAXLINE]; int ret_val = 0; fs_util_get_path(PKGDATADIR, "cgdb.txt", cgdb_help_file); ret_val = source_set_exec_line(src_win, cgdb_help_file, 1); if (ret_val == 0) if_draw(); else if (ret_val == 5) /* File does not exist */ if_display_message("No such file: %s", 0, cgdb_help_file); }
void if_set_focus(Focus f) { switch (f) { case GDB: focus = f; if_draw(); break; case CGDB: focus = f; if_draw(); break; case FILE_DLG: focus = f; if_draw(); break; case CGDB_STATUS_BAR: focus = f; if_draw(); default: return; } }
int command_do_disassemble(int param) { int ret; struct sviewer *sview = if_get_sview(); ret = source_set_exec_addr(sview, 0); if (!ret) { if_draw(); } else if (sview->addr_frame) { /* No disasm found - request it */ tgdb_request_disassemble_func(tgdb, DISASSEMBLE_FUNC_SOURCE_LINES); } return 0; }
/** * Runs a command in the shell. The shell may be interactive, and CGDB * will be paused for the duration of the shell. Any leading stuff, like * 'shell ' or '!' should be removed prior to calling this function. * * \param command The command to run at the shell. Empty string or null * means to invoke an interactive shell. * * \return The exit status of the system() call. */ int run_shell_command(const char *command) { int rv; /* Cleanly scroll the screen up for a prompt */ scrl(1); move(LINES - 1, 0); printf("\n"); /* Put the terminal in cooked mode and turn on echo */ endwin(); tty_set_attributes(STDIN_FILENO, &term_attributes); /* NULL or empty string means invoke user's shell */ if (command == NULL || strlen(command) == 0) { /* Check for SHELL environment variable */ char *shell = getenv("SHELL"); if (shell == NULL) { /* Run /bin/sh instead */ rv = system("/bin/sh"); } else { rv = system(shell); } } else { /* Execute the command passed in via system() */ rv = system(command); } /* Press any key to continue... */ fprintf(stderr, "Hit ENTER to continue..."); while (fgetc(stdin) != '\n') { } /* Turn off echo and put the terminal back into raw mode */ tty_cbreak(STDIN_FILENO, &term_attributes); if_draw(); return rv; }
/* if_layout: Update the layout of the screen based on current terminal size. * ---------- * * Return Value: Zero on success, -1 on failure. */ static int if_layout() { SWINDOW *gdb_scroller_win = NULL; SWINDOW *src_viewer_win = NULL; if (!curses_initialized) return -1; /* Verify the window size is reasonable */ validate_window_sizes(); /* Resize the source viewer window */ create_swindow(&src_viewer_win, get_src_height(), get_src_width(), get_src_row(), get_src_col()); if (src_viewer) { source_move(src_viewer, src_viewer_win); } else { src_viewer = source_new(src_viewer_win); } /* Resize the GDB I/O window */ create_swindow(&gdb_scroller_win, get_gdb_height(), get_gdb_width(), get_gdb_row(), get_gdb_col()); if (gdb_scroller) { scr_move(gdb_scroller, gdb_scroller_win); } else { gdb_scroller = scr_new(gdb_scroller_win); } /* Initialize the status bar window */ create_swindow(&status_win, get_src_status_height(), get_src_status_width(), get_src_status_row(), get_src_status_col()); /* Redraw the interface */ if_draw(); return 0; }
void if_display_help(void) { char cgdb_help_file[FSUTIL_PATH_MAX]; int ret_val = 0; fs_util_get_path(PKGDATADIR, "cgdb.txt", cgdb_help_file); /* File doesn't exist. Try to find cgdb.txt in the build dir in case * the user is running a built cgdb binary directly. */ if (!fs_verify_file_exists(cgdb_help_file)) fs_util_get_path(TOPBUILDDIR, "doc/cgdb.txt", cgdb_help_file); ret_val = source_set_exec_line(src_viewer, cgdb_help_file, 1, 0); if (ret_val == 0) { src_viewer->cur->language = TOKENIZER_LANGUAGE_CGDBHELP; source_highlight(src_viewer->cur); if_draw(); } else if (ret_val == 5) /* File does not exist */ if_display_message("No such file: ", WIN_REFRESH, 0, "%s", cgdb_help_file); }
/* tty_input: Handles user input to the tty I/O window. * ---------- * * key: Keystroke received. * * Return Value: 0 if internal key was used, * 2 if input to tty, * -1 : Error resizing terminal -- terminal too small */ static int tty_input(int key) { /* Handle special keys */ switch (key) { case CGDB_KEY_PPAGE: scr_up(tty_win, get_tty_height() - 1); break; case CGDB_KEY_NPAGE: scr_down(tty_win, get_tty_height() - 1); break; case CGDB_KEY_F11: scr_home(tty_win); break; case CGDB_KEY_F12: scr_end(tty_win); break; default: return 2; } if_draw(); return 0; }
void if_show_file(char *path, int sel_line, int exe_line) { if (source_set_exec_line(src_viewer, path, sel_line, exe_line) == 0) if_draw(); }
/** * 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; }
/* gdb_input: Handles user input to the GDB window. * ---------- * * key: Keystroke received. * * Return Value: 0 if internal key was used, * 1 if input to gdb or ... * -1 : Error resizing terminal -- terminal too small */ static int gdb_input(int key, int *last_key) { int result = 0; if (gdb_scroller->in_search_mode) return gdb_input_regex_input(gdb_scroller, key); if (gdb_scroller->in_scroll_mode) { /* Handle setting (mX) and going ('X) to gdb buffer marks */ if (last_key_pressed == 'm' || last_key_pressed == '\'') { int ret = 0; if (last_key_pressed == 'm') ret = scr_set_mark(gdb_scroller, key); else if(last_key_pressed == '\'') ret = scr_goto_mark(gdb_scroller, key); if (ret) { *last_key = 0; if_draw(); } return 0; } /* In scroll mode, all extra characters are not passed to * the active GDB command. result = 0 above ensures that. */ switch (key) { case 'm': case '\'': /* Mark keys - ignore them */ break; case CGDB_KEY_CTRL_U: scr_up(gdb_scroller, get_gdb_height() / 2); break; case CGDB_KEY_PPAGE: scr_up(gdb_scroller, get_gdb_height() - 1); break; case CGDB_KEY_CTRL_D: scr_down(gdb_scroller, get_gdb_height() / 2); break; case CGDB_KEY_NPAGE: scr_down(gdb_scroller, get_gdb_height() - 1); break; case CGDB_KEY_HOME: case CGDB_KEY_F11: scr_home(gdb_scroller); break; case 'G': case CGDB_KEY_END: case CGDB_KEY_F12: scr_end(gdb_scroller); break; case 'k': case CGDB_KEY_UP: case CGDB_KEY_CTRL_P: scr_up(gdb_scroller, 1); break; case 'j': case CGDB_KEY_DOWN: case CGDB_KEY_CTRL_N: scr_down(gdb_scroller, 1); break; case 'g': if (last_key_pressed == 'g') { scr_home(gdb_scroller); } break; case 'q': case 'i': case '\r': case '\n': case CGDB_KEY_CTRL_M: scr_end(gdb_scroller); gdb_scroller->in_scroll_mode = 0; break; case 'n': scr_search_regex(gdb_scroller, ibuf_get(regex_last), 2, regex_direction_last, cgdbrc_get_int(CGDBRC_IGNORECASE)); break; case 'N': scr_search_regex(gdb_scroller, ibuf_get(regex_last), 2, !regex_direction_last, cgdbrc_get_int(CGDBRC_IGNORECASE)); break; case '/': case '?': /* Capturing regular expressions */ regex_cur = ibuf_init(); regex_direction_cur = ('/' == key); orig_line_regex = gdb_scroller->current.r; sbc_kind = SBC_REGEX; scr_search_regex_init(gdb_scroller); break; } } else { switch (key) { case CGDB_KEY_PPAGE: scr_up(gdb_scroller, get_gdb_height() - 1); break; case CGDB_KEY_CTRL_L: scr_clear(gdb_scroller); /* The return 1 tells readline that gdb did not handle the * Ctrl-l. That way readline will handle it. Because * readline uses TERM=dumb, that means that it will clear * a single line and put out the prompt. */ result = 1; break; default: /* This tells the input to go to active GDB command */ result = 1; } } if_draw(); return result; }
/** * 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; }
void if_show_file(char *path, int line) { if (source_set_exec_line(src_win, path, line) == 0) if_draw(); }
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; }
/* source_input: Handles user input to the source window. * ------------- * * sview: Source viewer object * key: Keystroke received. */ static void source_input(struct sviewer *sview, int key) { static int number_line=0; if ('0' <= key && key <= '9') { number_line=number_line *10 ; number_line=number_line+key-'0'; } else { if (key!='g'){ number_line=0; } switch (key) { case CGDB_KEY_UP: case 'k': /* VI-style up-arrow */ source_vscroll(sview, -1); break; case CGDB_KEY_DOWN: case 'j': /* VI-style down-arrow */ source_vscroll(sview, 1); break; case CGDB_KEY_LEFT: case 'h': source_hscroll(sview, -1); break; case CGDB_KEY_RIGHT: case 'l': source_hscroll(sview, 1); break; case CGDB_KEY_CTRL_U: /* VI-style 1/2 page up */ source_vscroll(sview, -(get_src_height() / 2)); break; case CGDB_KEY_PPAGE: case CGDB_KEY_CTRL_B: /* VI-style page up */ source_vscroll(sview, -(get_src_height() - 1)); break; case CGDB_KEY_CTRL_D: /* VI-style 1/2 page down */ source_vscroll(sview, (get_src_height() / 2)); break; case CGDB_KEY_NPAGE: case CGDB_KEY_CTRL_F: /* VI-style page down */ source_vscroll(sview, get_src_height() - 1); break; case 'g': /* beggining of file */ if (last_key_pressed == 'g') source_set_sel_line(sview, 1); else if (number_line>0) { source_set_sel_line(sview, number_line); last_key_pressed=0; number_line=0; } break; case 'G': /* end of file */ source_set_sel_line(sview, 10000000); break; case '=': /* inc window by 1 */ increase_win_height(0); break; case '-': /* dec window by 1 */ decrease_win_height(0); break; case '+': /* inc to jump or inc tty */ increase_win_height(1); break; case '_': /* dec to jump or dec tty */ decrease_win_height(1); break; case 'o': /* Causes file dialog to be opened */ { extern int kui_input_acceptable; kui_input_acceptable = 0; tgdb_request_ptr request_ptr; request_ptr = tgdb_request_inferiors_source_files(tgdb); handle_request(tgdb, request_ptr); } break; case ' ': { enum tgdb_breakpoint_action t = TGDB_BREAKPOINT_ADD; toggle_breakpoint(sview, t); } break; case 't': { enum tgdb_breakpoint_action t = TGDB_TBREAKPOINT_ADD; toggle_breakpoint(sview, t); } break; default: break; } } /* Some extended features that are set by :set sc */ if_draw(); }
/* source_input: Handles user input to the source window. * ------------- * * sview: Source viewer object * key: Keystroke received. */ static void source_input(struct sviewer *sview, int key) { switch (key) { case CGDB_KEY_UP: case 'k': { /* VI-style up-arrow */ int lineno = 1; cgdb_string_to_int(ibuf_get(G_line_number), &lineno); source_vscroll(sview, -lineno); break; } case CGDB_KEY_DOWN: case 'j': { /* VI-style down-arrow */ int lineno = 1; cgdb_string_to_int(ibuf_get(G_line_number), &lineno); source_vscroll(sview, lineno); break; } case CGDB_KEY_LEFT: case 'h': source_hscroll(sview, -1); break; case CGDB_KEY_RIGHT: case 'l': source_hscroll(sview, 1); break; case CGDB_KEY_CTRL_U: /* VI-style 1/2 page up */ source_vscroll(sview, -(get_src_height() / 2)); break; case CGDB_KEY_PPAGE: case CGDB_KEY_CTRL_B: /* VI-style page up */ source_vscroll(sview, -(get_src_height() - 1)); break; case CGDB_KEY_CTRL_D: /* VI-style 1/2 page down */ source_vscroll(sview, (get_src_height() / 2)); break; case CGDB_KEY_NPAGE: case CGDB_KEY_CTRL_F: /* VI-style page down */ source_vscroll(sview, get_src_height() - 1); break; case 'g': /* beginning of file */ if (last_key_pressed == 'g') source_set_sel_line(sview, 1); break; case 'G': { /* end of file or a line number */ int lineno = -1; cgdb_string_to_int(ibuf_get(G_line_number), &lineno); source_set_sel_line(sview, lineno); break; } case '=': /* inc window by 1 */ increase_win_height(0); break; case '-': /* dec window by 1 */ decrease_win_height(0); break; case '+': increase_win_height(1); break; case '_': decrease_win_height(1); break; case 'o': /* Causes file dialog to be opened */ { extern int kui_input_acceptable; kui_input_acceptable = 0; tgdb_request_inferiors_source_files(tgdb); } break; case ' ': { enum tgdb_breakpoint_action t = TGDB_BREAKPOINT_ADD; toggle_breakpoint(sview, t); } break; case 't': { enum tgdb_breakpoint_action t = TGDB_TBREAKPOINT_ADD; toggle_breakpoint(sview, t); } break; default: break; } /* Store digits into G_line_number for 'G' command. */ if (key >= '0' && key <= '9') { ibuf_addchar(G_line_number, key); } else { ibuf_clear(G_line_number); } /* Some extended features that are set by :set sc */ if_draw(); }