summaryrefslogtreecommitdiffstats
path: root/contrib/less/line.c
diff options
context:
space:
mode:
authortjr <tjr@FreeBSD.org>2004-04-17 07:16:34 +0000
committertjr <tjr@FreeBSD.org>2004-04-17 07:16:34 +0000
commit44c4d557e2436dfbb703a9fc3e78fac79c574d4b (patch)
treef46d7e51d83360c5b6bdacf5b08e16a415ed61b5 /contrib/less/line.c
parentc0c85bc41cb6c023adae56cf0a7e3495bd528cb2 (diff)
downloadFreeBSD-src-44c4d557e2436dfbb703a9fc3e78fac79c574d4b.zip
FreeBSD-src-44c4d557e2436dfbb703a9fc3e78fac79c574d4b.tar.gz
Import less v381.
Diffstat (limited to 'contrib/less/line.c')
-rw-r--r--contrib/less/line.c95
1 files changed, 70 insertions, 25 deletions
diff --git a/contrib/less/line.c b/contrib/less/line.c
index 981d84e..14659f3 100644
--- a/contrib/less/line.c
+++ b/contrib/less/line.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.
@@ -18,7 +18,6 @@
#include "less.h"
#define IS_CONT(c) (((c) & 0xC0) == 0x80)
-#define LINENUM_WIDTH 8 /* Chars to use for line number */
public char *linebuf = NULL; /* Buffer which holds the current output line */
static char *attr = NULL; /* Extension of linebuf to hold attributes */
@@ -34,6 +33,7 @@ static int curr; /* Index into linebuf */
static int column; /* Printable length, accounting for
backspaces, etc. */
static int overstrike; /* Next char should overstrike previous char */
+static int last_overstrike = AT_NORMAL;
static int is_null_line; /* There is no current line */
static int lmargin; /* Left margin */
static int hilites; /* Number of hilites in this line */
@@ -92,6 +92,8 @@ expand_linebuf()
}
memcpy(new_buf, linebuf, size_linebuf * sizeof(char));
memcpy(new_attr, attr, size_linebuf * sizeof(char));
+ free(attr);
+ free(linebuf);
linebuf = new_buf;
attr = new_attr;
size_linebuf = new_size;
@@ -110,13 +112,11 @@ prewind()
is_null_line = 0;
pendc = '\0';
lmargin = 0;
+ if (status_col)
+ lmargin += 1;
#if HILITE_SEARCH
hilites = 0;
#endif
- if (status_col)
- lmargin += 1;
- if (linenums == OPT_ONPLUS)
- lmargin += LINENUM_WIDTH+1;
}
/*
@@ -126,7 +126,7 @@ prewind()
plinenum(pos)
POSITION pos;
{
- register int lno;
+ register LINENUM linenum = 0;
register int i;
if (linenums == OPT_ONPLUS)
@@ -139,7 +139,7 @@ plinenum(pos)
* {{ Since forw_raw_line modifies linebuf, we must
* do this first, before storing anything in linebuf. }}
*/
- lno = find_linenum(pos);
+ linenum = find_linenum(pos);
}
/*
@@ -162,11 +162,22 @@ plinenum(pos)
*/
if (linenums == OPT_ONPLUS)
{
- sprintf(&linebuf[curr], "%*d", LINENUM_WIDTH, lno);
- column += LINENUM_WIDTH;
- for (i = 0; i < LINENUM_WIDTH; i++)
- attr[curr++] = 0;
+ char buf[INT_STRLEN_BOUND(pos) + 2];
+ int n;
+
+ linenumtoa(linenum, buf);
+ n = strlen(buf);
+ if (n < MIN_LINENUM_WIDTH)
+ n = MIN_LINENUM_WIDTH;
+ sprintf(linebuf+curr, "%*s ", n, buf);
+ n++; /* One space after the line number. */
+ for (i = 0; i < n; i++)
+ attr[curr+i] = AT_NORMAL;
+ curr += n;
+ column += n;
+ lmargin += n;
}
+
/*
* Append enough spaces to bring us to the lmargin.
*/
@@ -401,6 +412,8 @@ store_char(c, a, pos)
{
register int w;
+ if (a != AT_NORMAL)
+ last_overstrike = a;
#if HILITE_SEARCH
if (is_hilited(pos, pos+1, 0))
{
@@ -553,6 +566,11 @@ pappend(c, pos)
return (r);
}
+#define IS_UTF8_4BYTE(c) ( ((c) & 0xf8) == 0xf0 )
+#define IS_UTF8_3BYTE(c) ( ((c) & 0xf0) == 0xe0 )
+#define IS_UTF8_2BYTE(c) ( ((c) & 0xe0) == 0xc0 )
+#define IS_UTF8_TRAIL(c) ( ((c) & 0xc0) == 0x80 )
+
static int
do_append(c, pos)
int c;
@@ -590,37 +608,64 @@ do_append(c, pos)
* or just deletion of the character in the buffer.
*/
overstrike--;
- if (utf_mode && curr > 1 && (char)c == linebuf[curr-2])
+ if (utf_mode && IS_UTF8_4BYTE(c) && curr > 2 && (char)c == linebuf[curr-3])
+ {
+ backc();
+ backc();
+ backc();
+ STORE_CHAR(linebuf[curr], AT_BOLD, pos);
+ overstrike = 3;
+ } else if (utf_mode && (IS_UTF8_3BYTE(c) || (overstrike==2 && IS_UTF8_TRAIL(c))) && curr > 1 && (char)c == linebuf[curr-2])
{
backc();
backc();
+ STORE_CHAR(linebuf[curr], AT_BOLD, pos);
overstrike = 2;
- } else if (utf_mode && curr > 0 && (char)c == linebuf[curr-1])
+ } else if (utf_mode && curr > 0 && (IS_UTF8_2BYTE(c) || (overstrike==1 && IS_UTF8_TRAIL(c))) && (char)c == linebuf[curr-1])
{
backc();
STORE_CHAR(linebuf[curr], AT_BOLD, pos);
overstrike = 1;
+ } else if (utf_mode && curr > 0 && IS_UTF8_TRAIL(c) && attr[curr-1] == AT_UNDERLINE)
+ {
+ STOREC(c, AT_UNDERLINE);
} else if ((char)c == linebuf[curr])
{
- STOREC(c, AT_BOLD);
+ /*
+ * Overstriking a char with itself means make it bold.
+ * But overstriking an underscore with itself is
+ * ambiguous. It could mean make it bold, or
+ * it could mean make it underlined.
+ * Use the previous overstrike to resolve it.
+ */
+ if (c == '_' && last_overstrike != AT_NORMAL)
+ STOREC(c, last_overstrike);
+ else
+ STOREC(c, AT_BOLD);
} else if (c == '_')
{
if (utf_mode)
{
- if (curr > 0 && IS_CONT(linebuf[curr]))
- attr[curr-1] = AT_UNDERLINE;
- if (curr > 1 && IS_CONT(linebuf[curr-1]))
- attr[curr-2] = AT_UNDERLINE;
- if (curr > 2 && IS_CONT(linebuf[curr-2]))
- attr[curr-3] = AT_UNDERLINE;
- if (curr > 3 && IS_CONT(linebuf[curr-3]))
- attr[curr-4] = AT_UNDERLINE;
- if (curr > 4 && IS_CONT(linebuf[curr-4]))
- attr[curr-5] = AT_UNDERLINE;
+ int i;
+ for (i = 0; i < 5; i++)
+ {
+ if (curr <= i || !IS_CONT(linebuf[curr-i]))
+ break;
+ attr[curr-i-1] = AT_UNDERLINE;
+ }
}
STOREC(linebuf[curr], AT_UNDERLINE);
} else if (linebuf[curr] == '_')
{
+ if (utf_mode)
+ {
+ if (IS_UTF8_2BYTE(c))
+ overstrike = 1;
+ else if (IS_UTF8_3BYTE(c))
+ overstrike = 2;
+ else if (IS_UTF8_4BYTE(c))
+ overstrike = 3;
+ }
STOREC(c, AT_UNDERLINE);
} else if (control_char(c))
goto do_control_char;
OpenPOWER on IntegriCloud