diff options
Diffstat (limited to 'miscutils')
-rw-r--r-- | miscutils/less.c | 129 |
1 files changed, 82 insertions, 47 deletions
diff --git a/miscutils/less.c b/miscutils/less.c index 3df1f3785..d6b71b9f2 100644 --- a/miscutils/less.c +++ b/miscutils/less.c @@ -72,27 +72,6 @@ enum { TILDES = 1, }; -static unsigned max_displayed_line; -static unsigned width; -static const char *empty_line_marker = "~"; - -static char *filename; -static char **files; -static unsigned num_files = 1; -static unsigned current_file = 1; -static const char **buffer; -static const char **flines; -static int cur_fline; /* signed */ -static unsigned max_fline; -static unsigned max_lineno; /* this one tracks linewrap */ - -static ssize_t eof_error = 1; /* eof if 0, error if < 0 */ -static char terminated = 1; -static size_t readpos; -static size_t readeof; -/* last position in last line, taking into account tabs */ -static size_t linepos; - /* Command line options */ enum { FLAG_E = 1, @@ -104,25 +83,79 @@ enum { LESS_STATE_MATCH_BACKWARDS = 1 << 15, }; -#if ENABLE_FEATURE_LESS_MARKS -static unsigned mark_lines[15][2]; -static unsigned num_marks; +#if !ENABLE_FEATURE_LESS_REGEXP +enum { pattern_valid = 0 }; #endif +struct globals { + int cur_fline; /* signed */ + int kbd_fd; /* fd to get input from */ +/* last position in last line, taking into account tabs */ + size_t linepos; + unsigned max_displayed_line; + unsigned max_fline; + unsigned max_lineno; /* this one tracks linewrap */ + unsigned width; + ssize_t eof_error; /* eof if 0, error if < 0 */ + size_t readpos; + size_t readeof; + const char **buffer; + const char **flines; + const char *empty_line_marker; + unsigned num_files; + unsigned current_file; + char *filename; + char **files; +#if ENABLE_FEATURE_LESS_MARKS + unsigned num_marks; + unsigned mark_lines[15][2]; +#endif #if ENABLE_FEATURE_LESS_REGEXP -static unsigned *match_lines; -static int match_pos; /* signed! */ -static unsigned num_matches; -static regex_t pattern; -static unsigned pattern_valid; -#else -enum { pattern_valid = 0 }; + unsigned *match_lines; + int match_pos; /* signed! */ + unsigned num_matches; + regex_t pattern; + smallint pattern_valid; #endif - -static struct termios term_orig, term_vi; - -/* File pointer to get input from */ -static int kbd_fd; + smallint terminated; + struct termios term_orig, term_less; +}; +#define G (*ptr_to_globals) +#define cur_fline (G.cur_fline ) +#define kbd_fd (G.kbd_fd ) +#define linepos (G.linepos ) +#define max_displayed_line (G.max_displayed_line) +#define max_fline (G.max_fline ) +#define max_lineno (G.max_lineno ) +#define width (G.width ) +#define eof_error (G.eof_error ) +#define readpos (G.readpos ) +#define readeof (G.readeof ) +#define buffer (G.buffer ) +#define flines (G.flines ) +#define empty_line_marker (G.empty_line_marker ) +#define num_files (G.num_files ) +#define current_file (G.current_file ) +#define filename (G.filename ) +#define files (G.files ) +#define num_marks (G.num_marks ) +#define mark_lines (G.mark_lines ) +#define match_lines (G.match_lines ) +#define match_pos (G.match_pos ) +#define num_matches (G.num_matches ) +#define pattern (G.pattern ) +#define pattern_valid (G.pattern_valid ) +#define terminated (G.terminated ) +#define term_orig (G.term_orig ) +#define term_less (G.term_less ) +#define INIT_G() do { \ + PTR_TO_GLOBALS = xzalloc(sizeof(G)); \ + empty_line_marker = "~"; \ + num_files = 1; \ + current_file = 1; \ + eof_error = 1; \ + terminated = 1; \ + } while (0) /* Reset terminal input to normal */ static void set_tty_cooked(void) @@ -380,12 +413,12 @@ static void cap_cur_fline(int nlines) } } -static char controls[] = +static const char controls[] = /* NUL: never encountered; TAB: not converted */ /**/"\x01\x02\x03\x04\x05\x06\x07\x08" "\x0a\x0b\x0c\x0d\x0e\x0f" "\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f" "\x7f\x9b"; /* DEL and infamous Meta-ESC :( */ -static char ctrlconv[] = +static const char ctrlconv[] = /* '\n': it's a former NUL - subst with '@', not 'J' */ "\x40\x41\x42\x43\x44\x45\x46\x47\x48\x49\x40\x4b\x4c\x4d\x4e\x4f" "\x50\x51\x52\x53\x54\x55\x56\x57\x58\x59\x5a\x5b\x5c\x5d\x5e\x5f"; @@ -604,7 +637,7 @@ static void getch_nowait(char* input, int sz) FD_SET(0, &readfds); } FD_SET(kbd_fd, &readfds); - tcsetattr(kbd_fd, TCSANOW, &term_vi); + tcsetattr(kbd_fd, TCSANOW, &term_less); select(kbd_fd + 1, &readfds, NULL, NULL, NULL); input[0] = '\0'; @@ -668,7 +701,7 @@ static char* less_gets(int sz) /* I be damned if I know why is it needed *repeatedly*, * but it is needed. Is it because of stdio? */ - tcsetattr(kbd_fd, TCSANOW, &term_vi); + tcsetattr(kbd_fd, TCSANOW, &term_less); read(kbd_fd, &c, 1); if (c == 0x0d) @@ -1244,6 +1277,8 @@ 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) */ @@ -1283,16 +1318,16 @@ int less_main(int argc, char **argv) tcgetattr(kbd_fd, &term_orig); signal(SIGTERM, sig_catcher); signal(SIGINT, sig_catcher); - term_vi = term_orig; - term_vi.c_lflag &= ~(ICANON | ECHO); - term_vi.c_iflag &= ~(IXON | ICRNL); - /*term_vi.c_oflag &= ~ONLCR;*/ - term_vi.c_cc[VMIN] = 1; - term_vi.c_cc[VTIME] = 0; + 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; /* Want to do it just once, but it doesn't work, */ /* so we are redoing it (see code above). Mystery... */ - /*tcsetattr(kbd_fd, TCSANOW, &term_vi);*/ + /*tcsetattr(kbd_fd, TCSANOW, &term_less);*/ reinitialize(); while (1) { |