Deleted Added
full compact
search.c (221715) search.c (237613)
1/* $FreeBSD: head/contrib/less/search.c 221715 2011-05-09 21:51:59Z delphij $ */
1/* $FreeBSD: head/contrib/less/search.c 237613 2012-06-26 23:17:33Z delphij $ */
2/*
2/*
3 * Copyright (C) 1984-2011 Mark Nudelman
3 * Copyright (C) 1984-2012 Mark Nudelman
4 *
5 * You may distribute under the terms of either the GNU General Public
6 * License or the Less License, as specified in the README file.
7 *
4 *
5 * You may distribute under the terms of either the GNU General Public
6 * License or the Less License, as specified in the README file.
7 *
8 * For more information about less, or for information on how to
9 * contact the author, see the README file.
8 * For more information, see the README file.
10 */
11
12
13/*
14 * Routines to search a file for a pattern.
15 */
16
17#include "less.h"

--- 45 unchanged lines hidden (view full) ---

63 * These are the static variables that represent the "remembered"
64 * search pattern and filter pattern.
65 */
66struct pattern_info {
67 DEFINE_PATTERN(compiled);
68 char* text;
69 int search_type;
70};
9 */
10
11
12/*
13 * Routines to search a file for a pattern.
14 */
15
16#include "less.h"

--- 45 unchanged lines hidden (view full) ---

62 * These are the static variables that represent the "remembered"
63 * search pattern and filter pattern.
64 */
65struct pattern_info {
66 DEFINE_PATTERN(compiled);
67 char* text;
68 int search_type;
69};
70
71#if NO_REGEX
72#define info_compiled(info) ((void*)0)
73#else
74#define info_compiled(info) ((info)->compiled)
75#endif
71
72static struct pattern_info search_info;
73static struct pattern_info filter_info;
74
75/*
76 * Are there any uppercase letters in this string?
77 */
78 static int

--- 16 unchanged lines hidden (view full) ---

