static void show_flag_status(void) { int keypress; int flag_val; clear_line(); bb_putchar('_'); keypress = less_getch(1); switch (keypress) { case 'M': flag_val = option_mask32 & FLAG_M; break; case 'm': flag_val = option_mask32 & FLAG_m; break; case '~': flag_val = option_mask32 & FLAG_TILDE; break; case 'N': flag_val = option_mask32 & FLAG_N; break; case 'E': flag_val = option_mask32 & FLAG_E; break; default: flag_val = 0; break; } clear_line(); printf(HIGHLIGHT"The status of the flag is: %u"NORMAL, flag_val != 0); }
static void colon_process(void) { int keypress; /* Clear the current line and print a prompt */ print_statusline(" :"); keypress = less_getch(2); switch (keypress) { case 'd': remove_current_file(); break; case 'e': examine_file(); break; #if ENABLE_FEATURE_LESS_FLAGS case 'f': m_status_print(); break; #endif case 'n': change_file(1); break; case 'p': change_file(-1); break; case 'q': less_exit(EXIT_SUCCESS); break; case 'x': change_file(0); break; } }
static void flag_change(void) { int keypress; clear_line(); bb_putchar('-'); keypress = less_getch(1); switch (keypress) { case 'M': option_mask32 ^= FLAG_M; break; case 'm': option_mask32 ^= FLAG_m; break; case 'E': option_mask32 ^= FLAG_E; break; case '~': option_mask32 ^= FLAG_TILDE; break; case 'S': option_mask32 ^= FLAG_S; buffer_fill_and_print(); break; #if ENABLE_FEATURE_LESS_LINENUMS case 'N': option_mask32 ^= FLAG_N; re_wrap(); buffer_fill_and_print(); break; #endif } }
int less_main(int argc, char **argv) { int keypress; INIT_G(); /* TODO: -x: do not interpret backspace, -xx: tab also */ /* -xxx: newline also */ /* -w N: assume width N (-xxx -w 32: hex viewer of sorts) */ getopt32(argv, "EMmN~"); argc -= optind; argv += optind; num_files = argc; files = argv; /* Another popular pager, most, detects when stdout * is not a tty and turns into cat. This makes sense. */ if (!isatty(STDOUT_FILENO)) return bb_cat(argv); kbd_fd = open(CURRENT_TTY, O_RDONLY); if (kbd_fd < 0) return bb_cat(argv); ndelay_on(kbd_fd); if (!num_files) { if (isatty(STDIN_FILENO)) { /* Just "less"? No args and no redirection? */ bb_error_msg("missing filename"); bb_show_usage(); } } else filename = xstrdup(files[0]); get_terminal_width_height(kbd_fd, &width, &max_displayed_line); /* 20: two tabstops + 4 */ if (width < 20 || max_displayed_line < 3) return bb_cat(argv); max_displayed_line -= 2; buffer = xmalloc((max_displayed_line+1) * sizeof(char *)); if (option_mask32 & FLAG_TILDE) empty_line_marker = ""; tcgetattr(kbd_fd, &term_orig); term_less = term_orig; term_less.c_lflag &= ~(ICANON | ECHO); term_less.c_iflag &= ~(IXON | ICRNL); /*term_less.c_oflag &= ~ONLCR;*/ term_less.c_cc[VMIN] = 1; term_less.c_cc[VTIME] = 0; /* We want to restore term_orig on exit */ bb_signals(BB_FATAL_SIGS, sig_catcher); reinitialize(); while (1) { keypress = less_getch(-1); /* -1: do not position cursor */ keypress_process(keypress); } }
static void add_mark(void) { int letter; print_statusline("Mark: "); letter = less_getch(sizeof("Mark: ") - 1); if (isalpha(letter)) { /* If we exceed 15 marks, start overwriting previous ones */ if (num_marks == 14) num_marks = 0; mark_lines[num_marks][0] = letter; mark_lines[num_marks][1] = cur_fline; num_marks++; } else { print_statusline("Invalid mark letter"); } }
static void goto_mark(void) { int letter; int i; print_statusline("Go to mark: "); letter = less_getch(sizeof("Go to mark: ") - 1); clear_line(); if (isalpha(letter)) { for (i = 0; i <= num_marks; i++) if (letter == mark_lines[i][0]) { buffer_line(mark_lines[i][1]); break; } if (num_marks == 14 && letter != mark_lines[14][0]) print_statusline("Mark not set"); } else print_statusline("Invalid mark letter"); }
static void flag_change(void) { int keypress; clear_line(); bb_putchar('-'); keypress = less_getch(1); switch (keypress) { case 'M': option_mask32 ^= FLAG_M; break; case 'm': option_mask32 ^= FLAG_m; break; case 'E': option_mask32 ^= FLAG_E; break; case '~': option_mask32 ^= FLAG_TILDE; break; } }
int less_main(int argc, char **argv) { int keypress; INIT_G(); /* TODO: -x: do not interpret backspace, -xx: tab also */ /* -xxx: newline also */ /* -w N: assume width N (-xxx -w 32: hex viewer of sorts) */ getopt32(argv, "EMmN~I" IF_FEATURE_LESS_DASHCMD("S")); argc -= optind; argv += optind; num_files = argc; files = argv; /* Another popular pager, most, detects when stdout * is not a tty and turns into cat. This makes sense. */ if (!isatty(STDOUT_FILENO)) return bb_cat(argv); if (!num_files) { if (isatty(STDIN_FILENO)) { /* Just "less"? No args and no redirection? */ bb_error_msg("missing filename"); bb_show_usage(); } } else { filename = xstrdup(files[0]); } if (option_mask32 & FLAG_TILDE) empty_line_marker = ""; kbd_fd = open(CURRENT_TTY, O_RDONLY); if (kbd_fd < 0) return bb_cat(argv); ndelay_on(kbd_fd); tcgetattr(kbd_fd, &term_orig); term_less = term_orig; term_less.c_lflag &= ~(ICANON | ECHO); term_less.c_iflag &= ~(IXON | ICRNL); /*term_less.c_oflag &= ~ONLCR;*/ term_less.c_cc[VMIN] = 1; term_less.c_cc[VTIME] = 0; get_terminal_width_height(kbd_fd, &width, &max_displayed_line); /* 20: two tabstops + 4 */ if (width < 20 || max_displayed_line < 3) return bb_cat(argv); max_displayed_line -= 2; /* We want to restore term_orig on exit */ bb_signals(BB_FATAL_SIGS, sig_catcher); #if ENABLE_FEATURE_LESS_WINCH signal(SIGWINCH, sigwinch_handler); #endif buffer = xmalloc((max_displayed_line+1) * sizeof(char *)); reinitialize(); while (1) { #if ENABLE_FEATURE_LESS_WINCH while (WINCH_COUNTER) { again: winch_counter--; get_terminal_width_height(kbd_fd, &width, &max_displayed_line); /* 20: two tabstops + 4 */ if (width < 20) width = 20; if (max_displayed_line < 3) max_displayed_line = 3; max_displayed_line -= 2; free(buffer); buffer = xmalloc((max_displayed_line+1) * sizeof(char *)); /* Avoid re-wrap and/or redraw if we already know * we need to do it again. These ops are expensive */ if (WINCH_COUNTER) goto again; re_wrap(); if (WINCH_COUNTER) goto again; buffer_fill_and_print(); /* This took some time. Loop back and check, * were there another SIGWINCH? */ } #endif keypress = less_getch(-1); /* -1: do not position cursor */ keypress_process(keypress); } }
static void number_process(int first_digit) { unsigned i; int num; int keypress; char num_input[sizeof(int)*4]; /* more than enough */ num_input[0] = first_digit; /* Clear the current line, print a prompt, and then print the digit */ clear_line(); printf(":%c", first_digit); /* Receive input until a letter is given */ i = 1; while (i < sizeof(num_input)-1) { keypress = less_getch(i + 1); if ((unsigned)keypress > 255 || !isdigit(num_input[i])) break; num_input[i] = keypress; bb_putchar(keypress); i++; } num_input[i] = '\0'; num = bb_strtou(num_input, NULL, 10); /* on format error, num == -1 */ if (num < 1 || num > MAXLINES) { buffer_print(); return; } /* We now know the number and the letter entered, so we process them */ switch (keypress) { case KEYCODE_DOWN: case 'z': case 'd': case 'e': case ' ': case '\015': buffer_down(num); break; case KEYCODE_UP: case 'b': case 'w': case 'y': case 'u': buffer_up(num); break; case 'g': case '<': case 'G': case '>': cur_fline = num + max_displayed_line; read_lines(); buffer_line(num - 1); break; case 'p': case '%': num = num * (max_fline / 100); /* + max_fline / 2; */ cur_fline = num + max_displayed_line; read_lines(); buffer_line(num); break; #if ENABLE_FEATURE_LESS_REGEXP case 'n': goto_match(match_pos + num); break; case '/': option_mask32 &= ~LESS_STATE_MATCH_BACKWARDS; regex_process(); break; case '?': option_mask32 |= LESS_STATE_MATCH_BACKWARDS; regex_process(); break; #endif } }