aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-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':