[prev in list] [next in list] [prev in thread] [next in thread] 

List:       busybox
Subject:    [PATCH 4/5] less: fix line number confusion
From:       Ron Yorston <rmy () pobox ! com>
Date:       2015-07-24 13:29:13
Message-ID: 55b23da9.pfCqHrOjorqrAACd%rmy () pobox ! com
[Download RAW message or body]

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>
---
 miscutils/less.c | 121 ++++++++++++++++++++++++++++++++++++++-----------------
 1 file changed, 83 insertions(+), 38 deletions(-)

diff --git a/miscutils/less.c b/miscutils/less.c
index 3e37794..f34b817 100644
--- a/miscutils/less.c
+++ b/miscutils/less.c
@@ -711,23 +711,6 @@ static void status_print(void)
 	print_hilite(p);
 }
 
-static void cap_cur_fline(int nlines)
-{
-	int diff;
-	if (cur_fline < 0)
-		cur_fline = 0;
-	if (cur_fline + max_displayed_line > max_fline + TILDES) {
-		cur_fline -= nlines;
-		if (cur_fline < 0)
-			cur_fline = 0;
-		diff = max_fline - (cur_fline + max_displayed_line) + TILDES;
-		/* As the number of lines requested was too large, we just move
-		 * to the end of the file */
-		if (diff > 0)
-			cur_fline += diff;
-	}
-}
-
 static const char controls[] ALIGN1 =
 	/* NUL: never encountered; TAB: not converted */
 	/**/"\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)
 	buffer_print();
 }
 
+/* move cur_fline to a given line number, reading lines if necessary */
+static void goto_lineno(int target)
+{
+	if (target <= 0 ) {
+		cur_fline = 0;
+	}
+	else if (target > LINENO(flines[cur_fline])) {
+ retry:
+		while (LINENO(flines[cur_fline]) != target && cur_fline < max_fline)
+			++cur_fline;
+		/* target not reached but more input is available */
+		if (LINENO(flines[cur_fline]) != target && eof_error > 0) {
+			read_lines();
+			goto retry;
+		}
+	}
+	else {
+		/* search backwards through already-read lines */
+		while (LINENO(flines[cur_fline]) != target && cur_fline > 0)
+			--cur_fline;
+	}
+}
+
+static void cap_cur_fline(void)
+{
+	if ((option_mask32 & FLAG_S)) {
+		if (cur_fline > max_fline)
+			cur_fline = max_fline;
+		if (LINENO(flines[cur_fline]) + max_displayed_line > max_lineno + TILDES) {
+			goto_lineno(max_lineno - max_displayed_line + TILDES);
+			read_lines();
+		}
+	}
+	else {
+		if (cur_fline + max_displayed_line > max_fline + TILDES)
+			cur_fline = max_fline - max_displayed_line + TILDES;
+		if (cur_fline < 0)
+			cur_fline = 0;
+	}
+}
+
 /* Move the buffer up and down in the file in order to scroll */
 static void buffer_down(int nlines)
 {
-	cur_fline += nlines;
+	if ((option_mask32 & FLAG_S))
+		goto_lineno(LINENO(flines[cur_fline]) + nlines);
+	else
+		cur_fline += nlines;
 	read_lines();
-	cap_cur_fline(nlines);
+	cap_cur_fline();
 	buffer_fill_and_print();
 }
 
 static void buffer_up(int nlines)
 {
-	cur_fline -= nlines;
-	if (cur_fline < 0) cur_fline = 0;
+	if ((option_mask32 & FLAG_S)) {
+		goto_lineno(LINENO(flines[cur_fline]) - nlines);
+	}
+	else {
+		cur_fline -= nlines;
+		if (cur_fline < 0)
+			cur_fline = 0;
+	}
 	read_lines();
 	buffer_fill_and_print();
 }
 
-static void buffer_line(int linenum)
+/* display a given line where the argument can be either an index into
+ * the flines array or a line number */
+static void buffer_to_line(int linenum, int is_lineno)
 {
-	if (linenum < 0)
-		linenum = 0;
-	cur_fline = linenum;
+	if (linenum <= 0)
+		cur_fline = 0;
+	else if (is_lineno)
+		goto_lineno(linenum);
+	else
+		cur_fline = linenum;
 	read_lines();
-	if (linenum + max_displayed_line > max_fline)
-		linenum = max_fline - max_displayed_line + TILDES;
-	if (linenum < 0)
-		linenum = 0;
-	cur_fline = linenum;
+	cap_cur_fline();
 	buffer_fill_and_print();
 }
 
+static void buffer_line(int linenum)
+{
+	buffer_to_line(linenum, FALSE);
+}
+
+static void buffer_lineno(int lineno)
+{
+	buffer_to_line(lineno, TRUE);
+}
+
 static void open_file_and_read_lines(void)
 {
 	if (filename) {
@@ -1324,7 +1368,7 @@ static void number_process(int first_digit)
 	i = 1;
 	while (i < sizeof(num_input)-1) {
 		keypress = less_getch(i + 1);
-		if ((unsigned)keypress > 255 || !isdigit(num_input[i]))
+		if ((unsigned)keypress > 255 || !isdigit(keypress))
 			break;
 		num_input[i] = keypress;
 		bb_putchar(keypress);
@@ -1348,15 +1392,16 @@ static void number_process(int first_digit)
 		buffer_up(num);
 		break;
 	case 'g': case '<': case 'G': case '>':
-		cur_fline = num + max_displayed_line;
-		read_lines();
-		buffer_line(num - 1);
+		buffer_lineno(num - 1);
 		break;
 	case 'p': case '%':
-		num = num * (max_fline / 100); /* + max_fline / 2; */
-		cur_fline = num + max_displayed_line;
-		read_lines();
-		buffer_line(num);
+#if ENABLE_FEATURE_LESS_FLAGS
+		update_num_lines();
+		num = num * (num_lines > 0 ? num_lines : max_lineno) / 100;
+#else
+		num = num * max_lineno / 100;
+#endif
+		buffer_lineno(num);
 		break;
 #if ENABLE_FEATURE_LESS_REGEXP
 	case 'n':
-- 
2.4.3

_______________________________________________
busybox mailing list
busybox@busybox.net
http://lists.busybox.net/mailman/listinfo/busybox
[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic