aboutsummaryrefslogtreecommitdiff
path: root/miscutils/less.c
diff options
context:
space:
mode:
authorRon Yorston <rmy@pobox.com>2015-07-24 14:29:13 +0100
committerDenys Vlasenko <vda.linux@googlemail.com>2015-07-31 16:22:08 +0200
commitd542d183e10dde1168fa85751194839c67add7fe (patch)
tree12ceebe88914fb3c5686ffd6cf48812aa072aa8d /miscutils/less.c
parentad1b4d5882586ad213992a97fc22f9c4bc9e0040 (diff)
downloadbusybox-w32-d542d183e10dde1168fa85751194839c67add7fe.tar.gz
busybox-w32-d542d183e10dde1168fa85751194839c67add7fe.tar.bz2
busybox-w32-d542d183e10dde1168fa85751194839c67add7fe.zip
less: fix line number confusion
Much of the code refers to lines using indices into the flines array (which splits lines into portions that fit on the terminal). In some cases this is wrong and actual line numbers should be used: - when lines are being truncated rather than wrapped (-S flag) - when line numbers have been entered by the user Also fix a bug in numeric input and improve the display at EOF. function old new delta goto_lineno - 111 +111 cap_cur_fline - 101 +101 buffer_to_line - 56 +56 buffer_up 35 66 +31 less_main 2606 2615 +9 goto_match 125 127 +2 buffer_down 81 56 -25 buffer_line 64 - -64 ------------------------------------------------------------------------------ (add/remove: 3/1 grow/shrink: 3/1 up/down: 310/-89) Total: 221 bytes Signed-off-by: Ron Yorston <rmy@pobox.com> Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
Diffstat (limited to 'miscutils/less.c')
-rw-r--r--miscutils/less.c119
1 files changed, 82 insertions, 37 deletions
diff --git a/miscutils/less.c b/miscutils/less.c
index 2a1797c7b..5c53cbdbf 100644
--- a/miscutils/less.c
+++ b/miscutils/less.c
@@ -711,23 +711,6 @@ static void status_print(void)
711 print_hilite(p); 711 print_hilite(p);
712} 712}
713 713
714static void cap_cur_fline(int nlines)
715{
716 int diff;
717 if (cur_fline < 0)
718 cur_fline = 0;
719 if (cur_fline + max_displayed_line > max_fline + TILDES) {
720 cur_fline -= nlines;
721 if (cur_fline < 0)
722 cur_fline = 0;
723 diff = max_fline - (cur_fline + max_displayed_line) + TILDES;
724 /* As the number of lines requested was too large, we just move
725 * to the end of the file */
726 if (diff > 0)
727 cur_fline += diff;
728 }
729}
730
731static const char controls[] ALIGN1 = 714static const char controls[] ALIGN1 =
732 /* NUL: never encountered; TAB: not converted */ 715 /* NUL: never encountered; TAB: not converted */
733 /**/"\x01\x02\x03\x04\x05\x06\x07\x08" "\x0a\x0b\x0c\x0d\x0e\x0f" 716 /**/"\x01\x02\x03\x04\x05\x06\x07\x08" "\x0a\x0b\x0c\x0d\x0e\x0f"
@@ -913,37 +896,98 @@ static void buffer_fill_and_print(void)
913 buffer_print(); 896 buffer_print();
914} 897}
915 898
899/* move cur_fline to a given line number, reading lines if necessary */
900static void goto_lineno(int target)
901{
902 if (target <= 0 ) {
903 cur_fline = 0;
904 }
905 else if (target > LINENO(flines[cur_fline])) {
906 retry:
907 while (LINENO(flines[cur_fline]) != target && cur_fline < max_fline)
908 ++cur_fline;
909 /* target not reached but more input is available */
910 if (LINENO(flines[cur_fline]) != target && eof_error > 0) {
911 read_lines();
912 goto retry;
913 }
914 }
915 else {
916 /* search backwards through already-read lines */
917 while (LINENO(flines[cur_fline]) != target && cur_fline > 0)
918 --cur_fline;
919 }
920}
921
922static void cap_cur_fline(void)
923{
924 if ((option_mask32 & FLAG_S)) {
925 if (cur_fline > max_fline)
926 cur_fline = max_fline;
927 if (LINENO(flines[cur_fline]) + max_displayed_line > max_lineno + TILDES) {
928 goto_lineno(max_lineno - max_displayed_line + TILDES);
929 read_lines();
930 }
931 }
932 else {
933 if (cur_fline + max_displayed_line > max_fline + TILDES)
934 cur_fline = max_fline - max_displayed_line + TILDES;
935 if (cur_fline < 0)
936 cur_fline = 0;
937 }
938}
939
916/* Move the buffer up and down in the file in order to scroll */ 940/* Move the buffer up and down in the file in order to scroll */
917static void buffer_down(int nlines) 941static void buffer_down(int nlines)
918{ 942{
919 cur_fline += nlines; 943 if ((option_mask32 & FLAG_S))
944 goto_lineno(LINENO(flines[cur_fline]) + nlines);
945 else
946 cur_fline += nlines;
920 read_lines(); 947 read_lines();
921 cap_cur_fline(nlines); 948 cap_cur_fline();
922 buffer_fill_and_print(); 949 buffer_fill_and_print();
923} 950}
924 951
925static void buffer_up(int nlines) 952static void buffer_up(int nlines)
926{ 953{
927 cur_fline -= nlines; 954 if ((option_mask32 & FLAG_S)) {
928 if (cur_fline < 0) cur_fline = 0; 955 goto_lineno(LINENO(flines[cur_fline]) - nlines);
956 }
957 else {
958 cur_fline -= nlines;
959 if (cur_fline < 0)
960 cur_fline = 0;
961 }
929 read_lines(); 962 read_lines();
930 buffer_fill_and_print(); 963 buffer_fill_and_print();
931} 964}
932 965
933static void buffer_line(int linenum) 966/* display a given line where the argument can be either an index into
967 * the flines array or a line number */
968static void buffer_to_line(int linenum, int is_lineno)
934{ 969{
935 if (linenum < 0) 970 if (linenum <= 0)
936 linenum = 0; 971 cur_fline = 0;
937 cur_fline = linenum; 972 else if (is_lineno)
973 goto_lineno(linenum);
974 else
975 cur_fline = linenum;
938 read_lines(); 976 read_lines();
939 if (linenum + max_displayed_line > max_fline) 977 cap_cur_fline();
940 linenum = max_fline - max_displayed_line + TILDES;
941 if (linenum < 0)
942 linenum = 0;
943 cur_fline = linenum;
944 buffer_fill_and_print(); 978 buffer_fill_and_print();
945} 979}
946 980
981static void buffer_line(int linenum)
982{
983 buffer_to_line(linenum, FALSE);
984}
985
986static void buffer_lineno(int lineno)
987{
988 buffer_to_line(lineno, TRUE);
989}
990
947static void open_file_and_read_lines(void) 991static void open_file_and_read_lines(void)
948{ 992{
949 if (filename) { 993 if (filename) {
@@ -1348,15 +1392,16 @@ static void number_process(int first_digit)
1348 buffer_up(num); 1392 buffer_up(num);
1349 break; 1393 break;
1350 case 'g': case '<': case 'G': case '>': 1394 case 'g': case '<': case 'G': case '>':
1351 cur_fline = num + max_displayed_line; 1395 buffer_lineno(num - 1);
1352 read_lines();
1353 buffer_line(num - 1);
1354 break; 1396 break;
1355 case 'p': case '%': 1397 case 'p': case '%':
1356 num = num * (max_fline / 100); /* + max_fline / 2; */ 1398#if ENABLE_FEATURE_LESS_FLAGS
1357 cur_fline = num + max_displayed_line; 1399 update_num_lines();
1358 read_lines(); 1400 num = num * (num_lines > 0 ? num_lines : max_lineno) / 100;
1359 buffer_line(num); 1401#else
1402 num = num * max_lineno / 100;
1403#endif
1404 buffer_lineno(num);
1360 break; 1405 break;
1361#if ENABLE_FEATURE_LESS_REGEXP 1406#if ENABLE_FEATURE_LESS_REGEXP
1362 case 'n': 1407 case 'n':