summaryrefslogtreecommitdiffstats
path: root/contrib/less/output.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/output.c
parentc0c85bc41cb6c023adae56cf0a7e3495bd528cb2 (diff)
downloadFreeBSD-src-44c4d557e2436dfbb703a9fc3e78fac79c574d4b.zip
FreeBSD-src-44c4d557e2436dfbb703a9fc3e78fac79c574d4b.tar.gz
Import less v381.
Diffstat (limited to 'contrib/less/output.c')
-rw-r--r--contrib/less/output.c236
1 files changed, 210 insertions, 26 deletions
diff --git a/contrib/less/output.c b/contrib/less/output.c
index d309303..7f5acba 100644
--- a/contrib/less/output.c
+++ b/contrib/less/output.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.
@@ -29,6 +29,15 @@ extern int screen_trashed;
extern int any_display;
extern int is_tty;
+#if MSDOS_COMPILER==BORLANDC || MSDOS_COMPILER==DJGPPC
+extern int ctldisp;
+extern int nm_fg_color, nm_bg_color;
+extern int bo_fg_color, bo_bg_color;
+extern int ul_fg_color, ul_bg_color;
+extern int so_fg_color, so_bg_color;
+extern int bl_fg_color, bl_bg_color;
+#endif
+
/*
* Display the line which is in the line buffer.
*/
@@ -149,6 +158,9 @@ flush()
{
col = 0;
row++;
+ } else if (*op == '\r')
+ {
+ col = 0;
} else
{
col++;
@@ -179,7 +191,156 @@ flush()
if (is_tty && any_display)
{
*ob = '\0';
- cputs(obuf);
+ if (ctldisp != OPT_ONPLUS)
+ cputs(obuf);
+ else
+ {
+ /*
+ * Look for SGR escape sequences, and convert them
+ * to color commands. Replace bold, underline,
+ * and italic escapes into colors specified via
+ * the -D command-line option.
+ */
+ char *anchor, *p, *p_next;
+ int buflen = ob - obuf;
+ unsigned char fg, bg, norm_attr;
+ /*
+ * Only dark colors mentioned here, so that
+ * bold has visible effect.
+ */
+ static enum COLORS screen_color[] = {
+ BLACK, RED, GREEN, BROWN,
+ BLUE, MAGENTA, CYAN, LIGHTGRAY
+ };
+
+ /* Normal text colors are used as baseline. */
+ bg = nm_bg_color & 0xf;
+ fg = nm_fg_color & 0xf;
+ norm_attr = (bg << 4) | fg;
+ for (anchor = p_next = obuf;
+ (p_next = memchr (p_next, ESC,
+ buflen - (p_next - obuf)))
+ != NULL; )
+ {
+ p = p_next;
+
+ /*
+ * Handle the null escape sequence
+ * (ESC-[m), which is used to restore
+ * the original color.
+ */
+ if (p[1] == '[' && is_ansi_end(p[2]))
+ {
+ textattr(norm_attr);
+ p += 3;
+ anchor = p_next = p;
+ continue;
+ }
+
+ if (p[1] == '[') /* "Esc-[" sequence */
+ {
+ /*
+ * If some chars seen since
+ * the last escape sequence,
+ * write it out to the screen
+ * using current text attributes.
+ */
+ if (p > anchor)
+ {
+ *p = '\0';
+ cputs (anchor);
+ *p = ESC;
+ anchor = p;
+ }
+ p += 2;
+ p_next = p;
+ while (!is_ansi_end(*p))
+ {
+ char *q;
+ long code = strtol(p, &q, 10);
+
+ if (!*q)
+ {
+ /*
+ * Incomplete sequence.
+ * Leave it unprocessed
+ * in the buffer.
+ */
+ int slop = q - anchor;
+ strcpy(obuf, anchor);
+ ob = &obuf[slop];
+ return;
+ }
+
+ if (q == p
+ || code > 49 || code < 0
+ || (!is_ansi_end(*q)
+ && *q != ';'))
+ {
+ p_next = q;
+ break;
+ }
+ if (*q == ';')
+ q++;
+
+ switch (code)
+ {
+ case 1: /* bold on */
+ fg = bo_fg_color;
+ bg = bo_bg_color;
+ break;
+ case 3: /* italic on */
+ fg = so_fg_color;
+ bg = so_bg_color;
+ break;
+ case 4: /* underline on */
+ fg = ul_fg_color;
+ bg = ul_bg_color;
+ break;
+ case 8: /* concealed on */
+ fg = (bg & 7) | 8;
+ break;
+ case 0: /* all attrs off */
+ case 22:/* bold off */
+ case 23:/* italic off */
+ case 24:/* underline off */
+ fg = nm_fg_color;
+ bg = nm_bg_color;
+ break;
+ case 30: case 31: case 32:
+ case 33: case 34: case 35:
+ case 36: case 37:
+ fg = (fg & 8) | (screen_color[code - 30]);
+ break;
+ case 39: /* default fg */
+ fg = nm_fg_color;
+ break;
+ case 40: case 41: case 42:
+ case 43: case 44: case 45:
+ case 46: case 47:
+ bg = (bg & 8) | (screen_color[code - 40]);
+ break;
+ case 49: /* default fg */
+ bg = nm_bg_color;
+ break;
+ }
+ p = q;
+ }
+ if (is_ansi_end(*p) && p > p_next)
+ {
+ bg &= 15;
+ fg &= 15;
+ textattr ((bg << 4)| fg);
+ p_next = anchor = p + 1;
+ } else
+ break;
+ } else
+ p_next++;
+ }
+
+ /* Output what's left in the buffer. */
+ cputs (anchor);
+ }
ob = obuf;
return;
}
@@ -239,35 +400,55 @@ putstr(s)
/*
+ * Convert an integral type to a string.
+ */
+#define TYPE_TO_A_FUNC(funcname, type) \
+void funcname(num, buf) \
+ type num; \
+ char *buf; \
+{ \
+ int neg = (num < 0); \
+ char tbuf[INT_STRLEN_BOUND(num)+2]; \
+ register char *s = tbuf + sizeof(tbuf); \
+ if (neg) num = -num; \
+ *--s = '\0'; \
+ do { \
+ *--s = (num % 10) + '0'; \
+ } while ((num /= 10) != 0); \
+ if (neg) *--s = '-'; \
+ strcpy(buf, s); \
+}
+
+TYPE_TO_A_FUNC(postoa, POSITION)
+TYPE_TO_A_FUNC(linenumtoa, LINENUM)
+TYPE_TO_A_FUNC(inttoa, int)
+
+/*
* Output an integer in a given radix.
*/
static int
-iprintnum(num, radix)
+iprint_int(num)
int num;
- int radix;
{
- register char *s;
- int r;
- int neg;
char buf[INT_STRLEN_BOUND(num)];
- neg = (num < 0);
- if (neg)
- num = -num;
-
- s = buf;
- do
- {
- *s++ = (num % radix) + '0';
- } while ((num /= radix) != 0);
+ inttoa(num, buf);
+ putstr(buf);
+ return (strlen(buf));
+}
- if (neg)
- *s++ = '-';
- r = s - buf;
+/*
+ * Output a line number in a given radix.
+ */
+ static int
+iprint_linenum(num)
+ LINENUM num;
+{
+ char buf[INT_STRLEN_BOUND(num)];
- while (s > buf)
- putchr(*--s);
- return (r);
+ linenumtoa(num, buf);
+ putstr(buf);
+ return (strlen(buf));
}
/*
@@ -280,7 +461,6 @@ less_printf(fmt, parg)
PARG *parg;
{
register char *s;
- register int n;
register int col;
col = 0;
@@ -293,7 +473,8 @@ less_printf(fmt, parg)
} else
{
++fmt;
- switch (*fmt++) {
+ switch (*fmt++)
+ {
case 's':
s = parg->p_string;
parg++;
@@ -304,9 +485,12 @@ less_printf(fmt, parg)
}
break;
case 'd':
- n = parg->p_int;
+ col += iprint_int(parg->p_int);
+ parg++;
+ break;
+ case 'n':
+ col += iprint_linenum(parg->p_linenum);
parg++;
- col += iprintnum(n, 10);
break;
}
}
OpenPOWER on IntegriCloud