int execute_builtin(cmd_t* cmd, job_list_t* jobs, history_t* hist) { // List jobs. if (strcmp(cmd->args[0], "jobs") == 0) { add_to_history(hist, cmd); return builtin_jobs(jobs); } // List history. if (strcmp(cmd->args[0], "history") == 0) { int exit_code = builtin_history(hist); add_to_history(hist, cmd); return exit_code; } // Exit. if (strcmp(cmd->args[0], "exit") == 0) { return builtin_exit(); } // Change directory. if (strcmp(cmd->args[0], "cd") == 0) { int exit_code = builtin_cd(cmd); if (exit_code == 0) { add_to_history(hist, cmd); } return exit_code; } // Print working directory. if (strcmp(cmd->args[0], "pwd") == 0) { add_to_history(hist, cmd); return builtin_pwd(); } // Bring to foreground. if (strcmp(cmd->args[0], "fg") == 0) { int exit_code = builtin_fg(cmd, jobs); if (exit_code == 0) { add_to_history(hist, cmd); } return exit_code; } // Execute from history. char* endptr = NULL; long num = strtol(cmd->args[0], &endptr, 10); if (*endptr == '\0' && !(num == 0 && errno == EINVAL)) { // Do not save to history to avoid confusion. int exit_code = builtin_exec_from_history(cmd, jobs, hist); freecmd(cmd); return exit_code; } // Command not found. return COMMAND_NOT_FOUND; }
static char *get_history_next(char *str) { add_to_history(str, hist_ind); if (current_hist_ind > hist_ind) hist_ind++; else printf("%c", BELL_KEY); return(History[hist_ind]); }
void pa_smoother_put(pa_smoother *s, pa_usec_t x, pa_usec_t y) { pa_usec_t ney; double nde; pa_assert(s); pa_assert(x >= s->time_offset); /* Fix up x value */ if (s->paused) x = s->pause_time; pa_assert(x >= s->time_offset); x -= s->time_offset; pa_assert(x >= s->ex); /* First, we calculate the position we'd estimate for x, so that * we can adjust our position smoothly from this one */ estimate(s, x, &ney, &nde); s->ex = x; s->ey = ney; s->de = nde; /* Then, we add the new measurement to our history */ add_to_history(s, x, y); /* And determine the average gradient of the history */ s->dp = avg_gradient(s, x); /* And calculate when we want to be on track again */ s->px = x + s->adjust_time; s->py = y + s->dp *s->adjust_time; s->abc_valid = FALSE; }
/** If @a loaded_in_frame is set, this was called just to indicate a move inside * a frameset, and we basically just reset the appropriate frame's view_state in * that case. When clicking on a link inside a frame, the frame URI is somehow * updated and added to the files-to-load queue, then ses_forward() is called * with @a loaded_in_frame unset, duplicating the whole frameset's location, * then later the file-to-load callback calls it for the particular frame with * @a loaded_in_frame set. */ struct view_state * ses_forward(struct session *ses, int loaded_in_frame) { struct location *loc = NULL; struct view_state *vs; if (!loaded_in_frame) { free_files(ses); mem_free_set(&ses->search_word, NULL); } x: if (!loaded_in_frame) { loc = mem_calloc(1, sizeof(*loc)); if (!loc) return NULL; copy_struct(&loc->download, &ses->loading); } if (ses->task.target.frame && *ses->task.target.frame) { struct frame *frame; assertm(have_location(ses), "no location yet"); if_assert_failed return NULL; if (!loaded_in_frame) { copy_location(loc, cur_loc(ses)); add_to_history(&ses->history, loc); } frame = ses_find_frame(ses, ses->task.target.frame); if (!frame) { if (!loaded_in_frame) { del_from_history(&ses->history, loc); destroy_location(loc); } mem_free_set(&ses->task.target.frame, NULL); goto x; } vs = &frame->vs; if (!loaded_in_frame) { destroy_vs(vs, 1); init_vs(vs, ses->loading_uri, vs->plain); } else { done_uri(vs->uri); vs->uri = get_uri_reference(ses->loading_uri); if (vs->doc_view) { /* vs->doc_view itself will get detached in * render_document_frames(), but that's too * late for us. */ vs->doc_view->vs = NULL; vs->doc_view = NULL; } #ifdef CONFIG_ECMASCRIPT vs->ecmascript_fragile = 1; #endif } } else {
static void sol_data_ready(int fd, void *cb_data) { ipmi_sol_t *sol = cb_data; soldata_t *sd = sol->soldata; int rv; struct timeval tv; unsigned char buf[128]; unsigned int readsize = sizeof(buf); if (!sd->history && (readsize > (sizeof(sd->outbuf) - sd->outlen))) readsize = sizeof(sd->outbuf) - sd->outlen; rv = read(fd, buf, readsize); if (rv < 0) { sd->logchan->log(sd->logchan, OS_ERROR, NULL, "Error reading from serial port: %d, disabling\n", errno); sol_port_error(sol); return; } else if (rv == 0) { /* End of input, socket probably closed. */ sol_port_error(sol); return; } if (sol->do_telnet) rv = sol_handle_telnet(sol, buf, rv); add_to_history(sol, buf, rv); if (((unsigned int) rv) > (sizeof(sd->outbuf) - sd->outlen)) { /* Overflow happened. */ rv = sizeof(sd->outbuf) - sd->outlen; } if (!sol->active) { sd->outlen = 0; return; } memcpy(sd->outbuf + sd->outlen, buf, rv); sd->outlen += rv; /* Looks strange, but will turn off read if the buffer is full */ set_read_enable(sd); if (!sd->waiting_ack) { send_data(sol, 0); sd->num_sends = 0; tv.tv_sec = 1; tv.tv_usec = 0; sd->sys->start_timer(sd->timer, &tv); } }
static char *get_history_prev(char *str) { add_to_history(str, hist_ind); hist_ind--; if (hist_ind < 0) { hist_ind = 0; printf("%c", BELL_KEY); }; return(History[hist_ind]); }
/* void new_window_cb(GtkMozEmbed *embed, GtkMozEmbed **newEmbed, guint chromemask, MinimoBrowser *browser) { // open_new_tab_cb (NULL, browser); // gtk_moz_embed_load_url(GTK_MOZ_EMBED(browser->mozEmbed), gMinimoLinkMessageURL ); // show_hide_tabs_cb (NULL, browser); MinimoBrowser *newBrowser = new_gtk_browser(chromemask); gtk_widget_set_usize(newBrowser->mozEmbed, 240, 320); *newEmbed = GTK_MOZ_EMBED(newBrowser->mozEmbed); } */ void location_changed_cb(GtkMozEmbed *embed, GtkLabel* label) { char *newLocation; newLocation = gtk_moz_embed_get_location(embed); if (newLocation) { gtk_label_set_text(label, newLocation); add_to_history(newLocation); g_free(newLocation); } }
/** * Main and Execute Commands */ int main(int argc, char* argv[]) { char input_buffer[COMMAND_LENGTH]; char *tokens[NUM_TOKENS]; char currentDir[COMMAND_LENGTH]; struct sigaction handler; handler.sa_handler = handle_SIGINT; sigaction(SIGINT, &handler, NULL); while (true) { getcwd(currentDir, sizeof(currentDir)); // Use write because we need to use read() to work with // signals, and read() is incompatible with printf(). write(STDOUT_FILENO, currentDir, strlen(currentDir)); write(STDOUT_FILENO, ">", strlen(">")); _Bool in_background = false; int token_count = 0; char *bufCopy = read_command(input_buffer, tokens, &in_background, &token_count); // Cmd was invalid, or it was part of the Ctr+C signal. // Nothing was copied, and therefore there is nothing to be run. if (bufCopy == NULL) { continue; } int handledInline = handle_inline_commands(tokens, bufCopy, input_buffer, &in_background); // Cmd was handled by the inline command handler. if (handledInline != 0) { continue; } pid_t pid = fork(); handle_fork(pid, in_background, tokens); add_to_history(bufCopy); // Cleanup any previously exited background child processes // (The zombies) while (waitpid(-1, NULL, WNOHANG) > 0); } return 0; }
void process_phrase(char *action, char *word, bool add_to_hist){ /* Add to history */ if(add_to_hist){ int errnum; errnum = add_to_history(word, hist_fname); } /* Look up and call the function */ func_symbol = scm_c_lookup(action); func = scm_variable_ref(func_symbol); ret_val = scm_call_1(func, scm_from_locale_string(word)); /* TODO: process output based on the result of the Scheme function */ /* SCM is_list = scm_list_p (ret_val); */ /* Print the output */ print_scheme_list(ret_val); }
static int checkinputs(char input, char *buff, char **ptr, t_history *history) { if (input == '\n') { if (history) add_to_history(buff, history); mvcright(ft_strlen(*ptr)); return (1); } else if (input == 4) { if (buff[0] == '\0') return (-1); return (0); } checkinputs_splitted(input, buff, ptr, history); return (2); }
void pa_smoother_put(pa_smoother *s, uint64_t x, uint64_t y) { uint64_t ney; double nde; bool is_new; pa_assert(s); /* Fix up x value */ if (s->paused) x = s->pause_time; x = PA_LIKELY(x >= s->time_offset) ? x - s->time_offset : 0; is_new = x >= s->ex; if (is_new) { /* First, we calculate the position we'd estimate for x, so that * we can adjust our position smoothly from this one */ estimate(s, x, &ney, &nde); s->ex = x; s->ey = ney; s->de = nde; s->ry = y; } /* Then, we add the new measurement to our history */ add_to_history(s, x, y); /* And determine the average gradient of the history */ s->dp = avg_gradient(s, x); /* And calculate when we want to be on track again */ if (s->smoothing) { s->px = s->ex + s->adjust_time; s->py = s->ry + (uint64_t) llrint(s->dp * (double) s->adjust_time); } else { s->px = s->ex; s->py = s->ry; } s->abc_valid = false; #ifdef DEBUG_DATA pa_log_debug("%p, put(%llu | %llu) = %llu", s, (unsigned long long) (x + s->time_offset), (unsigned long long) x, (unsigned long long) y); #endif }
void GLUI_CommandLine::deactivate( void ) { // if the commit_flag is set, add the current command to // history and call deactivate as normal // Trick deactivate into calling callback if and only if commit_flag set. // A bit subtle, but deactivate checks that orig_text and text // are the same to decide whether or not to call the callback. // Force them to be different for commit, and the same for no commit. if (commit_flag) { add_to_history(text.c_str()); orig_text = ""; Super::deactivate( ); set_text( "" ); commit_flag = false; } else { orig_text = text; } }
static BINDING_FUNCTION(binding_toggle_input) { if (input_size == 1) { input_size = MULTILINE_INPUT_SIZE; ncurses_input_update(line_index); } else { string_t s = string_init(("")); char *p, *tmp; int i; for (i = 0; lines[i]; i++) { char *tmp; string_append(s, (tmp = wcs_to_normal(lines[i]))); free_utf(tmp); if (lines[i + 1]) string_append(s, ("\r\n")); } tmp = string_free(s, 0); add_to_history(); input_size = 1; ncurses_input_update(0); for (p=tmp; *p && isspace(*p); p++); if (*p || config_send_white_lines) command_exec(window_current->target, window_current->session, tmp, 0); if (!tmp[0] || tmp[0] == '/' || !window_current->target) ncurses_typing_mod = 1; else { ncurses_typing_win = NULL; window_current->out_active = 1; } curs_set(1); xfree(tmp); } }
int main(void) { int exec_ret; while (1) { fputs("$", stdout); input = read_input(); if (input == NULL) { /* user entered ctrl+D, exit gracefully */ cleanup_and_exit(EXIT_SUCCESS); } if (strlen(input) > 0 && !is_blank(input) && input[0] != '|') { char *linecopy = strdup(input); struct commands *commands = parse_commands_with_pipes(input); /* add pipeline cmds & other commands to history */ if (commands->cmd_count > 1 || !is_history(input)) add_to_history(linecopy); free(linecopy); exec_ret = exec_commands(commands); cleanup_commands(commands); } free(input); /* get ready to exit */ if (exec_ret == -1) break; } cleanup_and_exit(EXIT_SUCCESS); return 0; }
int readline(char *buf, int size) { int idx; int len; int key; int i; int done; int hist_idx; int dir; if (size <= 0) { errno = EINVAL; return -1; } idx = 0; len = 0; done = 0; hist_idx = history_len; while (!done) { fflush(stdout); key = getkey(); if (key < 0) return key; if (key == KEY_TAB) { int start; int end; int split; char mask[MAXPATH]; struct direntry dirent; start = idx; while (start > 0 && !delimchar(buf[start - 1])) start--; end = split = start; while (end < len && !delimchar(buf[end])) { if (buf[end] == PS1 || buf[end] == PS2) split = end + 1; end++; } dir = find_dir(buf, start, end, split, mask); if (dir >= 0) { while (_readdir(dir, &dirent, 1) > 0) { int newlen = len - (end - split) + dirent.namelen; if (like(dirent.name, mask) && newlen < size - 1) { memmove(buf + split + dirent.namelen, buf + end, len - end); memcpy(buf + split, dirent.name, dirent.namelen); while (idx < split) putchar(buf[idx++]); while (idx > split) { putchar('\b'); idx--; } for (i = split; i < newlen; i++) putchar(buf[i]); if (newlen < len) { for (i = newlen; i < len; i++) putchar(' '); for (i = newlen; i < len; i++) putchar('\b'); } end = split + dirent.namelen; len = newlen; idx = end; for (i = end; i < len; i++) putchar('\b'); fflush(stdout); key = getkey(); if (key < 0) break; if (key != KEY_TAB) break; } } close(dir); if (key < 0) return key; } } switch (key) { case KEY_LEFT: if (idx > 0) { putchar('\b'); idx--; } break; case KEY_RIGHT: if (idx < len) { putchar(buf[idx]); idx++; } break; case KEY_CTRL_LEFT: if (idx > 0) { putchar('\b'); idx--; } while (idx > 0 && buf[idx - 1] != ' ') { putchar('\b'); idx--; } break; case KEY_CTRL_RIGHT: while (idx < len && buf[idx] != ' ') { putchar(buf[idx]); idx++; } if (idx < len) { putchar(buf[idx]); idx++; } break; case KEY_HOME: while (idx > 0) { putchar('\b'); idx--; } break; case KEY_END: while (idx < len) { putchar(buf[idx]); idx++; } break; case KEY_DEL: if (idx < len) { len--; memmove(buf + idx, buf + idx + 1, len - idx); for (i = idx; i < len; i++) putchar(buf[i]); putchar(' '); putchar('\b'); for (i = idx; i < len; i++) putchar('\b'); } break; case KEY_INS: insmode = !insmode; break; case KEY_BACKSPACE: if (idx > 0) { putchar('\b'); idx--; len--; memmove(buf + idx, buf + idx + 1, len - idx); for (i = idx; i < len; i++) putchar(buf[i]); putchar(' '); putchar('\b'); for (i = idx; i < len; i++) putchar('\b'); } break; case KEY_ESC: if (_break_on_escape) { buf[len] = 0; errno = EINTR; return -1; } else { for (i = 0; i < idx; i++) putchar('\b'); for (i = 0; i < len; i++) putchar(' '); for (i = 0; i < len; i++) putchar('\b'); idx = len = 0; } break; case KEY_EOF: if (len == 0) return -1; break; case KEY_ENTER: putchar('\r'); putchar('\n'); done = 1; break; case KEY_UP: if (hist_idx > 0) { hist_idx--; for (i = 0; i < idx; i++) putchar('\b'); for (i = 0; i < len; i++) putchar(' '); for (i = 0; i < len; i++) putchar('\b'); len = strlen(history[hist_idx]); if (len > size - 1) len = size - 1; idx = len; memcpy(buf, history[hist_idx], len); for (i = 0; i < len; i++) putchar(buf[i]); } break; case KEY_DOWN: if (hist_idx < history_len - 1) { hist_idx++; for (i = 0; i < idx; i++) putchar('\b'); for (i = 0; i < len; i++) putchar(' '); for (i = 0; i < len; i++) putchar('\b'); len = strlen(history[hist_idx]); if (len > size - 1) len = size - 1; idx = len; memcpy(buf, history[hist_idx], len); for (i = 0; i < len; i++) putchar(buf[i]); } break; case KEY_UNKNOWN: break; default: if (key >= 0x20 && key <= 0xFF) { if (insmode) { if (len < size - 1) { if (idx < len) memmove(buf + idx + 1, buf + idx, len - idx); buf[idx] = key; len++; for (i = idx; i < len; i++) putchar(buf[i]); idx++; for (i = idx; i < len; i++) putchar('\b'); } } else { if (idx < size - 1) { buf[idx] = key; putchar(buf[idx]); if (idx == len) len++; idx++; } } } } } buf[len] = 0; add_to_history(buf); return len; }
static BINDING_FUNCTION(binding_accept_line) { char *p, *txt; if (ncurses_noecho) { /* we are running ui-password-input */ ncurses_noecho = 0; ncurses_passbuf = xwcsdup(line); line[0] = 0; line_adjust(); return; } if (lines) { int i; lines = xrealloc(lines, (array_count((char **) lines) + 2) * sizeof(CHAR_T *)); for (i = array_count((char **) lines); i > lines_index; i--) lines[i + 1] = lines[i]; lines[lines_index + 1] = xmalloc(LINE_MAXLEN*sizeof(CHAR_T)); xwcscpy(lines[lines_index + 1], line + line_index); line[line_index] = 0; line_index = 0; line_start = 0; lines_index++; lines_adjust(); return; } if (arg != BINDING_HISTORY_NOEXEC) { txt = wcs_to_normal(line); for (p=txt; *p && isspace(*p); p++); if (*p || config_send_white_lines) command_exec(window_current->target, window_current->session, txt, 0); free_utf(txt); } if (ncurses_plugin_destroyed) return; if (!line[0] || line[0] == '/' || !window_current->target) /* if empty or command, just mark as modified */ ncurses_typing_mod = 1; else { /* if message, assume that its' handler has already disabled <composing/> */ ncurses_typing_win = NULL; window_current->out_active = 1; /* but also remember that it should have set <active/> chatstate */ } if (xwcscmp(line, TEXT(""))) { if (config_history_savedups || xwcscmp(line, history[1])) add_to_history(); } else { if (config_enter_scrolls) print("none", ""); } history[0] = line; history_index = 0; *line = 0; line_adjust(); }
/* shove_to_history: a key binding that saves the current line into * the history and then deletes the whole line. Useful for when you * are in the middle of a big line and need to "get out" to do something * else quick for just a second, and you dont want to have to retype * everything all over again */ extern void shove_to_history(char unused, char *not_used) { add_to_history(get_input()); input_clear_line(unused, not_used); }
const std::string &string_input_popup::query_string( const bool loop, const bool draw_only ) { if( !w ) { create_window(); } if( !ctxt ) { create_context(); } utf8_wrapper ret( _text ); utf8_wrapper edit( ctxt->get_edittext() ); if( _position == -1 ) { _position = ret.length(); } const int scrmax = _endx - _startx; // in output (console) cells, not characters of the string! int shift = 0; bool redraw = true; int ch = 0; do { if( _position < 0 ) { _position = 0; } const size_t left_shift = ret.substr( 0, _position ).display_width(); if( ( int )left_shift < shift ) { shift = 0; } else if( _position < ( int )ret.length() && ( int )left_shift + 1 >= shift + scrmax ) { // if the cursor is inside the input string, keep one cell right of // the cursor visible, because the cursor might be on a multi-cell // character. shift = left_shift - scrmax + 2; } else if( _position == ( int )ret.length() && ( int )left_shift >= shift + scrmax ) { // cursor is behind the end of the input string, keep the // trailing '_' visible (always a single cell character) shift = left_shift - scrmax + 1; } else if( shift < 0 ) { shift = 0; } const size_t xleft_shift = ret.substr_display( 0, shift ).display_width(); if( ( int )xleft_shift != shift ) { // This prevents a multi-cell character from been split, which is not possible // instead scroll a cell further to make that character disappear completely shift++; } if( redraw ) { redraw = false; draw( ret, edit, shift ); wrefresh( w ); } wrefresh( w ); if( draw_only ) { return _text; } const std::string action = ctxt->handle_input(); const input_event ev = ctxt->get_raw_input(); ch = ev.type == CATA_INPUT_KEYBOARD ? ev.get_first_input() : 0; if( callbacks[ch] ) { if( callbacks[ch]() ) { continue; } } // This class only registers the ANY_INPUT action by default. If the // client provides their own input_context with registered actions // besides ANY_INPUT, ignore those so that the client may handle them. if( action != "ANY_INPUT" ) { continue; } if( ch == KEY_ESCAPE ) { _text.clear(); _canceled = true; return _text; } else if( ch == '\n' ) { add_to_history( ret.str() ); _text = ret.str(); return _text; } else if( ch == KEY_UP ) { show_history( ret ); redraw = true; } else if( ch == KEY_DOWN || ch == KEY_NPAGE || ch == KEY_PPAGE || ch == KEY_BTAB || ch == 9 ) { /* absolutely nothing */ } else if( ch == KEY_RIGHT ) { if( _position + 1 <= ( int )ret.size() ) { _position++; } redraw = true; } else if( ch == KEY_LEFT ) { if( _position > 0 ) { _position--; } redraw = true; } else if( ch == 0x15 ) { // ctrl-u: delete all the things _position = 0; ret.erase( 0 ); redraw = true; // Move the cursor back and re-draw it } else if( ch == KEY_BACKSPACE ) { // but silently drop input if we're at 0, instead of adding '^' if( _position > 0 && _position <= ( int )ret.size() ) { //TODO: it is safe now since you only input ASCII chars _position--; ret.erase( _position, 1 ); redraw = true; } } else if( ch == KEY_HOME ) { _position = 0; redraw = true; } else if( ch == KEY_END ) { _position = ret.size(); redraw = true; } else if( ch == KEY_DC ) { if( _position < ( int )ret.size() ) { ret.erase( _position, 1 ); redraw = true; } } else if( ch == KEY_F( 2 ) ) { std::string tmp = get_input_string_from_file(); int tmplen = utf8_width( tmp ); if( tmplen > 0 && ( tmplen + utf8_width( ret.c_str() ) <= _max_length || _max_length == 0 ) ) { ret.append( tmp ); } } else if( !ev.text.empty() && _only_digits && !( isdigit( ev.text[0] ) || ev.text[0] == '-' ) ) { // ignore non-digit (and '-' is a digit as well) } else if( _max_length > 0 && ( int )ret.length() >= _max_length ) { // no further input possible, ignore key } else if( !ev.text.empty() ) { const utf8_wrapper t( ev.text ); ret.insert( _position, t ); _position += t.length(); edit.erase( 0 ); ctxt->set_edittext( edit.c_str() ); redraw = true; } else if( ev.edit_refresh ) { const utf8_wrapper t( ev.edit ); edit.erase( 0 ); edit.insert( 0, t ); ctxt->set_edittext( edit.c_str() ); redraw = true; } else if( ev.edit.empty() ) { edit.erase( 0 ); ctxt->set_edittext( edit.c_str() ); redraw = true; } } while( loop == true ); _text = ret.str(); return _text; }
void read_input(int mode, char *batch_path) { char c; int current_length = (BUFFER_SIZE + 1); line = (char *) malloc(sizeof(char) * (BUFFER_SIZE + 1)); char *path = (char *) malloc(sizeof(char) * (BUFFER_SIZE + 1)); fflush(stderr); printf("\n[SHELL ] "); fflush(stdout); int run = 1, len = 0; if (mode == BATCH) { if (open(batch_path, O_RDONLY) > 0) { batch_file = fopen(batch_path, "r"); } else { fprintf(stderr, "cann't open or read the file\n"); return; } } while (c != EOF && run) { if (mode == INTERACTIVE) c = getchar(); else { c = fgetc(batch_file); if (feof(stdin)) { run = 0; break; } } switch (c) { case '\n': if (line[0] == '\0') { len = 0; free_args(); bzero(line, current_length); fflush(stderr); printf("\n[SHELL ] "); fflush(stdout); } else { if (mode == BATCH) { printf("%s\n", line); } if (len >= BUFFER_SIZE) { fprintf(stderr, "buffer limit excited\n"); bzero(line, current_length); len = 0; continue; } add_to_history(line); free_args(); fill_argv(line); if (is_comment(line) == 0) { if (strchr(line, '=') != NULL && strcmp(args[0], "echo") != 0) { assign_var(line); } else { // free_args(); // fill_argv(line); if (strcmp(args[0], "echo") != 0) { int i; for (i = 0; args[i] != NULL; i++) { append_home_dir(args[i]); fix_echo_line(args[i]); } } else { int i; for (i = 1; args[i] != NULL; i++) { fix_echo_line(args[i]); } } if (strcmp("exit", line) == 0) { run = 0; break; } else if (strcmp("history", args[0]) == 0) { execute_history(); } else if (strcmp("cd", args[0]) == 0) cd(); else { strcpy(path, args[0]); if (strchr(path, '/') != NULL) { int fd; if ((fd = open(path, O_RDONLY)) > 0) { close(fd); call_execve(path); } else { fprintf(stderr, "%s: No such file or directory\n", args[0]); } } else { if (!is_command(path)) { fprintf(stderr, "%s: command not found\n", args[0]); } else { call_execve(path); } } } } } free_args(); fflush(stderr); printf("\n[SHELL ] "); fflush(stdout); bzero(line, BUFFER_SIZE); len = 0; } bzero(line, BUFFER_SIZE); break; default: len++; if (len < BUFFER_SIZE) { strncat(line, &c, 1); } break; } } if (mode == BATCH) fclose(batch_file); }
void note_show(ConboyNote *note, gboolean modify_history, gboolean scroll, gboolean select_row) { AppData *app_data = app_data_get(); UserInterface *ui = app_data->note_window; GtkTextBuffer *buffer = ui->buffer; GtkWindow *window = GTK_WINDOW(ui->window); /* Before we switch to a new note, we save the last one if it was modified. */ if (gtk_text_buffer_get_modified(buffer)) { note_save(ui); } /* Add to history */ if (modify_history || app_data->current_element == NULL) { add_to_history(note); } /* Toggle forward/backward buttons */ gtk_action_set_sensitive(ui->action_back, (gboolean) app_data->current_element->prev); gtk_action_set_sensitive(ui->action_forward, (gboolean) app_data->current_element->next); /* Block signals on TextBuffer until we are done with initializing the content. This is to prevent saves etc. */ g_signal_handlers_block_matched(buffer, G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, ui); conboy_note_window_show_note(ui, note); /* Format note title and update window title */ note_format_title(buffer); note_set_window_title_from_buffer(window, buffer); /* Replace this. And use note->title instead */ /* Show widget and set focus to the text view */ gtk_widget_show(GTK_WIDGET(window)); gtk_widget_grab_focus(GTK_WIDGET(ui->view)); while (gtk_events_pending()) { gtk_main_iteration_do(FALSE); } /* Select first row if wanted */ if (select_row) { GtkTextIter start, end; gtk_text_buffer_get_iter_at_line(buffer, &start, 2); end = start; gtk_text_iter_forward_to_line_end(&end); gtk_text_buffer_select_range(buffer, &start, &end); } /* Scroll to cursor position */ if (scroll && !select_row) { GtkTextIter iter; gtk_text_buffer_get_iter_at_offset(buffer, &iter, note->cursor_position); gtk_text_buffer_place_cursor(buffer, &iter); GtkTextMark *mark = gtk_text_buffer_get_insert(buffer); gtk_text_view_scroll_to_mark(ui->view, mark, 0.1, TRUE, 0, 0.5); } /* Set the buffer to unmodified */ gtk_text_buffer_set_modified(buffer, FALSE); /* unblock signals */ g_signal_handlers_unblock_matched(buffer, G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, ui); /* Update active tags */ conboy_note_buffer_update_active_tags(CONBOY_NOTE_BUFFER(buffer)); /* Update the state of the buttons */ conboy_note_window_update_button_states(ui); }
// Send completed lines to GDB void gdbChangeCB(Widget w, XtPointer, XtPointer) { if (private_gdb_output) return; string input = current_line(); bool at_prompt = gdb_input_at_prompt; if (at_prompt) input.gsub("\\\n", ""); int newlines = input.freq('\n'); string *lines = new string[newlines + 1]; split(input, lines, newlines, '\n'); private_gdb_input = true; if (newlines == 0 || (gdb_input_at_prompt && input.contains('\\', -1))) { // No newline found - line is still incomplete set_history_from_line(input, true); } else { // Process entered lines clear_isearch(); promptPosition = XmTextGetLastPosition(w); for (int i = 0; i < newlines; i++) { string cmd = lines[i]; tty_out(cmd + "\n"); if (gdb_input_at_prompt) { if (cmd.matches(rxwhite) || cmd.empty()) { // Empty line: repeat last command cmd = last_command_from_history(); } else { // Add new command to history add_to_history(cmd); } } if (at_prompt) { // We're typing at the GDB prompt: place CMD in command queue gdb_command(cmd, w); } else { // Pass anything else right to GDB, clearing the command queue. clearCommandQueue(); gdb->send_user_ctrl_cmd(cmd + "\n"); } } } private_gdb_input = false; delete[] lines; }
char *get_command_line(int new_cmd, int comp_type) { int c, ind = 0, len = 0, res; char input_buf[READ_BUF_SIZE]; char *str; if (set_term_flags() != 0) exit(1); get_history_new(new_cmd); memset(input_buf, 0, READ_BUF_SIZE); for (;;) { c = getchar(); len = strlen(input_buf); if (len >= (READ_BUF_SIZE - 1)) c = NL_KEY; switch (c) { case CTRL_A_KEY: go_to_begin(ind); ind = print_str_by_index(input_buf, 0, 0); break; case CTRL_B_KEY: printf("%c", '\b'); ind--; if (ind < 0) { ind = 0; printf("%c", ' '); }; break; case CTRL_D_KEY: if (ind == len) break; ind = delete_char(input_buf, len, ind, 1); break; case CTRL_E_KEY: ind = print_str_by_index(input_buf, ind, len); break; case CTRL_G_KEY: case CTRL_L_KEY: printf("%c", c); break; case CTRL_F_KEY: ind = print_str_by_index(input_buf, ind, ind + 1); break; case TAB_KEY: res = completion_func(comp_type, input_buf, &complition_struct); if (res == 0) break; if (res == 1) { strcpy(input_buf, complition_struct.items[0]); strcat(input_buf, " "); ind = print_str_by_index(input_buf, ind, -1); break; }; memset(input_buf, 0, READ_BUF_SIZE); strncpy(input_buf, complition_struct.items[0], complition_struct.comp_len); ind = print_str_by_index(input_buf, ind, -1); break; case NL_KEY: printf("%c", c); if (current_hist_ind != hist_ind) add_to_history(input_buf, hist_ind); if (strlen(input_buf) == 0) return(""); add_to_history(input_buf, current_hist_ind); return(History[current_hist_ind]); case CTRL_K_KEY: clear_line(ind, len); memset(input_buf + ind, 0, len - ind); print_str_by_index(input_buf, 0, ind); break; case CTRL_N_KEY: ungetc(DOWN_KEY, stdin); ungetc(CTRL2_KEY, stdin); ungetc(CTRL1_KEY, stdin); break; case CTRL_R_KEY: case CTRL_S_KEY: res = find_command(input_buf, hist_ind, (c == CTRL_S_KEY)); if (res != hist_ind) { hist_ind = res; memset(input_buf, 0, READ_BUF_SIZE); strcpy(input_buf, History[hist_ind]); }; print_str_by_index(Title, 0, -1); ind = print_str_by_index(input_buf, 0, -1); break; case CTRL1_KEY: c = getchar(); if (c != CTRL2_KEY) break; c = getchar(); switch (c) { case INSERT_KEY: getchar(); is_insert_key = (is_insert_key) ? 0 : 1; break; case DELETE_KEY: getchar(); if (ind == len) break; ind = delete_char(input_buf, len, ind, 1); break; case LEFT_KEY: printf("%c", '\b'); ind--; if (ind < 0) { ind = 0; printf("%c", ' '); }; break; case RIGHT_KEY: ind++; if (ind > len) ind = len; else print_str_by_index(input_buf, ind - 1, ind); break; case UP_KEY: case DOWN_KEY: clear_line(ind, len); if (c == UP_KEY) str = get_history_prev(input_buf); else str = get_history_next(input_buf); memset(input_buf, 0, READ_BUF_SIZE); strcpy(input_buf, str); len = strlen(input_buf); ind = print_str_by_index(input_buf, 0, len); break; case PGUP_KEY: case PGDOWN_KEY: getchar(); add_to_history(input_buf, hist_ind); clear_line(ind, len); hist_ind = (c == PGUP_KEY) ? 0 : current_hist_ind; str = History[hist_ind]; memset(input_buf, 0, READ_BUF_SIZE); strcpy(input_buf, str); len = strlen(input_buf); ind = print_str_by_index(input_buf, 0, len); break; case HOME_KEY: go_to_begin(ind); ind = print_str_by_index(input_buf, 0, 0); break; case END_KEY: ind = print_str_by_index(input_buf, ind, len); break; }; break; case CTRL_H_KEY: case BACKSP_KEY: ind = (ind <= 0) ? 0 : delete_char(input_buf, len, ind, 0); break; default: if (ind == len) { input_buf[ind++] = c; printf("%c", c); break; }; ind = add_char(input_buf, len, c, ind); break; }; if (ind >= (READ_BUF_SIZE - 1)) { if (current_hist_ind != hist_ind) add_to_history(input_buf, hist_ind); add_to_history(input_buf, current_hist_ind); return(History[current_hist_ind]); } }; return((char *)NULL); }
/* * Inserts a buffer either before or after an existing buffer into the queue * Checks for merges of prev/next buffer in the queue */ static void insert_merge_buffer(struct debug_q* que, struct memory_list* region, struct memory_ele* buffer, genoffset_t offset, genoffset_t length) { assert(buffer != NULL); assert(region != NULL); if (offset >= buffer->offset+buffer->length) {// insert after // buffer is on lower boundary // if (buffer->offset+length == offset) { buffer->length += length; DEBUG("dequeue merge after " "offset=%"PRIu64" length=%"PRIu64" to offset=%"PRIu64" " "length=%"PRIu64"\n", offset, length, buffer->offset, buffer->length); // check other boundary for merge if (buffer->next != NULL && (buffer->offset + buffer->length == buffer->next->offset)) { buffer->length += buffer->next->length; struct memory_ele* next = buffer->next; if (buffer->next->next != NULL) { buffer->next = buffer->next->next; buffer->next->next->prev = buffer; } DEBUG("dequeue merge after more offset=%"PRIu64" " "length=%"PRIu64" to offset=%"PRIu64" length=%"PRIu64" \n ", next->offset, next->length, buffer->offset, buffer->length); add_to_history(que, offset, length, "deq insert after" " on lower boundary and merge"); slab_free(&que->alloc, next); } else { add_to_history(que, offset, length, "deq insert after on lower boundary"); } } else { // check higher boundary if (buffer->next != NULL && buffer->next->offset == offset+length) { buffer->next->offset = offset; buffer->next->length += length; DEBUG("dequeue merge after more offset=%"PRIu64" " "length=%"PRIu64" to offset=%"PRIu64" length=%"PRIu64" \n ", offset, length, buffer->next->offset, buffer->next->length); add_to_history(que, offset, length, "deq insert after" " on higer boundary"); } else { // buffer->next can be null and the newly inserted buffer // is the inserted at the end -> check boundary if (buffer->next == NULL && buffer->offset + buffer->length == offset) { buffer->length += length; add_to_history(que, offset, length, "deq insert after" " on higer boundary end"); DEBUG("dequeue insert after merged offset=%"PRIu64" " "length=%"PRIu64" " "to offset=%"PRIu64" length=%"PRIu64" \n", offset, length, buffer->offset, buffer->length); } else { // insert in between struct memory_ele* ele = slab_alloc(&que->alloc); assert(ele != NULL); ele->offset = offset; ele->length = length; ele->next = buffer->next; ele->prev = buffer; if (buffer->next != NULL) { buffer->next->prev = ele; } buffer->next = ele; add_to_history(que, offset, length, "deq insert after" " in between"); DEBUG("dequeue insert after offset=%"PRIu64" length=%"PRIu64" " "after offset=%"PRIu64" length=%"PRIu64" \n", offset, length, buffer->offset, buffer->length); } } } } else { // insert before buffer // buffer is on lower boundary if (buffer->offset == offset+length) { buffer->length += length; buffer->offset = offset; // check other boundary if (buffer->prev != NULL && (buffer->prev->offset+ buffer->prev->length == buffer->offset)) { struct memory_ele* prev = buffer->prev; prev->length += buffer->length; prev->next = buffer->next; if (buffer->next != NULL) { buffer->next->prev = prev; } slab_free(&que->alloc, buffer); add_to_history(que, offset, length, "deq insert buffer" " before lower boundary merge"); DEBUG("dequeue merge before more offset=%"PRIu64" " "length=%"PRIu64" to offset=%"PRIu64" length=%"PRIu64" \n ", offset, length, prev->offset, prev->length); } else { add_to_history(que, offset, length, "deq insert buffer" " before lower boundary"); } } else { // check lower boundary if (buffer->prev != NULL && (buffer->prev->offset+ buffer->prev->length == offset)) { if (length == 0) { printf("Length is 0 \n"); buffer->prev->length += 2048; } buffer->prev->length += length; add_to_history(que, offset, length, "deq insert buffer" " before prev lower boundary merge"); DEBUG("dequeue merge before more offset=%"PRIu64" " "length=%"PRIu64" to offset=%"PRIu64" length=%"PRIu64" \n ", offset, length, buffer->prev->offset, buffer->prev->length); } else { // insert in between // insert in between struct memory_ele* ele = slab_alloc(&que->alloc); assert(ele != NULL); memset(ele, 0, sizeof(ele)); ele->offset = offset; ele->length = length; ele->next = buffer; ele->prev = buffer->prev; if (buffer->prev != NULL) { buffer->prev->next = ele; } else { region->buffers = ele; } buffer->prev = ele; add_to_history(que, offset, length, "deq insert buffer" " before in between"); DEBUG("dequeue insert before offset=%"PRIu64" length=%"PRIu64" " "next is offset=%"PRIu64" length=%"PRIu64" \n", offset, length, buffer->offset, buffer->length); } } } }
char *request(const char *prompt, const char * const default_string, const bool alpha_allowed, const int completion_type, const bool prefer_utf8) { set_attr(0); input_buffer[pos = len = offset = 0] = 0; encoding = ENC_ASCII; x = start_x = print_prompt(prompt); init_history(); if (default_string) { strncpy(input_buffer, default_string, MAX_INPUT_LINE_LEN); len = strlen(input_buffer); encoding = detect_encoding(input_buffer, len); input_refresh(); } bool first_char_typed = true, last_char_completion = false, selection = false; while(true) { assert(input_buffer[len] == 0); move_cursor(ne_lines - 1, x); int c; input_class ic; do c = get_key_code(); while((ic = CHAR_CLASS(c)) == IGNORE); /* ISO 10646 characters *above 256* can be added only to UTF-8 lines, or ASCII lines (making them, of course, UTF-8). */ if (ic == ALPHA && c > 0xFF && encoding != ENC_ASCII && encoding != ENC_UTF8) ic = INVALID; if (ic != TAB) last_char_completion = false; if (ic == TAB && !completion_type) ic = ALPHA; switch(ic) { case INVALID: alert(); break; case ALPHA: if (first_char_typed) { input_buffer[len = 0] = 0; clear_to_eol(); } if (encoding == ENC_ASCII && c > 0x7F) encoding = prefer_utf8 || c > 0xFF ? ENC_UTF8 : ENC_8_BIT; int c_len = encoding == ENC_UTF8 ? utf8seqlen(c) : 1; int c_width = output_width(c); assert(c_len > 0); if (len <= MAX_INPUT_LINE_LEN - c_len && (alpha_allowed || (c < 0x100 && isxdigit(c)) || c=='X' || c=='x')) { memmove(&input_buffer[pos + c_len], &input_buffer[pos], len - pos + 1); if (c_len == 1) input_buffer[pos] = c; else utf8str(c, &input_buffer[pos]); len += c_len; move_cursor(ne_lines - 1, x); if (x < ne_columns - c_width) { if (pos == len - c_len) output_char(c, 0, encoding); else if (char_ins_del_ok) insert_char(c, 0, encoding); else input_refresh(); } input_move_right(true); } break; case RETURN: selection = true; break; case TAB: if (completion_type == COMPLETE_FILE || completion_type == COMPLETE_SYNTAX) { bool quoted = false; char *prefix, *completion, *p; if (len && input_buffer[len - 1] == '"') { input_buffer[len - 1] = 0; if (prefix = strrchr(input_buffer, '"')) { quoted = true; prefix++; } else input_buffer[len - 1] = '"'; } if (!quoted) { prefix = strrchr(input_buffer, ' '); if (prefix) prefix++; else prefix = input_buffer; } if (last_char_completion || completion_type == COMPLETE_SYNTAX) { if (completion_type == COMPLETE_FILE ) completion = p = request_files(prefix, true); else completion = p = request_syntax(prefix, true); reset_window(); if (completion) { if (*completion) selection = true; else completion++; } } else { if (completion_type == COMPLETE_FILE ) completion = p = complete_filename(prefix); else completion = p = request_syntax(prefix, true); last_char_completion = true; if (!completion) alert(); } if (completion && (prefix - input_buffer) + strlen(completion) + 1 < MAX_INPUT_LINE_LEN) { const encoding_type completion_encoding = detect_encoding(completion, strlen(completion)); if (encoding == ENC_ASCII || completion_encoding == ENC_ASCII || encoding == completion_encoding) { strcpy(prefix, completion); if (quoted) strcat(prefix, "\""); len = strlen(input_buffer); pos = offset = 0; x = start_x; if (encoding == ENC_ASCII) encoding = completion_encoding; input_move_to_eol(); if (quoted) input_move_left(false); input_refresh(); } else alert(); } else if (quoted) strcat(prefix, "\""); free(p); } break; case COMMAND: if (c < 0) c = -c - 1; const int a = parse_command_line(key_binding[c], NULL, NULL, false); if (a >= 0) { switch(a) { case LINEUP_A: case LINEDOWN_A: case MOVESOF_A: case MOVEEOF_A: case PAGEUP_A: case PAGEDOWN_A: case NEXTPAGE_A: case PREVPAGE_A: if (history_buff) { switch(a) { case LINEUP_A: line_up(history_buff); break; case LINEDOWN_A: line_down(history_buff); break; case MOVESOF_A: move_to_sof(history_buff); break; case MOVEEOF_A: move_to_bof(history_buff); break; case PAGEUP_A: case PREVPAGE_A: prev_page(history_buff); break; case PAGEDOWN_A: case NEXTPAGE_A: next_page(history_buff); break; } /* In some cases, the default displayed on the command line will be the same as the first history item. In that case we skip it. */ if (first_char_typed == true && a == LINEUP_A && history_buff->cur_line_desc->line && !strncmp(history_buff->cur_line_desc->line, input_buffer, history_buff->cur_line_desc->line_len)) line_up(history_buff); if (history_buff->cur_line_desc->line) { strncpy(input_buffer, history_buff->cur_line_desc->line, min(history_buff->cur_line_desc->line_len,MAX_INPUT_LINE_LEN)); input_buffer[min(history_buff->cur_line_desc->line_len,MAX_INPUT_LINE_LEN)] = 0; len = strlen(input_buffer); encoding = detect_encoding(input_buffer, len); } else { input_buffer[len = 0] = 0; encoding = ENC_ASCII; } x = start_x; pos = 0; offset = 0; input_refresh(); } break; case MOVELEFT_A: input_move_left(true); break; case MOVERIGHT_A: input_move_right(true); break; case BACKSPACE_A: if (pos == 0) break; input_move_left(true); case DELETECHAR_A: if (len > 0 && pos < len) { int c_len = encoding == ENC_UTF8 ? utf8len(input_buffer[pos]) : 1; int c_width = get_char_width(&input_buffer[pos], encoding); memmove(&input_buffer[pos], &input_buffer[pos + c_len], len - pos - c_len + 1); len -= c_len; if (input_buffer_is_ascii()) encoding = ENC_ASCII; if (char_ins_del_ok) { int i, j; move_cursor(ne_lines - 1, x); delete_chars(c_width); for(i = x, j = pos; j < len && i + get_char_width(&input_buffer[j], encoding) < ne_columns - c_width; i += get_char_width(&input_buffer[j], encoding), j = next_pos(input_buffer, j, encoding)); if (j < len) { move_cursor(ne_lines - 1, i); while(j < len && i + get_char_width(&input_buffer[j], encoding) < ne_columns) { output_char(get_char(&input_buffer[j], encoding), 0, encoding); i += get_char_width(&input_buffer[j], encoding); j = next_pos(input_buffer, j, encoding); } } } else input_refresh(); } break; case DELETELINE_A: move_cursor(ne_lines - 1, start_x); clear_to_eol(); input_buffer[len = pos = offset = 0] = 0; encoding = ENC_ASCII; x = start_x; break; case DELETEEOL_A: input_buffer[len = pos] = 0; clear_to_eol(); if (input_buffer_is_ascii()) encoding = ENC_ASCII; break; case MOVEINCUP_A: if (x != start_x) { pos = offset; x = start_x; break; } case MOVESOL_A: input_move_to_sol(); break; case MOVEINCDOWN_A: { int i, j; for(i = x, j = pos; j < len && i + get_char_width(&input_buffer[j], encoding) < ne_columns; i += get_char_width(&input_buffer[j], encoding), j = next_pos(input_buffer, j, encoding)); if (j != pos && j < len) { pos = j; x = i; break; } } case MOVEEOL_A: input_move_to_eol(); break; case TOGGLESEOL_A: case TOGGLESEOF_A: if (pos != 0) input_move_to_sol(); else input_move_to_eol(); break; case PREVWORD_A: input_prev_word(); break; case NEXTWORD_A: input_next_word(); break; case REFRESH_A: input_refresh(); break; case PASTE_A: input_paste(); break; case AUTOCOMPLETE_A: input_autocomplete(); break; case ESCAPE_A: return NULL; default: break; } } break; default: break; } if (selection) { const line_desc * const last = (line_desc *)history_buff->line_desc_list.tail_pred->prev; assert(input_buffer[len] == 0); if (history_buff->num_lines == 0 || len != last->line_len || strncmp(input_buffer, last->line, last->line_len)) add_to_history(input_buffer); return input_buffer; } first_char_typed = false; } }
//------------------------------------------------------------------------------ static char* call_readline_impl(const char* prompt) { static int initialised = 0; int expand_result; char* text; char* expanded; char* prepared_prompt; char cwd_cache[MAX_PATH]; // Turn off EOL wrapping as Readline will take care of it. { HANDLE handle_stdout = GetStdHandle(STD_OUTPUT_HANDLE); SetConsoleMode(handle_stdout, ENABLE_PROCESSED_OUTPUT); } // Initialisation if (!initialised) { initialise_clink_settings(); initialise_lua(); initialise_fwrite(); load_history(); history_inhibit_expansion_function = history_expand_control; rl_catch_signals = 0; rl_startup_hook = initialise_hook; initialised = 1; } // If no prompt was provided assume the line is prompted already and // extract it. If a prompt was provided filter it through Lua. prepared_prompt = NULL; if (prompt == NULL) { prepared_prompt = extract_prompt(1); // Even though we're not going to display filtered result the extracted // prompt is run through Lua. This is a little bit of a hack, but helps // to keep behaviour consistent. if (prepared_prompt != NULL) { char buffer[1024]; str_cpy(buffer, prepared_prompt, sizeof(buffer)); lua_filter_prompt(buffer, sizeof_array(buffer)); } } else { prepared_prompt = filter_prompt(prompt); } GetCurrentDirectory(sizeof_array(cwd_cache), cwd_cache); do { // Call readline rl_already_prompted = (prompt == NULL); text = readline(prepared_prompt ? prepared_prompt : ""); if (!text) { goto call_readline_epilogue; } // Expand history designators in returned buffer. expanded = NULL; expand_result = expand_from_history(text, &expanded); if (expand_result > 0 && expanded != NULL) { free(text); text = expanded; // If there was some expansion then display the expanded result. if (expand_result > 0) { hooked_fprintf(NULL, "History expansion: %s\n", text); } } // Should we read the history from disk. if (get_clink_setting_int("history_io")) { load_history(); add_to_history(text); save_history(); } else add_to_history(text); } while (!text || expand_result == 2); call_readline_epilogue: free_prompt(prepared_prompt); SetCurrentDirectory(cwd_cache); return text; }
//------------------------------------------------------------------------------ static char* call_readline_impl(const char* prompt) { static int initialised = 0; int expand_result; char* text; char* expanded; char* prepared_prompt; char cwd_cache[MAX_PATH]; // Initialisation if (!initialised) { initialise_clink_settings(); initialise_lua(); load_history(); rl_catch_signals = 0; rl_startup_hook = initialise_hook; initialised = 1; } // If no prompt was provided assume the line is prompted already and // extract it. If a prompt was provided filter it through Lua. prepared_prompt = NULL; if (prompt == NULL) { prepared_prompt = extract_prompt(1); // Even though we're not going to display filtered result the extracted // prompt is run through Lua. This is a little bit of a hack, but helps // to keep behaviour consistent. if (prepared_prompt != NULL) { char buffer[1024]; str_cpy(buffer, prepared_prompt, sizeof(buffer)); lua_filter_prompt(buffer, sizeof_array(buffer)); } } else { prepared_prompt = filter_prompt(prompt); } GetCurrentDirectory(sizeof_array(cwd_cache), cwd_cache); // Call readline do { rl_already_prompted = (prompt == NULL); text = readline(prepared_prompt ? prepared_prompt : ""); if (!text) { goto call_readline_epilogue; } // Expand history designators in returned buffer. expanded = NULL; expand_result = history_expand(text, &expanded); if (expand_result < 0) { free(expanded); } else { free(text); text = expanded; // If there was some expansion then display the expanded result. if (expand_result > 0) { hooked_fprintf(NULL, "History expansion: %s\n", text); } } add_to_history(text); } while (!text || expand_result == 2); call_readline_epilogue: free_prompt(prepared_prompt); SetCurrentDirectory(cwd_cache); return text; }
// assumes that the buffer described by offset and length is contained // in the buffer that is given as a struct static void remove_split_buffer(struct debug_q* que, struct memory_list* region, struct memory_ele* buffer, genoffset_t offset, genoffset_t length) { // split the buffer // insert half before the buffer DEBUG("enqueue offset=%"PRIu64" length=%"PRIu64" buf->offset=%lu " "buf->length %lu \n", offset, length, buffer->offset, buffer->length); // check if buffer at beginning of region if (buffer->offset == offset) { buffer->offset += length; buffer->length -= length; if (buffer->length == 0) { add_to_history(que, offset, length, "enq cut of beginning remove"); DEBUG("enqueue remove buffer from list\n"); // remove if (buffer->prev != NULL) { buffer->prev->next = buffer->next; } else { region->buffers = buffer->next; } if (buffer->next != NULL) { buffer->next->prev = buffer->prev; } slab_free(&que->alloc, buffer); } else { add_to_history(que, offset, length, "enq cut of beginning"); } DEBUG("enqueue first cut off begining results in offset=%"PRIu64" " "length=%"PRIu64"\n", buffer->offset, buffer->length); return; } // check if buffer at end of region if ((buffer->offset+buffer->length) == (offset+length)) { buffer->length -= length; if (buffer->length == 0) { add_to_history(que, offset, length, "enq cut of end remove"); // remove if (buffer->prev != NULL) { buffer->prev = buffer->next; } if (buffer->next != NULL) { buffer->next->prev = buffer->prev; } slab_free(&que->alloc, buffer); } else { add_to_history(que, offset, length, "enq cut of end"); } DEBUG("enqueue first cut off end results in offset=%"PRIu64" " "length=%"PRIu64"\n", buffer->offset, buffer->length); return; } // now if this did not work need to split buffer that contains the // enqueued buffer into two buffers (might also result only in one) // inset half before buffer genoffset_t old_len = buffer->length; buffer->length = offset - buffer->offset; struct memory_ele* after = NULL; after = slab_alloc(&que->alloc); assert(after != NULL); memset(after, 0, sizeof(after)); after->offset = buffer->offset + buffer->length + length; after->length = old_len - buffer->length - length; // insert after buffer after->prev = buffer; after->next = buffer->next; if (buffer->next != NULL) { buffer->next->prev = after; } buffer->next = after; add_to_history(que, offset, length, "enq split buffer"); DEBUG("Split buffer length=%lu to " "offset=%"PRIu64" length=%"PRIu64" and " "offset=%lu length=%lu \n", old_len, buffer->offset, buffer->length, after->offset, after->length); }
int handle_inline_commands(char *tokens[], char *bufCopy, char *buff, _Bool *in_bg) { int reply = 0; if (strcmp(tokens[0], "exit") == 0) { reply = 1; free(bufCopy); exit(0); } else if (strcmp(tokens[0], "cd") == 0) { chdir(tokens[1]); add_to_history(bufCopy); reply = 1; } else if (strcmp(tokens[0], "pwd") == 0) { char dir[COMMAND_LENGTH]; getcwd(dir, sizeof(dir)); dir[strlen(dir)] = '\0'; write(STDOUT_FILENO, dir, strlen(dir)); write(STDOUT_FILENO, "\n", strlen("\n")); add_to_history(bufCopy); reply = 1; } else if (strcmp(tokens[0], "history") == 0) { add_to_history(bufCopy); print_history(); reply = 1; } else if (strcmp(tokens[0], "!!") == 0) { if (commandCounter <= 0) { printf("SHELL: Unknown history command.\n"); free(bufCopy); reply = -1; } else { retokenize_cmd(commandCursor-1, tokens, bufCopy, buff, in_bg); printf("%s\n", bufCopy); // Recurse, in case the command is to be handled // inline. reply = handle_inline_commands(tokens, bufCopy, buff, in_bg); } } else if (tokens[0][0] == '!') { int count = strlen(tokens[0]); for (int i = 0; i < count-1; ++i) tokens[0][i] = tokens[0][i+1]; tokens[0][count-1] = '\0'; int cmdNumber = atoi(tokens[0]); if (cmdNumber > commandCounter) { printf("SHELL: Unknown history command.\n"); free(bufCopy); reply = -1; } else if (cmdNumber == 0) { printf("SHELL: Unknown history command.\n"); free(bufCopy); reply = -1; } else { int cmdPosition = cmd_number_to_position(cmdNumber); retokenize_cmd(cmdPosition, tokens, bufCopy, buff, in_bg); printf("%s\n", bufCopy); // Recurse, in case the command is to be handled // inline. reply = handle_inline_commands(tokens, bufCopy, buff, in_bg); } } else if ((int)(*tokens[0]) == EM_VALUE) { free(bufCopy); reply = -1; /* Handle when they type a bunch of spaces and hit enter */ } else if (strlen(*tokens) == 0) { free(bufCopy); reply = -1; } else { reply = 0; } return reply; }