summaryrefslogtreecommitdiffstats
path: root/contrib/less/search.c
diff options
context:
space:
mode:
authordelphij <delphij@FreeBSD.org>2007-06-04 01:43:11 +0000
committerdelphij <delphij@FreeBSD.org>2007-06-04 01:43:11 +0000
commit2908bdb1f10f819d2713971e094aa9719b317184 (patch)
tree81e259b4b8551856ddf7763cc779172378fe60dc /contrib/less/search.c
parent9b5d103b5b51a6fea5caf2c8b1fc678d65a357c9 (diff)
downloadFreeBSD-src-2908bdb1f10f819d2713971e094aa9719b317184.zip
FreeBSD-src-2908bdb1f10f819d2713971e094aa9719b317184.tar.gz
Resolve conflicts.
Diffstat (limited to 'contrib/less/search.c')
-rw-r--r--contrib/less/search.c138
1 files changed, 102 insertions, 36 deletions
diff --git a/contrib/less/search.c b/contrib/less/search.c
index 63e5875..ccc07bd 100644
--- a/contrib/less/search.c
+++ b/contrib/less/search.c
@@ -1,6 +1,6 @@
/* $FreeBSD$ */
/*
- * Copyright (C) 1984-2005 Mark Nudelman
+ * Copyright (C) 1984-2007 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.
@@ -23,7 +23,7 @@
#if HAVE_POSIX_REGCOMP
#include <regex.h>
#ifdef REG_EXTENDED
-#define REGCOMP_FLAG (more_mode ? 0 : REG_EXTENDED)
+#define REGCOMP_FLAG (less_is_more ? 0 : REG_EXTENDED)
#else
#define REGCOMP_FLAG 0
#endif
@@ -53,9 +53,10 @@ extern int linenums;
extern int sc_height;
extern int jump_sline;
extern int bs_mode;
-extern int more_mode;
+extern int less_is_more;
extern int ctldisp;
extern int status_col;
+extern void * constant ml_search;
extern POSITION start_attnpos;
extern POSITION end_attnpos;
#if HILITE_SEARCH
@@ -65,6 +66,7 @@ extern int size_linebuf;
extern int squished;
extern int can_goto_line;
static int hide_hilite;
+static int oldbot;
static POSITION prep_startpos;
static POSITION prep_endpos;
@@ -112,15 +114,22 @@ static char *last_pattern = NULL;
#define CVT_ANSI 010 /* Remove ANSI escape sequences */
static void
-cvt_text(odst, osrc, ops)
+cvt_text(odst, osrc, lenp, ops)
char *odst;
char *osrc;
+ int *lenp;
int ops;
{
register char *dst;
register char *src;
+ register char *src_end;
- for (src = osrc, dst = odst; *src != '\0'; src++)
+ if (lenp != NULL)
+ src_end = osrc + *lenp;
+ else
+ src_end = osrc + strlen(osrc);
+
+ for (src = osrc, dst = odst; src < src_end; src++)
{
if ((ops & CVT_TO_LC) && IS_UPPER(*src))
/* Convert uppercase to lowercase. */
@@ -131,7 +140,7 @@ cvt_text(odst, osrc, ops)
else if ((ops & CVT_ANSI) && *src == ESC)
{
/* Skip to end of ANSI escape sequence. */
- while (src[1] != '\0')
+ while (src + 1 != src_end)
if (!is_ansi_middle(*++src))
break;
} else
@@ -141,6 +150,8 @@ cvt_text(odst, osrc, ops)
if ((ops & CVT_CRLF) && dst > odst && dst[-1] == '\r')
dst--;
*dst = '\0';
+ if (lenp != NULL)
+ *lenp = dst - odst;
}
/*
@@ -267,6 +278,8 @@ repaint_hilite(on)
put_line();
}
}
+ if (!oldbot)
+ lower_left();
hide_hilite = save_hide_hilite;
}
@@ -450,8 +463,9 @@ uncompile_pattern()
* Set sp and ep to the start and end of the matched string.
*/
static int
-match_pattern(line, sp, ep, notbol)
+match_pattern(line, line_len, sp, ep, notbol)
char *line;
+ int line_len;
char **sp;
char **ep;
int notbol;
@@ -459,7 +473,7 @@ match_pattern(line, sp, ep, notbol)
int matched;
if (last_search_type & SRCH_NO_REGEX)
- return (match(last_pattern, line, sp, ep));
+ return (match(last_pattern, strlen(last_pattern), line, line_len, sp, ep));
#if HAVE_POSIX_REGCOMP
{
@@ -481,7 +495,7 @@ match_pattern(line, sp, ep, notbol)
{
int flags = (notbol) ? PCRE_NOTBOL : 0;
int ovector[3];
- matched = pcre_exec(regpattern, NULL, line, strlen(line),
+ matched = pcre_exec(regpattern, NULL, line, line_len,
0, flags, ovector, 3) >= 0;
if (!matched)
return (0);
@@ -515,7 +529,7 @@ match_pattern(line, sp, ep, notbol)
*ep = regpattern->endp[0];
#endif
#if NO_REGEX
- matched = match(last_pattern, line, sp, ep);
+ matched = match(last_pattern, strlen(last_pattern), line, line_len, sp, ep);
#endif
return (matched);
}
@@ -652,11 +666,14 @@ add_hilite(anchor, hl)
}
static void
-adj_hilite_ansi(cvt_ops, line, npos)
+adj_hilite_ansi(cvt_ops, line, line_len, npos)
int cvt_ops;
char **line;
+ int line_len;
POSITION *npos;
{
+ char *line_end = *line + line_len;
+
if (cvt_ops & CVT_ANSI)
while (**line == ESC)
{
@@ -666,7 +683,7 @@ adj_hilite_ansi(cvt_ops, line, npos)
*/
(*line)++;
(*npos)++;
- while (**line != '\0')
+ while (*line < line_end)
{
(*npos)++;
if (!is_ansi_middle(*(*line)++))
@@ -685,6 +702,8 @@ adj_hilite(anchor, linepos, cvt_ops)
int cvt_ops;
{
char *line;
+ int line_len;
+ char *line_end;
struct hilite *hl;
int checkstart;
POSITION opos;
@@ -697,7 +716,8 @@ adj_hilite(anchor, linepos, cvt_ops)
* This may not be true if there are backspaces in the line.
* Get the raw line again. Look at each character.
*/
- (void) forw_raw_line(linepos, &line);
+ (void) forw_raw_line(linepos, &line, &line_len);
+ line_end = line + line_len;
opos = npos = linepos;
hl = anchor->hl_first;
checkstart = TRUE;
@@ -722,9 +742,9 @@ adj_hilite(anchor, linepos, cvt_ops)
hl = hl->hl_next;
continue; /* {{ necessary }} */
}
- if (*line == '\0')
+ if (line == line_end)
break;
- adj_hilite_ansi(cvt_ops, &line, &npos);
+ adj_hilite_ansi(cvt_ops, &line, line_end - line, &npos);
opos++;
npos++;
line++;
@@ -734,8 +754,8 @@ adj_hilite(anchor, linepos, cvt_ops)
{
npos++;
line++;
- adj_hilite_ansi(cvt_ops, &line, &npos);
- if (*line == '\0')
+ adj_hilite_ansi(cvt_ops, &line, line_end - line, &npos);
+ if (line == line_end)
{
--npos;
--line;
@@ -759,14 +779,16 @@ adj_hilite(anchor, linepos, cvt_ops)
* sp,ep delimit the first match already found.
*/
static void
-hilite_line(linepos, line, sp, ep, cvt_ops)
+hilite_line(linepos, line, line_len, sp, ep, cvt_ops)
POSITION linepos;
char *line;
+ int line_len;
char *sp;
char *ep;
int cvt_ops;
{
char *searchp;
+ char *line_end = line + line_len;
struct hilite *hl;
struct hilite hilites;
@@ -780,7 +802,7 @@ hilite_line(linepos, line, sp, ep, cvt_ops)
* substrings of the line, may mark more than is correct
* if the pattern starts with "^". This bug is fixed
* for those regex functions that accept a notbol parameter
- * (currently POSIX and V8-with-regexec2). }}
+ * (currently POSIX, PCRE and V8-with-regexec2). }}
*/
searchp = line;
/*
@@ -807,11 +829,11 @@ hilite_line(linepos, line, sp, ep, cvt_ops)
*/
if (ep > searchp)
searchp = ep;
- else if (*searchp != '\0')
+ else if (searchp != line_end)
searchp++;
else /* end of line */
break;
- } while (match_pattern(searchp, &sp, &ep, 1));
+ } while (match_pattern(searchp, line_end - searchp, &sp, &ep, 1));
/*
* If there were backspaces in the original line, they
@@ -942,7 +964,7 @@ search_pos(search_type)
pos = position(linenum);
if (search_type & SRCH_FORW)
{
- pos = forw_raw_line(pos, (char **)NULL);
+ pos = forw_raw_line(pos, (char **)NULL, (int *)NULL);
while (pos == NULL_POSITION)
{
if (++linenum >= sc_height)
@@ -976,6 +998,7 @@ search_range(pos, endpos, search_type, matches, maxlines, plinepos, pendpos)
POSITION *pendpos;
{
char *line;
+ int line_len;
LINENUM linenum;
char *sp, *ep;
int line_match;
@@ -1018,7 +1041,7 @@ search_range(pos, endpos, search_type, matches, maxlines, plinepos, pendpos)
* starting position of that line in linepos.
*/
linepos = pos;
- pos = forw_raw_line(pos, &line);
+ pos = forw_raw_line(pos, &line, &line_len);
if (linenum != 0)
linenum++;
} else
@@ -1027,7 +1050,7 @@ search_range(pos, endpos, search_type, matches, maxlines, plinepos, pendpos)
* Read the previous line and save the
* starting position of that line in linepos.
*/
- pos = back_raw_line(pos, &line);
+ pos = back_raw_line(pos, &line, &line_len);
linepos = pos;
if (linenum != 0)
linenum--;
@@ -1060,14 +1083,14 @@ search_range(pos, endpos, search_type, matches, maxlines, plinepos, pendpos)
* If we're doing backspace processing, delete backspaces.
*/
cvt_ops = get_cvt_ops();
- cvt_text(line, line, cvt_ops);
+ cvt_text(line, line, &line_len, cvt_ops);
/*
* Test the next line to see if we have a match.
* We are successful if we either want a match and got one,
* or if we want a non-match and got one.
*/
- line_match = match_pattern(line, &sp, &ep, 0);
+ line_match = match_pattern(line, line_len, &sp, &ep, 0);
line_match = (!(search_type & SRCH_NO_MATCH) && line_match) ||
((search_type & SRCH_NO_MATCH) && !line_match);
if (!line_match)
@@ -1084,7 +1107,7 @@ search_range(pos, endpos, search_type, matches, maxlines, plinepos, pendpos)
* hilite list and keep searching.
*/
if (line_match)
- hilite_line(linepos, line, sp, ep, cvt_ops);
+ hilite_line(linepos, line, line_len, sp, ep, cvt_ops);
#endif
} else if (--matches <= 0)
{
@@ -1101,7 +1124,7 @@ search_range(pos, endpos, search_type, matches, maxlines, plinepos, pendpos)
*/
clr_hilite();
if (line_match)
- hilite_line(linepos, line, sp, ep, cvt_ops);
+ hilite_line(linepos, line, line_len, sp, ep, cvt_ops);
}
#endif
if (plinepos != NULL)
@@ -1111,6 +1134,44 @@ search_range(pos, endpos, search_type, matches, maxlines, plinepos, pendpos)
}
}
+ /*
+ * search for a pattern in history. If found, compile that pattern.
+ */
+ static int
+hist_pattern(search_type)
+ int search_type;
+{
+#if CMD_HISTORY
+ char *pattern;
+
+ set_mlist(ml_search, 0);
+ pattern = cmd_lastpattern();
+ if (pattern == NULL)
+ return (0);
+
+ if (caseless == OPT_ONPLUS)
+ cvt_text(pattern, pattern, (int *)NULL, CVT_TO_LC);
+
+ if (compile_pattern(pattern, search_type) < 0)
+ return (0);
+
+ is_ucase_pattern = is_ucase(pattern);
+ if (is_ucase_pattern && caseless != OPT_ONPLUS)
+ is_caseless = 0;
+ else
+ is_caseless = caseless;
+
+#if HILITE_SEARCH
+ if (hilite_search == OPT_ONPLUS && !hide_hilite)
+ hilite_screen();
+#endif
+
+ return (1);
+#else /* CMD_HISTORY */
+ return (0);
+#endif /* CMD_HISTORY */
+}
+
/*
* Search for the n-th occurrence of a specified pattern,
* either forward or backward.
@@ -1134,7 +1195,7 @@ search(search_type, pattern, n)
/*
* A null pattern means use the previously compiled pattern.
*/
- if (!prev_pattern())
+ if (!prev_pattern() && !hist_pattern(search_type))
{
error("No previous regular expression", NULL_PARG);
return (-1);
@@ -1172,7 +1233,7 @@ search(search_type, pattern, n)
*/
ucase = is_ucase(pattern);
if (caseless == OPT_ONPLUS)
- cvt_text(pattern, pattern, CVT_TO_LC);
+ cvt_text(pattern, pattern, (int *)NULL, CVT_TO_LC);
if (compile_pattern(pattern, search_type) < 0)
return (-1);
/*
@@ -1300,7 +1361,7 @@ prep_hilite(spos, epos, maxlines)
{
max_epos = spos;
for (i = 0; i < maxlines; i++)
- max_epos = forw_raw_line(max_epos, (char **)NULL);
+ max_epos = forw_raw_line(max_epos, (char **)NULL, (int *)NULL);
}
/*
@@ -1396,18 +1457,23 @@ prep_hilite(spos, epos, maxlines)
* It supports no metacharacters like *, etc.
*/
static int
-match(pattern, buf, pfound, pend)
- char *pattern, *buf;
+match(pattern, pattern_len, buf, buf_len, pfound, pend)
+ char *pattern;
+ int pattern_len;
+ char *buf;
+ int buf_len;
char **pfound, **pend;
{
register char *pp, *lp;
+ register char *pattern_end = pattern + pattern_len;
+ register char *buf_end = buf + buf_len;
- for ( ; *buf != '\0'; buf++)
+ for ( ; buf < buf_end; buf++)
{
for (pp = pattern, lp = buf; *pp == *lp; pp++, lp++)
- if (*pp == '\0' || *lp == '\0')
+ if (pp == pattern_end || lp == buf_end)
break;
- if (*pp == '\0')
+ if (pp == pattern_end)
{
if (pfound != NULL)
*pfound = buf;
OpenPOWER on IntegriCloud