diff options
| author | Xin LI <delphij@FreeBSD.org> | 2012-06-26 20:38:53 +0000 |
|---|---|---|
| committer | Xin LI <delphij@FreeBSD.org> | 2012-06-26 20:38:53 +0000 |
| commit | ae8c2162b0f1c1823dae013469f900b9882b77a2 (patch) | |
| tree | 9492f724d6c5c2081c7f6b978b27d62af6523d31 /search.c | |
| parent | 5b2db585ea1bc974ea3553d32447fba4e9ec0c2a (diff) | |
Diffstat (limited to 'search.c')
| -rw-r--r-- | search.c | 93 |
1 files changed, 69 insertions, 24 deletions
diff --git a/search.c b/search.c index 143779ee06fcb..f09c068a55919 100644 --- a/search.c +++ b/search.c @@ -1,12 +1,11 @@ -/* - * Copyright (C) 1984-2011 Mark Nudelman - * - * You may distribute under the terms of either the GNU General Public - * License or the Less License, as specified in the README file. - * - * For more information about less, or for information on how to - * contact the author, see the README file. - */ +/*
+ * Copyright (C) 1984-2012 Mark Nudelman
+ *
+ * You may distribute under the terms of either the GNU General Public
+ * License or the Less License, as specified in the README file.
+ *
+ * For more information, see the README file.
+ */
/* @@ -66,6 +65,12 @@ struct pattern_info { char* text; int search_type; }; + +#if NO_REGEX +#define info_compiled(info) ((void*)0) +#else +#define info_compiled(info) ((info)->compiled) +#endif static struct pattern_info search_info; static struct pattern_info filter_info; @@ -98,10 +103,12 @@ set_pattern(info, pattern, search_type) char *pattern; int search_type; { +#if !NO_REGEX if (pattern == NULL) - CLEAR_PATTERN(search_info.compiled); + CLEAR_PATTERN(info->compiled); else if (compile_pattern(pattern, search_type, &info->compiled) < 0) return -1; +#endif /* Pattern compiled successfully; save the text too. */ if (info->text != NULL) free(info->text); @@ -135,7 +142,9 @@ clear_pattern(info) if (info->text != NULL) free(info->text); info->text = NULL; +#if !NO_REGEX uncompile_pattern(&info->compiled); +#endif } /* @@ -191,9 +200,11 @@ get_cvt_ops() prev_pattern(info) struct pattern_info *info; { - if (info->search_type & SRCH_NO_REGEX) - return (info->text != NULL); - return (!is_null_pattern(info->compiled)); +#if !NO_REGEX + if ((info->search_type & SRCH_NO_REGEX) == 0) + return (!is_null_pattern(info->compiled)); +#endif + return (info->text != NULL); } #if HILITE_SEARCH @@ -476,6 +487,47 @@ add_hilite(anchor, hl) } /* + * Hilight every character in a range of displayed characters. + */ + static void +create_hilites(linepos, start_index, end_index, chpos) + POSITION linepos; + int start_index; + int end_index; + int *chpos; +{ + struct hilite *hl; + int i; + + /* Start the first hilite. */ + hl = (struct hilite *) ecalloc(1, sizeof(struct hilite)); + hl->hl_startpos = linepos + chpos[start_index]; + + /* + * Step through the displayed chars. + * If the source position (before cvt) of the char is one more + * than the source pos of the previous char (the usual case), + * just increase the size of the current hilite by one. + * Otherwise (there are backspaces or something involved), + * finish the current hilite and start a new one. + */ + for (i = start_index+1; i <= end_index; i++) + { + if (chpos[i] != chpos[i-1] + 1 || i == end_index) + { + hl->hl_endpos = linepos + chpos[i-1] + 1; + add_hilite(&hilite_anchor, hl); + /* Start new hilite unless this is the last char. */ + if (i < end_index) + { + hl = (struct hilite *) ecalloc(1, sizeof(struct hilite)); + hl->hl_startpos = linepos + chpos[i]; + } + } + } +} + +/* * Make a hilite for each string in a physical line which matches * the current pattern. * sp,ep delimit the first match already found. @@ -492,7 +544,6 @@ hilite_line(linepos, line, line_len, chpos, sp, ep, cvt_ops) { char *searchp; char *line_end = line + line_len; - struct hilite *hl; if (sp == NULL || ep == NULL) return; @@ -508,13 +559,7 @@ hilite_line(linepos, line, line_len, chpos, sp, ep, cvt_ops) */ searchp = line; do { - if (ep > sp) - { - hl = (struct hilite *) ecalloc(1, sizeof(struct hilite)); - hl->hl_startpos = linepos + chpos[sp-line]; - hl->hl_endpos = linepos + chpos[ep-line]; - add_hilite(&hilite_anchor, hl); - } + create_hilites(linepos, sp-line, ep-line, chpos); /* * If we matched more than zero characters, * move to the first char after the string we matched. @@ -526,7 +571,7 @@ hilite_line(linepos, line, line_len, chpos, sp, ep, cvt_ops) searchp++; else /* end of line */ break; - } while (match_pattern(search_info.compiled, search_info.text, + } while (match_pattern(info_compiled(&search_info), search_info.text, searchp, line_end - searchp, &sp, &ep, 1, search_info.search_type)); } #endif @@ -798,7 +843,7 @@ search_range(pos, endpos, search_type, matches, maxlines, plinepos, pendpos) * If so, add an entry to the filter list. */ if ((search_type & SRCH_FIND_ALL) && prev_pattern(&filter_info)) { - int line_filter = match_pattern(filter_info.compiled, filter_info.text, + int line_filter = match_pattern(info_compiled(&filter_info), filter_info.text, cline, line_len, &sp, &ep, 0, filter_info.search_type); if (line_filter) { @@ -818,7 +863,7 @@ search_range(pos, endpos, search_type, matches, maxlines, plinepos, pendpos) */ if (prev_pattern(&search_info)) { - line_match = match_pattern(search_info.compiled, search_info.text, + line_match = match_pattern(info_compiled(&search_info), search_info.text, cline, line_len, &sp, &ep, 0, search_type); if (line_match) { |
