diff options
author | tjr <tjr@FreeBSD.org> | 2004-04-17 07:16:34 +0000 |
---|---|---|
committer | tjr <tjr@FreeBSD.org> | 2004-04-17 07:16:34 +0000 |
commit | 44c4d557e2436dfbb703a9fc3e78fac79c574d4b (patch) | |
tree | f46d7e51d83360c5b6bdacf5b08e16a415ed61b5 /contrib/less/line.c | |
parent | c0c85bc41cb6c023adae56cf0a7e3495bd528cb2 (diff) | |
download | FreeBSD-src-44c4d557e2436dfbb703a9fc3e78fac79c574d4b.zip FreeBSD-src-44c4d557e2436dfbb703a9fc3e78fac79c574d4b.tar.gz |
Import less v381.
Diffstat (limited to 'contrib/less/line.c')
-rw-r--r-- | contrib/less/line.c | 95 |
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; |