1*84d9c625SLionel Sambuc /* $NetBSD: search.c,v 1.4 2013/09/04 19:44:21 tron Exp $ */
2f7cf2976SLionel Sambuc
3f7cf2976SLionel Sambuc /*
4*84d9c625SLionel Sambuc * Copyright (C) 1984-2012 Mark Nudelman
5f7cf2976SLionel Sambuc *
6f7cf2976SLionel Sambuc * You may distribute under the terms of either the GNU General Public
7f7cf2976SLionel Sambuc * License or the Less License, as specified in the README file.
8f7cf2976SLionel Sambuc *
9*84d9c625SLionel Sambuc * For more information, see the README file.
10f7cf2976SLionel Sambuc */
11f7cf2976SLionel Sambuc
12f7cf2976SLionel Sambuc
13f7cf2976SLionel Sambuc /*
14f7cf2976SLionel Sambuc * Routines to search a file for a pattern.
15f7cf2976SLionel Sambuc */
16f7cf2976SLionel Sambuc
17f7cf2976SLionel Sambuc #include "less.h"
18f7cf2976SLionel Sambuc #include "pattern.h"
19f7cf2976SLionel Sambuc #include "position.h"
20f7cf2976SLionel Sambuc #include "charset.h"
21f7cf2976SLionel Sambuc
22f7cf2976SLionel Sambuc #define MINPOS(a,b) (((a) < (b)) ? (a) : (b))
23f7cf2976SLionel Sambuc #define MAXPOS(a,b) (((a) > (b)) ? (a) : (b))
24f7cf2976SLionel Sambuc
25f7cf2976SLionel Sambuc extern int sigs;
26f7cf2976SLionel Sambuc extern int how_search;
27f7cf2976SLionel Sambuc extern int caseless;
28f7cf2976SLionel Sambuc extern int linenums;
29f7cf2976SLionel Sambuc extern int sc_height;
30f7cf2976SLionel Sambuc extern int jump_sline;
31f7cf2976SLionel Sambuc extern int bs_mode;
32f7cf2976SLionel Sambuc extern int ctldisp;
33f7cf2976SLionel Sambuc extern int status_col;
34f7cf2976SLionel Sambuc extern void * constant ml_search;
35f7cf2976SLionel Sambuc extern POSITION start_attnpos;
36f7cf2976SLionel Sambuc extern POSITION end_attnpos;
37f7cf2976SLionel Sambuc extern int utf_mode;
38f7cf2976SLionel Sambuc extern int screen_trashed;
39f7cf2976SLionel Sambuc #if HILITE_SEARCH
40f7cf2976SLionel Sambuc extern int hilite_search;
41f7cf2976SLionel Sambuc extern int size_linebuf;
42f7cf2976SLionel Sambuc extern int squished;
43f7cf2976SLionel Sambuc extern int can_goto_line;
44f7cf2976SLionel Sambuc static int hide_hilite;
45f7cf2976SLionel Sambuc static POSITION prep_startpos;
46f7cf2976SLionel Sambuc static POSITION prep_endpos;
47f7cf2976SLionel Sambuc static int is_caseless;
48f7cf2976SLionel Sambuc static int is_ucase_pattern;
49f7cf2976SLionel Sambuc
50f7cf2976SLionel Sambuc struct hilite
51f7cf2976SLionel Sambuc {
52f7cf2976SLionel Sambuc struct hilite *hl_next;
53f7cf2976SLionel Sambuc POSITION hl_startpos;
54f7cf2976SLionel Sambuc POSITION hl_endpos;
55f7cf2976SLionel Sambuc };
56f7cf2976SLionel Sambuc static struct hilite hilite_anchor = { NULL, NULL_POSITION, NULL_POSITION };
57f7cf2976SLionel Sambuc static struct hilite filter_anchor = { NULL, NULL_POSITION, NULL_POSITION };
58f7cf2976SLionel Sambuc #define hl_first hl_next
59f7cf2976SLionel Sambuc #endif
60f7cf2976SLionel Sambuc
61f7cf2976SLionel Sambuc /*
62f7cf2976SLionel Sambuc * These are the static variables that represent the "remembered"
63f7cf2976SLionel Sambuc * search pattern and filter pattern.
64f7cf2976SLionel Sambuc */
65f7cf2976SLionel Sambuc struct pattern_info {
66f7cf2976SLionel Sambuc DEFINE_PATTERN(compiled);
67f7cf2976SLionel Sambuc char* text;
68f7cf2976SLionel Sambuc int search_type;
69f7cf2976SLionel Sambuc };
70f7cf2976SLionel Sambuc
71*84d9c625SLionel Sambuc #if NO_REGEX
72*84d9c625SLionel Sambuc #define info_compiled(info) ((void*)0)
73*84d9c625SLionel Sambuc #else
74*84d9c625SLionel Sambuc #define info_compiled(info) ((info)->compiled)
75*84d9c625SLionel Sambuc #endif
76*84d9c625SLionel Sambuc
77f7cf2976SLionel Sambuc static struct pattern_info search_info;
78f7cf2976SLionel Sambuc static struct pattern_info filter_info;
79f7cf2976SLionel Sambuc
80f7cf2976SLionel Sambuc /*
81f7cf2976SLionel Sambuc * Are there any uppercase letters in this string?
82f7cf2976SLionel Sambuc */
83f7cf2976SLionel Sambuc static int
is_ucase(str)84f7cf2976SLionel Sambuc is_ucase(str)
85f7cf2976SLionel Sambuc char *str;
86f7cf2976SLionel Sambuc {
87f7cf2976SLionel Sambuc char *str_end = str + strlen(str);
88f7cf2976SLionel Sambuc LWCHAR ch;
89f7cf2976SLionel Sambuc
90f7cf2976SLionel Sambuc while (str < str_end)
91f7cf2976SLionel Sambuc {
92f7cf2976SLionel Sambuc ch = step_char(&str, +1, str_end);
93f7cf2976SLionel Sambuc if (IS_UPPER(ch))
94f7cf2976SLionel Sambuc return (1);
95f7cf2976SLionel Sambuc }
96f7cf2976SLionel Sambuc return (0);
97f7cf2976SLionel Sambuc }
98f7cf2976SLionel Sambuc
99f7cf2976SLionel Sambuc /*
100f7cf2976SLionel Sambuc * Compile and save a search pattern.
101f7cf2976SLionel Sambuc */
102f7cf2976SLionel Sambuc static int
set_pattern(info,pattern,search_type)103f7cf2976SLionel Sambuc set_pattern(info, pattern, search_type)
104f7cf2976SLionel Sambuc struct pattern_info *info;
105f7cf2976SLionel Sambuc char *pattern;
106f7cf2976SLionel Sambuc int search_type;
107f7cf2976SLionel Sambuc {
108*84d9c625SLionel Sambuc #if !NO_REGEX
109f7cf2976SLionel Sambuc if (pattern == NULL)
110*84d9c625SLionel Sambuc CLEAR_PATTERN(info->compiled);
111f7cf2976SLionel Sambuc else if (compile_pattern(pattern, search_type, &info->compiled) < 0)
112f7cf2976SLionel Sambuc return -1;
113*84d9c625SLionel Sambuc #endif
114f7cf2976SLionel Sambuc /* Pattern compiled successfully; save the text too. */
115f7cf2976SLionel Sambuc if (info->text != NULL)
116f7cf2976SLionel Sambuc free(info->text);
117f7cf2976SLionel Sambuc info->text = NULL;
118f7cf2976SLionel Sambuc if (pattern != NULL)
119f7cf2976SLionel Sambuc {
120f7cf2976SLionel Sambuc info->text = (char *) ecalloc(1, strlen(pattern)+1);
121f7cf2976SLionel Sambuc strcpy(info->text, pattern);
122f7cf2976SLionel Sambuc }
123f7cf2976SLionel Sambuc info->search_type = search_type;
124f7cf2976SLionel Sambuc
125f7cf2976SLionel Sambuc /*
126f7cf2976SLionel Sambuc * Ignore case if -I is set OR
127f7cf2976SLionel Sambuc * -i is set AND the pattern is all lowercase.
128f7cf2976SLionel Sambuc */
129f7cf2976SLionel Sambuc is_ucase_pattern = is_ucase(pattern);
130f7cf2976SLionel Sambuc if (is_ucase_pattern && caseless != OPT_ONPLUS)
131f7cf2976SLionel Sambuc is_caseless = 0;
132f7cf2976SLionel Sambuc else
133f7cf2976SLionel Sambuc is_caseless = caseless;
134f7cf2976SLionel Sambuc return 0;
135f7cf2976SLionel Sambuc }
136f7cf2976SLionel Sambuc
137f7cf2976SLionel Sambuc /*
138f7cf2976SLionel Sambuc * Discard a saved pattern.
139f7cf2976SLionel Sambuc */
140f7cf2976SLionel Sambuc static void
clear_pattern(info)141f7cf2976SLionel Sambuc clear_pattern(info)
142f7cf2976SLionel Sambuc struct pattern_info *info;
143f7cf2976SLionel Sambuc {
144f7cf2976SLionel Sambuc if (info->text != NULL)
145f7cf2976SLionel Sambuc free(info->text);
146f7cf2976SLionel Sambuc info->text = NULL;
147*84d9c625SLionel Sambuc #if !NO_REGEX
148f7cf2976SLionel Sambuc uncompile_pattern(&info->compiled);
149*84d9c625SLionel Sambuc #endif
150f7cf2976SLionel Sambuc }
151f7cf2976SLionel Sambuc
152f7cf2976SLionel Sambuc /*
153f7cf2976SLionel Sambuc * Initialize saved pattern to nothing.
154f7cf2976SLionel Sambuc */
155f7cf2976SLionel Sambuc static void
init_pattern(info)156f7cf2976SLionel Sambuc init_pattern(info)
157f7cf2976SLionel Sambuc struct pattern_info *info;
158f7cf2976SLionel Sambuc {
159f7cf2976SLionel Sambuc CLEAR_PATTERN(info->compiled);
160f7cf2976SLionel Sambuc info->text = NULL;
161f7cf2976SLionel Sambuc info->search_type = 0;
162f7cf2976SLionel Sambuc }
163f7cf2976SLionel Sambuc
164f7cf2976SLionel Sambuc /*
165f7cf2976SLionel Sambuc * Initialize search variables.
166f7cf2976SLionel Sambuc */
167f7cf2976SLionel Sambuc public void
init_search()168f7cf2976SLionel Sambuc init_search()
169f7cf2976SLionel Sambuc {
170f7cf2976SLionel Sambuc init_pattern(&search_info);
171f7cf2976SLionel Sambuc init_pattern(&filter_info);
172f7cf2976SLionel Sambuc }
173f7cf2976SLionel Sambuc
174f7cf2976SLionel Sambuc /*
175f7cf2976SLionel Sambuc * Determine which text conversions to perform before pattern matching.
176f7cf2976SLionel Sambuc */
177f7cf2976SLionel Sambuc static int
get_cvt_ops()178f7cf2976SLionel Sambuc get_cvt_ops()
179f7cf2976SLionel Sambuc {
180f7cf2976SLionel Sambuc int ops = 0;
181f7cf2976SLionel Sambuc if (is_caseless || bs_mode == BS_SPECIAL)
182f7cf2976SLionel Sambuc {
183f7cf2976SLionel Sambuc if (is_caseless)
184f7cf2976SLionel Sambuc ops |= CVT_TO_LC;
185f7cf2976SLionel Sambuc if (bs_mode == BS_SPECIAL)
186f7cf2976SLionel Sambuc ops |= CVT_BS;
187f7cf2976SLionel Sambuc if (bs_mode != BS_CONTROL)
188f7cf2976SLionel Sambuc ops |= CVT_CRLF;
189f7cf2976SLionel Sambuc } else if (bs_mode != BS_CONTROL)
190f7cf2976SLionel Sambuc {
191f7cf2976SLionel Sambuc ops |= CVT_CRLF;
192f7cf2976SLionel Sambuc }
193f7cf2976SLionel Sambuc if (ctldisp == OPT_ONPLUS)
194f7cf2976SLionel Sambuc ops |= CVT_ANSI;
195f7cf2976SLionel Sambuc return (ops);
196f7cf2976SLionel Sambuc }
197f7cf2976SLionel Sambuc
198f7cf2976SLionel Sambuc /*
199f7cf2976SLionel Sambuc * Is there a previous (remembered) search pattern?
200f7cf2976SLionel Sambuc */
201f7cf2976SLionel Sambuc static int
prev_pattern(info)202f7cf2976SLionel Sambuc prev_pattern(info)
203f7cf2976SLionel Sambuc struct pattern_info *info;
204f7cf2976SLionel Sambuc {
205*84d9c625SLionel Sambuc #if !NO_REGEX
206*84d9c625SLionel Sambuc if ((info->search_type & SRCH_NO_REGEX) == 0)
207f7cf2976SLionel Sambuc return (!is_null_pattern(info->compiled));
208*84d9c625SLionel Sambuc #endif
209*84d9c625SLionel Sambuc return (info->text != NULL);
210f7cf2976SLionel Sambuc }
211f7cf2976SLionel Sambuc
212f7cf2976SLionel Sambuc #if HILITE_SEARCH
213f7cf2976SLionel Sambuc /*
214f7cf2976SLionel Sambuc * Repaint the hilites currently displayed on the screen.
215f7cf2976SLionel Sambuc * Repaint each line which contains highlighted text.
216f7cf2976SLionel Sambuc * If on==0, force all hilites off.
217f7cf2976SLionel Sambuc */
218f7cf2976SLionel Sambuc public void
repaint_hilite(on)219f7cf2976SLionel Sambuc repaint_hilite(on)
220f7cf2976SLionel Sambuc int on;
221f7cf2976SLionel Sambuc {
222f7cf2976SLionel Sambuc int slinenum;
223f7cf2976SLionel Sambuc POSITION pos;
224f7cf2976SLionel Sambuc POSITION epos;
225f7cf2976SLionel Sambuc int save_hide_hilite;
226f7cf2976SLionel Sambuc
227f7cf2976SLionel Sambuc if (squished)
228f7cf2976SLionel Sambuc repaint();
229f7cf2976SLionel Sambuc
230f7cf2976SLionel Sambuc save_hide_hilite = hide_hilite;
231f7cf2976SLionel Sambuc if (!on)
232f7cf2976SLionel Sambuc {
233f7cf2976SLionel Sambuc if (hide_hilite)
234f7cf2976SLionel Sambuc return;
235f7cf2976SLionel Sambuc hide_hilite = 1;
236f7cf2976SLionel Sambuc }
237f7cf2976SLionel Sambuc
238f7cf2976SLionel Sambuc if (!can_goto_line)
239f7cf2976SLionel Sambuc {
240f7cf2976SLionel Sambuc repaint();
241f7cf2976SLionel Sambuc hide_hilite = save_hide_hilite;
242f7cf2976SLionel Sambuc return;
243f7cf2976SLionel Sambuc }
244f7cf2976SLionel Sambuc
245f7cf2976SLionel Sambuc for (slinenum = TOP; slinenum < TOP + sc_height-1; slinenum++)
246f7cf2976SLionel Sambuc {
247f7cf2976SLionel Sambuc pos = position(slinenum);
248f7cf2976SLionel Sambuc if (pos == NULL_POSITION)
249f7cf2976SLionel Sambuc continue;
250f7cf2976SLionel Sambuc epos = position(slinenum+1);
251f7cf2976SLionel Sambuc (void) forw_line(pos);
252f7cf2976SLionel Sambuc goto_line(slinenum);
253f7cf2976SLionel Sambuc put_line();
254f7cf2976SLionel Sambuc }
255f7cf2976SLionel Sambuc lower_left();
256f7cf2976SLionel Sambuc hide_hilite = save_hide_hilite;
257f7cf2976SLionel Sambuc }
258f7cf2976SLionel Sambuc
259f7cf2976SLionel Sambuc /*
260f7cf2976SLionel Sambuc * Clear the attn hilite.
261f7cf2976SLionel Sambuc */
262f7cf2976SLionel Sambuc public void
clear_attn()263f7cf2976SLionel Sambuc clear_attn()
264f7cf2976SLionel Sambuc {
265f7cf2976SLionel Sambuc int slinenum;
266f7cf2976SLionel Sambuc POSITION old_start_attnpos;
267f7cf2976SLionel Sambuc POSITION old_end_attnpos;
268f7cf2976SLionel Sambuc POSITION pos;
269f7cf2976SLionel Sambuc POSITION epos;
270f7cf2976SLionel Sambuc int moved = 0;
271f7cf2976SLionel Sambuc
272f7cf2976SLionel Sambuc if (start_attnpos == NULL_POSITION)
273f7cf2976SLionel Sambuc return;
274f7cf2976SLionel Sambuc old_start_attnpos = start_attnpos;
275f7cf2976SLionel Sambuc old_end_attnpos = end_attnpos;
276f7cf2976SLionel Sambuc start_attnpos = end_attnpos = NULL_POSITION;
277f7cf2976SLionel Sambuc
278f7cf2976SLionel Sambuc if (!can_goto_line)
279f7cf2976SLionel Sambuc {
280f7cf2976SLionel Sambuc repaint();
281f7cf2976SLionel Sambuc return;
282f7cf2976SLionel Sambuc }
283f7cf2976SLionel Sambuc if (squished)
284f7cf2976SLionel Sambuc repaint();
285f7cf2976SLionel Sambuc
286f7cf2976SLionel Sambuc for (slinenum = TOP; slinenum < TOP + sc_height-1; slinenum++)
287f7cf2976SLionel Sambuc {
288f7cf2976SLionel Sambuc pos = position(slinenum);
289f7cf2976SLionel Sambuc if (pos == NULL_POSITION)
290f7cf2976SLionel Sambuc continue;
291f7cf2976SLionel Sambuc epos = position(slinenum+1);
292f7cf2976SLionel Sambuc if (pos < old_end_attnpos &&
293f7cf2976SLionel Sambuc (epos == NULL_POSITION || epos > old_start_attnpos))
294f7cf2976SLionel Sambuc {
295f7cf2976SLionel Sambuc (void) forw_line(pos);
296f7cf2976SLionel Sambuc goto_line(slinenum);
297f7cf2976SLionel Sambuc put_line();
298f7cf2976SLionel Sambuc moved = 1;
299f7cf2976SLionel Sambuc }
300f7cf2976SLionel Sambuc }
301f7cf2976SLionel Sambuc if (moved)
302f7cf2976SLionel Sambuc lower_left();
303f7cf2976SLionel Sambuc }
304f7cf2976SLionel Sambuc #endif
305f7cf2976SLionel Sambuc
306f7cf2976SLionel Sambuc /*
307f7cf2976SLionel Sambuc * Hide search string highlighting.
308f7cf2976SLionel Sambuc */
309f7cf2976SLionel Sambuc public void
undo_search()310f7cf2976SLionel Sambuc undo_search()
311f7cf2976SLionel Sambuc {
312f7cf2976SLionel Sambuc if (!prev_pattern(&search_info))
313f7cf2976SLionel Sambuc {
314f7cf2976SLionel Sambuc error("No previous regular expression", NULL_PARG);
315f7cf2976SLionel Sambuc return;
316f7cf2976SLionel Sambuc }
317f7cf2976SLionel Sambuc #if HILITE_SEARCH
318f7cf2976SLionel Sambuc hide_hilite = !hide_hilite;
319f7cf2976SLionel Sambuc repaint_hilite(1);
320f7cf2976SLionel Sambuc #endif
321f7cf2976SLionel Sambuc }
322f7cf2976SLionel Sambuc
323f7cf2976SLionel Sambuc #if HILITE_SEARCH
324f7cf2976SLionel Sambuc /*
325f7cf2976SLionel Sambuc * Clear the hilite list.
326f7cf2976SLionel Sambuc */
327f7cf2976SLionel Sambuc public void
clr_hlist(anchor)328f7cf2976SLionel Sambuc clr_hlist(anchor)
329f7cf2976SLionel Sambuc struct hilite *anchor;
330f7cf2976SLionel Sambuc {
331f7cf2976SLionel Sambuc struct hilite *hl;
332f7cf2976SLionel Sambuc struct hilite *nexthl;
333f7cf2976SLionel Sambuc
334f7cf2976SLionel Sambuc for (hl = anchor->hl_first; hl != NULL; hl = nexthl)
335f7cf2976SLionel Sambuc {
336f7cf2976SLionel Sambuc nexthl = hl->hl_next;
337f7cf2976SLionel Sambuc free((void*)hl);
338f7cf2976SLionel Sambuc }
339f7cf2976SLionel Sambuc anchor->hl_first = NULL;
340f7cf2976SLionel Sambuc prep_startpos = prep_endpos = NULL_POSITION;
341f7cf2976SLionel Sambuc }
342f7cf2976SLionel Sambuc
343f7cf2976SLionel Sambuc public void
clr_hilite()344f7cf2976SLionel Sambuc clr_hilite()
345f7cf2976SLionel Sambuc {
346f7cf2976SLionel Sambuc clr_hlist(&hilite_anchor);
347f7cf2976SLionel Sambuc }
348f7cf2976SLionel Sambuc
349f7cf2976SLionel Sambuc public void
clr_filter()350f7cf2976SLionel Sambuc clr_filter()
351f7cf2976SLionel Sambuc {
352f7cf2976SLionel Sambuc clr_hlist(&filter_anchor);
353f7cf2976SLionel Sambuc }
354f7cf2976SLionel Sambuc
355f7cf2976SLionel Sambuc /*
356f7cf2976SLionel Sambuc * Should any characters in a specified range be highlighted?
357f7cf2976SLionel Sambuc */
358f7cf2976SLionel Sambuc static int
is_hilited_range(pos,epos)359f7cf2976SLionel Sambuc is_hilited_range(pos, epos)
360f7cf2976SLionel Sambuc POSITION pos;
361f7cf2976SLionel Sambuc POSITION epos;
362f7cf2976SLionel Sambuc {
363f7cf2976SLionel Sambuc struct hilite *hl;
364f7cf2976SLionel Sambuc
365f7cf2976SLionel Sambuc /*
366f7cf2976SLionel Sambuc * Look at each highlight and see if any part of it falls in the range.
367f7cf2976SLionel Sambuc */
368f7cf2976SLionel Sambuc for (hl = hilite_anchor.hl_first; hl != NULL; hl = hl->hl_next)
369f7cf2976SLionel Sambuc {
370f7cf2976SLionel Sambuc if (hl->hl_endpos > pos &&
371f7cf2976SLionel Sambuc (epos == NULL_POSITION || epos > hl->hl_startpos))
372f7cf2976SLionel Sambuc return (1);
373f7cf2976SLionel Sambuc }
374f7cf2976SLionel Sambuc return (0);
375f7cf2976SLionel Sambuc }
376f7cf2976SLionel Sambuc
377f7cf2976SLionel Sambuc /*
378f7cf2976SLionel Sambuc * Is a line "filtered" -- that is, should it be hidden?
379f7cf2976SLionel Sambuc */
380f7cf2976SLionel Sambuc public int
is_filtered(pos)381f7cf2976SLionel Sambuc is_filtered(pos)
382f7cf2976SLionel Sambuc POSITION pos;
383f7cf2976SLionel Sambuc {
384f7cf2976SLionel Sambuc struct hilite *hl;
385f7cf2976SLionel Sambuc
386f7cf2976SLionel Sambuc if (ch_getflags() & CH_HELPFILE)
387f7cf2976SLionel Sambuc return (0);
388f7cf2976SLionel Sambuc
389f7cf2976SLionel Sambuc /*
390f7cf2976SLionel Sambuc * Look at each filter and see if the start position
391f7cf2976SLionel Sambuc * equals the start position of the line.
392f7cf2976SLionel Sambuc */
393f7cf2976SLionel Sambuc for (hl = filter_anchor.hl_first; hl != NULL; hl = hl->hl_next)
394f7cf2976SLionel Sambuc {
395f7cf2976SLionel Sambuc if (hl->hl_startpos == pos)
396f7cf2976SLionel Sambuc return (1);
397f7cf2976SLionel Sambuc }
398f7cf2976SLionel Sambuc return (0);
399f7cf2976SLionel Sambuc }
400f7cf2976SLionel Sambuc
401f7cf2976SLionel Sambuc /*
402f7cf2976SLionel Sambuc * Should any characters in a specified range be highlighted?
403f7cf2976SLionel Sambuc * If nohide is nonzero, don't consider hide_hilite.
404f7cf2976SLionel Sambuc */
405f7cf2976SLionel Sambuc public int
is_hilited(pos,epos,nohide,p_matches)406f7cf2976SLionel Sambuc is_hilited(pos, epos, nohide, p_matches)
407f7cf2976SLionel Sambuc POSITION pos;
408f7cf2976SLionel Sambuc POSITION epos;
409f7cf2976SLionel Sambuc int nohide;
410f7cf2976SLionel Sambuc int *p_matches;
411f7cf2976SLionel Sambuc {
412f7cf2976SLionel Sambuc int match;
413f7cf2976SLionel Sambuc
414f7cf2976SLionel Sambuc if (p_matches != NULL)
415f7cf2976SLionel Sambuc *p_matches = 0;
416f7cf2976SLionel Sambuc
417f7cf2976SLionel Sambuc if (!status_col &&
418f7cf2976SLionel Sambuc start_attnpos != NULL_POSITION &&
419f7cf2976SLionel Sambuc pos < end_attnpos &&
420f7cf2976SLionel Sambuc (epos == NULL_POSITION || epos > start_attnpos))
421f7cf2976SLionel Sambuc /*
422f7cf2976SLionel Sambuc * The attn line overlaps this range.
423f7cf2976SLionel Sambuc */
424f7cf2976SLionel Sambuc return (1);
425f7cf2976SLionel Sambuc
426f7cf2976SLionel Sambuc match = is_hilited_range(pos, epos);
427f7cf2976SLionel Sambuc if (!match)
428f7cf2976SLionel Sambuc return (0);
429f7cf2976SLionel Sambuc
430f7cf2976SLionel Sambuc if (p_matches != NULL)
431f7cf2976SLionel Sambuc /*
432f7cf2976SLionel Sambuc * Report matches, even if we're hiding highlights.
433f7cf2976SLionel Sambuc */
434f7cf2976SLionel Sambuc *p_matches = 1;
435f7cf2976SLionel Sambuc
436f7cf2976SLionel Sambuc if (hilite_search == 0)
437f7cf2976SLionel Sambuc /*
438f7cf2976SLionel Sambuc * Not doing highlighting.
439f7cf2976SLionel Sambuc */
440f7cf2976SLionel Sambuc return (0);
441f7cf2976SLionel Sambuc
442f7cf2976SLionel Sambuc if (!nohide && hide_hilite)
443f7cf2976SLionel Sambuc /*
444f7cf2976SLionel Sambuc * Highlighting is hidden.
445f7cf2976SLionel Sambuc */
446f7cf2976SLionel Sambuc return (0);
447f7cf2976SLionel Sambuc
448f7cf2976SLionel Sambuc return (1);
449f7cf2976SLionel Sambuc }
450f7cf2976SLionel Sambuc
451f7cf2976SLionel Sambuc /*
452f7cf2976SLionel Sambuc * Add a new hilite to a hilite list.
453f7cf2976SLionel Sambuc */
454f7cf2976SLionel Sambuc static void
add_hilite(anchor,hl)455f7cf2976SLionel Sambuc add_hilite(anchor, hl)
456f7cf2976SLionel Sambuc struct hilite *anchor;
457f7cf2976SLionel Sambuc struct hilite *hl;
458f7cf2976SLionel Sambuc {
459f7cf2976SLionel Sambuc struct hilite *ihl;
460f7cf2976SLionel Sambuc
461f7cf2976SLionel Sambuc /*
462f7cf2976SLionel Sambuc * Hilites are sorted in the list; find where new one belongs.
463f7cf2976SLionel Sambuc * Insert new one after ihl.
464f7cf2976SLionel Sambuc */
465f7cf2976SLionel Sambuc for (ihl = anchor; ihl->hl_next != NULL; ihl = ihl->hl_next)
466f7cf2976SLionel Sambuc {
467f7cf2976SLionel Sambuc if (ihl->hl_next->hl_startpos > hl->hl_startpos)
468f7cf2976SLionel Sambuc break;
469f7cf2976SLionel Sambuc }
470f7cf2976SLionel Sambuc
471f7cf2976SLionel Sambuc /*
472f7cf2976SLionel Sambuc * Truncate hilite so it doesn't overlap any existing ones
473f7cf2976SLionel Sambuc * above and below it.
474f7cf2976SLionel Sambuc */
475f7cf2976SLionel Sambuc if (ihl != anchor)
476f7cf2976SLionel Sambuc hl->hl_startpos = MAXPOS(hl->hl_startpos, ihl->hl_endpos);
477f7cf2976SLionel Sambuc if (ihl->hl_next != NULL)
478f7cf2976SLionel Sambuc hl->hl_endpos = MINPOS(hl->hl_endpos, ihl->hl_next->hl_startpos);
479f7cf2976SLionel Sambuc if (hl->hl_startpos >= hl->hl_endpos)
480f7cf2976SLionel Sambuc {
481f7cf2976SLionel Sambuc /*
482f7cf2976SLionel Sambuc * Hilite was truncated out of existence.
483f7cf2976SLionel Sambuc */
484f7cf2976SLionel Sambuc free(hl);
485f7cf2976SLionel Sambuc return;
486f7cf2976SLionel Sambuc }
487f7cf2976SLionel Sambuc hl->hl_next = ihl->hl_next;
488f7cf2976SLionel Sambuc ihl->hl_next = hl;
489f7cf2976SLionel Sambuc }
490f7cf2976SLionel Sambuc
491f7cf2976SLionel Sambuc /*
492*84d9c625SLionel Sambuc * Hilight every character in a range of displayed characters.
493*84d9c625SLionel Sambuc */
494*84d9c625SLionel Sambuc static void
create_hilites(linepos,start_index,end_index,chpos)495*84d9c625SLionel Sambuc create_hilites(linepos, start_index, end_index, chpos)
496*84d9c625SLionel Sambuc POSITION linepos;
497*84d9c625SLionel Sambuc int start_index;
498*84d9c625SLionel Sambuc int end_index;
499*84d9c625SLionel Sambuc int *chpos;
500*84d9c625SLionel Sambuc {
501*84d9c625SLionel Sambuc struct hilite *hl;
502*84d9c625SLionel Sambuc int i;
503*84d9c625SLionel Sambuc
504*84d9c625SLionel Sambuc /* Start the first hilite. */
505*84d9c625SLionel Sambuc hl = (struct hilite *) ecalloc(1, sizeof(struct hilite));
506*84d9c625SLionel Sambuc hl->hl_startpos = linepos + chpos[start_index];
507*84d9c625SLionel Sambuc
508*84d9c625SLionel Sambuc /*
509*84d9c625SLionel Sambuc * Step through the displayed chars.
510*84d9c625SLionel Sambuc * If the source position (before cvt) of the char is one more
511*84d9c625SLionel Sambuc * than the source pos of the previous char (the usual case),
512*84d9c625SLionel Sambuc * just increase the size of the current hilite by one.
513*84d9c625SLionel Sambuc * Otherwise (there are backspaces or something involved),
514*84d9c625SLionel Sambuc * finish the current hilite and start a new one.
515*84d9c625SLionel Sambuc */
516*84d9c625SLionel Sambuc for (i = start_index+1; i <= end_index; i++)
517*84d9c625SLionel Sambuc {
518*84d9c625SLionel Sambuc if (chpos[i] != chpos[i-1] + 1 || i == end_index)
519*84d9c625SLionel Sambuc {
520*84d9c625SLionel Sambuc hl->hl_endpos = linepos + chpos[i-1] + 1;
521*84d9c625SLionel Sambuc add_hilite(&hilite_anchor, hl);
522*84d9c625SLionel Sambuc /* Start new hilite unless this is the last char. */
523*84d9c625SLionel Sambuc if (i < end_index)
524*84d9c625SLionel Sambuc {
525*84d9c625SLionel Sambuc hl = (struct hilite *) ecalloc(1, sizeof(struct hilite));
526*84d9c625SLionel Sambuc hl->hl_startpos = linepos + chpos[i];
527*84d9c625SLionel Sambuc }
528*84d9c625SLionel Sambuc }
529*84d9c625SLionel Sambuc }
530*84d9c625SLionel Sambuc }
531*84d9c625SLionel Sambuc
532*84d9c625SLionel Sambuc /*
533f7cf2976SLionel Sambuc * Make a hilite for each string in a physical line which matches
534f7cf2976SLionel Sambuc * the current pattern.
535f7cf2976SLionel Sambuc * sp,ep delimit the first match already found.
536f7cf2976SLionel Sambuc */
537f7cf2976SLionel Sambuc static void
hilite_line(linepos,line,line_len,chpos,sp,ep,cvt_ops)538f7cf2976SLionel Sambuc hilite_line(linepos, line, line_len, chpos, sp, ep, cvt_ops)
539f7cf2976SLionel Sambuc POSITION linepos;
540f7cf2976SLionel Sambuc char *line;
541f7cf2976SLionel Sambuc int line_len;
542f7cf2976SLionel Sambuc int *chpos;
543f7cf2976SLionel Sambuc char *sp;
544f7cf2976SLionel Sambuc char *ep;
545f7cf2976SLionel Sambuc int cvt_ops;
546f7cf2976SLionel Sambuc {
547f7cf2976SLionel Sambuc char *searchp;
548f7cf2976SLionel Sambuc char *line_end = line + line_len;
549f7cf2976SLionel Sambuc
550f7cf2976SLionel Sambuc if (sp == NULL || ep == NULL)
551f7cf2976SLionel Sambuc return;
552f7cf2976SLionel Sambuc /*
553f7cf2976SLionel Sambuc * sp and ep delimit the first match in the line.
554f7cf2976SLionel Sambuc * Mark the corresponding file positions, then
555f7cf2976SLionel Sambuc * look for further matches and mark them.
556f7cf2976SLionel Sambuc * {{ This technique, of calling match_pattern on subsequent
557f7cf2976SLionel Sambuc * substrings of the line, may mark more than is correct
558f7cf2976SLionel Sambuc * if the pattern starts with "^". This bug is fixed
559f7cf2976SLionel Sambuc * for those regex functions that accept a notbol parameter
560f7cf2976SLionel Sambuc * (currently POSIX, PCRE and V8-with-regexec2). }}
561f7cf2976SLionel Sambuc */
562f7cf2976SLionel Sambuc searchp = line;
563f7cf2976SLionel Sambuc do {
564*84d9c625SLionel Sambuc create_hilites(linepos, sp-line, ep-line, chpos);
565f7cf2976SLionel Sambuc /*
566f7cf2976SLionel Sambuc * If we matched more than zero characters,
567f7cf2976SLionel Sambuc * move to the first char after the string we matched.
568f7cf2976SLionel Sambuc * If we matched zero, just move to the next char.
569f7cf2976SLionel Sambuc */
570f7cf2976SLionel Sambuc if (ep > searchp)
571f7cf2976SLionel Sambuc searchp = ep;
572f7cf2976SLionel Sambuc else if (searchp != line_end)
573f7cf2976SLionel Sambuc searchp++;
574f7cf2976SLionel Sambuc else /* end of line */
575f7cf2976SLionel Sambuc break;
576*84d9c625SLionel Sambuc } while (match_pattern(info_compiled(&search_info), search_info.text,
577f7cf2976SLionel Sambuc searchp, line_end - searchp, &sp, &ep, 1, search_info.search_type));
578f7cf2976SLionel Sambuc }
579f7cf2976SLionel Sambuc #endif
580f7cf2976SLionel Sambuc
581f7cf2976SLionel Sambuc /*
582f7cf2976SLionel Sambuc * Change the caseless-ness of searches.
583f7cf2976SLionel Sambuc * Updates the internal search state to reflect a change in the -i flag.
584f7cf2976SLionel Sambuc */
585f7cf2976SLionel Sambuc public void
chg_caseless()586f7cf2976SLionel Sambuc chg_caseless()
587f7cf2976SLionel Sambuc {
588f7cf2976SLionel Sambuc if (!is_ucase_pattern)
589f7cf2976SLionel Sambuc /*
590f7cf2976SLionel Sambuc * Pattern did not have uppercase.
591f7cf2976SLionel Sambuc * Just set the search caselessness to the global caselessness.
592f7cf2976SLionel Sambuc */
593f7cf2976SLionel Sambuc is_caseless = caseless;
594f7cf2976SLionel Sambuc else
595f7cf2976SLionel Sambuc /*
596f7cf2976SLionel Sambuc * Pattern did have uppercase.
597f7cf2976SLionel Sambuc * Discard the pattern; we can't change search caselessness now.
598f7cf2976SLionel Sambuc */
599f7cf2976SLionel Sambuc clear_pattern(&search_info);
600f7cf2976SLionel Sambuc }
601f7cf2976SLionel Sambuc
602f7cf2976SLionel Sambuc #if HILITE_SEARCH
603f7cf2976SLionel Sambuc /*
604f7cf2976SLionel Sambuc * Find matching text which is currently on screen and highlight it.
605f7cf2976SLionel Sambuc */
606f7cf2976SLionel Sambuc static void
hilite_screen()607f7cf2976SLionel Sambuc hilite_screen()
608f7cf2976SLionel Sambuc {
609f7cf2976SLionel Sambuc struct scrpos scrpos;
610f7cf2976SLionel Sambuc
611f7cf2976SLionel Sambuc get_scrpos(&scrpos);
612f7cf2976SLionel Sambuc if (scrpos.pos == NULL_POSITION)
613f7cf2976SLionel Sambuc return;
614f7cf2976SLionel Sambuc prep_hilite(scrpos.pos, position(BOTTOM_PLUS_ONE), -1);
615f7cf2976SLionel Sambuc repaint_hilite(1);
616f7cf2976SLionel Sambuc }
617f7cf2976SLionel Sambuc
618f7cf2976SLionel Sambuc /*
619f7cf2976SLionel Sambuc * Change highlighting parameters.
620f7cf2976SLionel Sambuc */
621f7cf2976SLionel Sambuc public void
chg_hilite()622f7cf2976SLionel Sambuc chg_hilite()
623f7cf2976SLionel Sambuc {
624f7cf2976SLionel Sambuc /*
625f7cf2976SLionel Sambuc * Erase any highlights currently on screen.
626f7cf2976SLionel Sambuc */
627f7cf2976SLionel Sambuc clr_hilite();
628f7cf2976SLionel Sambuc hide_hilite = 0;
629f7cf2976SLionel Sambuc
630f7cf2976SLionel Sambuc if (hilite_search == OPT_ONPLUS)
631f7cf2976SLionel Sambuc /*
632f7cf2976SLionel Sambuc * Display highlights.
633f7cf2976SLionel Sambuc */
634f7cf2976SLionel Sambuc hilite_screen();
635f7cf2976SLionel Sambuc }
636f7cf2976SLionel Sambuc #endif
637f7cf2976SLionel Sambuc
638f7cf2976SLionel Sambuc /*
639f7cf2976SLionel Sambuc * Figure out where to start a search.
640f7cf2976SLionel Sambuc */
641f7cf2976SLionel Sambuc static POSITION
search_pos(search_type)642f7cf2976SLionel Sambuc search_pos(search_type)
643f7cf2976SLionel Sambuc int search_type;
644f7cf2976SLionel Sambuc {
645f7cf2976SLionel Sambuc POSITION pos;
646f7cf2976SLionel Sambuc int linenum;
647f7cf2976SLionel Sambuc
648f7cf2976SLionel Sambuc if (empty_screen())
649f7cf2976SLionel Sambuc {
650f7cf2976SLionel Sambuc /*
651f7cf2976SLionel Sambuc * Start at the beginning (or end) of the file.
652f7cf2976SLionel Sambuc * The empty_screen() case is mainly for
653f7cf2976SLionel Sambuc * command line initiated searches;
654f7cf2976SLionel Sambuc * for example, "+/xyz" on the command line.
655f7cf2976SLionel Sambuc * Also for multi-file (SRCH_PAST_EOF) searches.
656f7cf2976SLionel Sambuc */
657f7cf2976SLionel Sambuc if (search_type & SRCH_FORW)
658f7cf2976SLionel Sambuc {
659f7cf2976SLionel Sambuc pos = ch_zero();
660f7cf2976SLionel Sambuc } else
661f7cf2976SLionel Sambuc {
662f7cf2976SLionel Sambuc pos = ch_length();
663f7cf2976SLionel Sambuc if (pos == NULL_POSITION)
664f7cf2976SLionel Sambuc {
665f7cf2976SLionel Sambuc (void) ch_end_seek();
666f7cf2976SLionel Sambuc pos = ch_length();
667f7cf2976SLionel Sambuc }
668f7cf2976SLionel Sambuc }
669f7cf2976SLionel Sambuc linenum = 0;
670f7cf2976SLionel Sambuc } else
671f7cf2976SLionel Sambuc {
672f7cf2976SLionel Sambuc int add_one = 0;
673f7cf2976SLionel Sambuc
674f7cf2976SLionel Sambuc if (how_search == OPT_ON)
675f7cf2976SLionel Sambuc {
676f7cf2976SLionel Sambuc /*
677f7cf2976SLionel Sambuc * Search does not include current screen.
678f7cf2976SLionel Sambuc */
679f7cf2976SLionel Sambuc if (search_type & SRCH_FORW)
680f7cf2976SLionel Sambuc linenum = BOTTOM_PLUS_ONE;
681f7cf2976SLionel Sambuc else
682f7cf2976SLionel Sambuc linenum = TOP;
683f7cf2976SLionel Sambuc } else if (how_search == OPT_ONPLUS && !(search_type & SRCH_AFTER_TARGET))
684f7cf2976SLionel Sambuc {
685f7cf2976SLionel Sambuc /*
686f7cf2976SLionel Sambuc * Search includes all of displayed screen.
687f7cf2976SLionel Sambuc */
688f7cf2976SLionel Sambuc if (search_type & SRCH_FORW)
689f7cf2976SLionel Sambuc linenum = TOP;
690f7cf2976SLionel Sambuc else
691f7cf2976SLionel Sambuc linenum = BOTTOM_PLUS_ONE;
692f7cf2976SLionel Sambuc } else
693f7cf2976SLionel Sambuc {
694f7cf2976SLionel Sambuc /*
695f7cf2976SLionel Sambuc * Search includes the part of current screen beyond the jump target.
696f7cf2976SLionel Sambuc * It starts at the jump target (if searching backwards),
697f7cf2976SLionel Sambuc * or at the jump target plus one (if forwards).
698f7cf2976SLionel Sambuc */
699f7cf2976SLionel Sambuc linenum = jump_sline;
700f7cf2976SLionel Sambuc if (search_type & SRCH_FORW)
701f7cf2976SLionel Sambuc add_one = 1;
702f7cf2976SLionel Sambuc }
703f7cf2976SLionel Sambuc linenum = adjsline(linenum);
704f7cf2976SLionel Sambuc pos = position(linenum);
705f7cf2976SLionel Sambuc if (add_one)
706f7cf2976SLionel Sambuc pos = forw_raw_line(pos, (char **)NULL, (int *)NULL);
707f7cf2976SLionel Sambuc }
708f7cf2976SLionel Sambuc
709f7cf2976SLionel Sambuc /*
710f7cf2976SLionel Sambuc * If the line is empty, look around for a plausible starting place.
711f7cf2976SLionel Sambuc */
712f7cf2976SLionel Sambuc if (search_type & SRCH_FORW)
713f7cf2976SLionel Sambuc {
714f7cf2976SLionel Sambuc while (pos == NULL_POSITION)
715f7cf2976SLionel Sambuc {
716f7cf2976SLionel Sambuc if (++linenum >= sc_height)
717f7cf2976SLionel Sambuc break;
718f7cf2976SLionel Sambuc pos = position(linenum);
719f7cf2976SLionel Sambuc }
720f7cf2976SLionel Sambuc } else
721f7cf2976SLionel Sambuc {
722f7cf2976SLionel Sambuc while (pos == NULL_POSITION)
723f7cf2976SLionel Sambuc {
724f7cf2976SLionel Sambuc if (--linenum < 0)
725f7cf2976SLionel Sambuc break;
726f7cf2976SLionel Sambuc pos = position(linenum);
727f7cf2976SLionel Sambuc }
728f7cf2976SLionel Sambuc }
729f7cf2976SLionel Sambuc return (pos);
730f7cf2976SLionel Sambuc }
731f7cf2976SLionel Sambuc
732f7cf2976SLionel Sambuc /*
733f7cf2976SLionel Sambuc * Search a subset of the file, specified by start/end position.
734f7cf2976SLionel Sambuc */
735f7cf2976SLionel Sambuc static int
search_range(pos,endpos,search_type,matches,maxlines,plinepos,pendpos)736f7cf2976SLionel Sambuc search_range(pos, endpos, search_type, matches, maxlines, plinepos, pendpos)
737f7cf2976SLionel Sambuc POSITION pos;
738f7cf2976SLionel Sambuc POSITION endpos;
739f7cf2976SLionel Sambuc int search_type;
740f7cf2976SLionel Sambuc int matches;
741f7cf2976SLionel Sambuc int maxlines;
742f7cf2976SLionel Sambuc POSITION *plinepos;
743f7cf2976SLionel Sambuc POSITION *pendpos;
744f7cf2976SLionel Sambuc {
745f7cf2976SLionel Sambuc char *line;
746f7cf2976SLionel Sambuc char *cline;
747f7cf2976SLionel Sambuc int line_len;
748f7cf2976SLionel Sambuc LINENUM linenum;
749f7cf2976SLionel Sambuc char *sp = NULL, *ep = NULL; /* XXX: GCC */
750f7cf2976SLionel Sambuc int line_match;
751f7cf2976SLionel Sambuc int cvt_ops;
752f7cf2976SLionel Sambuc int cvt_len;
753f7cf2976SLionel Sambuc int *chpos;
754f7cf2976SLionel Sambuc POSITION linepos, oldpos;
755f7cf2976SLionel Sambuc
756f7cf2976SLionel Sambuc linenum = find_linenum(pos);
757f7cf2976SLionel Sambuc oldpos = pos;
758f7cf2976SLionel Sambuc for (;;)
759f7cf2976SLionel Sambuc {
760f7cf2976SLionel Sambuc /*
761f7cf2976SLionel Sambuc * Get lines until we find a matching one or until
762f7cf2976SLionel Sambuc * we hit end-of-file (or beginning-of-file if we're
763f7cf2976SLionel Sambuc * going backwards), or until we hit the end position.
764f7cf2976SLionel Sambuc */
765f7cf2976SLionel Sambuc if (ABORT_SIGS())
766f7cf2976SLionel Sambuc {
767f7cf2976SLionel Sambuc /*
768f7cf2976SLionel Sambuc * A signal aborts the search.
769f7cf2976SLionel Sambuc */
770f7cf2976SLionel Sambuc return (-1);
771f7cf2976SLionel Sambuc }
772f7cf2976SLionel Sambuc
773f7cf2976SLionel Sambuc if ((endpos != NULL_POSITION && pos >= endpos) || maxlines == 0)
774f7cf2976SLionel Sambuc {
775f7cf2976SLionel Sambuc /*
776f7cf2976SLionel Sambuc * Reached end position without a match.
777f7cf2976SLionel Sambuc */
778f7cf2976SLionel Sambuc if (pendpos != NULL)
779f7cf2976SLionel Sambuc *pendpos = pos;
780f7cf2976SLionel Sambuc return (matches);
781f7cf2976SLionel Sambuc }
782f7cf2976SLionel Sambuc if (maxlines > 0)
783f7cf2976SLionel Sambuc maxlines--;
784f7cf2976SLionel Sambuc
785f7cf2976SLionel Sambuc if (search_type & SRCH_FORW)
786f7cf2976SLionel Sambuc {
787f7cf2976SLionel Sambuc /*
788f7cf2976SLionel Sambuc * Read the next line, and save the
789f7cf2976SLionel Sambuc * starting position of that line in linepos.
790f7cf2976SLionel Sambuc */
791f7cf2976SLionel Sambuc linepos = pos;
792f7cf2976SLionel Sambuc pos = forw_raw_line(pos, &line, &line_len);
793f7cf2976SLionel Sambuc if (linenum != 0)
794f7cf2976SLionel Sambuc linenum++;
795f7cf2976SLionel Sambuc } else
796f7cf2976SLionel Sambuc {
797f7cf2976SLionel Sambuc /*
798f7cf2976SLionel Sambuc * Read the previous line and save the
799f7cf2976SLionel Sambuc * starting position of that line in linepos.
800f7cf2976SLionel Sambuc */
801f7cf2976SLionel Sambuc pos = back_raw_line(pos, &line, &line_len);
802f7cf2976SLionel Sambuc linepos = pos;
803f7cf2976SLionel Sambuc if (linenum != 0)
804f7cf2976SLionel Sambuc linenum--;
805f7cf2976SLionel Sambuc }
806f7cf2976SLionel Sambuc
807f7cf2976SLionel Sambuc if (pos == NULL_POSITION)
808f7cf2976SLionel Sambuc {
809f7cf2976SLionel Sambuc /*
810f7cf2976SLionel Sambuc * Reached EOF/BOF without a match.
811f7cf2976SLionel Sambuc */
812f7cf2976SLionel Sambuc if (pendpos != NULL)
813f7cf2976SLionel Sambuc *pendpos = oldpos;
814f7cf2976SLionel Sambuc return (matches);
815f7cf2976SLionel Sambuc }
816f7cf2976SLionel Sambuc
817f7cf2976SLionel Sambuc /*
818f7cf2976SLionel Sambuc * If we're using line numbers, we might as well
819f7cf2976SLionel Sambuc * remember the information we have now (the position
820f7cf2976SLionel Sambuc * and line number of the current line).
821f7cf2976SLionel Sambuc * Don't do it for every line because it slows down
822f7cf2976SLionel Sambuc * the search. Remember the line number only if
823f7cf2976SLionel Sambuc * we're "far" from the last place we remembered it.
824f7cf2976SLionel Sambuc */
825f7cf2976SLionel Sambuc if (linenums && abs((int)(pos - oldpos)) > 2048)
826f7cf2976SLionel Sambuc add_lnum(linenum, pos);
827f7cf2976SLionel Sambuc oldpos = pos;
828f7cf2976SLionel Sambuc
829f7cf2976SLionel Sambuc if (is_filtered(linepos))
830f7cf2976SLionel Sambuc continue;
831f7cf2976SLionel Sambuc
832f7cf2976SLionel Sambuc /*
833f7cf2976SLionel Sambuc * If it's a caseless search, convert the line to lowercase.
834f7cf2976SLionel Sambuc * If we're doing backspace processing, delete backspaces.
835f7cf2976SLionel Sambuc */
836f7cf2976SLionel Sambuc cvt_ops = get_cvt_ops();
837f7cf2976SLionel Sambuc cvt_len = cvt_length(line_len, cvt_ops);
838f7cf2976SLionel Sambuc cline = (char *) ecalloc(1, cvt_len);
839f7cf2976SLionel Sambuc chpos = cvt_alloc_chpos(cvt_len);
840f7cf2976SLionel Sambuc cvt_text(cline, line, chpos, &line_len, cvt_ops);
841f7cf2976SLionel Sambuc
842f7cf2976SLionel Sambuc #if HILITE_SEARCH
843f7cf2976SLionel Sambuc /*
844f7cf2976SLionel Sambuc * Check to see if the line matches the filter pattern.
845f7cf2976SLionel Sambuc * If so, add an entry to the filter list.
846f7cf2976SLionel Sambuc */
847f7cf2976SLionel Sambuc if ((search_type & SRCH_FIND_ALL) && prev_pattern(&filter_info)) {
848*84d9c625SLionel Sambuc int line_filter = match_pattern(info_compiled(&filter_info), filter_info.text,
849f7cf2976SLionel Sambuc cline, line_len, &sp, &ep, 0, filter_info.search_type);
850f7cf2976SLionel Sambuc if (line_filter)
851f7cf2976SLionel Sambuc {
852f7cf2976SLionel Sambuc struct hilite *hl = (struct hilite *)
853f7cf2976SLionel Sambuc ecalloc(1, sizeof(struct hilite));
854f7cf2976SLionel Sambuc hl->hl_startpos = linepos;
855f7cf2976SLionel Sambuc hl->hl_endpos = pos;
856f7cf2976SLionel Sambuc add_hilite(&filter_anchor, hl);
857f7cf2976SLionel Sambuc }
858f7cf2976SLionel Sambuc }
859f7cf2976SLionel Sambuc #endif
860f7cf2976SLionel Sambuc
861f7cf2976SLionel Sambuc /*
862f7cf2976SLionel Sambuc * Test the next line to see if we have a match.
863f7cf2976SLionel Sambuc * We are successful if we either want a match and got one,
864f7cf2976SLionel Sambuc * or if we want a non-match and got one.
865f7cf2976SLionel Sambuc */
866f7cf2976SLionel Sambuc if (prev_pattern(&search_info))
867f7cf2976SLionel Sambuc {
868*84d9c625SLionel Sambuc line_match = match_pattern(info_compiled(&search_info), search_info.text,
869f7cf2976SLionel Sambuc cline, line_len, &sp, &ep, 0, search_type);
870f7cf2976SLionel Sambuc if (line_match)
871f7cf2976SLionel Sambuc {
872f7cf2976SLionel Sambuc /*
873f7cf2976SLionel Sambuc * Got a match.
874f7cf2976SLionel Sambuc */
875f7cf2976SLionel Sambuc if (search_type & SRCH_FIND_ALL)
876f7cf2976SLionel Sambuc {
877f7cf2976SLionel Sambuc #if HILITE_SEARCH
878f7cf2976SLionel Sambuc /*
879f7cf2976SLionel Sambuc * We are supposed to find all matches in the range.
880f7cf2976SLionel Sambuc * Just add the matches in this line to the
881f7cf2976SLionel Sambuc * hilite list and keep searching.
882f7cf2976SLionel Sambuc */
883f7cf2976SLionel Sambuc hilite_line(linepos, cline, line_len, chpos, sp, ep, cvt_ops);
884f7cf2976SLionel Sambuc #endif
885f7cf2976SLionel Sambuc } else if (--matches <= 0)
886f7cf2976SLionel Sambuc {
887f7cf2976SLionel Sambuc /*
888f7cf2976SLionel Sambuc * Found the one match we're looking for.
889f7cf2976SLionel Sambuc * Return it.
890f7cf2976SLionel Sambuc */
891f7cf2976SLionel Sambuc #if HILITE_SEARCH
892f7cf2976SLionel Sambuc if (hilite_search == OPT_ON)
893f7cf2976SLionel Sambuc {
894f7cf2976SLionel Sambuc /*
895f7cf2976SLionel Sambuc * Clear the hilite list and add only
896f7cf2976SLionel Sambuc * the matches in this one line.
897f7cf2976SLionel Sambuc */
898f7cf2976SLionel Sambuc clr_hilite();
899f7cf2976SLionel Sambuc hilite_line(linepos, cline, line_len, chpos, sp, ep, cvt_ops);
900f7cf2976SLionel Sambuc }
901f7cf2976SLionel Sambuc #endif
902f7cf2976SLionel Sambuc free(cline);
903f7cf2976SLionel Sambuc free(chpos);
904f7cf2976SLionel Sambuc if (plinepos != NULL)
905f7cf2976SLionel Sambuc *plinepos = linepos;
906f7cf2976SLionel Sambuc return (0);
907f7cf2976SLionel Sambuc }
908f7cf2976SLionel Sambuc }
909f7cf2976SLionel Sambuc }
910f7cf2976SLionel Sambuc free(cline);
911f7cf2976SLionel Sambuc free(chpos);
912f7cf2976SLionel Sambuc }
913f7cf2976SLionel Sambuc }
914f7cf2976SLionel Sambuc
915f7cf2976SLionel Sambuc /*
916f7cf2976SLionel Sambuc * search for a pattern in history. If found, compile that pattern.
917f7cf2976SLionel Sambuc */
918f7cf2976SLionel Sambuc static int
hist_pattern(search_type)919f7cf2976SLionel Sambuc hist_pattern(search_type)
920f7cf2976SLionel Sambuc int search_type;
921f7cf2976SLionel Sambuc {
922f7cf2976SLionel Sambuc #if CMD_HISTORY
923f7cf2976SLionel Sambuc char *pattern;
924f7cf2976SLionel Sambuc
925f7cf2976SLionel Sambuc set_mlist(ml_search, 0);
926f7cf2976SLionel Sambuc pattern = cmd_lastpattern();
927f7cf2976SLionel Sambuc if (pattern == NULL)
928f7cf2976SLionel Sambuc return (0);
929f7cf2976SLionel Sambuc
930f7cf2976SLionel Sambuc if (set_pattern(&search_info, pattern, search_type) < 0)
931f7cf2976SLionel Sambuc return (0);
932f7cf2976SLionel Sambuc
933f7cf2976SLionel Sambuc #if HILITE_SEARCH
934f7cf2976SLionel Sambuc if (hilite_search == OPT_ONPLUS && !hide_hilite)
935f7cf2976SLionel Sambuc hilite_screen();
936f7cf2976SLionel Sambuc #endif
937f7cf2976SLionel Sambuc
938f7cf2976SLionel Sambuc return (1);
939f7cf2976SLionel Sambuc #else /* CMD_HISTORY */
940f7cf2976SLionel Sambuc return (0);
941f7cf2976SLionel Sambuc #endif /* CMD_HISTORY */
942f7cf2976SLionel Sambuc }
943f7cf2976SLionel Sambuc
944f7cf2976SLionel Sambuc /*
945f7cf2976SLionel Sambuc * Search for the n-th occurrence of a specified pattern,
946f7cf2976SLionel Sambuc * either forward or backward.
947f7cf2976SLionel Sambuc * Return the number of matches not yet found in this file
948f7cf2976SLionel Sambuc * (that is, n minus the number of matches found).
949f7cf2976SLionel Sambuc * Return -1 if the search should be aborted.
950f7cf2976SLionel Sambuc * Caller may continue the search in another file
951f7cf2976SLionel Sambuc * if less than n matches are found in this file.
952f7cf2976SLionel Sambuc */
953f7cf2976SLionel Sambuc public int
search(search_type,pattern,n)954f7cf2976SLionel Sambuc search(search_type, pattern, n)
955f7cf2976SLionel Sambuc int search_type;
956f7cf2976SLionel Sambuc char *pattern;
957f7cf2976SLionel Sambuc int n;
958f7cf2976SLionel Sambuc {
959f7cf2976SLionel Sambuc POSITION pos;
960f7cf2976SLionel Sambuc
961f7cf2976SLionel Sambuc if (pattern == NULL || *pattern == '\0')
962f7cf2976SLionel Sambuc {
963f7cf2976SLionel Sambuc /*
964f7cf2976SLionel Sambuc * A null pattern means use the previously compiled pattern.
965f7cf2976SLionel Sambuc */
966f7cf2976SLionel Sambuc search_type |= SRCH_AFTER_TARGET;
967f7cf2976SLionel Sambuc if (!prev_pattern(&search_info) && !hist_pattern(search_type))
968f7cf2976SLionel Sambuc {
969f7cf2976SLionel Sambuc error("No previous regular expression", NULL_PARG);
970f7cf2976SLionel Sambuc return (-1);
971f7cf2976SLionel Sambuc }
972f7cf2976SLionel Sambuc if ((search_type & SRCH_NO_REGEX) !=
973f7cf2976SLionel Sambuc (search_info.search_type & SRCH_NO_REGEX))
974f7cf2976SLionel Sambuc {
975f7cf2976SLionel Sambuc error("Please re-enter search pattern", NULL_PARG);
976f7cf2976SLionel Sambuc return -1;
977f7cf2976SLionel Sambuc }
978f7cf2976SLionel Sambuc #if HILITE_SEARCH
979f7cf2976SLionel Sambuc if (hilite_search == OPT_ON)
980f7cf2976SLionel Sambuc {
981f7cf2976SLionel Sambuc /*
982f7cf2976SLionel Sambuc * Erase the highlights currently on screen.
983f7cf2976SLionel Sambuc * If the search fails, we'll redisplay them later.
984f7cf2976SLionel Sambuc */
985f7cf2976SLionel Sambuc repaint_hilite(0);
986f7cf2976SLionel Sambuc }
987f7cf2976SLionel Sambuc if (hilite_search == OPT_ONPLUS && hide_hilite)
988f7cf2976SLionel Sambuc {
989f7cf2976SLionel Sambuc /*
990f7cf2976SLionel Sambuc * Highlight any matches currently on screen,
991f7cf2976SLionel Sambuc * before we actually start the search.
992f7cf2976SLionel Sambuc */
993f7cf2976SLionel Sambuc hide_hilite = 0;
994f7cf2976SLionel Sambuc hilite_screen();
995f7cf2976SLionel Sambuc }
996f7cf2976SLionel Sambuc hide_hilite = 0;
997f7cf2976SLionel Sambuc #endif
998f7cf2976SLionel Sambuc } else
999f7cf2976SLionel Sambuc {
1000f7cf2976SLionel Sambuc /*
1001f7cf2976SLionel Sambuc * Compile the pattern.
1002f7cf2976SLionel Sambuc */
1003f7cf2976SLionel Sambuc if (set_pattern(&search_info, pattern, search_type) < 0)
1004f7cf2976SLionel Sambuc return (-1);
1005f7cf2976SLionel Sambuc #if HILITE_SEARCH
1006f7cf2976SLionel Sambuc if (hilite_search)
1007f7cf2976SLionel Sambuc {
1008f7cf2976SLionel Sambuc /*
1009f7cf2976SLionel Sambuc * Erase the highlights currently on screen.
1010f7cf2976SLionel Sambuc * Also permanently delete them from the hilite list.
1011f7cf2976SLionel Sambuc */
1012f7cf2976SLionel Sambuc repaint_hilite(0);
1013f7cf2976SLionel Sambuc hide_hilite = 0;
1014f7cf2976SLionel Sambuc clr_hilite();
1015f7cf2976SLionel Sambuc }
1016f7cf2976SLionel Sambuc if (hilite_search == OPT_ONPLUS)
1017f7cf2976SLionel Sambuc {
1018f7cf2976SLionel Sambuc /*
1019f7cf2976SLionel Sambuc * Highlight any matches currently on screen,
1020f7cf2976SLionel Sambuc * before we actually start the search.
1021f7cf2976SLionel Sambuc */
1022f7cf2976SLionel Sambuc hilite_screen();
1023f7cf2976SLionel Sambuc }
1024f7cf2976SLionel Sambuc #endif
1025f7cf2976SLionel Sambuc }
1026f7cf2976SLionel Sambuc
1027f7cf2976SLionel Sambuc /*
1028f7cf2976SLionel Sambuc * Figure out where to start the search.
1029f7cf2976SLionel Sambuc */
1030f7cf2976SLionel Sambuc pos = search_pos(search_type);
1031f7cf2976SLionel Sambuc if (pos == NULL_POSITION)
1032f7cf2976SLionel Sambuc {
1033f7cf2976SLionel Sambuc /*
1034f7cf2976SLionel Sambuc * Can't find anyplace to start searching from.
1035f7cf2976SLionel Sambuc */
1036f7cf2976SLionel Sambuc if (search_type & SRCH_PAST_EOF)
1037f7cf2976SLionel Sambuc return (n);
1038f7cf2976SLionel Sambuc /* repaint(); -- why was this here? */
1039f7cf2976SLionel Sambuc error("Nothing to search", NULL_PARG);
1040f7cf2976SLionel Sambuc return (-1);
1041f7cf2976SLionel Sambuc }
1042f7cf2976SLionel Sambuc
1043f7cf2976SLionel Sambuc n = search_range(pos, NULL_POSITION, search_type, n, -1,
1044f7cf2976SLionel Sambuc &pos, (POSITION*)NULL);
1045f7cf2976SLionel Sambuc if (n != 0)
1046f7cf2976SLionel Sambuc {
1047f7cf2976SLionel Sambuc /*
1048f7cf2976SLionel Sambuc * Search was unsuccessful.
1049f7cf2976SLionel Sambuc */
1050f7cf2976SLionel Sambuc #if HILITE_SEARCH
1051f7cf2976SLionel Sambuc if (hilite_search == OPT_ON && n > 0)
1052f7cf2976SLionel Sambuc /*
1053f7cf2976SLionel Sambuc * Redisplay old hilites.
1054f7cf2976SLionel Sambuc */
1055f7cf2976SLionel Sambuc repaint_hilite(1);
1056f7cf2976SLionel Sambuc #endif
1057f7cf2976SLionel Sambuc return (n);
1058f7cf2976SLionel Sambuc }
1059f7cf2976SLionel Sambuc
1060f7cf2976SLionel Sambuc if (!(search_type & SRCH_NO_MOVE))
1061f7cf2976SLionel Sambuc {
1062f7cf2976SLionel Sambuc /*
1063f7cf2976SLionel Sambuc * Go to the matching line.
1064f7cf2976SLionel Sambuc */
1065f7cf2976SLionel Sambuc jump_loc(pos, jump_sline);
1066f7cf2976SLionel Sambuc }
1067f7cf2976SLionel Sambuc
1068f7cf2976SLionel Sambuc #if HILITE_SEARCH
1069f7cf2976SLionel Sambuc if (hilite_search == OPT_ON)
1070f7cf2976SLionel Sambuc /*
1071f7cf2976SLionel Sambuc * Display new hilites in the matching line.
1072f7cf2976SLionel Sambuc */
1073f7cf2976SLionel Sambuc repaint_hilite(1);
1074f7cf2976SLionel Sambuc #endif
1075f7cf2976SLionel Sambuc return (0);
1076f7cf2976SLionel Sambuc }
1077f7cf2976SLionel Sambuc
1078f7cf2976SLionel Sambuc
1079f7cf2976SLionel Sambuc #if HILITE_SEARCH
1080f7cf2976SLionel Sambuc /*
1081f7cf2976SLionel Sambuc * Prepare hilites in a given range of the file.
1082f7cf2976SLionel Sambuc *
1083f7cf2976SLionel Sambuc * The pair (prep_startpos,prep_endpos) delimits a contiguous region
1084f7cf2976SLionel Sambuc * of the file that has been "prepared"; that is, scanned for matches for
1085f7cf2976SLionel Sambuc * the current search pattern, and hilites have been created for such matches.
1086f7cf2976SLionel Sambuc * If prep_startpos == NULL_POSITION, the prep region is empty.
1087f7cf2976SLionel Sambuc * If prep_endpos == NULL_POSITION, the prep region extends to EOF.
1088f7cf2976SLionel Sambuc * prep_hilite asks that the range (spos,epos) be covered by the prep region.
1089f7cf2976SLionel Sambuc */
1090f7cf2976SLionel Sambuc public void
prep_hilite(spos,epos,maxlines)1091f7cf2976SLionel Sambuc prep_hilite(spos, epos, maxlines)
1092f7cf2976SLionel Sambuc POSITION spos;
1093f7cf2976SLionel Sambuc POSITION epos;
1094f7cf2976SLionel Sambuc int maxlines;
1095f7cf2976SLionel Sambuc {
1096f7cf2976SLionel Sambuc POSITION nprep_startpos = prep_startpos;
1097f7cf2976SLionel Sambuc POSITION nprep_endpos = prep_endpos;
1098f7cf2976SLionel Sambuc POSITION new_epos;
1099f7cf2976SLionel Sambuc POSITION max_epos;
1100f7cf2976SLionel Sambuc int result;
1101f7cf2976SLionel Sambuc int i;
1102f7cf2976SLionel Sambuc
1103f7cf2976SLionel Sambuc /*
1104f7cf2976SLionel Sambuc * Search beyond where we're asked to search, so the prep region covers
1105f7cf2976SLionel Sambuc * more than we need. Do one big search instead of a bunch of small ones.
1106f7cf2976SLionel Sambuc */
1107f7cf2976SLionel Sambuc #define SEARCH_MORE (3*size_linebuf)
1108f7cf2976SLionel Sambuc
1109f7cf2976SLionel Sambuc if (!prev_pattern(&search_info) && !is_filtering())
1110f7cf2976SLionel Sambuc return;
1111f7cf2976SLionel Sambuc
1112f7cf2976SLionel Sambuc /*
1113f7cf2976SLionel Sambuc * If we're limited to a max number of lines, figure out the
1114f7cf2976SLionel Sambuc * file position we should stop at.
1115f7cf2976SLionel Sambuc */
1116f7cf2976SLionel Sambuc if (maxlines < 0)
1117f7cf2976SLionel Sambuc max_epos = NULL_POSITION;
1118f7cf2976SLionel Sambuc else
1119f7cf2976SLionel Sambuc {
1120f7cf2976SLionel Sambuc max_epos = spos;
1121f7cf2976SLionel Sambuc for (i = 0; i < maxlines; i++)
1122f7cf2976SLionel Sambuc max_epos = forw_raw_line(max_epos, (char **)NULL, (int *)NULL);
1123f7cf2976SLionel Sambuc }
1124f7cf2976SLionel Sambuc
1125f7cf2976SLionel Sambuc /*
1126f7cf2976SLionel Sambuc * Find two ranges:
1127f7cf2976SLionel Sambuc * The range that we need to search (spos,epos); and the range that
1128f7cf2976SLionel Sambuc * the "prep" region will then cover (nprep_startpos,nprep_endpos).
1129f7cf2976SLionel Sambuc */
1130f7cf2976SLionel Sambuc
1131f7cf2976SLionel Sambuc if (prep_startpos == NULL_POSITION ||
1132f7cf2976SLionel Sambuc (epos != NULL_POSITION && epos < prep_startpos) ||
1133f7cf2976SLionel Sambuc spos > prep_endpos)
1134f7cf2976SLionel Sambuc {
1135f7cf2976SLionel Sambuc /*
1136f7cf2976SLionel Sambuc * New range is not contiguous with old prep region.
1137f7cf2976SLionel Sambuc * Discard the old prep region and start a new one.
1138f7cf2976SLionel Sambuc */
1139f7cf2976SLionel Sambuc clr_hilite();
1140f7cf2976SLionel Sambuc clr_filter();
1141f7cf2976SLionel Sambuc if (epos != NULL_POSITION)
1142f7cf2976SLionel Sambuc epos += SEARCH_MORE;
1143f7cf2976SLionel Sambuc nprep_startpos = spos;
1144f7cf2976SLionel Sambuc } else
1145f7cf2976SLionel Sambuc {
1146f7cf2976SLionel Sambuc /*
1147f7cf2976SLionel Sambuc * New range partially or completely overlaps old prep region.
1148f7cf2976SLionel Sambuc */
1149f7cf2976SLionel Sambuc if (epos == NULL_POSITION)
1150f7cf2976SLionel Sambuc {
1151f7cf2976SLionel Sambuc /*
1152f7cf2976SLionel Sambuc * New range goes to end of file.
1153f7cf2976SLionel Sambuc */
1154f7cf2976SLionel Sambuc ;
1155f7cf2976SLionel Sambuc } else if (epos > prep_endpos)
1156f7cf2976SLionel Sambuc {
1157f7cf2976SLionel Sambuc /*
1158f7cf2976SLionel Sambuc * New range ends after old prep region.
1159f7cf2976SLionel Sambuc * Extend prep region to end at end of new range.
1160f7cf2976SLionel Sambuc */
1161f7cf2976SLionel Sambuc epos += SEARCH_MORE;
1162f7cf2976SLionel Sambuc } else /* (epos <= prep_endpos) */
1163f7cf2976SLionel Sambuc {
1164f7cf2976SLionel Sambuc /*
1165f7cf2976SLionel Sambuc * New range ends within old prep region.
1166f7cf2976SLionel Sambuc * Truncate search to end at start of old prep region.
1167f7cf2976SLionel Sambuc */
1168f7cf2976SLionel Sambuc epos = prep_startpos;
1169f7cf2976SLionel Sambuc }
1170f7cf2976SLionel Sambuc
1171f7cf2976SLionel Sambuc if (spos < prep_startpos)
1172f7cf2976SLionel Sambuc {
1173f7cf2976SLionel Sambuc /*
1174f7cf2976SLionel Sambuc * New range starts before old prep region.
1175f7cf2976SLionel Sambuc * Extend old prep region backwards to start at
1176f7cf2976SLionel Sambuc * start of new range.
1177f7cf2976SLionel Sambuc */
1178f7cf2976SLionel Sambuc if (spos < SEARCH_MORE)
1179f7cf2976SLionel Sambuc spos = 0;
1180f7cf2976SLionel Sambuc else
1181f7cf2976SLionel Sambuc spos -= SEARCH_MORE;
1182f7cf2976SLionel Sambuc nprep_startpos = spos;
1183f7cf2976SLionel Sambuc } else /* (spos >= prep_startpos) */
1184f7cf2976SLionel Sambuc {
1185f7cf2976SLionel Sambuc /*
1186f7cf2976SLionel Sambuc * New range starts within or after old prep region.
1187f7cf2976SLionel Sambuc * Trim search to start at end of old prep region.
1188f7cf2976SLionel Sambuc */
1189f7cf2976SLionel Sambuc spos = prep_endpos;
1190f7cf2976SLionel Sambuc }
1191f7cf2976SLionel Sambuc }
1192f7cf2976SLionel Sambuc
1193f7cf2976SLionel Sambuc if (epos != NULL_POSITION && max_epos != NULL_POSITION &&
1194f7cf2976SLionel Sambuc epos > max_epos)
1195f7cf2976SLionel Sambuc /*
1196f7cf2976SLionel Sambuc * Don't go past the max position we're allowed.
1197f7cf2976SLionel Sambuc */
1198f7cf2976SLionel Sambuc epos = max_epos;
1199f7cf2976SLionel Sambuc
1200f7cf2976SLionel Sambuc if (epos == NULL_POSITION || epos > spos)
1201f7cf2976SLionel Sambuc {
1202f7cf2976SLionel Sambuc int search_type = SRCH_FORW | SRCH_FIND_ALL;
1203f7cf2976SLionel Sambuc search_type |= (search_info.search_type & SRCH_NO_REGEX);
1204f7cf2976SLionel Sambuc result = search_range(spos, epos, search_type, 0,
1205f7cf2976SLionel Sambuc maxlines, (POSITION*)NULL, &new_epos);
1206f7cf2976SLionel Sambuc if (result < 0)
1207f7cf2976SLionel Sambuc return;
1208f7cf2976SLionel Sambuc if (prep_endpos == NULL_POSITION || new_epos > prep_endpos)
1209f7cf2976SLionel Sambuc nprep_endpos = new_epos;
1210f7cf2976SLionel Sambuc }
1211f7cf2976SLionel Sambuc prep_startpos = nprep_startpos;
1212f7cf2976SLionel Sambuc prep_endpos = nprep_endpos;
1213f7cf2976SLionel Sambuc }
1214f7cf2976SLionel Sambuc
1215f7cf2976SLionel Sambuc /*
1216f7cf2976SLionel Sambuc * Set the pattern to be used for line filtering.
1217f7cf2976SLionel Sambuc */
1218f7cf2976SLionel Sambuc public void
set_filter_pattern(pattern,search_type)1219f7cf2976SLionel Sambuc set_filter_pattern(pattern, search_type)
1220f7cf2976SLionel Sambuc char *pattern;
1221f7cf2976SLionel Sambuc int search_type;
1222f7cf2976SLionel Sambuc {
1223f7cf2976SLionel Sambuc clr_filter();
1224f7cf2976SLionel Sambuc if (pattern == NULL || *pattern == '\0')
1225f7cf2976SLionel Sambuc clear_pattern(&filter_info);
1226f7cf2976SLionel Sambuc else
1227f7cf2976SLionel Sambuc set_pattern(&filter_info, pattern, search_type);
1228f7cf2976SLionel Sambuc screen_trashed = 1;
1229f7cf2976SLionel Sambuc }
1230f7cf2976SLionel Sambuc
1231f7cf2976SLionel Sambuc /*
1232f7cf2976SLionel Sambuc * Is there a line filter in effect?
1233f7cf2976SLionel Sambuc */
1234f7cf2976SLionel Sambuc public int
is_filtering()1235f7cf2976SLionel Sambuc is_filtering()
1236f7cf2976SLionel Sambuc {
1237f7cf2976SLionel Sambuc if (ch_getflags() & CH_HELPFILE)
1238f7cf2976SLionel Sambuc return (0);
1239f7cf2976SLionel Sambuc return prev_pattern(&filter_info);
1240f7cf2976SLionel Sambuc }
1241f7cf2976SLionel Sambuc #endif
1242f7cf2976SLionel Sambuc
1243f7cf2976SLionel Sambuc #if HAVE_V8_REGCOMP
1244f7cf2976SLionel Sambuc /*
1245f7cf2976SLionel Sambuc * This function is called by the V8 regcomp to report
1246f7cf2976SLionel Sambuc * errors in regular expressions.
1247f7cf2976SLionel Sambuc */
1248f7cf2976SLionel Sambuc void
regerror(s)1249f7cf2976SLionel Sambuc regerror(s)
1250f7cf2976SLionel Sambuc char *s;
1251f7cf2976SLionel Sambuc {
1252f7cf2976SLionel Sambuc PARG parg;
1253f7cf2976SLionel Sambuc
1254f7cf2976SLionel Sambuc parg.p_string = s;
1255f7cf2976SLionel Sambuc error("%s", &parg);
1256f7cf2976SLionel Sambuc }
1257f7cf2976SLionel Sambuc #endif
1258f7cf2976SLionel Sambuc
1259