=================================================================== RCS file: /cvsrepo/anoncvs/cvs/src/usr.bin/less/output.c,v retrieving revision 1.9 retrieving revision 1.10 diff -c -r1.9 -r1.10 *** src/usr.bin/less/output.c 2014/04/25 13:38:21 1.9 --- src/usr.bin/less/output.c 2015/11/05 22:08:44 1.10 *************** *** 6,26 **** * * For more information, see the README file. */ - /* * High level routines dealing with the output to the screen. */ #include "less.h" - #if MSDOS_COMPILER==WIN32C - #include "windows.h" - #endif ! public int errmsgs; /* Count of messages displayed by error() */ ! public int need_clr; ! public int final_attr; ! public int at_prompt; extern volatile sig_atomic_t sigs; extern int sc_width; --- 6,23 ---- * * For more information, see the README file. */ + /* + * Modified for use with illumos. + * Copyright 2014 Garrett D'Amore + */ /* * High level routines dealing with the output to the screen. */ #include "less.h" ! int errmsgs; /* Count of messages displayed by error() */ extern volatile sig_atomic_t sigs; extern int sc_width; *************** *** 30,56 **** extern int is_tty; extern int oldbot; ! #if MSDOS_COMPILER==WIN32C || 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. */ ! public void ! put_line() { ! register int c; ! register int i; int a; ! if (ABORT_SIGS()) ! { /* * Don't output if a signal is pending. */ --- 27,45 ---- extern int is_tty; extern int oldbot; ! static int need_clr; /* * Display the line which is in the line buffer. */ ! void ! put_line(void) { ! int c; ! int i; int a; ! if (ABORT_SIGS()) { /* * Don't output if a signal is pending. */ *************** *** 58,73 **** return; } ! final_attr = AT_NORMAL; ! ! for (i = 0; (c = gline(i, &a)) != '\0'; i++) ! { at_switch(a); - final_attr = a; if (c == '\b') putbs(); else ! putchr(c); } at_exit(); --- 47,58 ---- return; } ! for (i = 0; (c = gline(i, &a)) != '\0'; i++) { at_switch(a); if (c == '\b') putbs(); else ! (void) putchr(c); } at_exit(); *************** *** 92,323 **** * sure these messages can be seen before they are * overwritten or scrolled away. */ ! public void ! flush() { ! register int n; ! register int fd; ssize_t nwritten; ! n = ob - obuf; if (n == 0) return; - #if MSDOS_COMPILER==MSOFTC - if (is_tty && any_display) - { - *ob = '\0'; - _outtext(obuf); - ob = obuf; - return; - } - #else - #if MSDOS_COMPILER==WIN32C || MSDOS_COMPILER==BORLANDC || MSDOS_COMPILER==DJGPPC - if (is_tty && any_display) - { - *ob = '\0'; - if (ctldisp != OPT_ONPLUS) - WIN32textout(obuf, ob - 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; - unsigned char fg, bg; - static unsigned char at; - #if MSDOS_COMPILER==WIN32C - /* Screen colors used by 3x and 4x SGR commands. */ - static unsigned char screen_color[] = { - 0, /* BLACK */ - FOREGROUND_RED, - FOREGROUND_GREEN, - FOREGROUND_RED|FOREGROUND_GREEN, - FOREGROUND_BLUE, - FOREGROUND_BLUE|FOREGROUND_RED, - FOREGROUND_BLUE|FOREGROUND_GREEN, - FOREGROUND_BLUE|FOREGROUND_GREEN|FOREGROUND_RED - }; - #else - static enum COLORS screen_color[] = { - BLACK, RED, GREEN, BROWN, - BLUE, MAGENTA, CYAN, LIGHTGRAY - }; - #endif - - for (anchor = p_next = obuf; - (p_next = memchr(p_next, ESC, ob - p_next)) != NULL; ) - { - p = p_next; - if (p[1] == '[') /* "ESC-[" sequence */ - { - if (p > anchor) - { - /* - * If some chars seen since - * the last escape sequence, - * write them out to the screen. - */ - WIN32textout(anchor, p-anchor); - anchor = p; - } - p += 2; /* Skip the "ESC-[" */ - if (is_ansi_end(*p)) - { - /* - * Handle null escape sequence - * "ESC[m", which restores - * the normal color. - */ - p++; - anchor = p_next = p; - at = 0; - WIN32setcolors(nm_fg_color, nm_bg_color); - continue; - } - p_next = p; - - /* - * Select foreground/background colors - * based on the escape sequence. - */ - fg = nm_fg_color; - bg = nm_bg_color; - while (!is_ansi_end(*p)) - { - char *q; - long code = strtol(p, &q, 10); - - if (*q == '\0') - { - /* - * Incomplete sequence. - * Leave it unprocessed - * in the buffer. - */ - int slop = q - anchor; - /* {{ strlcpy args overlap! }} */ - strlcpy(obuf, anchor, - sizeof(obuf)); - 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) - { - default: - /* case 0: all attrs off */ - fg = nm_fg_color; - bg = nm_bg_color; - at = 0; - break; - case 1: /* bold on */ - at |= 1; - break; - case 3: /* italic on */ - case 7: /* inverse on */ - at |= 2; - break; - case 4: /* underline on */ - at |= 4; - break; - case 5: /* slow blink on */ - case 6: /* fast blink on */ - at |= 8; - break; - case 8: /* concealed on */ - fg = (bg & 7) | 8; - break; - case 22: /* bold off */ - at &= ~1; - break; - case 23: /* italic off */ - case 27: /* inverse off */ - at &= ~2; - break; - case 24: /* underline off */ - at &= ~4; - 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) - break; - if (at & 1) - { - /* - * If \e[1m use defined bold - * color, else set intensity. - */ - if (p[-2] == '[') - { - #if MSDOS_COMPILER==WIN32C - fg |= FOREGROUND_INTENSITY; - bg |= BACKGROUND_INTENSITY; - #else - fg = bo_fg_color; - bg = bo_bg_color; - #endif - } else - fg |= 8; - } else if (at & 2) - { - fg = so_fg_color; - bg = so_bg_color; - } else if (at & 4) - { - fg = ul_fg_color; - bg = ul_bg_color; - } else if (at & 8) - { - fg = bl_fg_color; - bg = bl_bg_color; - } - fg &= 0xf; - bg &= 0xf; - WIN32setcolors(fg, bg); - p_next = anchor = p + 1; - } else - p_next++; - } - - /* Output what's left in the buffer. */ - WIN32textout(anchor, ob - anchor); - } - ob = obuf; - return; - } - #endif - #endif fd = (any_display) ? STDOUT_FILENO : STDERR_FILENO; nwritten = write(fd, obuf, n); if (nwritten != n) { --- 77,93 ---- * sure these messages can be seen before they are * overwritten or scrolled away. */ ! void ! flush(void) { ! int n; ! int fd; ssize_t nwritten; ! n = (intptr_t)ob - (intptr_t)obuf; if (n == 0) return; fd = (any_display) ? STDOUT_FILENO : STDERR_FILENO; nwritten = write(fd, obuf, n); if (nwritten != n) { *************** *** 331,434 **** /* * Output a character. */ ! public int ! putchr(c) ! int c; { ! #if 0 /* fake UTF-8 output for testing */ ! extern int utf_mode; ! if (utf_mode) ! { ! static char ubuf[MAX_UTF_CHAR_LEN]; ! static int ubuf_len = 0; ! static int ubuf_index = 0; ! if (ubuf_len == 0) ! { ! ubuf_len = utf_len(c); ! ubuf_index = 0; ! } ! ubuf[ubuf_index++] = c; ! if (ubuf_index < ubuf_len) ! return c; ! c = get_wchar(ubuf) & 0xFF; ! ubuf_len = 0; ! } ! #endif ! if (need_clr) ! { need_clr = 0; clear_bot(); } - #if MSDOS_COMPILER - if (c == '\n' && is_tty) - { - /* remove_top(1); */ - putchr('\r'); - } - #else - #ifdef _OSK - if (c == '\n' && is_tty) /* In OS-9, '\n' == 0x0D */ - putchr(0x0A); - #endif - #endif /* * Some versions of flush() write to *ob, so we must flush * when we are still one char from the end of obuf. */ ! if (ob >= &obuf[sizeof(obuf)-1]) flush(); ! *ob++ = c; ! at_prompt = 0; return (c); } /* * Output a string. */ ! public void ! putstr(s) ! register char *s; { while (*s != '\0') ! putchr(*s++); } /* * Convert an integral type to a string. */ ! #define TYPE_TO_A_FUNC(funcname, type) \ ! void funcname(num, buf, len) \ ! type num; \ ! char *buf; \ ! size_t len; \ ! { \ ! 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 = '-'; \ ! strlcpy(buf, s, len); \ } ! 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 ! iprint_int(num) ! int num; { char buf[INT_STRLEN_BOUND(num)]; ! inttoa(num, buf, sizeof(buf)); putstr(buf); return (strlen(buf)); } --- 101,168 ---- /* * Output a character. */ ! int ! putchr(int c) { ! if (need_clr) { need_clr = 0; clear_bot(); } /* * Some versions of flush() write to *ob, so we must flush * when we are still one char from the end of obuf. */ ! if (ob >= &obuf[sizeof (obuf)-1]) flush(); ! *ob++ = (char)c; return (c); } /* * Output a string. */ ! void ! putstr(const char *s) { while (*s != '\0') ! (void) putchr(*s++); } /* * Convert an integral type to a string. */ ! #define TYPE_TO_A_FUNC(funcname, type) \ ! void \ ! funcname(type num, char *buf, size_t len) \ ! { \ ! int neg = (num < 0); \ ! char tbuf[INT_STRLEN_BOUND(num)+2]; \ ! char *s = tbuf + sizeof (tbuf); \ ! if (neg) \ ! num = -num; \ ! *--s = '\0'; \ ! do { \ ! *--s = (num % 10) + '0'; \ ! } while ((num /= 10) != 0); \ ! if (neg) \ ! *--s = '-'; \ ! (void) strlcpy(buf, s, len); \ } ! TYPE_TO_A_FUNC(postoa, off_t) TYPE_TO_A_FUNC(linenumtoa, LINENUM) TYPE_TO_A_FUNC(inttoa, int) /* * Output an integer in a given radix. */ ! static int ! iprint_int(int num) { char buf[INT_STRLEN_BOUND(num)]; ! inttoa(num, buf, sizeof (buf)); putstr(buf); return (strlen(buf)); } *************** *** 436,448 **** /* * Output a line number in a given radix. */ ! static int ! iprint_linenum(num) ! LINENUM num; { char buf[INT_STRLEN_BOUND(num)]; ! linenumtoa(num, buf, sizeof(buf)); putstr(buf); return (strlen(buf)); } --- 170,181 ---- /* * Output a line number in a given radix. */ ! static int ! iprint_linenum(LINENUM num) { char buf[INT_STRLEN_BOUND(num)]; ! linenumtoa(num, buf, sizeof (buf)); putstr(buf); return (strlen(buf)); } *************** *** 451,482 **** * This function implements printf-like functionality * using a more portable argument list mechanism than printf's. */ ! static int ! less_printf(fmt, parg) ! register char *fmt; ! PARG *parg; { register char *s; register int col; col = 0; ! while (*fmt != '\0') ! { ! if (*fmt != '%') ! { ! putchr(*fmt++); col++; ! } else ! { ++fmt; ! switch (*fmt++) ! { case 's': s = parg->p_string; parg++; ! while (*s != '\0') ! { ! putchr(*s++); col++; } break; --- 184,208 ---- * This function implements printf-like functionality * using a more portable argument list mechanism than printf's. */ ! static int ! less_printf(const char *fmt, PARG *parg) { register char *s; register int col; col = 0; ! while (*fmt != '\0') { ! if (*fmt != '%') { ! (void) putchr(*fmt++); col++; ! } else { ++fmt; ! switch (*fmt++) { case 's': s = parg->p_string; parg++; ! while (*s != '\0') { ! (void) putchr(*s++); col++; } break; *************** *** 499,535 **** * If some other non-trivial char is pressed, unget it, so it will * become the next command. */ ! public void ! get_return() { int c; - #if ONLY_RETURN - while ((c = getchr()) != '\n' && c != '\r') - bell(); - #else c = getchr(); if (c != '\n' && c != '\r' && c != ' ' && c != READ_INTR) ungetcc(c); - #endif } /* * Output a message in the lower left corner of the screen * and wait for carriage return. */ ! public void ! error(fmt, parg) ! char *fmt; ! PARG *parg; { int col = 0; static char return_to_continue[] = " (press RETURN)"; errmsgs++; ! if (any_display && is_tty) ! { if (!oldbot) squish_check(); at_exit(); --- 225,253 ---- * If some other non-trivial char is pressed, unget it, so it will * become the next command. */ ! void ! get_return(void) { int c; c = getchr(); if (c != '\n' && c != '\r' && c != ' ' && c != READ_INTR) ungetcc(c); } /* * Output a message in the lower left corner of the screen * and wait for carriage return. */ ! void ! error(const char *fmt, PARG *parg) { int col = 0; static char return_to_continue[] = " (press RETURN)"; errmsgs++; ! if (any_display && is_tty) { if (!oldbot) squish_check(); at_exit(); *************** *** 540,558 **** col += less_printf(fmt, parg); ! if (!(any_display && is_tty)) ! { ! putchr('\n'); return; } putstr(return_to_continue); at_exit(); ! col += sizeof(return_to_continue) + so_e_width; get_return(); lower_left(); ! clear_eol(); if (col >= sc_width) /* --- 258,275 ---- col += less_printf(fmt, parg); ! if (!(any_display && is_tty)) { ! (void) putchr('\n'); return; } putstr(return_to_continue); at_exit(); ! col += sizeof (return_to_continue) + so_e_width; get_return(); lower_left(); ! clear_eol(); if (col >= sc_width) /* *************** *** 573,582 **** * Usually used to warn that we are beginning a potentially * time-consuming operation. */ ! public void ! ierror(fmt, parg) ! char *fmt; ! PARG *parg; { at_exit(); clear_bot(); --- 290,297 ---- * Usually used to warn that we are beginning a potentially * time-consuming operation. */ ! void ! ierror(const char *fmt, PARG *parg) { at_exit(); clear_bot(); *************** *** 592,601 **** * Output a message in the lower left corner of the screen * and return a single-character response. */ ! public int ! query(fmt, parg) ! char *fmt; ! PARG *parg; { register int c; int col = 0; --- 307,314 ---- * Output a message in the lower left corner of the screen * and return a single-character response. */ ! int ! query(const char *fmt, PARG *parg) { register int c; int col = 0; *************** *** 606,614 **** (void) less_printf(fmt, parg); c = getchr(); ! if (!(any_display && is_tty)) ! { ! putchr('\n'); return (c); } --- 319,326 ---- (void) less_printf(fmt, parg); c = getchr(); ! if (!(any_display && is_tty)) { ! (void) putchr('\n'); return (c); }