[BACK]Return to output.c CVS log [TXT][DIR] Up to [local] / src / usr.bin / less

Diff for /src/usr.bin/less/output.c between version 1.9 and 1.10

version 1.9, 2014/04/25 13:38:21 version 1.10, 2015/11/05 22:08:44
Line 6 
Line 6 
  *   *
  * For more information, see the README file.   * For more information, see the README file.
  */   */
   /*
    * Modified for use with illumos.
    * Copyright 2014 Garrett D'Amore <garrett@damore.org>
    */
   
   
 /*  /*
  * High level routines dealing with the output to the screen.   * High level routines dealing with the output to the screen.
  */   */
   
 #include "less.h"  #include "less.h"
 #if MSDOS_COMPILER==WIN32C  
 #include "windows.h"  
 #endif  
   
 public int errmsgs;     /* Count of messages displayed by error() */  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 volatile sig_atomic_t sigs;
 extern int sc_width;  extern int sc_width;
Line 30 
Line 27 
 extern int is_tty;  extern int is_tty;
 extern int oldbot;  extern int oldbot;
   
 #if MSDOS_COMPILER==WIN32C || MSDOS_COMPILER==BORLANDC || MSDOS_COMPILER==DJGPPC  static int need_clr;
 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.   * Display the line which is in the line buffer.
  */   */
         public void  void
 put_line()  put_line(void)
 {  {
         register int c;          int c;
         register int i;          int i;
         int a;          int a;
   
         if (ABORT_SIGS())          if (ABORT_SIGS()) {
         {  
                 /*                  /*
                  * Don't output if a signal is pending.                   * Don't output if a signal is pending.
                  */                   */
Line 58 
Line 47 
                 return;                  return;
         }          }
   
         final_attr = AT_NORMAL;          for (i = 0;  (c = gline(i, &a)) != '\0';  i++) {
   
         for (i = 0;  (c = gline(i, &a)) != '\0';  i++)  
         {  
                 at_switch(a);                  at_switch(a);
                 final_attr = a;  
                 if (c == '\b')                  if (c == '\b')
                         putbs();                          putbs();
                 else                  else
                         putchr(c);                          (void) putchr(c);
         }          }
   
         at_exit();          at_exit();
Line 92 
Line 77 
  * sure these messages can be seen before they are   * sure these messages can be seen before they are
  * overwritten or scrolled away.   * overwritten or scrolled away.
  */   */
         public void  void
 flush()  flush(void)
 {  {
         register int n;          int n;
         register int fd;          int fd;
         ssize_t nwritten;          ssize_t nwritten;
   
         n = ob - obuf;          n = (intptr_t)ob - (intptr_t)obuf;
         if (n == 0)          if (n == 0)
                 return;                  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;          fd = (any_display) ? STDOUT_FILENO : STDERR_FILENO;
         nwritten = write(fd, obuf, n);          nwritten = write(fd, obuf, n);
         if (nwritten != n) {          if (nwritten != n) {
Line 331 
Line 101 
 /*  /*
  * Output a character.   * Output a character.
  */   */
         public int  int
 putchr(c)  putchr(int c)
         int c;  
 {  {
 #if 0 /* fake UTF-8 output for testing */          if (need_clr) {
         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;                  need_clr = 0;
                 clear_bot();                  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           * Some versions of flush() write to *ob, so we must flush
          * when we are still one char from the end of obuf.           * when we are still one char from the end of obuf.
          */           */
         if (ob >= &obuf[sizeof(obuf)-1])          if (ob >= &obuf[sizeof (obuf)-1])
                 flush();                  flush();
         *ob++ = c;          *ob++ = (char)c;
         at_prompt = 0;  
         return (c);          return (c);
 }  }
   
 /*  /*
  * Output a string.   * Output a string.
  */   */
         public void  void
 putstr(s)  putstr(const char *s)
         register char *s;  
 {  {
         while (*s != '\0')          while (*s != '\0')
                 putchr(*s++);                  (void) putchr(*s++);
 }  }
   
   
 /*  /*
  * Convert an integral type to a string.   * Convert an integral type to a string.
  */   */
 #define TYPE_TO_A_FUNC(funcname, type) \  #define TYPE_TO_A_FUNC(funcname, type)          \
 void funcname(num, buf, len) \  void                                            \
         type num; \  funcname(type num, char *buf, size_t len)       \
         char *buf; \  {                                               \
         size_t len; \          int neg = (num < 0);                    \
 { \          char tbuf[INT_STRLEN_BOUND(num)+2];     \
         int neg = (num < 0); \          char *s = tbuf + sizeof (tbuf);         \
         char tbuf[INT_STRLEN_BOUND(num)+2]; \          if (neg)                                \
         register char *s = tbuf + sizeof(tbuf); \                  num = -num;                     \
         if (neg) num = -num; \          *--s = '\0';                            \
         *--s = '\0'; \          do {                                    \
         do { \                  *--s = (num % 10) + '0';        \
                 *--s = (num % 10) + '0'; \          } while ((num /= 10) != 0);             \
         } while ((num /= 10) != 0); \          if (neg)                                \
         if (neg) *--s = '-'; \                   *--s = '-';                    \
         strlcpy(buf, s, len); \          (void) strlcpy(buf, s, len);            \
 }  }
   
 TYPE_TO_A_FUNC(postoa, POSITION)  TYPE_TO_A_FUNC(postoa, off_t)
 TYPE_TO_A_FUNC(linenumtoa, LINENUM)  TYPE_TO_A_FUNC(linenumtoa, LINENUM)
 TYPE_TO_A_FUNC(inttoa, int)  TYPE_TO_A_FUNC(inttoa, int)
   
 /*  /*
  * Output an integer in a given radix.   * Output an integer in a given radix.
  */   */
         static int  static int
 iprint_int(num)  iprint_int(int num)
         int num;  
 {  {
         char buf[INT_STRLEN_BOUND(num)];          char buf[INT_STRLEN_BOUND(num)];
   
         inttoa(num, buf, sizeof(buf));          inttoa(num, buf, sizeof (buf));
         putstr(buf);          putstr(buf);
         return (strlen(buf));          return (strlen(buf));
 }  }
Line 436 
Line 170 
 /*  /*
  * Output a line number in a given radix.   * Output a line number in a given radix.
  */   */
         static int  static int
 iprint_linenum(num)  iprint_linenum(LINENUM num)
         LINENUM num;  
 {  {
         char buf[INT_STRLEN_BOUND(num)];          char buf[INT_STRLEN_BOUND(num)];
   
         linenumtoa(num, buf, sizeof(buf));          linenumtoa(num, buf, sizeof (buf));
         putstr(buf);          putstr(buf);
         return (strlen(buf));          return (strlen(buf));
 }  }
Line 451 
Line 184 
  * This function implements printf-like functionality   * This function implements printf-like functionality
  * using a more portable argument list mechanism than printf's.   * using a more portable argument list mechanism than printf's.
  */   */
         static int  static int
 less_printf(fmt, parg)  less_printf(const char *fmt, PARG *parg)
         register char *fmt;  
         PARG *parg;  
 {  {
         register char *s;          register char *s;
         register int col;          register int col;
   
         col = 0;          col = 0;
         while (*fmt != '\0')          while (*fmt != '\0') {
         {                  if (*fmt != '%') {
                 if (*fmt != '%')                          (void) putchr(*fmt++);
                 {  
                         putchr(*fmt++);  
                         col++;                          col++;
                 } else                  } else {
                 {  
                         ++fmt;                          ++fmt;
                         switch (*fmt++)                          switch (*fmt++) {
                         {  
                         case 's':                          case 's':
                                 s = parg->p_string;                                  s = parg->p_string;
                                 parg++;                                  parg++;
                                 while (*s != '\0')                                  while (*s != '\0') {
                                 {                                          (void) putchr(*s++);
                                         putchr(*s++);  
                                         col++;                                          col++;
                                 }                                  }
                                 break;                                  break;
Line 499 
Line 225 
  * If some other non-trivial char is pressed, unget it, so it will   * If some other non-trivial char is pressed, unget it, so it will
  * become the next command.   * become the next command.
  */   */
         public void  void
 get_return()  get_return(void)
 {  {
         int c;          int c;
   
 #if ONLY_RETURN  
         while ((c = getchr()) != '\n' && c != '\r')  
                 bell();  
 #else  
         c = getchr();          c = getchr();
         if (c != '\n' && c != '\r' && c != ' ' && c != READ_INTR)          if (c != '\n' && c != '\r' && c != ' ' && c != READ_INTR)
                 ungetcc(c);                  ungetcc(c);
 #endif  
 }  }
   
 /*  /*
  * Output a message in the lower left corner of the screen   * Output a message in the lower left corner of the screen
  * and wait for carriage return.   * and wait for carriage return.
  */   */
         public void  void
 error(fmt, parg)  error(const char *fmt, PARG *parg)
         char *fmt;  
         PARG *parg;  
 {  {
         int col = 0;          int col = 0;
         static char return_to_continue[] = "  (press RETURN)";          static char return_to_continue[] = "  (press RETURN)";
   
         errmsgs++;          errmsgs++;
   
         if (any_display && is_tty)          if (any_display && is_tty) {
         {  
                 if (!oldbot)                  if (!oldbot)
                         squish_check();                          squish_check();
                 at_exit();                  at_exit();
Line 540 
Line 258 
   
         col += less_printf(fmt, parg);          col += less_printf(fmt, parg);
   
         if (!(any_display && is_tty))          if (!(any_display && is_tty)) {
         {                  (void) putchr('\n');
                 putchr('\n');  
                 return;                  return;
         }          }
   
         putstr(return_to_continue);          putstr(return_to_continue);
         at_exit();          at_exit();
         col += sizeof(return_to_continue) + so_e_width;          col += sizeof (return_to_continue) + so_e_width;
   
         get_return();          get_return();
         lower_left();          lower_left();
     clear_eol();          clear_eol();
   
         if (col >= sc_width)          if (col >= sc_width)
                 /*                  /*
Line 573 
Line 290 
  * Usually used to warn that we are beginning a potentially   * Usually used to warn that we are beginning a potentially
  * time-consuming operation.   * time-consuming operation.
  */   */
         public void  void
 ierror(fmt, parg)  ierror(const char *fmt, PARG *parg)
         char *fmt;  
         PARG *parg;  
 {  {
         at_exit();          at_exit();
         clear_bot();          clear_bot();
Line 592 
Line 307 
  * Output a message in the lower left corner of the screen   * Output a message in the lower left corner of the screen
  * and return a single-character response.   * and return a single-character response.
  */   */
         public int  int
 query(fmt, parg)  query(const char *fmt, PARG *parg)
         char *fmt;  
         PARG *parg;  
 {  {
         register int c;          register int c;
         int col = 0;          int col = 0;
Line 606 
Line 319 
         (void) less_printf(fmt, parg);          (void) less_printf(fmt, parg);
         c = getchr();          c = getchr();
   
         if (!(any_display && is_tty))          if (!(any_display && is_tty)) {
         {                  (void) putchr('\n');
                 putchr('\n');  
                 return (c);                  return (c);
         }          }
   

Legend:
Removed from v.1.9  
changed lines
  Added in v.1.10