summaryrefslogtreecommitdiffstats
path: root/contrib/less/search.c
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/less/search.c')
-rw-r--r--contrib/less/search.c126
1 files changed, 84 insertions, 42 deletions
diff --git a/contrib/less/search.c b/contrib/less/search.c
index 31133fb..7d0af8b 100644
--- a/contrib/less/search.c
+++ b/contrib/less/search.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 1984-2000 Mark Nudelman
+ * Copyright (C) 1984-2002 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.
@@ -52,6 +52,7 @@ extern int linenums;
extern int sc_height;
extern int jump_sline;
extern int bs_mode;
+extern int ctldisp;
extern int status_col;
extern POSITION start_attnpos;
extern POSITION end_attnpos;
@@ -106,6 +107,7 @@ static char *last_pattern = NULL;
#define CVT_TO_LC 01 /* Convert upper-case to lower-case */
#define CVT_BS 02 /* Do backspace processing */
#define CVT_CRLF 04 /* Remove CR after LF */
+#define CVT_ANSI 010 /* Remove ANSI escape sequences */
static void
cvt_text(odst, osrc, ops)
@@ -116,17 +118,23 @@ cvt_text(odst, osrc, ops)
register char *dst;
register char *src;
- for (src = osrc, dst = odst; *src != '\0'; src++, dst++)
+ for (src = osrc, dst = odst; *src != '\0'; src++)
{
if ((ops & CVT_TO_LC) && isupper((unsigned char) *src))
/* Convert uppercase to lowercase. */
- *dst = tolower((unsigned char) *src);
+ *dst++ = tolower((unsigned char) *src);
else if ((ops & CVT_BS) && *src == '\b' && dst > odst)
/* Delete BS and preceding char. */
- dst -= 2;
- else
+ dst--;
+ else if ((ops & CVT_ANSI) && *src == ESC)
+ {
+ /* Skip to end of ANSI escape sequence. */
+ while (src[1] != '\0')
+ if (is_ansi_end(*++src))
+ break;
+ } else
/* Just copy. */
- *dst = *src;
+ *dst++ = *src;
}
if ((ops & CVT_CRLF) && dst > odst && dst[-1] == '\r')
dst--;
@@ -134,6 +142,30 @@ cvt_text(odst, osrc, ops)
}
/*
+ * Determine which conversions to perform.
+ */
+ static int
+get_cvt_ops()
+{
+ int ops = 0;
+ if (is_caseless || bs_mode == BS_SPECIAL)
+ {
+ if (is_caseless)
+ ops |= CVT_TO_LC;
+ if (bs_mode == BS_SPECIAL)
+ ops |= CVT_BS;
+ if (bs_mode != BS_CONTROL)
+ ops |= CVT_CRLF;
+ } else if (bs_mode != BS_CONTROL)
+ {
+ ops |= CVT_CRLF;
+ }
+ if (ctldisp == OPT_ONPLUS)
+ ops |= CVT_ANSI;
+ return (ops);
+}
+
+/*
* Are there any uppercase letters in this string?
*/
static int
@@ -587,9 +619,10 @@ add_hilite(anchor, hl)
* Adjust hl_startpos & hl_endpos to account for backspace processing.
*/
static void
-adj_hilite(anchor, linepos)
+adj_hilite(anchor, linepos, cvt_ops)
struct hilite *anchor;
POSITION linepos;
+ int cvt_ops;
{
char *line;
struct hilite *hl;
@@ -631,18 +664,39 @@ adj_hilite(anchor, linepos)
}
if (*line == '\0')
break;
+ if (cvt_ops & CVT_ANSI)
+ {
+ while (line[0] == ESC)
+ {
+ /*
+ * Found an ESC. The file position moves
+ * forward past the entire ANSI escape sequence.
+ */
+ line++;
+ npos++;
+ while (*line != '\0')
+ {
+ npos++;
+ if (is_ansi_end(*line++))
+ break;
+ }
+ }
+ }
opos++;
npos++;
line++;
- while (line[0] == '\b' && line[1] != '\0')
+ if (cvt_ops & CVT_BS)
{
- /*
- * Found a backspace. The file position moves
- * forward by 2 relative to the processed line
- * which was searched in hilite_line.
- */
- npos += 2;
- line += 2;
+ while (line[0] == '\b' && line[1] != '\0')
+ {
+ /*
+ * Found a backspace. The file position moves
+ * forward by 2 relative to the processed line
+ * which was searched in hilite_line.
+ */
+ npos += 2;
+ line += 2;
+ }
}
}
}
@@ -653,11 +707,12 @@ adj_hilite(anchor, linepos)
* sp,ep delimit the first match already found.
*/
static void
-hilite_line(linepos, line, sp, ep)
+hilite_line(linepos, line, sp, ep, cvt_ops)
POSITION linepos;
char *line;
char *sp;
char *ep;
+ int cvt_ops;
{
char *searchp;
struct hilite *hl;
@@ -706,15 +761,13 @@ hilite_line(linepos, line, sp, ep)
break;
} while (match_pattern(searchp, &sp, &ep, 1));
- if (bs_mode == BS_SPECIAL)
- {
- /*
- * If there were backspaces in the original line, they
- * were removed, and hl_startpos/hl_endpos are not correct.
- * {{ This is very ugly. }}
- */
- adj_hilite(&hilites, linepos);
- }
+ /*
+ * If there were backspaces in the original line, they
+ * were removed, and hl_startpos/hl_endpos are not correct.
+ * {{ This is very ugly. }}
+ */
+ adj_hilite(&hilites, linepos, cvt_ops);
+
/*
* Now put the hilites into the real list.
*/
@@ -871,9 +924,10 @@ search_range(pos, endpos, search_type, matches, maxlines, plinepos, pendpos)
POSITION *pendpos;
{
char *line;
- int linenum;
+ LINENUM linenum;
char *sp, *ep;
int line_match;
+ int cvt_ops;
POSITION linepos, oldpos;
linenum = find_linenum(pos);
@@ -953,20 +1007,8 @@ search_range(pos, endpos, search_type, matches, maxlines, plinepos, pendpos)
* If it's a caseless search, convert the line to lowercase.
* If we're doing backspace processing, delete backspaces.
*/
- if (is_caseless || bs_mode == BS_SPECIAL)
- {
- int ops = 0;
- if (is_caseless)
- ops |= CVT_TO_LC;
- if (bs_mode == BS_SPECIAL)
- ops |= CVT_BS;
- if (bs_mode != BS_CONTROL)
- ops |= CVT_CRLF;
- cvt_text(line, line, ops);
- } else if (bs_mode != BS_CONTROL)
- {
- cvt_text(line, line, CVT_CRLF);
- }
+ cvt_ops = get_cvt_ops();
+ cvt_text(line, line, cvt_ops);
/*
* Test the next line to see if we have a match.
@@ -990,7 +1032,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);
+ hilite_line(linepos, line, sp, ep, cvt_ops);
#endif
} else if (--matches <= 0)
{
@@ -1007,7 +1049,7 @@ search_range(pos, endpos, search_type, matches, maxlines, plinepos, pendpos)
*/
clr_hilite();
if (line_match)
- hilite_line(linepos, line, sp, ep);
+ hilite_line(linepos, line, sp, ep, cvt_ops);
}
#endif
if (plinepos != NULL)
OpenPOWER on IntegriCloud