aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRon Yorston <rmy@pobox.com>2015-07-21 22:28:09 +0200
committerDenys Vlasenko <vda.linux@googlemail.com>2015-07-21 22:28:09 +0200
commit193ba408a4fd3313b1dc2eb5eb25885cfa4363f6 (patch)
tree1062a000b0d330756ec8e88e14052d803634f2a9
parent35ae2ccb40924efcd0fd0c873cc9e56c58851222 (diff)
downloadbusybox-w32-193ba408a4fd3313b1dc2eb5eb25885cfa4363f6.tar.gz
busybox-w32-193ba408a4fd3313b1dc2eb5eb25885cfa4363f6.tar.bz2
busybox-w32-193ba408a4fd3313b1dc2eb5eb25885cfa4363f6.zip
less: improvements to verbose status messages
Make verbose status messages (-m/-M flags) behave more like the real `less` command: - fix display of line numbers so they're correct whether lines are being truncated (-S flag) or wrapped. - don't display total lines or percentage when lines are read from stdin: we don't have that information until we reach EOF. When we do reach EOF the additional information is displayed. - when lines are read from a file count the total number of lines so that we can display percentages. Counting lines is avoided until the information is actually needed. If the user pages to EOF the separate read pass can be avoided entirely. Fixes Bug 7586 function old new delta m_status_print 195 382 +187 safe_lineno - 35 +35 reinitialize 172 182 +10 read_lines 675 685 +10 buffer_fill_and_print 178 169 -9 ------------------------------------------------------------------------------ (add/remove: 1/0 grow/shrink: 3/1 up/down: 242/-9) Total: 233 bytes Signed-off-by: Ron Yorston <rmy@pobox.com> Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
-rw-r--r--miscutils/less.c83
1 files changed, 69 insertions, 14 deletions
diff --git a/miscutils/less.c b/miscutils/less.c
index 90c103888..dd932c5ed 100644
--- a/miscutils/less.c
+++ b/miscutils/less.c
@@ -165,6 +165,11 @@ enum {
165enum { pattern_valid = 0 }; 165enum { pattern_valid = 0 };
166#endif 166#endif
167 167
168enum {
169 READING_FILE = -1,
170 READING_STDIN = -2
171};
172
168struct globals { 173struct globals {
169 int cur_fline; /* signed */ 174 int cur_fline; /* signed */
170 int kbd_fd; /* fd to get input from */ 175 int kbd_fd; /* fd to get input from */
@@ -188,6 +193,9 @@ struct globals {
188 unsigned current_file; 193 unsigned current_file;
189 char *filename; 194 char *filename;
190 char **files; 195 char **files;
196#if ENABLE_FEATURE_LESS_FLAGS
197 int num_lines; /* input source if < 0, line count if >= 0 */
198#endif
191#if ENABLE_FEATURE_LESS_MARKS 199#if ENABLE_FEATURE_LESS_MARKS
192 unsigned num_marks; 200 unsigned num_marks;
193 unsigned mark_lines[15][2]; 201 unsigned mark_lines[15][2];
@@ -229,6 +237,7 @@ struct globals {
229#define current_file (G.current_file ) 237#define current_file (G.current_file )
230#define filename (G.filename ) 238#define filename (G.filename )
231#define files (G.files ) 239#define files (G.files )
240#define num_lines (G.num_lines )
232#define num_marks (G.num_marks ) 241#define num_marks (G.num_marks )
233#define mark_lines (G.mark_lines ) 242#define mark_lines (G.mark_lines )
234#if ENABLE_FEATURE_LESS_REGEXP 243#if ENABLE_FEATURE_LESS_REGEXP
@@ -574,6 +583,10 @@ static void read_lines(void)
574 print_statusline(bb_msg_read_error); 583 print_statusline(bb_msg_read_error);
575 } 584 }
576 } 585 }
586#if ENABLE_FEATURE_LESS_FLAGS
587 else if (eof_error == 0)
588 num_lines = max_lineno;
589#endif
577 590
578 fill_match_lines(old_max_fline); 591 fill_match_lines(old_max_fline);
579#if ENABLE_FEATURE_LESS_REGEXP 592#if ENABLE_FEATURE_LESS_REGEXP
@@ -584,18 +597,23 @@ static void read_lines(void)
584} 597}
585 598
586#if ENABLE_FEATURE_LESS_FLAGS 599#if ENABLE_FEATURE_LESS_FLAGS
587/* Interestingly, writing calc_percent as a function saves around 32 bytes 600static int safe_lineno(int fline)
588 * on my build. */
589static int calc_percent(void)
590{ 601{
591 unsigned p = (100 * (cur_fline+max_displayed_line+1) + max_fline/2) / (max_fline+1); 602 if (fline >= max_fline)
592 return p <= 100 ? p : 100; 603 fline = max_fline - 1;
604
605 /* also catches empty file (max_fline == 0) */
606 if (fline < 0)
607 return 0;
608
609 return LINENO(flines[fline]) + 1;
593} 610}
594 611
595/* Print a status line if -M was specified */ 612/* Print a status line if -M was specified */
596static void m_status_print(void) 613static void m_status_print(void)
597{ 614{
598 int percentage; 615 int first, last;
616 unsigned percent;
599 617
600 if (less_gets_pos >= 0) /* don't touch statusline while input is done! */ 618 if (less_gets_pos >= 0) /* don't touch statusline while input is done! */
601 return; 619 return;
@@ -604,17 +622,51 @@ static void m_status_print(void)
604 printf(HIGHLIGHT"%s", filename); 622 printf(HIGHLIGHT"%s", filename);
605 if (num_files > 1) 623 if (num_files > 1)
606 printf(" (file %i of %i)", current_file, num_files); 624 printf(" (file %i of %i)", current_file, num_files);
607 printf(" lines %i-%i/%i ", 625
608 cur_fline + 1, cur_fline + max_displayed_line + 1, 626 first = safe_lineno(cur_fline);
609 max_fline + 1); 627 last = (option_mask32 & FLAG_S)
628 ? MIN(first + max_displayed_line, max_lineno)
629 : safe_lineno(cur_fline + max_displayed_line);
630 printf(" lines %i-%i", first, last);
631
632 if (num_lines == READING_FILE) {
633 int count, fd;
634 ssize_t len, i;
635 char buf[4096];
636 struct stat stbuf;
637
638 /* count number of lines in file */
639 count = 0;
640 fd = open(filename, O_RDONLY);
641 if (fd < 0)
642 goto skip;
643 if (fstat(fd, &stbuf) != 0 || !S_ISREG(stbuf.st_mode))
644 goto do_close;
645 while ((len = safe_read(fd, buf, sizeof(buf))) > 0) {
646 for (i = 0; i < len; ++i) {
647 if (buf[i] == '\n' && ++count == MAXLINES)
648 goto done;
649 }
650 }
651 done:
652 num_lines = count;
653 do_close:
654 close(fd);
655 skip: ;
656 }
657
658 if (num_lines >= 0)
659 printf("/%i", num_lines);
660
610 if (cur_fline >= (int)(max_fline - max_displayed_line)) { 661 if (cur_fline >= (int)(max_fline - max_displayed_line)) {
611 printf("(END)"NORMAL); 662 printf(" (END)");
612 if (num_files > 1 && current_file != num_files) 663 if (num_files > 1 && current_file != num_files)
613 printf(HIGHLIGHT" - next: %s"NORMAL, files[current_file]); 664 printf(" - next: %s", files[current_file]);
614 return; 665 } else if (num_lines > 0) {
666 percent = (100 * last + num_lines/2) / num_lines;
667 printf(" %i%%", percent <= 100 ? percent : 100);
615 } 668 }
616 percentage = calc_percent(); 669 printf(NORMAL);
617 printf("%i%%"NORMAL, percentage);
618} 670}
619#endif 671#endif
620 672
@@ -915,6 +967,9 @@ static void reinitialize(void)
915 max_fline = -1; 967 max_fline = -1;
916 cur_fline = 0; 968 cur_fline = 0;
917 max_lineno = 0; 969 max_lineno = 0;
970#if ENABLE_FEATURE_LESS_FLAGS
971 num_lines = filename ? READING_FILE : READING_STDIN;
972#endif
918 open_file_and_read_lines(); 973 open_file_and_read_lines();
919#if ENABLE_FEATURE_LESS_ASK_TERMINAL 974#if ENABLE_FEATURE_LESS_ASK_TERMINAL
920 if (G.winsize_err) 975 if (G.winsize_err)