3 * Copyright (C) 1984-2007 Mark Nudelman
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.
8 * For more information about less, or for information on how to
9 * contact the author, see the README file.
14 * Routines to search a file for a pattern.
21 #define MINPOS(a,b) (((a) < (b)) ? (a) : (b))
22 #define MAXPOS(a,b) (((a) > (b)) ? (a) : (b))
24 #if HAVE_POSIX_REGCOMP
27 #define REGCOMP_FLAG (less_is_more ? 0 : REG_EXTENDED)
29 #define REGCOMP_FLAG 0
51 extern int how_search
;
55 extern int jump_sline
;
57 extern int less_is_more
;
59 extern int status_col
;
60 extern void * constant ml_search
;
61 extern POSITION start_attnpos
;
62 extern POSITION end_attnpos
;
64 extern int hilite_search
;
65 extern int screen_trashed
;
66 extern int size_linebuf
;
68 extern int can_goto_line
;
70 static int hide_hilite
;
72 static POSITION prep_startpos
;
73 static POSITION prep_endpos
;
77 struct hilite
*hl_next
;
81 static struct hilite hilite_anchor
= { NULL
, NULL_POSITION
, NULL_POSITION
};
82 #define hl_first hl_next
86 * These are the static variables that represent the "remembered"
89 #if HAVE_POSIX_REGCOMP
90 static regex_t
*regpattern
= NULL
;
93 pcre
*regpattern
= NULL
;
99 static char *cpattern
= NULL
;
102 static struct regexp
*regpattern
= NULL
;
105 static int is_caseless
;
106 static int is_ucase_pattern
;
107 static int last_search_type
;
108 static char *last_pattern
= NULL
;
110 #define CVT_TO_LC 01 /* Convert upper-case to lower-case */
111 #define CVT_BS 02 /* Do backspace processing */
112 #define CVT_CRLF 04 /* Remove CR after LF */
113 #define CVT_ANSI 010 /* Remove ANSI escape sequences */
116 * Get the length of a buffer needed to convert a string.
125 * Just copying a string in UTF-8 mode can cause it to grow
127 * Six output bytes for one input byte is the worst case
128 * (and unfortunately is far more than is needed in any
129 * non-pathological situation, so this is very wasteful).
136 * Convert text. Perform one or more of these transformations:
139 cvt_text(odst
, osrc
, lenp
, ops
)
147 register char *src_end
;
151 src_end
= osrc
+ *lenp
;
153 src_end
= osrc
+ strlen(osrc
);
155 for (src
= osrc
, dst
= odst
; src
< src_end
; )
157 ch
= step_char(&src
, +1, src_end
);
158 if ((ops
& CVT_TO_LC
) && IS_UPPER(ch
))
160 /* Convert uppercase to lowercase. */
161 put_wchar(&dst
, TO_LOWER(ch
));
162 } else if ((ops
& CVT_BS
) && ch
== '\b' && dst
> odst
)
164 /* Delete backspace and preceding char. */
167 } while (dst
> odst
&&
168 !IS_ASCII_OCTET(*dst
) && !IS_UTF8_LEAD(*dst
));
169 } else if ((ops
& CVT_ANSI
) && IS_CSI_START(ch
))
171 /* Skip to end of ANSI escape sequence. */
172 while (src
+ 1 != src_end
)
173 if (!is_ansi_middle(*++src
))
179 if ((ops
& CVT_CRLF
) && dst
> odst
&& dst
[-1] == '\r')
187 * Determine which conversions to perform.
193 if (is_caseless
|| bs_mode
== BS_SPECIAL
)
197 if (bs_mode
== BS_SPECIAL
)
199 if (bs_mode
!= BS_CONTROL
)
201 } else if (bs_mode
!= BS_CONTROL
)
205 if (ctldisp
== OPT_ONPLUS
)
211 * Are there any uppercase letters in this string?
217 char *str_end
= str
+ strlen(str
);
220 while (str
< str_end
)
222 ch
= step_char(&str
, +1, str_end
);
230 * Is there a previous (remembered) search pattern?
235 if (last_search_type
& SRCH_NO_REGEX
)
236 return (last_pattern
!= NULL
);
237 #if HAVE_POSIX_REGCOMP
238 return (regpattern
!= NULL
);
241 return (regpattern
!= NULL
);
244 return (re_pattern
!= 0);
247 return (cpattern
!= NULL
);
250 return (regpattern
!= NULL
);
253 return (last_pattern
!= NULL
);
259 * Repaint the hilites currently displayed on the screen.
260 * Repaint each line which contains highlighted text.
261 * If on==0, force all hilites off.
270 int save_hide_hilite
;
275 save_hide_hilite
= hide_hilite
;
286 hide_hilite
= save_hide_hilite
;
290 for (slinenum
= TOP
; slinenum
< TOP
+ sc_height
-1; slinenum
++)
292 pos
= position(slinenum
);
293 if (pos
== NULL_POSITION
)
295 epos
= position(slinenum
+1);
298 * If any character in the line is highlighted,
301 * {{ This doesn't work -- if line is drawn with highlights
302 * which should be erased (e.g. toggle -i with status column),
303 * we must redraw the line even if it has no highlights.
304 * For now, just repaint every line. }}
306 if (is_hilited(pos
, epos
, 1, NULL
))
309 (void) forw_line(pos
);
316 hide_hilite
= save_hide_hilite
;
320 * Clear the attn hilite.
326 POSITION old_start_attnpos
;
327 POSITION old_end_attnpos
;
332 if (start_attnpos
== NULL_POSITION
)
334 old_start_attnpos
= start_attnpos
;
335 old_end_attnpos
= end_attnpos
;
336 start_attnpos
= end_attnpos
= NULL_POSITION
;
346 for (slinenum
= TOP
; slinenum
< TOP
+ sc_height
-1; slinenum
++)
348 pos
= position(slinenum
);
349 if (pos
== NULL_POSITION
)
351 epos
= position(slinenum
+1);
352 if (pos
< old_end_attnpos
&&
353 (epos
== NULL_POSITION
|| epos
> old_start_attnpos
))
355 (void) forw_line(pos
);
367 * Hide search string highlighting.
374 error("No previous regular expression", NULL_PARG
);
378 hide_hilite
= !hide_hilite
;
384 * Compile a search pattern, for future use by match_pattern.
387 compile_pattern2(pattern
, search_type
)
391 if ((search_type
& SRCH_NO_REGEX
) == 0)
393 #if HAVE_POSIX_REGCOMP
394 regex_t
*s
= (regex_t
*) ecalloc(1, sizeof(regex_t
));
395 if (regcomp(s
, pattern
, REGCOMP_FLAG
))
398 error("Invalid pattern", NULL_PARG
);
401 if (regpattern
!= NULL
)
407 const char *errstring
;
410 comp
= pcre_compile(pattern
, 0,
411 &errstring
, &erroffset
, NULL
);
414 parg
.p_string
= (char *) errstring
;
422 if ((parg
.p_string
= re_comp(pattern
)) != NULL
)
431 if ((s
= regcmp(pattern
, 0)) == NULL
)
433 error("Invalid pattern", NULL_PARG
);
436 if (cpattern
!= NULL
)
442 if ((s
= regcomp(pattern
)) == NULL
)
445 * regcomp has already printed an error message
450 if (regpattern
!= NULL
)
456 if (last_pattern
!= NULL
)
458 last_pattern
= (char *) calloc(1, strlen(pattern
)+1);
459 if (last_pattern
!= NULL
)
460 strcpy(last_pattern
, pattern
);
462 last_search_type
= search_type
;
467 * Like compile_pattern, but convert the pattern to lowercase if necessary.
470 compile_pattern(pattern
, search_type
)
477 if (caseless
!= OPT_ONPLUS
)
478 cvt_pattern
= pattern
;
481 cvt_pattern
= (char*) ecalloc(1, cvt_length(strlen(pattern
), CVT_TO_LC
));
482 cvt_text(cvt_pattern
, pattern
, (int *)NULL
, CVT_TO_LC
);
484 result
= compile_pattern2(cvt_pattern
, search_type
);
485 if (cvt_pattern
!= pattern
)
491 * Forget that we have a compiled pattern.
496 #if HAVE_POSIX_REGCOMP
497 if (regpattern
!= NULL
)
502 if (regpattern
!= NULL
)
503 pcre_free(regpattern
);
510 if (cpattern
!= NULL
)
515 if (regpattern
!= NULL
)
523 * Perform a pattern match with the previously compiled pattern.
524 * Set sp and ep to the start and end of the matched string.
527 match_pattern(line
, line_len
, sp
, ep
, notbol
)
536 if (last_search_type
& SRCH_NO_REGEX
)
537 return (match(last_pattern
, strlen(last_pattern
), line
, line_len
, sp
, ep
));
539 #if HAVE_POSIX_REGCOMP
542 int flags
= (notbol
) ? REG_NOTBOL
: 0;
543 matched
= !regexec(regpattern
, line
, 1, &rm
, flags
);
547 *sp
= line
+ rm
.rm_so
;
548 *ep
= line
+ rm
.rm_eo
;
557 int flags
= (notbol
) ? PCRE_NOTBOL
: 0;
559 matched
= pcre_exec(regpattern
, NULL
, line
, line_len
,
560 0, flags
, ovector
, 3) >= 0;
563 *sp
= line
+ ovector
[0];
564 *ep
= line
+ ovector
[1];
568 matched
= (re_exec(line
) == 1);
570 * re_exec doesn't seem to provide a way to get the matched string.
575 *ep
= regex(cpattern
, line
);
576 matched
= (*ep
!= NULL
);
583 matched
= regexec2(regpattern
, line
, notbol
);
585 matched
= regexec(regpattern
, line
);
589 *sp
= regpattern
->startp
[0];
590 *ep
= regpattern
->endp
[0];
593 matched
= match(last_pattern
, strlen(last_pattern
), line
, line_len
, sp
, ep
);
600 * Clear the hilite list.
606 struct hilite
*nexthl
;
608 for (hl
= hilite_anchor
.hl_first
; hl
!= NULL
; hl
= nexthl
)
610 nexthl
= hl
->hl_next
;
613 hilite_anchor
.hl_first
= NULL
;
614 prep_startpos
= prep_endpos
= NULL_POSITION
;
618 * Should any characters in a specified range be highlighted?
621 is_hilited_range(pos
, epos
)
628 * Look at each highlight and see if any part of it falls in the range.
630 for (hl
= hilite_anchor
.hl_first
; hl
!= NULL
; hl
= hl
->hl_next
)
632 if (hl
->hl_endpos
> pos
&&
633 (epos
== NULL_POSITION
|| epos
> hl
->hl_startpos
))
640 * Should any characters in a specified range be highlighted?
641 * If nohide is nonzero, don't consider hide_hilite.
644 is_hilited(pos
, epos
, nohide
, p_matches
)
652 if (p_matches
!= NULL
)
656 start_attnpos
!= NULL_POSITION
&&
658 (epos
== NULL_POSITION
|| epos
> start_attnpos
))
660 * The attn line overlaps this range.
664 match
= is_hilited_range(pos
, epos
);
668 if (p_matches
!= NULL
)
670 * Report matches, even if we're hiding highlights.
674 if (hilite_search
== 0)
676 * Not doing highlighting.
680 if (!nohide
&& hide_hilite
)
682 * Highlighting is hidden.
690 * Add a new hilite to a hilite list.
693 add_hilite(anchor
, hl
)
694 struct hilite
*anchor
;
700 * Hilites are sorted in the list; find where new one belongs.
701 * Insert new one after ihl.
703 for (ihl
= anchor
; ihl
->hl_next
!= NULL
; ihl
= ihl
->hl_next
)
705 if (ihl
->hl_next
->hl_startpos
> hl
->hl_startpos
)
710 * Truncate hilite so it doesn't overlap any existing ones
711 * above and below it.
714 hl
->hl_startpos
= MAXPOS(hl
->hl_startpos
, ihl
->hl_endpos
);
715 if (ihl
->hl_next
!= NULL
)
716 hl
->hl_endpos
= MINPOS(hl
->hl_endpos
, ihl
->hl_next
->hl_startpos
);
717 if (hl
->hl_startpos
>= hl
->hl_endpos
)
720 * Hilite was truncated out of existence.
725 hl
->hl_next
= ihl
->hl_next
;
730 * Adjust hl_startpos & hl_endpos to account for processing by cvt_text.
733 adj_hilite(anchor
, linepos
, cvt_ops
)
734 struct hilite
*anchor
;
750 * The line was already scanned and hilites were added (in hilite_line).
751 * But it was assumed that each char position in the line
752 * correponds to one char position in the file.
753 * This may not be true if cvt_text modified the line.
754 * Get the raw line again. Look at each character.
756 (void) forw_raw_line(linepos
, &line
, &line_len
);
757 line_end
= line
+ line_len
;
758 opos
= npos
= linepos
;
759 hl
= anchor
->hl_first
;
764 * See if we need to adjust the current hl_startpos or
765 * hl_endpos. After adjusting startpos[i], move to endpos[i].
766 * After adjusting endpos[i], move to startpos[i+1].
767 * The hilite list must be sorted thus:
768 * startpos[0] < endpos[0] <= startpos[1] < endpos[1] <= etc.
770 if (checkstart
&& hl
->hl_startpos
== opos
)
772 hl
->hl_startpos
= npos
;
774 continue; /* {{ not really necessary }} */
775 } else if (!checkstart
&& hl
->hl_endpos
== opos
)
777 hl
->hl_endpos
= npos
;
780 continue; /* {{ necessary }} */
782 if (line
== line_end
)
785 /* Get the next char from the line. */
787 ch
= step_char(&line
, +1, line_end
);
788 ncwidth
= line
- oline
;
791 /* Figure out how this char was processed by cvt_text. */
792 if ((cvt_ops
& CVT_BS
) && ch
== '\b')
794 /* Skip the backspace and the following char. */
796 ch
= step_char(&line
, +1, line_end
);
797 ncwidth
= line
- oline
;
799 } else if ((cvt_ops
& CVT_TO_LC
) && IS_UPPER(ch
))
801 /* Converted uppercase to lower.
802 * Note that this may have changed the number of bytes
803 * that the character occupies. */
806 put_wchar(&dst
, TO_LOWER(ch
));
808 } else if ((cvt_ops
& CVT_ANSI
) && IS_CSI_START(ch
))
810 /* Skip to end of ANSI escape sequence. */
811 while (line
< line_end
)
814 if (!is_ansi_middle(*++line
))
819 /* Ordinary unprocessed character. */
826 * Make a hilite for each string in a physical line which matches
827 * the current pattern.
828 * sp,ep delimit the first match already found.
831 hilite_line(linepos
, line
, line_len
, sp
, ep
, cvt_ops
)
840 char *line_end
= line
+ line_len
;
842 struct hilite hilites
;
844 if (sp
== NULL
|| ep
== NULL
)
847 * sp and ep delimit the first match in the line.
848 * Mark the corresponding file positions, then
849 * look for further matches and mark them.
850 * {{ This technique, of calling match_pattern on subsequent
851 * substrings of the line, may mark more than is correct
852 * if the pattern starts with "^". This bug is fixed
853 * for those regex functions that accept a notbol parameter
854 * (currently POSIX, PCRE and V8-with-regexec2). }}
858 * Put the hilites into a temporary list until they're adjusted.
860 hilites
.hl_first
= NULL
;
865 * Assume that each char position in the "line"
866 * buffer corresponds to one char position in the file.
867 * This is not quite true; we need to adjust later.
869 hl
= (struct hilite
*) ecalloc(1, sizeof(struct hilite
));
870 hl
->hl_startpos
= linepos
+ (sp
-line
);
871 hl
->hl_endpos
= linepos
+ (ep
-line
);
872 add_hilite(&hilites
, hl
);
875 * If we matched more than zero characters,
876 * move to the first char after the string we matched.
877 * If we matched zero, just move to the next char.
881 else if (searchp
!= line_end
)
883 else /* end of line */
885 } while (match_pattern(searchp
, line_end
- searchp
, &sp
, &ep
, 1));
888 * If there were backspaces in the original line, they
889 * were removed, and hl_startpos/hl_endpos are not correct.
890 * {{ This is very ugly. }}
892 adj_hilite(&hilites
, linepos
, cvt_ops
);
895 * Now put the hilites into the real list.
897 while ((hl
= hilites
.hl_next
) != NULL
)
899 hilites
.hl_next
= hl
->hl_next
;
900 add_hilite(&hilite_anchor
, hl
);
906 * Change the caseless-ness of searches.
907 * Updates the internal search state to reflect a change in the -i flag.
912 if (!is_ucase_pattern
)
914 * Pattern did not have uppercase.
915 * Just set the search caselessness to the global caselessness.
917 is_caseless
= caseless
;
920 * Pattern did have uppercase.
921 * Discard the pattern; we can't change search caselessness now.
928 * Find matching text which is currently on screen and highlight it.
933 struct scrpos scrpos
;
936 if (scrpos
.pos
== NULL_POSITION
)
938 prep_hilite(scrpos
.pos
, position(BOTTOM_PLUS_ONE
), -1);
943 * Change highlighting parameters.
949 * Erase any highlights currently on screen.
954 if (hilite_search
== OPT_ONPLUS
)
956 * Display highlights.
963 * Figure out where to start a search.
966 search_pos(search_type
)
975 * Start at the beginning (or end) of the file.
976 * The empty_screen() case is mainly for
977 * command line initiated searches;
978 * for example, "+/xyz" on the command line.
979 * Also for multi-file (SRCH_PAST_EOF) searches.
981 if (search_type
& SRCH_FORW
)
987 if (pos
== NULL_POSITION
)
989 (void) ch_end_seek();
998 * Search does not include current screen.
1000 if (search_type
& SRCH_FORW
)
1001 linenum
= BOTTOM_PLUS_ONE
;
1004 pos
= position(linenum
);
1008 * Search includes current screen.
1009 * It starts at the jump target (if searching backwards),
1010 * or at the jump target plus one (if forwards).
1012 linenum
= adjsline(jump_sline
);
1013 pos
= position(linenum
);
1014 if (search_type
& SRCH_FORW
)
1016 pos
= forw_raw_line(pos
, (char **)NULL
, (int *)NULL
);
1017 while (pos
== NULL_POSITION
)
1019 if (++linenum
>= sc_height
)
1021 pos
= position(linenum
);
1025 while (pos
== NULL_POSITION
)
1029 pos
= position(linenum
);
1037 * Search a subset of the file, specified by start/end position.
1040 search_range(pos
, endpos
, search_type
, matches
, maxlines
, plinepos
, pendpos
)
1056 POSITION linepos
, oldpos
;
1058 linenum
= find_linenum(pos
);
1063 * Get lines until we find a matching one or until
1064 * we hit end-of-file (or beginning-of-file if we're
1065 * going backwards), or until we hit the end position.
1070 * A signal aborts the search.
1075 if ((endpos
!= NULL_POSITION
&& pos
>= endpos
) || maxlines
== 0)
1078 * Reached end position without a match.
1080 if (pendpos
!= NULL
)
1087 if (search_type
& SRCH_FORW
)
1090 * Read the next line, and save the
1091 * starting position of that line in linepos.
1094 pos
= forw_raw_line(pos
, &line
, &line_len
);
1100 * Read the previous line and save the
1101 * starting position of that line in linepos.
1103 pos
= back_raw_line(pos
, &line
, &line_len
);
1109 if (pos
== NULL_POSITION
)
1112 * Reached EOF/BOF without a match.
1114 if (pendpos
!= NULL
)
1120 * If we're using line numbers, we might as well
1121 * remember the information we have now (the position
1122 * and line number of the current line).
1123 * Don't do it for every line because it slows down
1124 * the search. Remember the line number only if
1125 * we're "far" from the last place we remembered it.
1127 if (linenums
&& abs((int)(pos
- oldpos
)) > 1024)
1128 add_lnum(linenum
, pos
);
1132 * If it's a caseless search, convert the line to lowercase.
1133 * If we're doing backspace processing, delete backspaces.
1135 cvt_ops
= get_cvt_ops();
1136 cline
= calloc(1, cvt_length(line_len
, cvt_ops
));
1137 cvt_text(cline
, line
, &line_len
, cvt_ops
);
1140 * Test the next line to see if we have a match.
1141 * We are successful if we either want a match and got one,
1142 * or if we want a non-match and got one.
1144 line_match
= match_pattern(cline
, line_len
, &sp
, &ep
, 0);
1145 line_match
= (!(search_type
& SRCH_NO_MATCH
) && line_match
) ||
1146 ((search_type
& SRCH_NO_MATCH
) && !line_match
);
1155 if (search_type
& SRCH_FIND_ALL
)
1159 * We are supposed to find all matches in the range.
1160 * Just add the matches in this line to the
1161 * hilite list and keep searching.
1164 hilite_line(linepos
, cline
, line_len
, sp
, ep
, cvt_ops
);
1167 } else if (--matches
<= 0)
1170 * Found the one match we're looking for.
1174 if (hilite_search
== OPT_ON
)
1177 * Clear the hilite list and add only
1178 * the matches in this one line.
1182 hilite_line(linepos
, cline
, line_len
, sp
, ep
, cvt_ops
);
1186 if (plinepos
!= NULL
)
1187 *plinepos
= linepos
;
1194 * search for a pattern in history. If found, compile that pattern.
1197 hist_pattern(search_type
)
1203 set_mlist(ml_search
, 0);
1204 pattern
= cmd_lastpattern();
1205 if (pattern
== NULL
)
1208 if (compile_pattern(pattern
, search_type
) < 0)
1211 is_ucase_pattern
= is_ucase(pattern
);
1212 if (is_ucase_pattern
&& caseless
!= OPT_ONPLUS
)
1215 is_caseless
= caseless
;
1218 if (hilite_search
== OPT_ONPLUS
&& !hide_hilite
)
1223 #else /* CMD_HISTORY */
1225 #endif /* CMD_HISTORY */
1229 * Search for the n-th occurrence of a specified pattern,
1230 * either forward or backward.
1231 * Return the number of matches not yet found in this file
1232 * (that is, n minus the number of matches found).
1233 * Return -1 if the search should be aborted.
1234 * Caller may continue the search in another file
1235 * if less than n matches are found in this file.
1238 search(search_type
, pattern
, n
)
1246 if (pattern
== NULL
|| *pattern
== '\0')
1249 * A null pattern means use the previously compiled pattern.
1251 if (!prev_pattern() && !hist_pattern(search_type
))
1253 error("No previous regular expression", NULL_PARG
);
1256 if ((search_type
& SRCH_NO_REGEX
) !=
1257 (last_search_type
& SRCH_NO_REGEX
))
1259 error("Please re-enter search pattern", NULL_PARG
);
1263 if (hilite_search
== OPT_ON
)
1266 * Erase the highlights currently on screen.
1267 * If the search fails, we'll redisplay them later.
1271 if (hilite_search
== OPT_ONPLUS
&& hide_hilite
)
1274 * Highlight any matches currently on screen,
1275 * before we actually start the search.
1285 * Compile the pattern.
1287 if (compile_pattern(pattern
, search_type
) < 0)
1290 * Ignore case if -I is set OR
1291 * -i is set AND the pattern is all lowercase.
1293 is_ucase_pattern
= is_ucase(pattern
);
1294 if (is_ucase_pattern
&& caseless
!= OPT_ONPLUS
)
1297 is_caseless
= caseless
;
1302 * Erase the highlights currently on screen.
1303 * Also permanently delete them from the hilite list.
1309 if (hilite_search
== OPT_ONPLUS
)
1312 * Highlight any matches currently on screen,
1313 * before we actually start the search.
1321 * Figure out where to start the search.
1323 pos
= search_pos(search_type
);
1324 if (pos
== NULL_POSITION
)
1327 * Can't find anyplace to start searching from.
1329 if (search_type
& SRCH_PAST_EOF
)
1331 /* repaint(); -- why was this here? */
1332 error("Nothing to search", NULL_PARG
);
1336 n
= search_range(pos
, NULL_POSITION
, search_type
, n
, -1,
1337 &pos
, (POSITION
*)NULL
);
1341 * Search was unsuccessful.
1344 if (hilite_search
== OPT_ON
&& n
> 0)
1346 * Redisplay old hilites.
1353 if (!(search_type
& SRCH_NO_MOVE
))
1356 * Go to the matching line.
1358 jump_loc(pos
, jump_sline
);
1362 if (hilite_search
== OPT_ON
)
1364 * Display new hilites in the matching line.
1374 * Prepare hilites in a given range of the file.
1376 * The pair (prep_startpos,prep_endpos) delimits a contiguous region
1377 * of the file that has been "prepared"; that is, scanned for matches for
1378 * the current search pattern, and hilites have been created for such matches.
1379 * If prep_startpos == NULL_POSITION, the prep region is empty.
1380 * If prep_endpos == NULL_POSITION, the prep region extends to EOF.
1381 * prep_hilite asks that the range (spos,epos) be covered by the prep region.
1384 prep_hilite(spos
, epos
, maxlines
)
1389 POSITION nprep_startpos
= prep_startpos
;
1390 POSITION nprep_endpos
= prep_endpos
;
1396 * Search beyond where we're asked to search, so the prep region covers
1397 * more than we need. Do one big search instead of a bunch of small ones.
1399 #define SEARCH_MORE (3*size_linebuf)
1401 if (!prev_pattern())
1405 * If we're limited to a max number of lines, figure out the
1406 * file position we should stop at.
1409 max_epos
= NULL_POSITION
;
1413 for (i
= 0; i
< maxlines
; i
++)
1414 max_epos
= forw_raw_line(max_epos
, (char **)NULL
, (int *)NULL
);
1419 * The range that we need to search (spos,epos); and the range that
1420 * the "prep" region will then cover (nprep_startpos,nprep_endpos).
1423 if (prep_startpos
== NULL_POSITION
||
1424 (epos
!= NULL_POSITION
&& epos
< prep_startpos
) ||
1428 * New range is not contiguous with old prep region.
1429 * Discard the old prep region and start a new one.
1432 if (epos
!= NULL_POSITION
)
1433 epos
+= SEARCH_MORE
;
1434 nprep_startpos
= spos
;
1438 * New range partially or completely overlaps old prep region.
1440 if (epos
== NULL_POSITION
)
1443 * New range goes to end of file.
1446 } else if (epos
> prep_endpos
)
1449 * New range ends after old prep region.
1450 * Extend prep region to end at end of new range.
1452 epos
+= SEARCH_MORE
;
1453 } else /* (epos <= prep_endpos) */
1456 * New range ends within old prep region.
1457 * Truncate search to end at start of old prep region.
1459 epos
= prep_startpos
;
1462 if (spos
< prep_startpos
)
1465 * New range starts before old prep region.
1466 * Extend old prep region backwards to start at
1467 * start of new range.
1469 if (spos
< SEARCH_MORE
)
1472 spos
-= SEARCH_MORE
;
1473 nprep_startpos
= spos
;
1474 } else /* (spos >= prep_startpos) */
1477 * New range starts within or after old prep region.
1478 * Trim search to start at end of old prep region.
1484 if (epos
!= NULL_POSITION
&& max_epos
!= NULL_POSITION
&&
1487 * Don't go past the max position we're allowed.
1491 if (epos
== NULL_POSITION
|| epos
> spos
)
1493 result
= search_range(spos
, epos
, SRCH_FORW
|SRCH_FIND_ALL
, 0,
1494 maxlines
, (POSITION
*)NULL
, &new_epos
);
1497 if (prep_endpos
== NULL_POSITION
|| new_epos
> prep_endpos
)
1498 nprep_endpos
= new_epos
;
1500 prep_startpos
= nprep_startpos
;
1501 prep_endpos
= nprep_endpos
;
1506 * Simple pattern matching function.
1507 * It supports no metacharacters like *, etc.
1510 match(pattern
, pattern_len
, buf
, buf_len
, pfound
, pend
)
1515 char **pfound
, **pend
;
1517 register char *pp
, *lp
;
1518 register char *pattern_end
= pattern
+ pattern_len
;
1519 register char *buf_end
= buf
+ buf_len
;
1521 for ( ; buf
< buf_end
; buf
++)
1523 for (pp
= pattern
, lp
= buf
; *pp
== *lp
; pp
++, lp
++)
1524 if (pp
== pattern_end
|| lp
== buf_end
)
1526 if (pp
== pattern_end
)
1540 * This function is called by the V8 regcomp to report
1541 * errors in regular expressions.