[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.1.1.1 and 1.1.1.2

version 1.1.1.1, 1996/09/21 05:39:43 version 1.1.1.2, 2003/04/13 18:21:21
Line 1 
Line 1 
 /*  /*
  * Copyright (c) 1984,1985,1989,1994,1995  Mark Nudelman   * Copyright (C) 1984-2002  Mark Nudelman
  * All rights reserved.  
  *   *
  * Redistribution and use in source and binary forms, with or without   * You may distribute under the terms of either the GNU General Public
  * modification, are permitted provided that the following conditions   * License or the Less License, as specified in the README file.
  * are met:  
  * 1. Redistributions of source code must retain the above copyright  
  *    notice, this list of conditions and the following disclaimer.  
  * 2. Redistributions in binary form must reproduce the above copyright  
  *    notice in the documentation and/or other materials provided with  
  *    the distribution.  
  *   *
  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY   * For more information about less, or for information on how to
  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE   * contact the author, see the README file.
  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR  
  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE  
  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR  
  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT  
  * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR  
  * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,  
  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE  
  * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN  
  * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.  
  */   */
   
   
Line 30 
Line 14 
  */   */
   
 #include "less.h"  #include "less.h"
   #if MSDOS_COMPILER==WIN32C
   #include "windows.h"
   #endif
   
 public int errmsgs;     /* Count of messages displayed by error() */  public int errmsgs;     /* Count of messages displayed by error() */
 public int need_clr;  public int need_clr;
   public int final_attr;
   
 extern int sigs;  extern int sigs;
 extern int sc_width;  extern int sc_width;
 extern int so_s_width, so_e_width;  extern int so_s_width, so_e_width;
 extern int screen_trashed;  extern int screen_trashed;
 extern int any_display;  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.   * Display the line which is in the line buffer.
  */   */
Line 102 
Line 100 
         case AT_BLINK:          bl_exit();      break;          case AT_BLINK:          bl_exit();      break;
         case AT_STANDOUT:       so_exit();      break;          case AT_STANDOUT:       so_exit();      break;
         }          }
           final_attr = curr_attr;
 }  }
   
 static char obuf[1024];  static char obuf[OUTBUF_SIZE];
 static char *ob = obuf;  static char *ob = obuf;
   
 /*  /*
Line 129 
Line 128 
         register int n;          register int n;
         register int fd;          register int fd;
   
 #if MSOFTC  
         *ob = '\0';  
         _outtext(obuf);  
         ob = obuf;  
 #else  
         n = ob - obuf;          n = ob - obuf;
         if (n == 0)          if (n == 0)
                 return;                  return;
   #if MSDOS_COMPILER==WIN32C
           if (is_tty && any_display)
           {
                   char *op;
                   DWORD nwritten = 0;
                   CONSOLE_SCREEN_BUFFER_INFO scr;
                   int row;
                   int col;
                   int olen;
                   extern HANDLE con_out;
   
                   olen = ob - obuf;
                   /*
                    * There is a bug in Win32 WriteConsole() if we're
                    * writing in the last cell with a different color.
                    * To avoid color problems in the bottom line,
                    * we scroll the screen manually, before writing.
                    */
                   GetConsoleScreenBufferInfo(con_out, &scr);
                   col = scr.dwCursorPosition.X;
                   row = scr.dwCursorPosition.Y;
                   for (op = obuf;  op < obuf + olen;  op++)
                   {
                           if (*op == '\n')
                           {
                                   col = 0;
                                   row++;
                           } else if (*op == '\r')
                           {
                                   col = 0;
                           } else
                           {
                                   col++;
                                   if (col >= sc_width)
                                   {
                                           col = 0;
                                           row++;
                                   }
                           }
                   }
                   if (row > scr.srWindow.Bottom)
                           win32_scroll_up(row - scr.srWindow.Bottom);
                   WriteConsole(con_out, obuf, olen, &nwritten, NULL);
                   ob = obuf;
                   return;
           }
   #else
   #if MSDOS_COMPILER==MSOFTC
           if (is_tty && any_display)
           {
                   *ob = '\0';
                   _outtext(obuf);
                   ob = obuf;
                   return;
           }
   #else
   #if MSDOS_COMPILER==BORLANDC || MSDOS_COMPILER==DJGPPC
           if (is_tty && any_display)
           {
                   *ob = '\0';
                   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;
           }
   #endif
   #endif
   #endif
         fd = (any_display) ? 1 : 2;          fd = (any_display) ? 1 : 2;
         if (write(fd, obuf, n) != n)          if (write(fd, obuf, n) != n)
                 screen_trashed = 1;                  screen_trashed = 1;
         ob = obuf;          ob = obuf;
 #endif  
 }  }
   
 /*  /*
Line 151 
Line 360 
 putchr(c)  putchr(c)
         int c;          int c;
 {  {
         if (ob >= &obuf[sizeof(obuf)])  
                 flush();  
         if (need_clr)          if (need_clr)
         {          {
                 need_clr = 0;                  need_clr = 0;
                 clear_bot();                  clear_bot();
         }          }
 #if MSOFTC  #if MSDOS_COMPILER
         if (c == '\n')          if (c == '\n' && is_tty)
           {
                   /* remove_top(1); */
                 putchr('\r');                  putchr('\r');
           }
   #else
   #ifdef _OSK
           if (c == '\n' && is_tty)  /* In OS-9, '\n' == 0x0D */
                   putchr(0x0A);
 #endif  #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;          *ob++ = c;
         return (c);          return (c);
 }  }