95 * Compile and save a search pattern.
96 */
97 static int
98set_pattern(info, pattern, search_type)
99 struct pattern_info *info;
100 char *pattern;
101 int search_type;
102{
76
77static struct pattern_info search_info;
78static struct pattern_info filter_info;
79
80/*
81 * Are there any uppercase letters in this string?
82 */
83 static int

--- 16 unchanged lines hidden (view full) ---

100 * Compile and save a search pattern.
101 */
102 static int
103set_pattern(info, pattern, search_type)
104 struct pattern_info *info;
105 char *pattern;
106 int search_type;
107{
108#if !NO_REGEX
103 if (pattern == NULL)
109 if (pattern == NULL)
104 CLEAR_PATTERN(search_info.compiled);
110 CLEAR_PATTERN(info->compiled);
105 else if (compile_pattern(pattern, search_type, &info->compiled) < 0)
106 return -1;
111 else if (compile_pattern(pattern, search_type, &info->compiled) < 0)
112 return -1;
113#endif
107 /* Pattern compiled successfully; save the text too. */
108 if (info->text != NULL)
109 free(info->text);
110 info->text = NULL;
111 if (pattern != NULL)
112 {
113 info->text = (char *) ecalloc(1, strlen(pattern)+1);
114 strcpy(info->text, pattern);

--- 17 unchanged lines hidden (view full) ---

132 */
133 static void
134clear_pattern(info)
135 struct pattern_info *info;
136{
137 if (info->text != NULL)
138 free(info->text);
139 info->text = NULL;
114 /* Pattern compiled successfully; save the text too. */
115 if (info->text != NULL)
116 free(info->text);
117 info->text = NULL;
118 if (pattern != NULL)
119 {
120 info->text = (char *) ecalloc(1, strlen(pattern)+1);
121 strcpy(info->text, pattern);

--- 17 unchanged lines hidden (view full) ---

139 */
140 static void
141clear_pattern(info)
142 struct pattern_info *info;
143{
144 if (info->text != NULL)
145 free(info->text);
146 info->text = NULL;
147#if !NO_REGEX
140 uncompile_pattern(&info->compiled);
148 uncompile_pattern(&info->compiled);
149#endif
141}
142
143/*
144 * Initialize saved pattern to nothing.
145 */
146 static void
147init_pattern(info)
148 struct pattern_info *info;

--- 39 unchanged lines hidden (view full) ---

188
189/*
190 * Is there a previous (remembered) search pattern?
191 */
192 static int
193prev_pattern(info)
194 struct pattern_info *info;
195{
150}
151
152/*
153 * Initialize saved pattern to nothing.
154 */
155 static void
156init_pattern(info)
157 struct pattern_info *info;

--- 39 unchanged lines hidden (view full) ---

197
198/*
199 * Is there a previous (remembered) search pattern?
200 */
201 static int
202prev_pattern(info)
203 struct pattern_info *info;
204{
196 if (info->search_type & SRCH_NO_REGEX)
197 return (info->text != NULL);
198 return (!is_null_pattern(info->compiled));
205#if !NO_REGEX
206 if ((info->search_type & SRCH_NO_REGEX) == 0)
207 return (!is_null_pattern(info->compiled));
208#endif
209 return (info->text != NULL);
199}
200
201#if HILITE_SEARCH
202/*
203 * Repaint the hilites currently displayed on the screen.
204 * Repaint each line which contains highlighted text.
205 * If on==0, force all hilites off.
206 */

--- 266 unchanged lines hidden (view full) ---

473 free(hl);
474 return;
475 }
476 hl->hl_next = ihl->hl_next;
477 ihl->hl_next = hl;
478}
479
480/*
210}
211
212#if HILITE_SEARCH
213/*
214 * Repaint the hilites currently displayed on the screen.
215 * Repaint each line which contains highlighted text.
216 * If on==0, force all hilites off.
217 */

--- 266 unchanged lines hidden (view full) ---

484 free(hl);
485 return;
486 }
487 hl->hl_next = ihl->hl_next;
488 ihl->hl_next = hl;
489}
490
491/*
492 * Hilight every character in a range of displayed characters.
493 */
494 static void
495create_hilites(linepos, start_index, end_index, chpos)
496 POSITION linepos;
497 int start_index;
498 int end_index;
499 int *chpos;
500{
501 struct hilite *hl;
502 int i;
503
504 /* Start the first hilite. */
505 hl = (struct hilite *) ecalloc(1, sizeof(struct hilite));
506 hl->hl_startpos = linepos + chpos[start_index];
507
508 /*
509 * Step through the displayed chars.
510 * If the source position (before cvt) of the char is one more
511 * than the source pos of the previous char (the usual case),
512 * just increase the size of the current hilite by one.
513 * Otherwise (there are backspaces or something involved),
514 * finish the current hilite and start a new one.
515 */
516 for (i = start_index+1; i <= end_index; i++)
517 {
518 if (chpos[i] != chpos[i-1] + 1 || i == end_index)
519 {
520 hl->hl_endpos = linepos + chpos[i-1] + 1;
521 add_hilite(&hilite_anchor, hl);
522 /* Start new hilite unless this is the last char. */
523 if (i < end_index)
524 {
525 hl = (struct hilite *) ecalloc(1, sizeof(struct hilite));
526 hl->hl_startpos = linepos + chpos[i];
527 }
528 }
529 }
530}
531
532/*
481 * Make a hilite for each string in a physical line which matches
482 * the current pattern.
483 * sp,ep delimit the first match already found.
484 */
485 static void
486hilite_line(linepos, line, line_len, chpos, sp, ep, cvt_ops)
487 POSITION linepos;
488 char *line;
489 int line_len;
490 int *chpos;
491 char *sp;
492 char *ep;
493 int cvt_ops;
494{
495 char *searchp;
496 char *line_end = line + line_len;
533 * Make a hilite for each string in a physical line which matches
534 * the current pattern.
535 * sp,ep delimit the first match already found.
536 */
537 static void
538hilite_line(linepos, line, line_len, chpos, sp, ep, cvt_ops)
539 POSITION linepos;
540 char *line;
541 int line_len;
542 int *chpos;
543 char *sp;
544 char *ep;
545 int cvt_ops;
546{
547 char *searchp;
548 char *line_end = line + line_len;
497 struct hilite *hl;
498
499 if (sp == NULL || ep == NULL)
500 return;
501 /*
502 * sp and ep delimit the first match in the line.
503 * Mark the corresponding file positions, then
504 * look for further matches and mark them.
505 * {{ This technique, of calling match_pattern on subsequent
506 * substrings of the line, may mark more than is correct
507 * if the pattern starts with "^". This bug is fixed
508 * for those regex functions that accept a notbol parameter
509 * (currently POSIX, PCRE and V8-with-regexec2). }}
510 */
511 searchp = line;
512 do {
549
550 if (sp == NULL || ep == NULL)
551 return;
552 /*
553 * sp and ep delimit the first match in the line.
554 * Mark the corresponding file positions, then
555 * look for further matches and mark them.
556 * {{ This technique, of calling match_pattern on subsequent
557 * substrings of the line, may mark more than is correct
558 * if the pattern starts with "^". This bug is fixed
559 * for those regex functions that accept a notbol parameter
560 * (currently POSIX, PCRE and V8-with-regexec2). }}
561 */
562 searchp = line;
563 do {
513 if (ep > sp)
514 {
515 hl = (struct hilite *) ecalloc(1, sizeof(struct hilite));
516 hl->hl_startpos = linepos + chpos[sp-line];
517 hl->hl_endpos = linepos + chpos[ep-line];
518 add_hilite(&hilite_anchor, hl);
519 }
564 create_hilites(linepos, sp-line, ep-line, chpos);
520 /*
521 * If we matched more than zero characters,
522 * move to the first char after the string we matched.
523 * If we matched zero, just move to the next char.
524 */
525 if (ep > searchp)
526 searchp = ep;
527 else if (searchp != line_end)
528 searchp++;
529 else /* end of line */
530 break;
565 /*
566 * If we matched more than zero characters,
567 * move to the first char after the string we matched.
568 * If we matched zero, just move to the next char.
569 */
570 if (ep > searchp)
571 searchp = ep;
572 else if (searchp != line_end)
573 searchp++;
574 else /* end of line */
575 break;
531 } while (match_pattern(search_info.compiled, search_info.text,
576 } while (match_pattern(info_compiled(&search_info), search_info.text,
532 searchp, line_end - searchp, &sp, &ep, 1, search_info.search_type));
533}
534#endif
535
536/*
537 * Change the caseless-ness of searches.
538 * Updates the internal search state to reflect a change in the -i flag.
539 */

--- 255 unchanged lines hidden (view full) ---

795 cvt_text(cline, line, chpos, &line_len, cvt_ops);
796
797#if HILITE_SEARCH
798 /*
799 * Check to see if the line matches the filter pattern.
800 * If so, add an entry to the filter list.
801 */
802 if ((search_type & SRCH_FIND_ALL) && prev_pattern(&filter_info)) {
577 searchp, line_end - searchp, &sp, &ep, 1, search_info.search_type));
578}
579#endif
580
581/*
582 * Change the caseless-ness of searches.
583 * Updates the internal search state to reflect a change in the -i flag.
584 */

--- 255 unchanged lines hidden (view full) ---

840 cvt_text(cline, line, chpos, &line_len, cvt_ops);
841
842#if HILITE_SEARCH
843 /*
844 * Check to see if the line matches the filter pattern.
845 * If so, add an entry to the filter list.
846 */
847 if ((search_type & SRCH_FIND_ALL) && prev_pattern(&filter_info)) {
803 int line_filter = match_pattern(filter_info.compiled, filter_info.text,
848 int line_filter = match_pattern(info_compiled(&filter_info), filter_info.text,
804 cline, line_len, &sp, &ep, 0, filter_info.search_type);
805 if (line_filter)
806 {
807 struct hilite *hl = (struct hilite *)
808 ecalloc(1, sizeof(struct hilite));
809 hl->hl_startpos = linepos;
810 hl->hl_endpos = pos;
811 add_hilite(&filter_anchor, hl);
812 }
813 }
814#endif
815
816 /*
817 * Test the next line to see if we have a match.
818 * We are successful if we either want a match and got one,
819 * or if we want a non-match and got one.
820 */
821 if (prev_pattern(&search_info))
822 {
849 cline, line_len, &sp, &ep, 0, filter_info.search_type);
850 if (line_filter)
851 {
852 struct hilite *hl = (struct hilite *)
853 ecalloc(1, sizeof(struct hilite));
854 hl->hl_startpos = linepos;
855 hl->hl_endpos = pos;
856 add_hilite(&filter_anchor, hl);
857 }
858 }
859#endif
860
861 /*
862 * Test the next line to see if we have a match.
863 * We are successful if we either want a match and got one,
864 * or if we want a non-match and got one.
865 */
866 if (prev_pattern(&search_info))
867 {
823 line_match = match_pattern(search_info.compiled, search_info.text,
868 line_match = match_pattern(info_compiled(&search_info), search_info.text,
824 cline, line_len, &sp, &ep, 0, search_type);
825 if (line_match)
826 {
827 /*
828 * Got a match.
829 */
830 if (search_type & SRCH_FIND_ALL)
831 {

--- 382 unchanged lines hidden ---
869 cline, line_len, &sp, &ep, 0, search_type);
870 if (line_match)
871 {
872 /*
873 * Got a match.
874 */
875 if (search_type & SRCH_FIND_ALL)
876 {

--- 382 unchanged lines hidden ---