version 1.9, 2014/05/28 11:39:15 |
version 1.10, 2015/11/05 22:08:44 |
|
|
* |
* |
* For more information, see the README file. |
* For more information, see the README file. |
*/ |
*/ |
|
/* |
|
* Modified for use with illumos. |
|
* Copyright 2014 Garrett D'Amore <garrett@damore.org> |
|
*/ |
|
|
|
|
/* |
/* |
* Routines to search a file for a pattern. |
* Routines to search a file for a pattern. |
*/ |
*/ |
|
|
#include "position.h" |
#include "position.h" |
#include "charset.h" |
#include "charset.h" |
|
|
#define MINPOS(a,b) (((a) < (b)) ? (a) : (b)) |
#define MINPOS(a, b) (((a) < (b)) ? (a) : (b)) |
#define MAXPOS(a,b) (((a) > (b)) ? (a) : (b)) |
#define MAXPOS(a, b) (((a) > (b)) ? (a) : (b)) |
|
|
extern volatile sig_atomic_t sigs; |
extern volatile sig_atomic_t sigs; |
extern int how_search; |
extern int how_search; |
|
|
extern int bs_mode; |
extern int bs_mode; |
extern int ctldisp; |
extern int ctldisp; |
extern int status_col; |
extern int status_col; |
extern void * constant ml_search; |
extern void *const ml_search; |
extern POSITION start_attnpos; |
extern off_t start_attnpos; |
extern POSITION end_attnpos; |
extern off_t end_attnpos; |
extern int utf_mode; |
extern int utf_mode; |
extern int screen_trashed; |
extern int screen_trashed; |
#if HILITE_SEARCH |
|
extern int hilite_search; |
extern int hilite_search; |
extern int size_linebuf; |
extern int size_linebuf; |
extern int squished; |
extern int squished; |
extern int can_goto_line; |
extern int can_goto_line; |
extern int less_is_more; |
|
static int hide_hilite; |
static int hide_hilite; |
static POSITION prep_startpos; |
static off_t prep_startpos; |
static POSITION prep_endpos; |
static off_t prep_endpos; |
static int is_caseless; |
static int is_caseless; |
static int is_ucase_pattern; |
static int is_ucase_pattern; |
|
|
struct hilite |
struct hilite { |
{ |
|
struct hilite *hl_next; |
struct hilite *hl_next; |
POSITION hl_startpos; |
off_t hl_startpos; |
POSITION hl_endpos; |
off_t hl_endpos; |
}; |
}; |
static struct hilite hilite_anchor = { NULL, NULL_POSITION, NULL_POSITION }; |
static struct hilite hilite_anchor = { NULL, -1, -1 }; |
static struct hilite filter_anchor = { NULL, NULL_POSITION, NULL_POSITION }; |
static struct hilite filter_anchor = { NULL, -1, -1 }; |
#define hl_first hl_next |
#define hl_first hl_next |
#endif |
|
|
|
/* |
/* |
* These are the static variables that represent the "remembered" |
* These are the static variables that represent the "remembered" |
* search pattern and filter pattern. |
* search pattern and filter pattern. |
*/ |
*/ |
struct pattern_info { |
struct pattern_info { |
DEFINE_PATTERN(compiled); |
regex_t *compiled; |
char* text; |
char *text; |
int search_type; |
int search_type; |
}; |
}; |
|
|
#if NO_REGEX |
#define info_compiled(info) ((info)->compiled) |
#define info_compiled(info) ((void*)0) |
|
#else |
|
#define info_compiled(info) ((info)->compiled) |
|
#endif |
|
|
|
static struct pattern_info search_info; |
static struct pattern_info search_info; |
static struct pattern_info filter_info; |
static struct pattern_info filter_info; |
|
|
/* |
/* |
* Are there any uppercase letters in this string? |
* Are there any uppercase letters in this string? |
*/ |
*/ |
static int |
static int |
is_ucase(str) |
is_ucase(char *str) |
char *str; |
|
{ |
{ |
char *str_end = str + strlen(str); |
char *str_end = str + strlen(str); |
LWCHAR ch; |
LWCHAR ch; |
|
|
while (str < str_end) |
while (str < str_end) { |
{ |
|
ch = step_char(&str, +1, str_end); |
ch = step_char(&str, +1, str_end); |
if (IS_UPPER(ch)) |
if (isupper(ch)) |
return (1); |
return (1); |
} |
} |
return (0); |
return (0); |
|
|
/* |
/* |
* Compile and save a search pattern. |
* Compile and save a search pattern. |
*/ |
*/ |
static int |
static int |
set_pattern(info, pattern, search_type) |
set_pattern(struct pattern_info *info, char *pattern, int search_type) |
struct pattern_info *info; |
|
char *pattern; |
|
int search_type; |
|
{ |
{ |
#if !NO_REGEX |
|
if (pattern == NULL) |
if (pattern == NULL) |
CLEAR_PATTERN(info->compiled); |
info->compiled = NULL; |
else if (compile_pattern(pattern, search_type, &info->compiled) < 0) |
else if (compile_pattern(pattern, search_type, &info->compiled) < 0) |
return -1; |
return (-1); |
#endif |
|
/* Pattern compiled successfully; save the text too. */ |
/* Pattern compiled successfully; save the text too. */ |
if (info->text != NULL) |
if (info->text != NULL) |
free(info->text); |
free(info->text); |
info->text = NULL; |
info->text = NULL; |
if (pattern != NULL) |
if (pattern != NULL) { |
info->text = save(pattern); |
info->text = estrdup(pattern); |
|
} |
info->search_type = search_type; |
info->search_type = search_type; |
|
|
/* |
/* |
|
|
* -i is set AND the pattern is all lowercase. |
* -i is set AND the pattern is all lowercase. |
*/ |
*/ |
is_ucase_pattern = is_ucase(pattern); |
is_ucase_pattern = is_ucase(pattern); |
if (is_ucase_pattern && caseless != OPT_ONPLUS && (caseless != OPT_ON || !less_is_more)) |
if (is_ucase_pattern && caseless != OPT_ONPLUS) |
is_caseless = 0; |
is_caseless = 0; |
else |
else |
is_caseless = caseless; |
is_caseless = caseless; |
return 0; |
return (0); |
} |
} |
|
|
/* |
/* |
* Discard a saved pattern. |
* Discard a saved pattern. |
*/ |
*/ |
static void |
static void |
clear_pattern(info) |
clear_pattern(struct pattern_info *info) |
struct pattern_info *info; |
|
{ |
{ |
if (info->text != NULL) |
if (info->text != NULL) |
free(info->text); |
free(info->text); |
info->text = NULL; |
info->text = NULL; |
#if !NO_REGEX |
|
uncompile_pattern(&info->compiled); |
uncompile_pattern(&info->compiled); |
#endif |
|
} |
} |
|
|
/* |
/* |
* Initialize saved pattern to nothing. |
* Initialize saved pattern to nothing. |
*/ |
*/ |
static void |
static void |
init_pattern(info) |
init_pattern(struct pattern_info *info) |
struct pattern_info *info; |
|
{ |
{ |
CLEAR_PATTERN(info->compiled); |
info->compiled = NULL; |
info->text = NULL; |
info->text = NULL; |
info->search_type = 0; |
info->search_type = 0; |
} |
} |
|
|
/* |
/* |
* Initialize search variables. |
* Initialize search variables. |
*/ |
*/ |
public void |
void |
init_search() |
init_search(void) |
{ |
{ |
init_pattern(&search_info); |
init_pattern(&search_info); |
init_pattern(&filter_info); |
init_pattern(&filter_info); |
|
|
/* |
/* |
* Determine which text conversions to perform before pattern matching. |
* Determine which text conversions to perform before pattern matching. |
*/ |
*/ |
static int |
static int |
get_cvt_ops() |
get_cvt_ops(void) |
{ |
{ |
int ops = 0; |
int ops = 0; |
if (is_caseless || bs_mode == BS_SPECIAL) |
if (is_caseless || bs_mode == BS_SPECIAL) { |
{ |
if (is_caseless) |
if (is_caseless) |
|
ops |= CVT_TO_LC; |
ops |= CVT_TO_LC; |
if (bs_mode == BS_SPECIAL) |
if (bs_mode == BS_SPECIAL) |
ops |= CVT_BS; |
ops |= CVT_BS; |
if (bs_mode != BS_CONTROL) |
if (bs_mode != BS_CONTROL) |
ops |= CVT_CRLF; |
ops |= CVT_CRLF; |
} else if (bs_mode != BS_CONTROL) |
} else if (bs_mode != BS_CONTROL) { |
{ |
|
ops |= CVT_CRLF; |
ops |= CVT_CRLF; |
} |
} |
if (ctldisp == OPT_ONPLUS) |
if (ctldisp == OPT_ONPLUS) |
|
|
/* |
/* |
* Is there a previous (remembered) search pattern? |
* Is there a previous (remembered) search pattern? |
*/ |
*/ |
static int |
static int |
prev_pattern(info) |
prev_pattern(struct pattern_info *info) |
struct pattern_info *info; |
|
{ |
{ |
#if !NO_REGEX |
|
if ((info->search_type & SRCH_NO_REGEX) == 0) |
if ((info->search_type & SRCH_NO_REGEX) == 0) |
return (!is_null_pattern(info->compiled)); |
return (!is_null_pattern(info->compiled)); |
#endif |
|
return (info->text != NULL); |
return (info->text != NULL); |
} |
} |
|
|
#if HILITE_SEARCH |
|
/* |
/* |
* Repaint the hilites currently displayed on the screen. |
* Repaint the hilites currently displayed on the screen. |
* Repaint each line which contains highlighted text. |
* Repaint each line which contains highlighted text. |
* If on==0, force all hilites off. |
* If on==0, force all hilites off. |
*/ |
*/ |
public void |
void |
repaint_hilite(on) |
repaint_hilite(int on) |
int on; |
|
{ |
{ |
int slinenum; |
int slinenum; |
POSITION pos; |
off_t pos; |
POSITION epos; |
|
int save_hide_hilite; |
int save_hide_hilite; |
|
|
if (squished) |
if (squished) |
repaint(); |
repaint(); |
|
|
save_hide_hilite = hide_hilite; |
save_hide_hilite = hide_hilite; |
if (!on) |
if (!on) { |
{ |
|
if (hide_hilite) |
if (hide_hilite) |
return; |
return; |
hide_hilite = 1; |
hide_hilite = 1; |
} |
} |
|
|
if (!can_goto_line) |
if (!can_goto_line) { |
{ |
|
repaint(); |
repaint(); |
hide_hilite = save_hide_hilite; |
hide_hilite = save_hide_hilite; |
return; |
return; |
} |
} |
|
|
for (slinenum = TOP; slinenum < TOP + sc_height-1; slinenum++) |
for (slinenum = TOP; slinenum < TOP + sc_height-1; slinenum++) { |
{ |
|
pos = position(slinenum); |
pos = position(slinenum); |
if (pos == NULL_POSITION) |
if (pos == -1) |
continue; |
continue; |
epos = position(slinenum+1); |
|
(void) forw_line(pos); |
(void) forw_line(pos); |
goto_line(slinenum); |
goto_line(slinenum); |
put_line(); |
put_line(); |
|
|
/* |
/* |
* Clear the attn hilite. |
* Clear the attn hilite. |
*/ |
*/ |
public void |
void |
clear_attn() |
clear_attn(void) |
{ |
{ |
int slinenum; |
int slinenum; |
POSITION old_start_attnpos; |
off_t old_start_attnpos; |
POSITION old_end_attnpos; |
off_t old_end_attnpos; |
POSITION pos; |
off_t pos; |
POSITION epos; |
off_t epos; |
int moved = 0; |
int moved = 0; |
|
|
if (start_attnpos == NULL_POSITION) |
if (start_attnpos == -1) |
return; |
return; |
old_start_attnpos = start_attnpos; |
old_start_attnpos = start_attnpos; |
old_end_attnpos = end_attnpos; |
old_end_attnpos = end_attnpos; |
start_attnpos = end_attnpos = NULL_POSITION; |
start_attnpos = end_attnpos = -1; |
|
|
if (!can_goto_line) |
if (!can_goto_line) { |
{ |
|
repaint(); |
repaint(); |
return; |
return; |
} |
} |
if (squished) |
if (squished) |
repaint(); |
repaint(); |
|
|
for (slinenum = TOP; slinenum < TOP + sc_height-1; slinenum++) |
for (slinenum = TOP; slinenum < TOP + sc_height-1; slinenum++) { |
{ |
|
pos = position(slinenum); |
pos = position(slinenum); |
if (pos == NULL_POSITION) |
if (pos == -1) |
continue; |
continue; |
epos = position(slinenum+1); |
epos = position(slinenum+1); |
if (pos < old_end_attnpos && |
if (pos < old_end_attnpos && |
(epos == NULL_POSITION || epos > old_start_attnpos)) |
(epos == -1 || epos > old_start_attnpos)) { |
{ |
|
(void) forw_line(pos); |
(void) forw_line(pos); |
goto_line(slinenum); |
goto_line(slinenum); |
put_line(); |
put_line(); |
|
|
if (moved) |
if (moved) |
lower_left(); |
lower_left(); |
} |
} |
#endif |
|
|
|
/* |
/* |
* Hide search string highlighting. |
* Hide search string highlighting. |
*/ |
*/ |
public void |
void |
undo_search() |
undo_search(void) |
{ |
{ |
if (!prev_pattern(&search_info)) |
if (!prev_pattern(&search_info)) { |
{ |
|
error("No previous regular expression", NULL_PARG); |
error("No previous regular expression", NULL_PARG); |
return; |
return; |
} |
} |
#if HILITE_SEARCH |
|
hide_hilite = !hide_hilite; |
hide_hilite = !hide_hilite; |
repaint_hilite(1); |
repaint_hilite(1); |
#endif |
|
} |
} |
|
|
#if HILITE_SEARCH |
|
/* |
/* |
* Clear the hilite list. |
* Clear the hilite list. |
*/ |
*/ |
public void |
static void |
clr_hlist(anchor) |
clr_hlist(struct hilite *anchor) |
struct hilite *anchor; |
|
{ |
{ |
struct hilite *hl; |
struct hilite *hl; |
struct hilite *nexthl; |
struct hilite *nexthl; |
|
|
for (hl = anchor->hl_first; hl != NULL; hl = nexthl) |
for (hl = anchor->hl_first; hl != NULL; hl = nexthl) { |
{ |
|
nexthl = hl->hl_next; |
nexthl = hl->hl_next; |
free((void*)hl); |
free((void*)hl); |
} |
} |
anchor->hl_first = NULL; |
anchor->hl_first = NULL; |
prep_startpos = prep_endpos = NULL_POSITION; |
prep_startpos = prep_endpos = -1; |
} |
} |
|
|
public void |
void |
clr_hilite() |
clr_hilite(void) |
{ |
{ |
clr_hlist(&hilite_anchor); |
clr_hlist(&hilite_anchor); |
} |
} |
|
|
public void |
static void |
clr_filter() |
clr_filter(void) |
{ |
{ |
clr_hlist(&filter_anchor); |
clr_hlist(&filter_anchor); |
} |
} |
|
|
* Should any characters in a specified range be highlighted? |
* Should any characters in a specified range be highlighted? |
*/ |
*/ |
static int |
static int |
is_hilited_range(pos, epos) |
is_hilited_range(off_t pos, off_t epos) |
POSITION pos; |
|
POSITION epos; |
|
{ |
{ |
struct hilite *hl; |
struct hilite *hl; |
|
|
/* |
/* |
* Look at each highlight and see if any part of it falls in the range. |
* Look at each highlight and see if any part of it falls in the range. |
*/ |
*/ |
for (hl = hilite_anchor.hl_first; hl != NULL; hl = hl->hl_next) |
for (hl = hilite_anchor.hl_first; hl != NULL; hl = hl->hl_next) { |
{ |
|
if (hl->hl_endpos > pos && |
if (hl->hl_endpos > pos && |
(epos == NULL_POSITION || epos > hl->hl_startpos)) |
(epos == -1 || epos > hl->hl_startpos)) |
return (1); |
return (1); |
} |
} |
return (0); |
return (0); |
} |
} |
|
|
/* |
/* |
* Is a line "filtered" -- that is, should it be hidden? |
* Is a line "filtered" -- that is, should it be hidden? |
*/ |
*/ |
public int |
int |
is_filtered(pos) |
is_filtered(off_t pos) |
POSITION pos; |
|
{ |
{ |
struct hilite *hl; |
struct hilite *hl; |
|
|
|
|
* Look at each filter and see if the start position |
* Look at each filter and see if the start position |
* equals the start position of the line. |
* equals the start position of the line. |
*/ |
*/ |
for (hl = filter_anchor.hl_first; hl != NULL; hl = hl->hl_next) |
for (hl = filter_anchor.hl_first; hl != NULL; hl = hl->hl_next) { |
{ |
|
if (hl->hl_startpos == pos) |
if (hl->hl_startpos == pos) |
return (1); |
return (1); |
} |
} |
|
|
* Should any characters in a specified range be highlighted? |
* Should any characters in a specified range be highlighted? |
* If nohide is nonzero, don't consider hide_hilite. |
* If nohide is nonzero, don't consider hide_hilite. |
*/ |
*/ |
public int |
int |
is_hilited(pos, epos, nohide, p_matches) |
is_hilited(off_t pos, off_t epos, int nohide, int *p_matches) |
POSITION pos; |
|
POSITION epos; |
|
int nohide; |
|
int *p_matches; |
|
{ |
{ |
int match; |
int match; |
|
|
|
|
*p_matches = 0; |
*p_matches = 0; |
|
|
if (!status_col && |
if (!status_col && |
start_attnpos != NULL_POSITION && |
start_attnpos != -1 && |
pos < end_attnpos && |
pos < end_attnpos && |
(epos == NULL_POSITION || epos > start_attnpos)) |
(epos == -1 || epos > start_attnpos)) |
/* |
/* |
* The attn line overlaps this range. |
* The attn line overlaps this range. |
*/ |
*/ |
|
|
/* |
/* |
* Add a new hilite to a hilite list. |
* Add a new hilite to a hilite list. |
*/ |
*/ |
static void |
static void |
add_hilite(anchor, hl) |
add_hilite(struct hilite *anchor, struct hilite *hl) |
struct hilite *anchor; |
|
struct hilite *hl; |
|
{ |
{ |
struct hilite *ihl; |
struct hilite *ihl; |
|
|
|
|
if (ihl != anchor) |
if (ihl != anchor) |
hl->hl_startpos = MAXPOS(hl->hl_startpos, ihl->hl_endpos); |
hl->hl_startpos = MAXPOS(hl->hl_startpos, ihl->hl_endpos); |
if (ihl->hl_next != NULL) |
if (ihl->hl_next != NULL) |
hl->hl_endpos = MINPOS(hl->hl_endpos, ihl->hl_next->hl_startpos); |
hl->hl_endpos = MINPOS(hl->hl_endpos, |
if (hl->hl_startpos >= hl->hl_endpos) |
ihl->hl_next->hl_startpos); |
{ |
if (hl->hl_startpos >= hl->hl_endpos) { |
/* |
/* |
* Hilite was truncated out of existence. |
* Hilite was truncated out of existence. |
*/ |
*/ |
|
|
/* |
/* |
* Hilight every character in a range of displayed characters. |
* Hilight every character in a range of displayed characters. |
*/ |
*/ |
static void |
static void |
create_hilites(linepos, start_index, end_index, chpos) |
create_hilites(off_t linepos, int start_index, int end_index, int *chpos) |
POSITION linepos; |
|
int start_index; |
|
int end_index; |
|
int *chpos; |
|
{ |
{ |
struct hilite *hl; |
struct hilite *hl; |
int i; |
int i; |
|
|
/* Start the first hilite. */ |
/* Start the first hilite. */ |
hl = (struct hilite *) ecalloc(1, sizeof(struct hilite)); |
hl = ecalloc(1, sizeof (struct hilite)); |
hl->hl_startpos = linepos + chpos[start_index]; |
hl->hl_startpos = linepos + chpos[start_index]; |
|
|
/* |
/* |
|
|
* Otherwise (there are backspaces or something involved), |
* Otherwise (there are backspaces or something involved), |
* finish the current hilite and start a new one. |
* finish the current hilite and start a new one. |
*/ |
*/ |
for (i = start_index+1; i <= end_index; i++) |
for (i = start_index+1; i <= end_index; i++) { |
{ |
if (chpos[i] != chpos[i-1] + 1 || i == end_index) { |
if (chpos[i] != chpos[i-1] + 1 || i == end_index) |
|
{ |
|
hl->hl_endpos = linepos + chpos[i-1] + 1; |
hl->hl_endpos = linepos + chpos[i-1] + 1; |
add_hilite(&hilite_anchor, hl); |
add_hilite(&hilite_anchor, hl); |
/* Start new hilite unless this is the last char. */ |
/* Start new hilite unless this is the last char. */ |
if (i < end_index) |
if (i < end_index) { |
{ |
hl = ecalloc(1, sizeof (struct hilite)); |
hl = (struct hilite *) ecalloc(1, sizeof(struct hilite)); |
|
hl->hl_startpos = linepos + chpos[i]; |
hl->hl_startpos = linepos + chpos[i]; |
} |
} |
} |
} |
|
|
} |
} |
|
|
/* |
/* |
* Make a hilite for each string in a physical line which matches |
* Make a hilite for each string in a physical line which matches |
* the current pattern. |
* the current pattern. |
* sp,ep delimit the first match already found. |
* sp,ep delimit the first match already found. |
*/ |
*/ |
static void |
static void |
hilite_line(linepos, line, line_len, chpos, sp, ep, cvt_ops) |
hilite_line(off_t linepos, char *line, int line_len, int *chpos, |
POSITION linepos; |
char *sp, char *ep) |
char *line; |
|
int line_len; |
|
int *chpos; |
|
char *sp; |
|
char *ep; |
|
int cvt_ops; |
|
{ |
{ |
char *searchp; |
char *searchp; |
char *line_end = line + line_len; |
char *line_end = line + line_len; |
|
|
*/ |
*/ |
searchp = line; |
searchp = line; |
do { |
do { |
create_hilites(linepos, sp-line, ep-line, chpos); |
create_hilites(linepos, (intptr_t)sp - (intptr_t)line, |
|
(intptr_t)ep - (intptr_t)line, chpos); |
/* |
/* |
* If we matched more than zero characters, |
* If we matched more than zero characters, |
* move to the first char after the string we matched. |
* move to the first char after the string we matched. |
|
|
else /* end of line */ |
else /* end of line */ |
break; |
break; |
} while (match_pattern(info_compiled(&search_info), search_info.text, |
} while (match_pattern(info_compiled(&search_info), search_info.text, |
searchp, line_end - searchp, &sp, &ep, 1, search_info.search_type)); |
searchp, (intptr_t)line_end - (intptr_t)searchp, &sp, &ep, 1, |
|
search_info.search_type)); |
} |
} |
#endif |
|
|
|
/* |
/* |
* Change the caseless-ness of searches. |
* Change the caseless-ness of searches. |
* Updates the internal search state to reflect a change in the -i flag. |
* Updates the internal search state to reflect a change in the -i flag. |
*/ |
*/ |
public void |
void |
chg_caseless() |
chg_caseless(void) |
{ |
{ |
if (!is_ucase_pattern) |
if (!is_ucase_pattern) |
/* |
/* |
|
|
clear_pattern(&search_info); |
clear_pattern(&search_info); |
} |
} |
|
|
#if HILITE_SEARCH |
|
/* |
/* |
* Find matching text which is currently on screen and highlight it. |
* Find matching text which is currently on screen and highlight it. |
*/ |
*/ |
static void |
static void |
hilite_screen() |
hilite_screen(void) |
{ |
{ |
struct scrpos scrpos; |
struct scrpos scrpos; |
|
|
get_scrpos(&scrpos); |
get_scrpos(&scrpos); |
if (scrpos.pos == NULL_POSITION) |
if (scrpos.pos == -1) |
return; |
return; |
prep_hilite(scrpos.pos, position(BOTTOM_PLUS_ONE), -1); |
prep_hilite(scrpos.pos, position(BOTTOM_PLUS_ONE), -1); |
repaint_hilite(1); |
repaint_hilite(1); |
|
|
/* |
/* |
* Change highlighting parameters. |
* Change highlighting parameters. |
*/ |
*/ |
public void |
void |
chg_hilite() |
chg_hilite(void) |
{ |
{ |
/* |
/* |
* Erase any highlights currently on screen. |
* Erase any highlights currently on screen. |
|
|
*/ |
*/ |
hilite_screen(); |
hilite_screen(); |
} |
} |
#endif |
|
|
|
/* |
/* |
* Figure out where to start a search. |
* Figure out where to start a search. |
*/ |
*/ |
static POSITION |
static off_t |
search_pos(search_type) |
search_pos(int search_type) |
int search_type; |
|
{ |
{ |
POSITION pos; |
off_t pos; |
int linenum; |
int linenum; |
|
|
if (empty_screen()) |
if (empty_screen()) { |
{ |
|
/* |
/* |
* Start at the beginning (or end) of the file. |
* Start at the beginning (or end) of the file. |
* The empty_screen() case is mainly for |
* The empty_screen() case is mainly for |
* command line initiated searches; |
* command line initiated searches; |
* for example, "+/xyz" on the command line. |
* for example, "+/xyz" on the command line. |
* Also for multi-file (SRCH_PAST_EOF) searches. |
* Also for multi-file (SRCH_PAST_EOF) searches. |
*/ |
*/ |
if (search_type & SRCH_FORW) |
if (search_type & SRCH_FORW) { |
{ |
|
pos = ch_zero(); |
pos = ch_zero(); |
} else |
} else { |
{ |
|
pos = ch_length(); |
pos = ch_length(); |
if (pos == NULL_POSITION) |
if (pos == -1) { |
{ |
|
(void) ch_end_seek(); |
(void) ch_end_seek(); |
pos = ch_length(); |
pos = ch_length(); |
} |
} |
} |
} |
linenum = 0; |
linenum = 0; |
} else |
} else { |
{ |
|
int add_one = 0; |
int add_one = 0; |
|
|
if (how_search == OPT_ON) |
if (how_search == OPT_ON) { |
{ |
|
/* |
/* |
* Search does not include current screen. |
* Search does not include current screen. |
*/ |
*/ |
|
|
linenum = BOTTOM_PLUS_ONE; |
linenum = BOTTOM_PLUS_ONE; |
else |
else |
linenum = TOP; |
linenum = TOP; |
} else if (how_search == OPT_ONPLUS && !(search_type & SRCH_AFTER_TARGET)) |
} else if (how_search == OPT_ONPLUS && |
{ |
!(search_type & SRCH_AFTER_TARGET)) { |
/* |
/* |
* Search includes all of displayed screen. |
* Search includes all of displayed screen. |
*/ |
*/ |
|
|
linenum = TOP; |
linenum = TOP; |
else |
else |
linenum = BOTTOM_PLUS_ONE; |
linenum = BOTTOM_PLUS_ONE; |
} else |
} else { |
{ |
|
/* |
/* |
* Search includes the part of current screen beyond the jump target. |
* Search includes the part of current screen beyond |
* It starts at the jump target (if searching backwards), |
* the jump target. |
* or at the jump target plus one (if forwards). |
* It starts at the jump target (if searching |
|
* backwards), or at the jump target plus one |
|
* (if forwards). |
*/ |
*/ |
linenum = jump_sline; |
linenum = jump_sline; |
if (search_type & SRCH_FORW) |
if (search_type & SRCH_FORW) |
add_one = 1; |
add_one = 1; |
} |
} |
linenum = adjsline(linenum); |
linenum = adjsline(linenum); |
pos = position(linenum); |
pos = position(linenum); |
if (add_one) |
if (add_one) |
pos = forw_raw_line(pos, (char **)NULL, (int *)NULL); |
pos = forw_raw_line(pos, NULL, NULL); |
} |
} |
|
|
/* |
/* |
* If the line is empty, look around for a plausible starting place. |
* If the line is empty, look around for a plausible starting place. |
*/ |
*/ |
if (search_type & SRCH_FORW) |
if (search_type & SRCH_FORW) { |
{ |
while (pos == -1) { |
while (pos == NULL_POSITION) |
if (++linenum >= sc_height) |
{ |
break; |
if (++linenum >= sc_height) |
pos = position(linenum); |
break; |
} |
pos = position(linenum); |
} else { |
} |
while (pos == -1) { |
} else |
if (--linenum < 0) |
{ |
break; |
while (pos == NULL_POSITION) |
pos = position(linenum); |
{ |
} |
if (--linenum < 0) |
|
break; |
|
pos = position(linenum); |
|
} |
|
} |
} |
return (pos); |
return (pos); |
} |
} |
|
|
/* |
/* |
* Search a subset of the file, specified by start/end position. |
* Search a subset of the file, specified by start/end position. |
*/ |
*/ |
static int |
static int |
search_range(pos, endpos, search_type, matches, maxlines, plinepos, pendpos) |
search_range(off_t pos, off_t endpos, int search_type, int matches, |
POSITION pos; |
int maxlines, off_t *plinepos, off_t *pendpos) |
POSITION endpos; |
|
int search_type; |
|
int matches; |
|
int maxlines; |
|
POSITION *plinepos; |
|
POSITION *pendpos; |
|
{ |
{ |
char *line; |
char *line; |
char *cline; |
char *cline; |
|
|
int cvt_ops; |
int cvt_ops; |
int cvt_len; |
int cvt_len; |
int *chpos; |
int *chpos; |
POSITION linepos, oldpos; |
off_t linepos, oldpos; |
|
|
linenum = find_linenum(pos); |
linenum = find_linenum(pos); |
oldpos = pos; |
oldpos = pos; |
for (;;) |
for (;;) { |
{ |
|
/* |
/* |
* Get lines until we find a matching one or until |
* Get lines until we find a matching one or until |
* we hit end-of-file (or beginning-of-file if we're |
* we hit end-of-file (or beginning-of-file if we're |
* going backwards), or until we hit the end position. |
* going backwards), or until we hit the end position. |
*/ |
*/ |
if (ABORT_SIGS()) |
if (ABORT_SIGS()) { |
{ |
|
/* |
/* |
* A signal aborts the search. |
* A signal aborts the search. |
*/ |
*/ |
return (-1); |
return (-1); |
} |
} |
|
|
if ((endpos != NULL_POSITION && pos >= endpos) || maxlines == 0) |
if ((endpos != -1 && pos >= endpos) || |
{ |
maxlines == 0) { |
/* |
/* |
* Reached end position without a match. |
* Reached end position without a match. |
*/ |
*/ |
|
|
if (maxlines > 0) |
if (maxlines > 0) |
maxlines--; |
maxlines--; |
|
|
if (search_type & SRCH_FORW) |
if (search_type & SRCH_FORW) { |
{ |
|
/* |
/* |
* Read the next line, and save the |
* Read the next line, and save the |
* starting position of that line in linepos. |
* starting position of that line in linepos. |
*/ |
*/ |
linepos = pos; |
linepos = pos; |
pos = forw_raw_line(pos, &line, &line_len); |
pos = forw_raw_line(pos, &line, &line_len); |
if (linenum != 0) |
if (linenum != 0) |
linenum++; |
linenum++; |
} else |
} else { |
{ |
|
/* |
/* |
* Read the previous line and save the |
* Read the previous line and save the |
* starting position of that line in linepos. |
* starting position of that line in linepos. |
|
|
linenum--; |
linenum--; |
} |
} |
|
|
if (pos == NULL_POSITION) |
if (pos == -1) { |
{ |
|
/* |
/* |
* Reached EOF/BOF without a match. |
* Reached EOF/BOF without a match. |
*/ |
*/ |
|
|
* If we're doing backspace processing, delete backspaces. |
* If we're doing backspace processing, delete backspaces. |
*/ |
*/ |
cvt_ops = get_cvt_ops(); |
cvt_ops = get_cvt_ops(); |
cvt_len = cvt_length(line_len, cvt_ops); |
cvt_len = cvt_length(line_len); |
cline = (char *) ecalloc(1, cvt_len); |
cline = ecalloc(1, cvt_len); |
chpos = cvt_alloc_chpos(cvt_len); |
chpos = cvt_alloc_chpos(cvt_len); |
cvt_text(cline, line, chpos, &line_len, cvt_ops); |
cvt_text(cline, line, chpos, &line_len, cvt_ops); |
|
|
#if HILITE_SEARCH |
|
/* |
/* |
* Check to see if the line matches the filter pattern. |
* Check to see if the line matches the filter pattern. |
* If so, add an entry to the filter list. |
* If so, add an entry to the filter list. |
*/ |
*/ |
if ((search_type & SRCH_FIND_ALL) && prev_pattern(&filter_info)) { |
if ((search_type & SRCH_FIND_ALL) && |
int line_filter = match_pattern(info_compiled(&filter_info), filter_info.text, |
prev_pattern(&filter_info)) { |
cline, line_len, &sp, &ep, 0, filter_info.search_type); |
int line_filter = |
if (line_filter) |
match_pattern(info_compiled(&filter_info), |
{ |
filter_info.text, cline, line_len, &sp, &ep, 0, |
struct hilite *hl = (struct hilite *) |
filter_info.search_type); |
ecalloc(1, sizeof(struct hilite)); |
if (line_filter) { |
|
struct hilite *hl = |
|
ecalloc(1, sizeof (struct hilite)); |
hl->hl_startpos = linepos; |
hl->hl_startpos = linepos; |
hl->hl_endpos = pos; |
hl->hl_endpos = pos; |
add_hilite(&filter_anchor, hl); |
add_hilite(&filter_anchor, hl); |
} |
} |
} |
} |
#endif |
|
|
|
/* |
/* |
* Test the next line to see if we have a match. |
* Test the next line to see if we have a match. |
* We are successful if we either want a match and got one, |
* We are successful if we either want a match and got one, |
* or if we want a non-match and got one. |
* or if we want a non-match and got one. |
*/ |
*/ |
if (prev_pattern(&search_info)) |
if (prev_pattern(&search_info)) { |
{ |
line_match = match_pattern(info_compiled(&search_info), |
line_match = match_pattern(info_compiled(&search_info), search_info.text, |
search_info.text, cline, line_len, &sp, &ep, 0, |
cline, line_len, &sp, &ep, 0, search_type); |
search_type); |
if (line_match) |
if (line_match) { |
{ |
|
/* |
/* |
* Got a match. |
* Got a match. |
*/ |
*/ |
if (search_type & SRCH_FIND_ALL) |
if (search_type & SRCH_FIND_ALL) { |
{ |
|
#if HILITE_SEARCH |
|
/* |
/* |
* We are supposed to find all matches in the range. |
* We are supposed to find all matches |
* Just add the matches in this line to the |
* in the range. |
* hilite list and keep searching. |
* Just add the matches in this line |
|
* to the hilite list and keep |
|
* searching. |
*/ |
*/ |
hilite_line(linepos, cline, line_len, chpos, sp, ep, cvt_ops); |
hilite_line(linepos, cline, line_len, |
#endif |
chpos, sp, ep); |
} else if (--matches <= 0) |
} else if (--matches <= 0) { |
{ |
|
/* |
/* |
* Found the one match we're looking for. |
* Found the one match we're looking |
* Return it. |
* for. Return it. |
*/ |
*/ |
#if HILITE_SEARCH |
if (hilite_search == OPT_ON) { |
if (hilite_search == OPT_ON) |
|
{ |
|
/* |
/* |
* Clear the hilite list and add only |
* Clear the hilite list and |
|
* add only |
* the matches in this one line. |
* the matches in this one line. |
*/ |
*/ |
clr_hilite(); |
clr_hilite(); |
hilite_line(linepos, cline, line_len, chpos, sp, ep, cvt_ops); |
hilite_line(linepos, cline, |
|
line_len, chpos, sp, ep); |
} |
} |
#endif |
|
free(cline); |
free(cline); |
free(chpos); |
free(chpos); |
if (plinepos != NULL) |
if (plinepos != NULL) |
|
|
/* |
/* |
* search for a pattern in history. If found, compile that pattern. |
* search for a pattern in history. If found, compile that pattern. |
*/ |
*/ |
static int |
static int |
hist_pattern(search_type) |
hist_pattern(int search_type) |
int search_type; |
|
{ |
{ |
#if CMD_HISTORY |
|
char *pattern; |
char *pattern; |
|
|
set_mlist(ml_search, 0); |
set_mlist(ml_search, 0); |
|
|
if (set_pattern(&search_info, pattern, search_type) < 0) |
if (set_pattern(&search_info, pattern, search_type) < 0) |
return (0); |
return (0); |
|
|
#if HILITE_SEARCH |
|
if (hilite_search == OPT_ONPLUS && !hide_hilite) |
if (hilite_search == OPT_ONPLUS && !hide_hilite) |
hilite_screen(); |
hilite_screen(); |
#endif |
|
|
|
return (1); |
return (1); |
#else /* CMD_HISTORY */ |
|
return (0); |
|
#endif /* CMD_HISTORY */ |
|
} |
} |
|
|
/* |
/* |
* Search for the n-th occurrence of a specified pattern, |
* Search for the n-th occurrence of a specified pattern, |
* either forward or backward. |
* either forward or backward. |
* Return the number of matches not yet found in this file |
* Return the number of matches not yet found in this file |
* (that is, n minus the number of matches found). |
* (that is, n minus the number of matches found). |
* Return -1 if the search should be aborted. |
* Return -1 if the search should be aborted. |
* Caller may continue the search in another file |
* Caller may continue the search in another file |
* if less than n matches are found in this file. |
* if less than n matches are found in this file. |
*/ |
*/ |
public int |
int |
search(search_type, pattern, n) |
search(int search_type, char *pattern, int n) |
int search_type; |
|
char *pattern; |
|
int n; |
|
{ |
{ |
POSITION pos; |
off_t pos; |
|
|
if (pattern == NULL || *pattern == '\0') |
if (pattern == NULL || *pattern == '\0') { |
{ |
|
/* |
/* |
* A null pattern means use the previously compiled pattern. |
* A null pattern means use the previously compiled pattern. |
*/ |
*/ |
search_type |= SRCH_AFTER_TARGET; |
search_type |= SRCH_AFTER_TARGET; |
if (!prev_pattern(&search_info) && !hist_pattern(search_type)) |
if (!prev_pattern(&search_info) && !hist_pattern(search_type)) { |
{ |
|
error("No previous regular expression", NULL_PARG); |
error("No previous regular expression", NULL_PARG); |
return (-1); |
return (-1); |
} |
} |
if ((search_type & SRCH_NO_REGEX) != |
if ((search_type & SRCH_NO_REGEX) != |
(search_info.search_type & SRCH_NO_REGEX)) |
(search_info.search_type & SRCH_NO_REGEX)) { |
{ |
|
error("Please re-enter search pattern", NULL_PARG); |
error("Please re-enter search pattern", NULL_PARG); |
return -1; |
return (-1); |
} |
} |
#if HILITE_SEARCH |
if (hilite_search == OPT_ON) { |
if (hilite_search == OPT_ON) |
|
{ |
|
/* |
/* |
* Erase the highlights currently on screen. |
* Erase the highlights currently on screen. |
* If the search fails, we'll redisplay them later. |
* If the search fails, we'll redisplay them later. |
*/ |
*/ |
repaint_hilite(0); |
repaint_hilite(0); |
} |
} |
if (hilite_search == OPT_ONPLUS && hide_hilite) |
if (hilite_search == OPT_ONPLUS && hide_hilite) { |
{ |
|
/* |
/* |
* Highlight any matches currently on screen, |
* Highlight any matches currently on screen, |
* before we actually start the search. |
* before we actually start the search. |
|
|
hilite_screen(); |
hilite_screen(); |
} |
} |
hide_hilite = 0; |
hide_hilite = 0; |
#endif |
} else { |
} else |
|
{ |
|
/* |
/* |
* Compile the pattern. |
* Compile the pattern. |
*/ |
*/ |
if (set_pattern(&search_info, pattern, search_type) < 0) |
if (set_pattern(&search_info, pattern, search_type) < 0) |
return (-1); |
return (-1); |
#if HILITE_SEARCH |
if (hilite_search) { |
if (hilite_search) |
|
{ |
|
/* |
/* |
* Erase the highlights currently on screen. |
* Erase the highlights currently on screen. |
* Also permanently delete them from the hilite list. |
* Also permanently delete them from the hilite list. |
|
|
hide_hilite = 0; |
hide_hilite = 0; |
clr_hilite(); |
clr_hilite(); |
} |
} |
if (hilite_search == OPT_ONPLUS) |
if (hilite_search == OPT_ONPLUS) { |
{ |
|
/* |
/* |
* Highlight any matches currently on screen, |
* Highlight any matches currently on screen, |
* before we actually start the search. |
* before we actually start the search. |
*/ |
*/ |
hilite_screen(); |
hilite_screen(); |
} |
} |
#endif |
|
} |
} |
|
|
/* |
/* |
* Figure out where to start the search. |
* Figure out where to start the search. |
*/ |
*/ |
pos = search_pos(search_type); |
pos = search_pos(search_type); |
if (pos == NULL_POSITION) |
if (pos == -1) { |
{ |
|
/* |
/* |
* Can't find anyplace to start searching from. |
* Can't find anyplace to start searching from. |
*/ |
*/ |
|
|
return (-1); |
return (-1); |
} |
} |
|
|
n = search_range(pos, NULL_POSITION, search_type, n, -1, |
n = search_range(pos, -1, search_type, n, -1, &pos, NULL); |
&pos, (POSITION*)NULL); |
if (n != 0) { |
if (n != 0) |
|
{ |
|
/* |
/* |
* Search was unsuccessful. |
* Search was unsuccessful. |
*/ |
*/ |
#if HILITE_SEARCH |
|
if (hilite_search == OPT_ON && n > 0) |
if (hilite_search == OPT_ON && n > 0) |
/* |
/* |
* Redisplay old hilites. |
* Redisplay old hilites. |
*/ |
*/ |
repaint_hilite(1); |
repaint_hilite(1); |
#endif |
|
return (n); |
return (n); |
} |
} |
|
|
if (!(search_type & SRCH_NO_MOVE)) |
if (!(search_type & SRCH_NO_MOVE)) { |
{ |
|
/* |
/* |
* Go to the matching line. |
* Go to the matching line. |
*/ |
*/ |
jump_loc(pos, jump_sline); |
jump_loc(pos, jump_sline); |
} |
} |
|
|
#if HILITE_SEARCH |
|
if (hilite_search == OPT_ON) |
if (hilite_search == OPT_ON) |
/* |
/* |
* Display new hilites in the matching line. |
* Display new hilites in the matching line. |
*/ |
*/ |
repaint_hilite(1); |
repaint_hilite(1); |
#endif |
|
return (0); |
return (0); |
} |
} |
|
|
|
|
#if HILITE_SEARCH |
|
/* |
/* |
* Prepare hilites in a given range of the file. |
* Prepare hilites in a given range of the file. |
* |
* |
* The pair (prep_startpos,prep_endpos) delimits a contiguous region |
* The pair (prep_startpos,prep_endpos) delimits a contiguous region |
* of the file that has been "prepared"; that is, scanned for matches for |
* of the file that has been "prepared"; that is, scanned for matches for |
* the current search pattern, and hilites have been created for such matches. |
* the current search pattern, and hilites have been created for such matches. |
* If prep_startpos == NULL_POSITION, the prep region is empty. |
* If prep_startpos == -1, the prep region is empty. |
* If prep_endpos == NULL_POSITION, the prep region extends to EOF. |
* If prep_endpos == -1, the prep region extends to EOF. |
* prep_hilite asks that the range (spos,epos) be covered by the prep region. |
* prep_hilite asks that the range (spos,epos) be covered by the prep region. |
*/ |
*/ |
public void |
void |
prep_hilite(spos, epos, maxlines) |
prep_hilite(off_t spos, off_t epos, int maxlines) |
POSITION spos; |
|
POSITION epos; |
|
int maxlines; |
|
{ |
{ |
POSITION nprep_startpos = prep_startpos; |
off_t nprep_startpos = prep_startpos; |
POSITION nprep_endpos = prep_endpos; |
off_t nprep_endpos = prep_endpos; |
POSITION new_epos; |
off_t new_epos; |
POSITION max_epos; |
off_t max_epos; |
int result; |
int result; |
int i; |
int i; |
|
|
|
|
* If we're limited to a max number of lines, figure out the |
* If we're limited to a max number of lines, figure out the |
* file position we should stop at. |
* file position we should stop at. |
*/ |
*/ |
if (maxlines < 0) |
if (maxlines < 0) { |
max_epos = NULL_POSITION; |
max_epos = -1; |
else |
} else { |
{ |
|
max_epos = spos; |
max_epos = spos; |
for (i = 0; i < maxlines; i++) |
for (i = 0; i < maxlines; i++) |
max_epos = forw_raw_line(max_epos, (char **)NULL, (int *)NULL); |
max_epos = forw_raw_line(max_epos, NULL, NULL); |
} |
} |
|
|
/* |
/* |
|
|
* the "prep" region will then cover (nprep_startpos,nprep_endpos). |
* the "prep" region will then cover (nprep_startpos,nprep_endpos). |
*/ |
*/ |
|
|
if (prep_startpos == NULL_POSITION || |
if (prep_startpos == -1 || |
(epos != NULL_POSITION && epos < prep_startpos) || |
(epos != -1 && epos < prep_startpos) || |
spos > prep_endpos) |
spos > prep_endpos) { |
{ |
|
/* |
/* |
* New range is not contiguous with old prep region. |
* New range is not contiguous with old prep region. |
* Discard the old prep region and start a new one. |
* Discard the old prep region and start a new one. |
*/ |
*/ |
clr_hilite(); |
clr_hilite(); |
clr_filter(); |
clr_filter(); |
if (epos != NULL_POSITION) |
if (epos != -1) |
epos += SEARCH_MORE; |
epos += SEARCH_MORE; |
nprep_startpos = spos; |
nprep_startpos = spos; |
} else |
} else { |
{ |
|
/* |
/* |
* New range partially or completely overlaps old prep region. |
* New range partially or completely overlaps old prep region. |
*/ |
*/ |
if (epos == NULL_POSITION) |
if (epos != -1) { |
{ |
if (epos > prep_endpos) { |
/* |
/* |
* New range goes to end of file. |
* New range ends after old prep region. |
*/ |
* Extend prep region to end at end of new |
; |
* range. |
} else if (epos > prep_endpos) |
*/ |
{ |
epos += SEARCH_MORE; |
/* |
|
* New range ends after old prep region. |
} else { |
* Extend prep region to end at end of new range. |
/* |
*/ |
* New range ends within old prep region. |
epos += SEARCH_MORE; |
* Truncate search to end at start of old prep |
} else /* (epos <= prep_endpos) */ |
* region. |
{ |
*/ |
/* |
epos = prep_startpos; |
* New range ends within old prep region. |
} |
* Truncate search to end at start of old prep region. |
|
*/ |
|
epos = prep_startpos; |
|
} |
} |
|
|
if (spos < prep_startpos) |
if (spos < prep_startpos) { |
{ |
|
/* |
/* |
* New range starts before old prep region. |
* New range starts before old prep region. |
* Extend old prep region backwards to start at |
* Extend old prep region backwards to start at |
* start of new range. |
* start of new range. |
*/ |
*/ |
if (spos < SEARCH_MORE) |
if (spos < SEARCH_MORE) |
|
|
else |
else |
spos -= SEARCH_MORE; |
spos -= SEARCH_MORE; |
nprep_startpos = spos; |
nprep_startpos = spos; |
} else /* (spos >= prep_startpos) */ |
} else { /* (spos >= prep_startpos) */ |
{ |
|
/* |
/* |
* New range starts within or after old prep region. |
* New range starts within or after old prep region. |
* Trim search to start at end of old prep region. |
* Trim search to start at end of old prep region. |
|
|
} |
} |
} |
} |
|
|
if (epos != NULL_POSITION && max_epos != NULL_POSITION && |
if (epos != -1 && max_epos != -1 && |
epos > max_epos) |
epos > max_epos) |
/* |
/* |
* Don't go past the max position we're allowed. |
* Don't go past the max position we're allowed. |
*/ |
*/ |
epos = max_epos; |
epos = max_epos; |
|
|
if (epos == NULL_POSITION || epos > spos) |
if (epos == -1 || epos > spos) { |
{ |
|
int search_type = SRCH_FORW | SRCH_FIND_ALL; |
int search_type = SRCH_FORW | SRCH_FIND_ALL; |
search_type |= (search_info.search_type & SRCH_NO_REGEX); |
search_type |= (search_info.search_type & SRCH_NO_REGEX); |
result = search_range(spos, epos, search_type, 0, |
result = search_range(spos, epos, search_type, 0, |
maxlines, (POSITION*)NULL, &new_epos); |
maxlines, NULL, &new_epos); |
if (result < 0) |
if (result < 0) |
return; |
return; |
if (prep_endpos == NULL_POSITION || new_epos > prep_endpos) |
if (prep_endpos == -1 || new_epos > prep_endpos) |
nprep_endpos = new_epos; |
nprep_endpos = new_epos; |
} |
} |
prep_startpos = nprep_startpos; |
prep_startpos = nprep_startpos; |
|
|
/* |
/* |
* Set the pattern to be used for line filtering. |
* Set the pattern to be used for line filtering. |
*/ |
*/ |
public void |
void |
set_filter_pattern(pattern, search_type) |
set_filter_pattern(char *pattern, int search_type) |
char *pattern; |
|
int search_type; |
|
{ |
{ |
clr_filter(); |
clr_filter(); |
if (pattern == NULL || *pattern == '\0') |
if (pattern == NULL || *pattern == '\0') |
clear_pattern(&filter_info); |
clear_pattern(&filter_info); |
else |
else |
set_pattern(&filter_info, pattern, search_type); |
(void) set_pattern(&filter_info, pattern, search_type); |
screen_trashed = 1; |
screen_trashed = 1; |
} |
} |
|
|
/* |
/* |
* Is there a line filter in effect? |
* Is there a line filter in effect? |
*/ |
*/ |
public int |
int |
is_filtering() |
is_filtering(void) |
{ |
{ |
if (ch_getflags() & CH_HELPFILE) |
if (ch_getflags() & CH_HELPFILE) |
return (0); |
return (0); |
return prev_pattern(&filter_info); |
return (prev_pattern(&filter_info)); |
} |
} |
#endif |
|
|
|
#if HAVE_V8_REGCOMP |
|
/* |
|
* This function is called by the V8 regcomp to report |
|
* errors in regular expressions. |
|
*/ |
|
void |
|
regerror(s) |
|
char *s; |
|
{ |
|
PARG parg; |
|
|
|
parg.p_string = s; |
|
error("%s", &parg); |
|
} |
|
#endif |
|
|
|