Line 179 
Line 400 
   
   
 /*  /*
    * 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.   * Output an integer in a given radix.
  */   */
         static int          static int
 iprintnum(num, radix)  iprint_int(num)
         int num;          int num;
         int radix;  
 {  {
         register char *s;          char buf[INT_STRLEN_BOUND(num)];
         int r;  
         int neg;  
         char buf[10];  
   
         if (neg = (num < 0))          inttoa(num, buf);
                 num = -num;          putstr(buf);
           return (strlen(buf));
   }
   
         s = buf;  /*
         do   * Output a line number in a given radix.
         {   */
                 *s++ = (num % radix) + '0';          static int
         } while ((num /= radix) != 0);  iprint_linenum(num)
           LINENUM num;
   {
           char buf[INT_STRLEN_BOUND(num)];
   
         if (neg)          linenumtoa(num, buf);
                 *s++ = '-';          putstr(buf);
         r = s - buf;          return (strlen(buf));
   
         while (s > buf)  
                 putchr(*--s);  
         return (r);  
 }  }
   
 /*  /*
Line 214 
Line 456 
  * using a more portable argument list mechanism than printf's.   * using a more portable argument list mechanism than printf's.
  */   */
         static int          static int
 iprintf(fmt, parg)  less_printf(fmt, parg)
         register char *fmt;          register char *fmt;
         PARG *parg;          PARG *parg;
 {  {
         register char *s;          register char *s;
         register int n;  
         register int col;          register int col;
   
         col = 0;          col = 0;
Line 232 
Line 473 
                 } else                  } else
                 {                  {
                         ++fmt;                          ++fmt;
                         switch (*fmt++) {                          switch (*fmt++)
                           {
                         case 's':                          case 's':
                                 s = parg->p_string;                                  s = parg->p_string;
                                 parg++;                                  parg++;
Line 243 
Line 485 
                                 }                                  }
                                 break;                                  break;
                         case 'd':                          case 'd':
                                 n = parg->p_int;                                  col += iprint_int(parg->p_int);
                                 parg++;                                  parg++;
                                 col += iprintnum(n, 10);  
                                 break;                                  break;
                           case 'n':
                                   col += iprint_linenum(parg->p_linenum);
                                   parg++;
                                   break;
                         }                          }
                 }                  }
         }          }
Line 254 
Line 499 
 }  }
   
 /*  /*
    * Get a RETURN.
    * 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   * Output a message in the lower left corner of the screen
  * and wait for carriage return.   * and wait for carriage return.
  */   */
Line 262 
Line 527 
         char *fmt;          char *fmt;
         PARG *parg;          PARG *parg;
 {  {
         int c;  
         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)          if (any_display && is_tty)
         {          {
                 clear_bot();                  clear_bot();
                 so_enter();                  so_enter();
                 col += so_s_width;                  col += so_s_width;
         }          }
   
         col += iprintf(fmt, parg);          col += less_printf(fmt, parg);
   
         if (!any_display)          if (!(any_display && is_tty))
         {          {
                 putchr('\n');                  putchr('\n');
                 return;                  return;
Line 287 
Line 551 
         so_exit();          so_exit();
         col += sizeof(return_to_continue) + so_e_width;          col += sizeof(return_to_continue) + so_e_width;
   
 #if ONLY_RETURN          get_return();
         while ((c = getchr()) != '\n' && c != '\r')  
                 bell();  
 #else  
         c = getchr();  
         if (c != '\n' && c != '\r' && c != ' ' && c != READ_INTR)  
                 ungetcc(c);  
 #endif  
         lower_left();          lower_left();
   
         if (col >= sc_width)          if (col >= sc_width)
Line 323 
Line 580 
 {  {
         clear_bot();          clear_bot();
         so_enter();          so_enter();
         (void) iprintf(fmt, parg);          (void) less_printf(fmt, parg);
         putstr(intr_to_abort);          putstr(intr_to_abort);
         so_exit();          so_exit();
         flush();          flush();
Line 342 
Line 599 
         register int c;          register int c;
         int col = 0;          int col = 0;
   
         if (any_display)          if (any_display && is_tty)
                 clear_bot();                  clear_bot();
   
         (void) iprintf(fmt, parg);          (void) less_printf(fmt, parg);
         c = getchr();          c = getchr();
   
         if (!any_display)          if (!(any_display && is_tty))
         {          {
                 putchr('\n');                  putchr('\n');
                 return (c);                  return (c);

Legend:
Removed from v.1.1.1.1  
changed lines
  Added in v.1.1.1.2