aboutsummaryrefslogtreecommitdiff
path: root/miscutils/less.c
diff options
context:
space:
mode:
Diffstat (limited to 'miscutils/less.c')
-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)