2 * Copyright (C) 1984-2008 Mark Nudelman
4 * You may distribute under the terms of either the GNU General Public
5 * License or the Less License, as specified in the README file.
7 * For more information about less, or for information on how to
8 * contact the author, see the README file.
13 * Routines to search a file for a pattern.
20 #define MINPOS(a,b) (((a) < (b)) ? (a) : (b))
21 #define MAXPOS(a,b) (((a) > (b)) ? (a) : (b))
23 #if HAVE_POSIX_REGCOMP
26 #define REGCOMP_FLAG REG_EXTENDED
28 #define REGCOMP_FLAG 0
50 extern int how_search
;
54 extern int jump_sline
;
57 extern int status_col
;
58 extern void * constant ml_search
;
59 extern POSITION start_attnpos
;
60 extern POSITION end_attnpos
;
62 extern int screen_trashed
;
64 extern int hilite_search
;
65 extern int size_linebuf
;
67 extern int can_goto_line
;
68 static int hide_hilite
;
70 static POSITION prep_startpos
;
71 static POSITION prep_endpos
;
75 struct hilite
*hl_next
;
79 static struct hilite hilite_anchor
= { NULL
, NULL_POSITION
, NULL_POSITION
};
80 static struct hilite filter_anchor
= { NULL
, NULL_POSITION
, NULL_POSITION
};
81 #define hl_first hl_next
85 * These are the static variables that represent the "remembered"
88 #if HAVE_POSIX_REGCOMP
89 #define DEFINE_PATTERN(name) static regex_t *name = NULL
92 #define DEFINE_PATTERN(name) pcre *name = NULL;
95 #define DEFINE_PATTERN(name) int name = 0;
98 #define DEFINE_PATTERN(name) static char *name = NULL;
101 #define DEFINE_PATTERN(name) static struct regexp *name = NULL;
104 DEFINE_PATTERN(search_pattern
);
105 DEFINE_PATTERN(filter_pattern
);
107 static int is_caseless
;
108 static int is_ucase_pattern
;
109 static int last_search_type
;
110 static int last_filter_type
;
111 static char *last_pattern
= NULL
;
113 #define CVT_TO_LC 01 /* Convert upper-case to lower-case */
114 #define CVT_BS 02 /* Do backspace processing */
115 #define CVT_CRLF 04 /* Remove CR after LF */
116 #define CVT_ANSI 010 /* Remove ANSI escape sequences */
119 * Get the length of a buffer needed to convert a string.
128 * Just copying a string in UTF-8 mode can cause it to grow
130 * Six output bytes for one input byte is the worst case
131 * (and unfortunately is far more than is needed in any
132 * non-pathological situation, so this is very wasteful).
139 * Convert text. Perform the transformations specified by ops.
142 cvt_text(odst
, osrc
, lenp
, ops
)
150 register char *src_end
;
154 src_end
= osrc
+ *lenp
;
156 src_end
= osrc
+ strlen(osrc
);
158 for (src
= osrc
, dst
= odst
; src
< src_end
; )
160 ch
= step_char(&src
, +1, src_end
);
161 if ((ops
& CVT_TO_LC
) && IS_UPPER(ch
))
163 /* Convert uppercase to lowercase. */
164 put_wchar(&dst
, TO_LOWER(ch
));
165 } else if ((ops
& CVT_BS
) && ch
== '\b' && dst
> odst
)
167 /* Delete backspace and preceding char. */
170 } while (dst
> odst
&&
171 !IS_ASCII_OCTET(*dst
) && !IS_UTF8_LEAD(*dst
));
172 } else if ((ops
& CVT_ANSI
) && IS_CSI_START(ch
))
174 /* Skip to end of ANSI escape sequence. */
175 src
++; /* skip the CSI start char */
176 while (src
< src_end
)
177 if (!is_ansi_middle(*src
++))
183 if ((ops
& CVT_CRLF
) && dst
> odst
&& dst
[-1] == '\r')
191 * Determine which conversions to perform.
197 if (is_caseless
|| bs_mode
== BS_SPECIAL
)
201 if (bs_mode
== BS_SPECIAL
)
203 if (bs_mode
!= BS_CONTROL
)
205 } else if (bs_mode
!= BS_CONTROL
)
209 if (ctldisp
== OPT_ONPLUS
)
215 * Are there any uppercase letters in this string?
221 char *str_end
= str
+ strlen(str
);
224 while (str
< str_end
)
226 ch
= step_char(&str
, +1, str_end
);
234 * Is there a previous (remembered) search pattern?
239 if (last_search_type
& SRCH_NO_REGEX
)
240 return (last_pattern
!= NULL
);
241 #if HAVE_POSIX_REGCOMP
242 return (search_pattern
!= NULL
);
245 return (search_pattern
!= NULL
);
248 return (search_pattern
!= 0);
251 return (search_pattern
!= NULL
);
254 return (search_pattern
!= NULL
);
257 return (search_pattern
!= NULL
);
263 * Repaint the hilites currently displayed on the screen.
264 * Repaint each line which contains highlighted text.
265 * If on==0, force all hilites off.
274 int save_hide_hilite
;
279 save_hide_hilite
= hide_hilite
;
290 hide_hilite
= save_hide_hilite
;
294 for (slinenum
= TOP
; slinenum
< TOP
+ sc_height
-1; slinenum
++)
296 pos
= position(slinenum
);
297 if (pos
== NULL_POSITION
)
299 epos
= position(slinenum
+1);
302 * If any character in the line is highlighted,
305 * {{ This doesn't work -- if line is drawn with highlights
306 * which should be erased (e.g. toggle -i with status column),
307 * we must redraw the line even if it has no highlights.
308 * For now, just repaint every line. }}
310 if (is_hilited(pos
, epos
, 1, NULL
))
313 (void) forw_line(pos
);
320 hide_hilite
= save_hide_hilite
;
324 * Clear the attn hilite.
330 POSITION old_start_attnpos
;
331 POSITION old_end_attnpos
;
336 if (start_attnpos
== NULL_POSITION
)
338 old_start_attnpos
= start_attnpos
;
339 old_end_attnpos
= end_attnpos
;
340 start_attnpos
= end_attnpos
= NULL_POSITION
;
350 for (slinenum
= TOP
; slinenum
< TOP
+ sc_height
-1; slinenum
++)
352 pos
= position(slinenum
);
353 if (pos
== NULL_POSITION
)
355 epos
= position(slinenum
+1);
356 if (pos
< old_end_attnpos
&&
357 (epos
== NULL_POSITION
|| epos
> old_start_attnpos
))
359 (void) forw_line(pos
);
371 * Hide search string highlighting.
378 error("No previous regular expression", NULL_PARG
);
382 hide_hilite
= !hide_hilite
;
388 * Compile a search pattern, for future use by match_pattern.
391 compile_pattern2(pattern
, search_type
, comp_pattern
)
396 if ((search_type
& SRCH_NO_REGEX
) == 0)
398 #if HAVE_POSIX_REGCOMP
399 regex_t
*comp
= (regex_t
*) ecalloc(1, sizeof(regex_t
));
400 regex_t
**pcomp
= (regex_t
**) comp_pattern
;
401 if (regcomp(comp
, pattern
, REGCOMP_FLAG
))
404 error("Invalid pattern", NULL_PARG
);
413 pcre
**pcomp
= (pcre
**) comp_pattern
;
414 const char *errstring
;
417 comp
= pcre_compile(pattern
, 0,
418 &errstring
, &erroffset
, NULL
);
421 parg
.p_string
= (char *) errstring
;
429 int *pcomp
= (int *) comp_pattern
;
430 if ((parg
.p_string
= re_comp(pattern
)) != NULL
)
439 char **pcomp
= (char **) comp_pattern
;
440 if ((comp
= regcmp(pattern
, 0)) == NULL
)
442 error("Invalid pattern", NULL_PARG
);
451 struct regexp
**pcomp
= (struct regexp
**) comp_pattern
;
452 if ((comp
= regcomp(pattern
)) == NULL
)
455 * regcomp has already printed an error message
466 if (comp_pattern
== (void **) &search_pattern
)
468 if (last_pattern
!= NULL
)
470 last_pattern
= (char *) calloc(1, strlen(pattern
)+1);
471 if (last_pattern
!= NULL
)
472 strcpy(last_pattern
, pattern
);
473 last_search_type
= search_type
;
476 last_filter_type
= search_type
;
482 * Like compile_pattern2, but convert the pattern to lowercase if necessary.
485 compile_pattern(pattern
, search_type
, comp_pattern
)
493 if (caseless
!= OPT_ONPLUS
)
494 cvt_pattern
= pattern
;
497 cvt_pattern
= (char*) ecalloc(1, cvt_length(strlen(pattern
), CVT_TO_LC
));
498 cvt_text(cvt_pattern
, pattern
, (int *)NULL
, CVT_TO_LC
);
500 result
= compile_pattern2(cvt_pattern
, search_type
, comp_pattern
);
501 if (cvt_pattern
!= pattern
)
507 * Forget that we have a compiled pattern.
510 uncompile_pattern(pattern
)
513 #if HAVE_POSIX_REGCOMP
514 regex_t
**pcomp
= (regex_t
**) pattern
;
520 pcre
**pcomp
= (pcre
**) pattern
;
526 int *pcomp
= (int *) pattern
;
530 char **pcomp
= (char **) pattern
;
536 struct regexp
**pcomp
= (struct regexp
**) pattern
;
544 uncompile_search_pattern()
546 uncompile_pattern(&search_pattern
);
551 uncompile_filter_pattern()
553 uncompile_pattern(&filter_pattern
);
557 * Is a compiled pattern null?
560 is_null_pattern(pattern
)
563 #if HAVE_POSIX_REGCOMP
564 return (pattern
== NULL
);
567 return (pattern
== NULL
);
570 return (pattern
== 0);
573 return (pattern
== NULL
);
576 return (pattern
== NULL
);
581 * Perform a pattern match with the previously compiled pattern.
582 * Set sp and ep to the start and end of the matched string.
585 match_pattern(pattern
, line
, line_len
, sp
, ep
, notbol
, search_type
)
595 #if HAVE_POSIX_REGCOMP
596 regex_t
*spattern
= (regex_t
*) pattern
;
599 pcre
*spattern
= (pcre
*) pattern
;
602 int spattern
= (int) pattern
;
605 char *spattern
= (char *) pattern
;
608 struct regexp
*spattern
= (struct regexp
*) pattern
;
611 if (search_type
& SRCH_NO_REGEX
)
612 return (match(last_pattern
, strlen(last_pattern
), line
, line_len
, sp
, ep
));
614 #if HAVE_POSIX_REGCOMP
617 int flags
= (notbol
) ? REG_NOTBOL
: 0;
618 matched
= !regexec(spattern
, line
, 1, &rm
, flags
);
622 *sp
= line
+ rm
.rm_so
;
623 *ep
= line
+ rm
.rm_eo
;
633 int flags
= (notbol
) ? PCRE_NOTBOL
: 0;
635 matched
= pcre_exec(spattern
, NULL
, line
, line_len
,
636 0, flags
, ovector
, 3) >= 0;
639 *sp
= line
+ ovector
[0];
640 *ep
= line
+ ovector
[1];
645 matched
= (re_exec(line
) == 1);
647 * re_exec doesn't seem to provide a way to get the matched string.
652 *ep
= regex(spattern
, line
);
653 matched
= (*ep
!= NULL
);
659 matched
= regexec2(spattern
, line
, notbol
);
661 matched
= regexec(spattern
, line
);
665 *sp
= spattern
->startp
[0];
666 *ep
= spattern
->endp
[0];
670 matched
= match(last_pattern
, strlen(last_pattern
), line
, line_len
, sp
, ep
);
672 matched
= (!(search_type
& SRCH_NO_MATCH
) && matched
) ||
673 ((search_type
& SRCH_NO_MATCH
) && !matched
);
679 * Clear the hilite list.
683 struct hilite
*anchor
;
686 struct hilite
*nexthl
;
688 for (hl
= anchor
->hl_first
; hl
!= NULL
; hl
= nexthl
)
690 nexthl
= hl
->hl_next
;
693 anchor
->hl_first
= NULL
;
694 prep_startpos
= prep_endpos
= NULL_POSITION
;
700 clr_hlist(&hilite_anchor
);
706 clr_hlist(&filter_anchor
);
710 * Should any characters in a specified range be highlighted?
713 is_hilited_range(pos
, epos
)
720 * Look at each highlight and see if any part of it falls in the range.
722 for (hl
= hilite_anchor
.hl_first
; hl
!= NULL
; hl
= hl
->hl_next
)
724 if (hl
->hl_endpos
> pos
&&
725 (epos
== NULL_POSITION
|| epos
> hl
->hl_startpos
))
732 * Is a line "filtered" -- that is, should it be hidden?
740 if (ch_getflags() & CH_HELPFILE
)
744 * Look at each filter and see if the start position
745 * equals the start position of the line.
747 for (hl
= filter_anchor
.hl_first
; hl
!= NULL
; hl
= hl
->hl_next
)
749 if (hl
->hl_startpos
== pos
)
756 * Should any characters in a specified range be highlighted?
757 * If nohide is nonzero, don't consider hide_hilite.
760 is_hilited(pos
, epos
, nohide
, p_matches
)
768 if (p_matches
!= NULL
)
772 start_attnpos
!= NULL_POSITION
&&
774 (epos
== NULL_POSITION
|| epos
> start_attnpos
))
776 * The attn line overlaps this range.
780 match
= is_hilited_range(pos
, epos
);
784 if (p_matches
!= NULL
)
786 * Report matches, even if we're hiding highlights.
790 if (hilite_search
== 0)
792 * Not doing highlighting.
796 if (!nohide
&& hide_hilite
)
798 * Highlighting is hidden.
806 * Add a new hilite to a hilite list.
809 add_hilite(anchor
, hl
)
810 struct hilite
*anchor
;
816 * Hilites are sorted in the list; find where new one belongs.
817 * Insert new one after ihl.
819 for (ihl
= anchor
; ihl
->hl_next
!= NULL
; ihl
= ihl
->hl_next
)
821 if (ihl
->hl_next
->hl_startpos
> hl
->hl_startpos
)
826 * Truncate hilite so it doesn't overlap any existing ones
827 * above and below it.
830 hl
->hl_startpos
= MAXPOS(hl
->hl_startpos
, ihl
->hl_endpos
);
831 if (ihl
->hl_next
!= NULL
)
832 hl
->hl_endpos
= MINPOS(hl
->hl_endpos
, ihl
->hl_next
->hl_startpos
);
833 if (hl
->hl_startpos
>= hl
->hl_endpos
)
836 * Hilite was truncated out of existence.
841 hl
->hl_next
= ihl
->hl_next
;
846 * Adjust hl_startpos & hl_endpos to account for processing by cvt_text.
849 adj_hilite(anchor
, linepos
, cvt_ops
)
850 struct hilite
*anchor
;
868 * The line was already scanned and hilites were added (in hilite_line).
869 * But it was assumed that each char position in the line
870 * correponds to one char position in the file.
871 * This may not be true if cvt_text modified the line.
872 * Get the raw line again. Look at each character.
874 (void) forw_raw_line(linepos
, &line
, &line_len
);
875 line_end
= line
+ line_len
;
876 opos
= npos
= linepos
;
877 hl
= anchor
->hl_first
;
880 hl_opos
= hl_npos
= hl
->hl_startpos
;
883 while (hl
!= NULL
&& line
< line_end
)
886 * See if we need to adjust the current hl_startpos or
887 * hl_endpos. After adjusting startpos[i], move to endpos[i].
888 * After adjusting endpos[i], move to startpos[i+1].
889 * The hilite list must be sorted thus:
890 * startpos[0] < endpos[0] <= startpos[1] < endpos[1] <= etc.
893 ch
= step_char(&line
, +1, line_end
);
894 ncwidth
= line
- oline
;
897 /* Figure out how this char was processed by cvt_text. */
898 if ((cvt_ops
& CVT_BS
) && ch
== '\b')
900 /* Skip the backspace and the following char. */
902 ch
= step_char(&line
, +1, line_end
);
903 ncwidth
= line
- oline
;
905 } else if ((cvt_ops
& CVT_TO_LC
) && IS_UPPER(ch
))
907 /* Converted uppercase to lower.
908 * Note that this may have changed the number of bytes
909 * that the character occupies. */
912 put_wchar(&dst
, TO_LOWER(ch
));
914 } else if ((cvt_ops
& CVT_ANSI
) && IS_CSI_START(ch
))
916 /* Skip to end of ANSI escape sequence. */
917 line
++; /* skip the CSI start char */
919 while (line
< line_end
)
922 if (!is_ansi_middle(*line
++))
927 /* Ordinary unprocessed character. */
931 if (opos
== hl_opos
) {
932 /* Adjust highlight position. */
938 * We've moved past the highlight position; store the
939 * adjusted highlight position and move to the next highlight.
943 hl
->hl_startpos
= hl_npos
;
944 hl_opos
= hl
->hl_endpos
;
948 hl
->hl_endpos
= hl_npos
;
951 hl_opos
= hl
->hl_startpos
;
960 * Make a hilite for each string in a physical line which matches
961 * the current pattern.
962 * sp,ep delimit the first match already found.
965 hilite_line(linepos
, line
, line_len
, sp
, ep
, cvt_ops
)
974 char *line_end
= line
+ line_len
;
976 struct hilite hilites
;
978 if (sp
== NULL
|| ep
== NULL
)
981 * sp and ep delimit the first match in the line.
982 * Mark the corresponding file positions, then
983 * look for further matches and mark them.
984 * {{ This technique, of calling match_pattern on subsequent
985 * substrings of the line, may mark more than is correct
986 * if the pattern starts with "^". This bug is fixed
987 * for those regex functions that accept a notbol parameter
988 * (currently POSIX, PCRE and V8-with-regexec2). }}
992 * Put the hilites into a temporary list until they're adjusted.
994 hilites
.hl_first
= NULL
;
999 * Assume that each char position in the "line"
1000 * buffer corresponds to one char position in the file.
1001 * This is not quite true; we need to adjust later.
1003 hl
= (struct hilite
*) ecalloc(1, sizeof(struct hilite
));
1004 hl
->hl_startpos
= linepos
+ (sp
-line
);
1005 hl
->hl_endpos
= linepos
+ (ep
-line
);
1006 add_hilite(&hilites
, hl
);
1009 * If we matched more than zero characters,
1010 * move to the first char after the string we matched.
1011 * If we matched zero, just move to the next char.
1015 else if (searchp
!= line_end
)
1017 else /* end of line */
1019 } while (match_pattern(search_pattern
, searchp
, line_end
- searchp
, &sp
, &ep
, 1, last_search_type
));
1022 * If there were backspaces in the original line, they
1023 * were removed, and hl_startpos/hl_endpos are not correct.
1024 * {{ This is very ugly. }}
1026 adj_hilite(&hilites
, linepos
, cvt_ops
);
1029 * Now put the hilites into the real list.
1031 while ((hl
= hilites
.hl_next
) != NULL
)
1033 hilites
.hl_next
= hl
->hl_next
;
1034 add_hilite(&hilite_anchor
, hl
);
1040 * Change the caseless-ness of searches.
1041 * Updates the internal search state to reflect a change in the -i flag.
1046 if (!is_ucase_pattern
)
1048 * Pattern did not have uppercase.
1049 * Just set the search caselessness to the global caselessness.
1051 is_caseless
= caseless
;
1054 * Pattern did have uppercase.
1055 * Discard the pattern; we can't change search caselessness now.
1057 uncompile_search_pattern();
1062 * Find matching text which is currently on screen and highlight it.
1067 struct scrpos scrpos
;
1069 get_scrpos(&scrpos
);
1070 if (scrpos
.pos
== NULL_POSITION
)
1072 prep_hilite(scrpos
.pos
, position(BOTTOM_PLUS_ONE
), -1);
1077 * Change highlighting parameters.
1083 * Erase any highlights currently on screen.
1088 if (hilite_search
== OPT_ONPLUS
)
1090 * Display highlights.
1097 * Figure out where to start a search.
1100 search_pos(search_type
)
1109 * Start at the beginning (or end) of the file.
1110 * The empty_screen() case is mainly for
1111 * command line initiated searches;
1112 * for example, "+/xyz" on the command line.
1113 * Also for multi-file (SRCH_PAST_EOF) searches.
1115 if (search_type
& SRCH_FORW
)
1121 if (pos
== NULL_POSITION
)
1123 (void) ch_end_seek();
1132 * Search does not include current screen.
1134 if (search_type
& SRCH_FORW
)
1135 linenum
= BOTTOM_PLUS_ONE
;
1138 pos
= position(linenum
);
1142 * Search includes current screen.
1143 * It starts at the jump target (if searching backwards),
1144 * or at the jump target plus one (if forwards).
1146 linenum
= adjsline(jump_sline
);
1147 pos
= position(linenum
);
1148 if (search_type
& SRCH_FORW
)
1150 pos
= forw_raw_line(pos
, (char **)NULL
, (int *)NULL
);
1151 while (pos
== NULL_POSITION
)
1153 if (++linenum
>= sc_height
)
1155 pos
= position(linenum
);
1159 while (pos
== NULL_POSITION
)
1163 pos
= position(linenum
);
1171 * Search a subset of the file, specified by start/end position.
1174 search_range(pos
, endpos
, search_type
, matches
, maxlines
, plinepos
, pendpos
)
1190 POSITION linepos
, oldpos
;
1192 linenum
= find_linenum(pos
);
1197 * Get lines until we find a matching one or until
1198 * we hit end-of-file (or beginning-of-file if we're
1199 * going backwards), or until we hit the end position.
1204 * A signal aborts the search.
1209 if ((endpos
!= NULL_POSITION
&& pos
>= endpos
) || maxlines
== 0)
1212 * Reached end position without a match.
1214 if (pendpos
!= NULL
)
1221 if (search_type
& SRCH_FORW
)
1224 * Read the next line, and save the
1225 * starting position of that line in linepos.
1228 pos
= forw_raw_line(pos
, &line
, &line_len
);
1234 * Read the previous line and save the
1235 * starting position of that line in linepos.
1237 pos
= back_raw_line(pos
, &line
, &line_len
);
1243 if (pos
== NULL_POSITION
)
1246 * Reached EOF/BOF without a match.
1248 if (pendpos
!= NULL
)
1254 * If we're using line numbers, we might as well
1255 * remember the information we have now (the position
1256 * and line number of the current line).
1257 * Don't do it for every line because it slows down
1258 * the search. Remember the line number only if
1259 * we're "far" from the last place we remembered it.
1261 if (linenums
&& abs((int)(pos
- oldpos
)) > 1024)
1262 add_lnum(linenum
, pos
);
1265 if (is_filtered(linepos
))
1269 * If it's a caseless search, convert the line to lowercase.
1270 * If we're doing backspace processing, delete backspaces.
1272 cvt_ops
= get_cvt_ops();
1273 cline
= calloc(1, cvt_length(line_len
, cvt_ops
));
1274 cvt_text(cline
, line
, &line_len
, cvt_ops
);
1278 * Check to see if the line matches the filter pattern.
1279 * If so, add an entry to the filter list.
1281 if ((search_type
& SRCH_FIND_ALL
) &&
1282 !is_null_pattern(filter_pattern
))
1284 int line_filter
= match_pattern(filter_pattern
,
1285 cline
, line_len
, &sp
, &ep
, 0, last_filter_type
);
1288 struct hilite
*hl
= (struct hilite
*)
1289 ecalloc(1, sizeof(struct hilite
));
1290 hl
->hl_startpos
= linepos
;
1291 hl
->hl_endpos
= pos
;
1292 add_hilite(&filter_anchor
, hl
);
1298 * Test the next line to see if we have a match.
1299 * We are successful if we either want a match and got one,
1300 * or if we want a non-match and got one.
1302 if (!is_null_pattern(search_pattern
))
1304 line_match
= match_pattern(search_pattern
,
1305 cline
, line_len
, &sp
, &ep
, 0, search_type
);
1311 if (search_type
& SRCH_FIND_ALL
)
1315 * We are supposed to find all matches in the range.
1316 * Just add the matches in this line to the
1317 * hilite list and keep searching.
1319 hilite_line(linepos
, cline
, line_len
, sp
, ep
, cvt_ops
);
1321 } else if (--matches
<= 0)
1324 * Found the one match we're looking for.
1328 if (hilite_search
== OPT_ON
)
1331 * Clear the hilite list and add only
1332 * the matches in this one line.
1335 hilite_line(linepos
, cline
, line_len
, sp
, ep
, cvt_ops
);
1339 if (plinepos
!= NULL
)
1340 *plinepos
= linepos
;
1350 * search for a pattern in history. If found, compile that pattern.
1353 hist_pattern(search_type
)
1359 set_mlist(ml_search
, 0);
1360 pattern
= cmd_lastpattern();
1361 if (pattern
== NULL
)
1364 if (compile_pattern(pattern
, search_type
, &search_pattern
) < 0)
1367 is_ucase_pattern
= is_ucase(pattern
);
1368 if (is_ucase_pattern
&& caseless
!= OPT_ONPLUS
)
1371 is_caseless
= caseless
;
1374 if (hilite_search
== OPT_ONPLUS
&& !hide_hilite
)
1379 #else /* CMD_HISTORY */
1381 #endif /* CMD_HISTORY */
1385 * Search for the n-th occurrence of a specified pattern,
1386 * either forward or backward.
1387 * Return the number of matches not yet found in this file
1388 * (that is, n minus the number of matches found).
1389 * Return -1 if the search should be aborted.
1390 * Caller may continue the search in another file
1391 * if less than n matches are found in this file.
1394 search(search_type
, pattern
, n
)
1401 if (pattern
== NULL
|| *pattern
== '\0')
1404 * A null pattern means use the previously compiled pattern.
1406 if (!prev_pattern() && !hist_pattern(search_type
))
1408 error("No previous regular expression", NULL_PARG
);
1411 if ((search_type
& SRCH_NO_REGEX
) !=
1412 (last_search_type
& SRCH_NO_REGEX
))
1414 error("Please re-enter search pattern", NULL_PARG
);
1418 if (hilite_search
== OPT_ON
)
1421 * Erase the highlights currently on screen.
1422 * If the search fails, we'll redisplay them later.
1426 if (hilite_search
== OPT_ONPLUS
&& hide_hilite
)
1429 * Highlight any matches currently on screen,
1430 * before we actually start the search.
1440 * Compile the pattern.
1442 if (compile_pattern(pattern
, search_type
, &search_pattern
) < 0)
1445 * Ignore case if -I is set OR
1446 * -i is set AND the pattern is all lowercase.
1448 is_ucase_pattern
= is_ucase(pattern
);
1449 if (is_ucase_pattern
&& caseless
!= OPT_ONPLUS
)
1452 is_caseless
= caseless
;
1457 * Erase the highlights currently on screen.
1458 * Also permanently delete them from the hilite list.
1464 if (hilite_search
== OPT_ONPLUS
)
1467 * Highlight any matches currently on screen,
1468 * before we actually start the search.
1476 * Figure out where to start the search.
1478 pos
= search_pos(search_type
);
1479 if (pos
== NULL_POSITION
)
1482 * Can't find anyplace to start searching from.
1484 if (search_type
& SRCH_PAST_EOF
)
1486 /* repaint(); -- why was this here? */
1487 error("Nothing to search", NULL_PARG
);
1491 n
= search_range(pos
, NULL_POSITION
, search_type
, n
, -1,
1492 &pos
, (POSITION
*)NULL
);
1496 * Search was unsuccessful.
1499 if (hilite_search
== OPT_ON
&& n
> 0)
1501 * Redisplay old hilites.
1508 if (!(search_type
& SRCH_NO_MOVE
))
1511 * Go to the matching line.
1513 jump_loc(pos
, jump_sline
);
1517 if (hilite_search
== OPT_ON
)
1519 * Display new hilites in the matching line.
1529 * Prepare hilites in a given range of the file.
1531 * The pair (prep_startpos,prep_endpos) delimits a contiguous region
1532 * of the file that has been "prepared"; that is, scanned for matches for
1533 * the current search pattern, and hilites have been created for such matches.
1534 * If prep_startpos == NULL_POSITION, the prep region is empty.
1535 * If prep_endpos == NULL_POSITION, the prep region extends to EOF.
1536 * prep_hilite asks that the range (spos,epos) be covered by the prep region.
1539 prep_hilite(spos
, epos
, maxlines
)
1544 POSITION nprep_startpos
= prep_startpos
;
1545 POSITION nprep_endpos
= prep_endpos
;
1551 * Search beyond where we're asked to search, so the prep region covers
1552 * more than we need. Do one big search instead of a bunch of small ones.
1554 #define SEARCH_MORE (3*size_linebuf)
1556 if (!prev_pattern() && !is_filtering())
1560 * If we're limited to a max number of lines, figure out the
1561 * file position we should stop at.
1564 max_epos
= NULL_POSITION
;
1568 for (i
= 0; i
< maxlines
; i
++)
1569 max_epos
= forw_raw_line(max_epos
, (char **)NULL
, (int *)NULL
);
1574 * The range that we need to search (spos,epos); and the range that
1575 * the "prep" region will then cover (nprep_startpos,nprep_endpos).
1578 if (prep_startpos
== NULL_POSITION
||
1579 (epos
!= NULL_POSITION
&& epos
< prep_startpos
) ||
1583 * New range is not contiguous with old prep region.
1584 * Discard the old prep region and start a new one.
1588 if (epos
!= NULL_POSITION
)
1589 epos
+= SEARCH_MORE
;
1590 nprep_startpos
= spos
;
1594 * New range partially or completely overlaps old prep region.
1596 if (epos
== NULL_POSITION
)
1599 * New range goes to end of file.
1602 } else if (epos
> prep_endpos
)
1605 * New range ends after old prep region.
1606 * Extend prep region to end at end of new range.
1608 epos
+= SEARCH_MORE
;
1609 } else /* (epos <= prep_endpos) */
1612 * New range ends within old prep region.
1613 * Truncate search to end at start of old prep region.
1615 epos
= prep_startpos
;
1618 if (spos
< prep_startpos
)
1621 * New range starts before old prep region.
1622 * Extend old prep region backwards to start at
1623 * start of new range.
1625 if (spos
< SEARCH_MORE
)
1628 spos
-= SEARCH_MORE
;
1629 nprep_startpos
= spos
;
1630 } else /* (spos >= prep_startpos) */
1633 * New range starts within or after old prep region.
1634 * Trim search to start at end of old prep region.
1640 if (epos
!= NULL_POSITION
&& max_epos
!= NULL_POSITION
&&
1643 * Don't go past the max position we're allowed.
1647 if (epos
== NULL_POSITION
|| epos
> spos
)
1649 result
= search_range(spos
, epos
, SRCH_FORW
|SRCH_FIND_ALL
, 0,
1650 maxlines
, (POSITION
*)NULL
, &new_epos
);
1653 if (prep_endpos
== NULL_POSITION
|| new_epos
> prep_endpos
)
1654 nprep_endpos
= new_epos
;
1656 prep_startpos
= nprep_startpos
;
1657 prep_endpos
= nprep_endpos
;
1661 * Set the pattern to be used for line filtering.
1664 set_filter_pattern(pattern
, search_type
)
1669 if (pattern
== NULL
|| *pattern
== '\0')
1670 uncompile_filter_pattern();
1672 compile_pattern(pattern
, search_type
, &filter_pattern
);
1677 * Is there a line filter in effect?
1682 if (ch_getflags() & CH_HELPFILE
)
1684 return !is_null_pattern(filter_pattern
);
1689 * Simple pattern matching function.
1690 * It supports no metacharacters like *, etc.
1693 match(pattern
, pattern_len
, buf
, buf_len
, pfound
, pend
)
1698 char **pfound
, **pend
;
1700 register char *pp
, *lp
;
1701 register char *pattern_end
= pattern
+ pattern_len
;
1702 register char *buf_end
= buf
+ buf_len
;
1704 for ( ; buf
< buf_end
; buf
++)
1706 for (pp
= pattern
, lp
= buf
; *pp
== *lp
; pp
++, lp
++)
1707 if (pp
== pattern_end
|| lp
== buf_end
)
1709 if (pp
== pattern_end
)
1723 * This function is called by the V8 regcomp to report
1724 * errors in regular expressions.