aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBernhard Reutner-Fischer <rep.dot.nop@gmail.com>2006-05-19 10:54:46 +0000
committerBernhard Reutner-Fischer <rep.dot.nop@gmail.com>2006-05-19 10:54:46 +0000
commit0c4b9fdda1cdc6b68f6cf531cb88f438228fcd3c (patch)
tree43229ed1da8de60d92c482ee565414d92ad8c6a3
parent4ab339129edcea77e0a08228636114dd8ebd6093 (diff)
downloadbusybox-w32-0c4b9fdda1cdc6b68f6cf531cb88f438228fcd3c.tar.gz
busybox-w32-0c4b9fdda1cdc6b68f6cf531cb88f438228fcd3c.tar.bz2
busybox-w32-0c4b9fdda1cdc6b68f6cf531cb88f438228fcd3c.zip
Resync less.c with current svn to fix a segfault in searching.
(revisions 14889, 14890, 14891, 14896, 14897, 14905, 14961 from trunk)
-rw-r--r--miscutils/less.c368
1 files changed, 173 insertions, 195 deletions
diff --git a/miscutils/less.c b/miscutils/less.c
index df55b50ac..84e4b612d 100644
--- a/miscutils/less.c
+++ b/miscutils/less.c
@@ -2,24 +2,12 @@
2/* 2/*
3 * Mini less implementation for busybox 3 * Mini less implementation for busybox
4 * 4 *
5 *
6 * Copyright (C) 2005 by Rob Sullivan <cogito.ergo.cogito@gmail.com> 5 * Copyright (C) 2005 by Rob Sullivan <cogito.ergo.cogito@gmail.com>
7 * 6 *
8 * This program is free software; you can redistribute it and/or modify 7 * Licensed under the GPL v2 or later, see the file LICENSE in this tarball.
9 * it under the terms of the GNU General Public License as published by 8 */
10 * the Free Software Foundation; either version 2 of the License, or 9
11 * (at your option) any later version. 10/*
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
21 * 02111-1307 USA
22 *
23 * This program needs a lot of development, so consider it in a beta stage 11 * This program needs a lot of development, so consider it in a beta stage
24 * at best. 12 * at best.
25 * 13 *
@@ -116,11 +104,11 @@ static int num_marks;
116 104
117#ifdef CONFIG_FEATURE_LESS_REGEXP 105#ifdef CONFIG_FEATURE_LESS_REGEXP
118static int match_found; 106static int match_found;
119static int match_lines[100]; 107static int *match_lines;
120static int match_pos; 108static int match_pos;
121static int num_matches; 109static int num_matches;
122static int match_backwards; 110static int match_backwards;
123static int num_back_match = 1; 111static regex_t old_pattern;
124#endif 112#endif
125 113
126/* Needed termios structures */ 114/* Needed termios structures */
@@ -130,19 +118,21 @@ static struct termios term_orig, term_vi;
130static FILE *inp; 118static FILE *inp;
131 119
132/* Reset terminal input to normal */ 120/* Reset terminal input to normal */
133static void set_tty_cooked(void) { 121static void set_tty_cooked(void)
122{
134 fflush(stdout); 123 fflush(stdout);
135 tcsetattr(fileno(inp), TCSANOW, &term_orig); 124 tcsetattr(fileno(inp), TCSANOW, &term_orig);
136} 125}
137 126
138/* Set terminal input to raw mode (taken from vi.c) */ 127/* Set terminal input to raw mode (taken from vi.c) */
139static void set_tty_raw(void) { 128static void set_tty_raw(void)
129{
140 tcsetattr(fileno(inp), TCSANOW, &term_vi); 130 tcsetattr(fileno(inp), TCSANOW, &term_vi);
141} 131}
142 132
143/* Exit the program gracefully */ 133/* Exit the program gracefully */
144static void tless_exit(int code) { 134static void tless_exit(int code)
145 135{
146 /* TODO: We really should save the terminal state when we start, 136 /* TODO: We really should save the terminal state when we start,
147 and restore it when we exit. Less does this with the 137 and restore it when we exit. Less does this with the
148 "ti" and "te" termcap commands; can this be done with 138 "ti" and "te" termcap commands; can this be done with
@@ -155,8 +145,8 @@ static void tless_exit(int code) {
155/* Grab a character from input without requiring the return key. If the 145/* Grab a character from input without requiring the return key. If the
156 character is ASCII \033, get more characters and assign certain sequences 146 character is ASCII \033, get more characters and assign certain sequences
157 special return codes. Note that this function works best with raw input. */ 147 special return codes. Note that this function works best with raw input. */
158static int tless_getch(void) { 148static int tless_getch(void)
159 149{
160 int input; 150 int input;
161 151
162 set_tty_raw(); 152 set_tty_raw();
@@ -191,18 +181,20 @@ static int tless_getch(void) {
191 181
192/* Move the cursor to a position (x,y), where (0,0) is the 182/* Move the cursor to a position (x,y), where (0,0) is the
193 top-left corner of the console */ 183 top-left corner of the console */
194static void move_cursor(int x, int y) { 184static void move_cursor(int x, int y)
185{
195 printf("\033[%i;%iH", x, y); 186 printf("\033[%i;%iH", x, y);
196} 187}
197 188
198static void clear_line(void) { 189static void clear_line(void)
190{
199 move_cursor(height, 0); 191 move_cursor(height, 0);
200 printf("\033[K"); 192 printf("\033[K");
201} 193}
202 194
203/* This adds line numbers to every line, as the -N flag necessitates */ 195/* This adds line numbers to every line, as the -N flag necessitates */
204static void add_linenumbers(void) { 196static void add_linenumbers(void)
205 197{
206 char current_line[256]; 198 char current_line[256];
207 int i; 199 int i;
208 200
@@ -212,8 +204,8 @@ static void add_linenumbers(void) {
212 } 204 }
213} 205}
214 206
215static void data_readlines(void) { 207static void data_readlines(void)
216 208{
217 int i; 209 int i;
218 char current_line[256]; 210 char current_line[256];
219 FILE *fp; 211 FILE *fp;
@@ -223,7 +215,7 @@ static void data_readlines(void) {
223 for (i = 0; (feof(fp)==0) && (i <= MAXLINES); i++) { 215 for (i = 0; (feof(fp)==0) && (i <= MAXLINES); i++) {
224 strcpy(current_line, ""); 216 strcpy(current_line, "");
225 fgets(current_line, 256, fp); 217 fgets(current_line, 256, fp);
226 if(fp != stdin) 218 if (fp != stdin)
227 bb_xferror(fp, filename); 219 bb_xferror(fp, filename);
228 flines = xrealloc(flines, (i+1) * sizeof(char *)); 220 flines = xrealloc(flines, (i+1) * sizeof(char *));
229 flines[i] = bb_xstrdup(current_line); 221 flines[i] = bb_xstrdup(current_line);
@@ -237,31 +229,25 @@ static void data_readlines(void) {
237 229
238 fclose(fp); 230 fclose(fp);
239 231
240 if(inp == NULL) 232 if (inp == NULL)
241 inp = (inp_stdin) ? bb_xfopen(CURRENT_TTY, "r") : stdin; 233 inp = (inp_stdin) ? bb_xfopen(CURRENT_TTY, "r") : stdin;
242 234
243 if (flags & FLAG_N) 235 if (flags & FLAG_N)
244 add_linenumbers(); 236 add_linenumbers();
245} 237}
246 238
247/* Turn a percentage into a line number */
248static int reverse_percent(int percentage) {
249 double linenum = percentage;
250 linenum = ((linenum / 100) * num_flines) - 1;
251 return(linenum);
252}
253
254#ifdef CONFIG_FEATURE_LESS_FLAGS 239#ifdef CONFIG_FEATURE_LESS_FLAGS
255 240
256/* Interestingly, writing calc_percent as a function and not a prototype saves around 32 bytes 241/* Interestingly, writing calc_percent as a function and not a prototype saves around 32 bytes
257 * on my build. */ 242 * on my build. */
258static int calc_percent(void) { 243static int calc_percent(void)
244{
259 return ((100 * (line_pos + height - 2) / num_flines) + 1); 245 return ((100 * (line_pos + height - 2) / num_flines) + 1);
260} 246}
261 247
262/* Print a status line if -M was specified */ 248/* Print a status line if -M was specified */
263static void m_status_print(void) { 249static void m_status_print(void)
264 250{
265 int percentage; 251 int percentage;
266 252
267 if (!past_eof) { 253 if (!past_eof) {
@@ -295,8 +281,8 @@ static void m_status_print(void) {
295} 281}
296 282
297/* Print a status line if -m was specified */ 283/* Print a status line if -m was specified */
298static void medium_status_print(void) { 284static void medium_status_print(void)
299 285{
300 int percentage; 286 int percentage;
301 percentage = calc_percent(); 287 percentage = calc_percent();
302 288
@@ -310,8 +296,8 @@ static void medium_status_print(void) {
310#endif 296#endif
311 297
312/* Print the status line */ 298/* Print the status line */
313static void status_print(void) { 299static void status_print(void)
314 300{
315 /* Change the status if flags have been set */ 301 /* Change the status if flags have been set */
316#ifdef CONFIG_FEATURE_LESS_FLAGS 302#ifdef CONFIG_FEATURE_LESS_FLAGS
317 if (flags & FLAG_M) 303 if (flags & FLAG_M)
@@ -340,8 +326,8 @@ static void status_print(void) {
340} 326}
341 327
342/* Print the buffer */ 328/* Print the buffer */
343static void buffer_print(void) { 329static void buffer_print(void)
344 330{
345 int i; 331 int i;
346 332
347 printf("%s", CLEAR); 333 printf("%s", CLEAR);
@@ -360,11 +346,11 @@ static void buffer_print(void) {
360} 346}
361 347
362/* Initialise the buffer */ 348/* Initialise the buffer */
363static void buffer_init(void) { 349static void buffer_init(void)
364 350{
365 int i; 351 int i;
366 352
367 if(buffer == NULL) { 353 if (buffer == NULL) {
368 /* malloc the number of lines needed for the buffer */ 354 /* malloc the number of lines needed for the buffer */
369 buffer = xrealloc(buffer, height * sizeof(char *)); 355 buffer = xrealloc(buffer, height * sizeof(char *));
370 } else { 356 } else {
@@ -385,8 +371,8 @@ static void buffer_init(void) {
385} 371}
386 372
387/* Move the buffer up and down in the file in order to scroll */ 373/* Move the buffer up and down in the file in order to scroll */
388static void buffer_down(int nlines) { 374static void buffer_down(int nlines)
389 375{
390 int i; 376 int i;
391 377
392 if (!past_eof) { 378 if (!past_eof) {
@@ -415,8 +401,8 @@ static void buffer_down(int nlines) {
415 } 401 }
416} 402}
417 403
418static void buffer_up(int nlines) { 404static void buffer_up(int nlines)
419 405{
420 int i; 406 int i;
421 int tilde_line; 407 int tilde_line;
422 408
@@ -467,15 +453,14 @@ static void buffer_up(int nlines) {
467 } 453 }
468} 454}
469 455
470static void buffer_line(int linenum) { 456static void buffer_line(int linenum)
471 457{
472 int i; 458 int i;
473
474 past_eof = 0; 459 past_eof = 0;
475 460
476 if (linenum < 1 || linenum > num_flines) { 461 if (linenum < 0 || linenum > num_flines) {
477 clear_line(); 462 clear_line();
478 printf("%s%s%i%s", HIGHLIGHT, "Cannot seek to line number ", linenum, NORMAL); 463 printf("%s%s%i%s", HIGHLIGHT, "Cannot seek to line number ", linenum + 1, NORMAL);
479 } 464 }
480 else if (linenum < (num_flines - height - 2)) { 465 else if (linenum < (num_flines - height - 2)) {
481 for (i = 0; i < (height - 1); i++) { 466 for (i = 0; i < (height - 1); i++) {
@@ -483,6 +468,7 @@ static void buffer_line(int linenum) {
483 buffer[i] = bb_xstrdup(flines[linenum + i]); 468 buffer[i] = bb_xstrdup(flines[linenum + i]);
484 } 469 }
485 line_pos = linenum; 470 line_pos = linenum;
471 buffer_print();
486 } 472 }
487 else { 473 else {
488 for (i = 0; i < (height - 1); i++) { 474 for (i = 0; i < (height - 1); i++) {
@@ -495,12 +481,13 @@ static void buffer_line(int linenum) {
495 line_pos = linenum; 481 line_pos = linenum;
496 /* Set past_eof so buffer_down and buffer_up act differently */ 482 /* Set past_eof so buffer_down and buffer_up act differently */
497 past_eof = 1; 483 past_eof = 1;
484 buffer_print();
498 } 485 }
499} 486}
500 487
501/* Reinitialise everything for a new file - free the memory and start over */ 488/* Reinitialise everything for a new file - free the memory and start over */
502static void reinitialise(void) { 489static void reinitialise(void)
503 490{
504 int i; 491 int i;
505 492
506 for (i = 0; i <= num_flines; i++) 493 for (i = 0; i <= num_flines; i++)
@@ -512,8 +499,8 @@ static void reinitialise(void) {
512 buffer_print(); 499 buffer_print();
513} 500}
514 501
515static void examine_file(void) { 502static void examine_file(void)
516 503{
517 int newline_offset; 504 int newline_offset;
518 505
519 clear_line(); 506 clear_line();
@@ -538,7 +525,8 @@ static void examine_file(void) {
538 * 0: go to the first file 525 * 0: go to the first file
539 * 1: go forward one file 526 * 1: go forward one file
540*/ 527*/
541static void change_file (int direction) { 528static void change_file(int direction)
529{
542 if (current_file != ((direction > 0) ? num_files : 1)) { 530 if (current_file != ((direction > 0) ? num_files : 1)) {
543 current_file = direction ? current_file + direction : 1; 531 current_file = direction ? current_file + direction : 1;
544 strcpy(filename, files[current_file - 1]); 532 strcpy(filename, files[current_file - 1]);
@@ -550,8 +538,8 @@ static void change_file (int direction) {
550 } 538 }
551} 539}
552 540
553static void remove_current_file(void) { 541static void remove_current_file(void)
554 542{
555 int i; 543 int i;
556 544
557 if (current_file != 1) { 545 if (current_file != 1) {
@@ -571,8 +559,8 @@ static void remove_current_file(void) {
571 } 559 }
572} 560}
573 561
574static void colon_process(void) { 562static void colon_process(void)
575 563{
576 int keypress; 564 int keypress;
577 565
578 /* Clear the current line and print a prompt */ 566 /* Clear the current line and print a prompt */
@@ -616,132 +604,128 @@ static void colon_process(void) {
616/* Get a regular expression from the user, and then go through the current 604/* Get a regular expression from the user, and then go through the current
617 file line by line, running a processing regex function on each one. */ 605 file line by line, running a processing regex function on each one. */
618 606
619static char *insert_highlights (char *line, int start, int end) { 607static char *process_regex_on_line(char *line, regex_t *pattern, int action)
620 608{
621 return bb_xasprintf("%.*s%s%.*s%s%s", start, line, HIGHLIGHT,
622 end - start, line + start, NORMAL, line + end);
623}
624
625static char *process_regex_on_line(char *line, regex_t *pattern) {
626 /* This function takes the regex and applies it to the line. 609 /* This function takes the regex and applies it to the line.
627 Each part of the line that matches has the HIGHLIGHT 610 Each part of the line that matches has the HIGHLIGHT
628 and NORMAL escape sequences placed around it by 611 and NORMAL escape sequences placed around it by
629 insert_highlights, and then the line is returned. */ 612 insert_highlights if action = 1, or has the escape sequences
630 613 removed if action = 0, and then the line is returned. */
631 int match_status; 614 int match_status;
632 char *line2 = (char *) malloc((sizeof(char) * (strlen(line) + 1)) + 64); 615 char *line2 = (char *) xmalloc((sizeof(char) * (strlen(line) + 1)) + 64);
633 char sub_line[256]; 616 char *growline = "";
634 int prev_eo = 0;
635 regmatch_t match_structs; 617 regmatch_t match_structs;
636 618
637 memset(sub_line, 0, 256); 619 line2 = bb_xstrdup(line);
638 strcpy(line2, line);
639 620
640 match_found = 0; 621 match_found = 0;
641 match_status = regexec(pattern, line2, 1, &match_structs, 0); 622 match_status = regexec(pattern, line2, 1, &match_structs, 0);
642 623
643 while (match_status == 0) { 624 while (match_status == 0) {
644
645 memset(sub_line, 0, 256);
646
647 if (match_found == 0) 625 if (match_found == 0)
648 match_found = 1; 626 match_found = 1;
649 627
650 line2 = insert_highlights(line2, match_structs.rm_so + prev_eo, match_structs.rm_eo + prev_eo); 628 if (action) {
651 if ((size_t)match_structs.rm_eo + 11 + prev_eo < strlen(line2)) 629 growline = bb_xasprintf("%s%.*s%s%.*s%s", growline, match_structs.rm_so, line2, HIGHLIGHT, match_structs.rm_eo - match_structs.rm_so, line2 + match_structs.rm_so, NORMAL);
652 strcat(sub_line, line2 + match_structs.rm_eo + 11 + prev_eo); 630 }
653 631 else {
654 prev_eo += match_structs.rm_eo + 11; 632 growline = bb_xasprintf("%s%.*s%.*s", growline, match_structs.rm_so - 4, line2, match_structs.rm_eo - match_structs.rm_so, line2 + match_structs.rm_so);
655 match_status = regexec(pattern, sub_line, 1, &match_structs, REG_NOTBOL); 633 }
634
635 line2 += match_structs.rm_eo;
636 match_status = regexec(pattern, line2, 1, &match_structs, REG_NOTBOL);
656 } 637 }
657 638
658 return line2; 639 growline = bb_xasprintf("%s%s", growline, line2);
640
641 return (match_found ? growline : line);
642
643 free(growline);
644 free(line2);
659} 645}
660 646
661static void regex_process(void) { 647static void goto_match(int match)
648{
649 /* This goes to a specific match - all line positions of matches are
650 stored within the match_lines[] array. */
651 if ((match < num_matches) && (match >= 0)) {
652 buffer_line(match_lines[match]);
653 match_pos = match;
654 }
655}
662 656
657static void regex_process(void)
658{
663 char uncomp_regex[100]; 659 char uncomp_regex[100];
664 char current_line[256]; 660 char *current_line;
665 int i; 661 int i;
666 int j = 0; 662 int j = 0;
667 regex_t *pattern; 663 regex_t pattern;
668
669 /* Reset variables */
670 match_lines[0] = -1;
671 match_pos = 0;
672 num_matches = 0;
673 match_found = 0;
674
675 pattern = (regex_t *) malloc(sizeof(regex_t));
676 memset(pattern, 0, sizeof(regex_t));
677
678 /* Get the uncompiled regular expression from the user */ 664 /* Get the uncompiled regular expression from the user */
679 clear_line(); 665 clear_line();
680 putchar((match_backwards) ? '?' : '/'); 666 putchar((match_backwards) ? '?' : '/');
681 uncomp_regex[0] = 0; 667 uncomp_regex[0] = 0;
682 fgets(uncomp_regex, sizeof(uncomp_regex), stdin); 668 fgets(uncomp_regex, sizeof(uncomp_regex), inp);
683 i = strlen(uncomp_regex); 669
684 if(i > 0) { 670 if (strlen(uncomp_regex) == 1) {
685 if(uncomp_regex[i-1] == '\n') 671 if (num_matches)
686 uncomp_regex[i-1] = '\0'; 672 goto_match(match_backwards ? match_pos - 1 : match_pos + 1);
687 else 673 else
688 while((i = getchar()) != '\n' && i != EOF); 674 buffer_print();
675 return;
689 } 676 }
690 677 uncomp_regex[strlen(uncomp_regex) - 1] = '\0';
678
691 /* Compile the regex and check for errors */ 679 /* Compile the regex and check for errors */
692 xregcomp(pattern, uncomp_regex, 0); 680 xregcomp(&pattern, uncomp_regex, 0);
693 681
682 if (num_matches) {
683 /* Get rid of all the highlights we added previously */
684 for (i = 0; i <= num_flines; i++) {
685 current_line = process_regex_on_line(flines[i], &old_pattern, 0);
686 flines[i] = bb_xstrdup(current_line);
687 }
688 }
689 old_pattern = pattern;
690
691 /* Reset variables */
692 match_lines = xrealloc(match_lines, sizeof(int));
693 match_lines[0] = -1;
694 match_pos = 0;
695 num_matches = 0;
696 match_found = 0;
694 /* Run the regex on each line of the current file here */ 697 /* Run the regex on each line of the current file here */
695 for (i = 0; i <= num_flines; i++) { 698 for (i = 0; i <= num_flines; i++) {
696 strcpy(current_line, process_regex_on_line(flines[i], pattern)); 699 current_line = process_regex_on_line(flines[i], &pattern, 1);
697 flines[i] = bb_xstrdup(current_line); 700 flines[i] = bb_xstrdup(current_line);
698 if (match_found) { 701 if (match_found) {
702 match_lines = xrealloc(match_lines, (j + 1) * sizeof(int));
699 match_lines[j] = i; 703 match_lines[j] = i;
700 j++; 704 j++;
701 } 705 }
702 } 706 }
703 707
704 num_matches = j; 708 num_matches = j;
705 if ((match_lines[0] != -1) && (num_flines > height - 2)) 709 if ((match_lines[0] != -1) && (num_flines > height - 2)) {
706 buffer_line(match_lines[0]); 710 if (match_backwards) {
707 else 711 for (i = 0; i < num_matches; i++) {
708 buffer_init(); 712 if (match_lines[i] > line_pos) {
709} 713 match_pos = i - 1;
710 714 buffer_line(match_lines[match_pos]);
711static void goto_match(int match) { 715 break;
712 716 }
713 /* This goes to a specific match - all line positions of matches are 717 }
714 stored within the match_lines[] array. */
715 if ((match < num_matches) && (match >= 0)) {
716 buffer_line(match_lines[match]);
717 match_pos = match;
718 }
719}
720
721static void search_backwards(void) {
722
723 int current_linepos = line_pos;
724 int i;
725
726 match_backwards = 1;
727 regex_process();
728
729 for (i = 0; i < num_matches; i++) {
730 if (match_lines[i] > current_linepos) {
731 buffer_line(match_lines[i - num_back_match]);
732 break;
733 } 718 }
719 else
720 buffer_line(match_lines[0]);
734 } 721 }
735 722 else
736 /* Reset variables */ 723 buffer_init();
737 match_backwards = 0;
738 num_back_match = 1;
739
740} 724}
741#endif 725#endif
742 726
743static void number_process(int first_digit) { 727static void number_process(int first_digit)
744 728{
745 int i = 1; 729 int i = 1;
746 int num; 730 int num;
747 char num_input[80]; 731 char num_input[80];
@@ -764,8 +748,10 @@ static void number_process(int first_digit) {
764 keypress = num_input[i]; 748 keypress = num_input[i];
765 num_input[i] = '\0'; 749 num_input[i] = '\0';
766 num = strtol(num_input, &endptr, 10); 750 num = strtol(num_input, &endptr, 10);
767 if (endptr==num_input || *endptr!='\0' || num < 1 || num > MAXLINES) 751 if (endptr==num_input || *endptr!='\0' || num < 1 || num > MAXLINES) {
768 goto END; 752 buffer_print();
753 return;
754 }
769 755
770 /* We now know the number and the letter entered, so we process them */ 756 /* We now know the number and the letter entered, so we process them */
771 switch (keypress) { 757 switch (keypress) {
@@ -780,31 +766,29 @@ static void number_process(int first_digit) {
780 buffer_line(num - 1); 766 buffer_line(num - 1);
781 break; 767 break;
782 case 'p': case '%': 768 case 'p': case '%':
783 buffer_line(reverse_percent(num)); 769 buffer_line(((num / 100) * num_flines) - 1);
784 break; 770 break;
785#ifdef CONFIG_FEATURE_LESS_REGEXP 771#ifdef CONFIG_FEATURE_LESS_REGEXP
786 case 'n': 772 case 'n':
787 goto_match(match_pos + num - 1); 773 goto_match(match_pos + num);
788 break; 774 break;
789 case '/': 775 case '/':
776 match_backwards = 0;
790 regex_process(); 777 regex_process();
791 goto_match(num - 1);
792 break; 778 break;
793 case '?': 779 case '?':
794 num_back_match = num; 780 match_backwards = 1;
795 search_backwards(); 781 regex_process();
796 break; 782 break;
797#endif 783#endif
798 default: 784 default:
799 break; 785 break;
800 } 786 }
801END:
802 buffer_print();
803} 787}
804 788
805#ifdef CONFIG_FEATURE_LESS_FLAGCS 789#ifdef CONFIG_FEATURE_LESS_FLAGCS
806static void flag_change(void) { 790static void flag_change(void)
807 791{
808 int keypress; 792 int keypress;
809 793
810 clear_line(); 794 clear_line();
@@ -829,8 +813,8 @@ static void flag_change(void) {
829 } 813 }
830} 814}
831 815
832static void show_flag_status(void) { 816static void show_flag_status(void)
833 817{
834 int keypress; 818 int keypress;
835 int flag_val; 819 int flag_val;
836 820
@@ -864,18 +848,17 @@ static void show_flag_status(void) {
864} 848}
865#endif 849#endif
866 850
867static void full_repaint(void) { 851static void full_repaint(void)
868 852{
869 int temp_line_pos = line_pos; 853 int temp_line_pos = line_pos;
870 data_readlines(); 854 data_readlines();
871 buffer_init(); 855 buffer_init();
872 buffer_line(temp_line_pos); 856 buffer_line(temp_line_pos);
873 buffer_print();
874} 857}
875 858
876 859
877static void save_input_to_file(void) { 860static void save_input_to_file(void)
878 861{
879 char current_line[256]; 862 char current_line[256];
880 int i; 863 int i;
881 FILE *fp; 864 FILE *fp;
@@ -884,7 +867,7 @@ static void save_input_to_file(void) {
884 printf("Log file: "); 867 printf("Log file: ");
885 fgets(current_line, 256, inp); 868 fgets(current_line, 256, inp);
886 current_line[strlen(current_line) - 1] = '\0'; 869 current_line[strlen(current_line) - 1] = '\0';
887 if (strlen(current_line)) { 870 if (strlen(current_line) > 1) {
888 fp = bb_xfopen(current_line, "w"); 871 fp = bb_xfopen(current_line, "w");
889 for (i = 0; i < num_flines; i++) 872 for (i = 0; i < num_flines; i++)
890 fprintf(fp, "%s", flines[i]); 873 fprintf(fp, "%s", flines[i]);
@@ -896,8 +879,8 @@ static void save_input_to_file(void) {
896} 879}
897 880
898#ifdef CONFIG_FEATURE_LESS_MARKS 881#ifdef CONFIG_FEATURE_LESS_MARKS
899static void add_mark(void) { 882static void add_mark(void)
900 883{
901 int letter; 884 int letter;
902 int mark_line; 885 int mark_line;
903 886
@@ -922,8 +905,8 @@ static void add_mark(void) {
922 } 905 }
923} 906}
924 907
925static void goto_mark(void) { 908static void goto_mark(void)
926 909{
927 int letter; 910 int letter;
928 int i; 911 int i;
929 912
@@ -949,8 +932,8 @@ static void goto_mark(void) {
949 932
950#ifdef CONFIG_FEATURE_LESS_BRACKETS 933#ifdef CONFIG_FEATURE_LESS_BRACKETS
951 934
952static char opp_bracket (char bracket) { 935static char opp_bracket(char bracket)
953 936{
954 switch (bracket) { 937 switch (bracket) {
955 case '{': case '[': 938 case '{': case '[':
956 return bracket + 2; 939 return bracket + 2;
@@ -970,8 +953,8 @@ static char opp_bracket (char bracket) {
970 } 953 }
971} 954}
972 955
973static void match_right_bracket(char bracket) { 956static void match_right_bracket(char bracket)
974 957{
975 int bracket_line = -1; 958 int bracket_line = -1;
976 int i; 959 int i;
977 960
@@ -991,12 +974,11 @@ static void match_right_bracket(char bracket) {
991 printf("%s%s%s", HIGHLIGHT, "No matching bracket found", NORMAL); 974 printf("%s%s%s", HIGHLIGHT, "No matching bracket found", NORMAL);
992 975
993 buffer_line(bracket_line - height + 2); 976 buffer_line(bracket_line - height + 2);
994 buffer_print();
995 } 977 }
996} 978}
997 979
998static void match_left_bracket (char bracket) { 980static void match_left_bracket(char bracket)
999 981{
1000 int bracket_line = -1; 982 int bracket_line = -1;
1001 int i; 983 int i;
1002 984
@@ -1019,13 +1001,13 @@ static void match_left_bracket (char bracket) {
1019 printf("%s%s%s", HIGHLIGHT, "No matching bracket found", NORMAL); 1001 printf("%s%s%s", HIGHLIGHT, "No matching bracket found", NORMAL);
1020 1002
1021 buffer_line(bracket_line); 1003 buffer_line(bracket_line);
1022 buffer_print();
1023 } 1004 }
1024} 1005}
1025 1006
1026#endif /* CONFIG_FEATURE_LESS_BRACKETS */ 1007#endif /* CONFIG_FEATURE_LESS_BRACKETS */
1027 1008
1028static void keypress_process(int keypress) { 1009static void keypress_process(int keypress)
1010{
1029 switch (keypress) { 1011 switch (keypress) {
1030 case KEY_DOWN: case 'e': case 'j': case '\015': 1012 case KEY_DOWN: case 'e': case 'j': case '\015':
1031 buffer_down(1); 1013 buffer_down(1);
@@ -1052,12 +1034,10 @@ static void keypress_process(int keypress) {
1052 buffer_print(); 1034 buffer_print();
1053 break; 1035 break;
1054 case 'g': case 'p': case '<': case '%': 1036 case 'g': case 'p': case '<': case '%':
1055 buffer_up(num_flines + 1); 1037 buffer_line(0);
1056 buffer_print();
1057 break; 1038 break;
1058 case 'G': case '>': 1039 case 'G': case '>':
1059 buffer_down(num_flines + 1); 1040 buffer_line(num_flines - height + 2);
1060 buffer_print();
1061 break; 1041 break;
1062 case 'q': case 'Q': 1042 case 'q': case 'Q':
1063 tless_exit(0); 1043 tless_exit(0);
@@ -1093,20 +1073,18 @@ static void keypress_process(int keypress) {
1093#endif 1073#endif
1094#ifdef CONFIG_FEATURE_LESS_REGEXP 1074#ifdef CONFIG_FEATURE_LESS_REGEXP
1095 case '/': 1075 case '/':
1076 match_backwards = 0;
1096 regex_process(); 1077 regex_process();
1097 buffer_print();
1098 break; 1078 break;
1099 case 'n': 1079 case 'n':
1100 goto_match(match_pos + 1); 1080 goto_match(match_pos + 1);
1101 buffer_print();
1102 break; 1081 break;
1103 case 'N': 1082 case 'N':
1104 goto_match(match_pos - 1); 1083 goto_match(match_pos - 1);
1105 buffer_print();
1106 break; 1084 break;
1107 case '?': 1085 case '?':
1108 search_backwards(); 1086 match_backwards = 1;
1109 buffer_print(); 1087 regex_process();
1110 break; 1088 break;
1111#endif 1089#endif
1112#ifdef CONFIG_FEATURE_LESS_FLAGCS 1090#ifdef CONFIG_FEATURE_LESS_FLAGCS