home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 11 Util / 11-Util.zip / LESS177.ZIP / src / output.c < prev    next >
C/C++ Source or Header  |  1992-07-18  |  5KB  |  338 lines

  1. /*
  2.  * High level routines dealing with the output to the screen.
  3.  */
  4.  
  5. #include "less.h"
  6.  
  7. public int errmsgs;    /* Count of messages displayed by error() */
  8. public int need_clr;
  9.  
  10. extern int sigs;
  11. extern int sc_width;
  12. extern int so_s_width, so_e_width;
  13. extern int screen_trashed;
  14. extern int any_display;
  15. #if __MSDOS__
  16. extern int output_mode;
  17. #endif
  18.  
  19. /*
  20.  * Display the line which is in the line buffer.
  21.  */
  22.     public void
  23. put_line()
  24. {
  25.     register int c;
  26.     register int i;
  27.     int a;
  28.     int curr_attr;
  29.  
  30.     if (sigs)
  31.     {
  32.         /*
  33.          * Don't output if a signal is pending.
  34.          */
  35.         screen_trashed = 1;
  36.         return;
  37.     }
  38.  
  39.     curr_attr = NORMAL;
  40.  
  41.     for (i = 0;  (c = gline(i, &a)) != '\0';  i++)
  42.     {
  43.         if (a != curr_attr)
  44.         {
  45.             /*
  46.              * Changing attributes.
  47.              * Display the exit sequence for the old attribute
  48.              * and the enter sequence for the new one.
  49.              */
  50.             switch (curr_attr)
  51.             {
  52.             case UNDERLINE:    ul_exit();    break;
  53.             case BOLD:    bo_exit();    break;
  54.             case BLINK:    bl_exit();    break;
  55.             }
  56.             switch (a)
  57.             {
  58.             case UNDERLINE:    ul_enter();    break;
  59.             case BOLD:    bo_enter();    break;
  60.             case BLINK:    bl_enter();    break;
  61.             }
  62.             curr_attr = a;
  63.         }
  64.         if (curr_attr == INVIS)
  65.             continue;
  66.         if (c == '\b')
  67.             putbs();
  68.         else
  69.             putchr(c);
  70.     }
  71. }
  72.  
  73. static char obuf[1024];
  74. static char *ob = obuf;
  75.  
  76. /*
  77.  * Flush buffered output.
  78.  *
  79.  * If we haven't displayed any file data yet,
  80.  * output messages on error output (file descriptor 2),
  81.  * otherwise output on standard output (file descriptor 1).
  82.  *
  83.  * This has the desirable effect of producing all
  84.  * error messages on error output if standard output
  85.  * is directed to a file.  It also does the same if
  86.  * we never produce any real output; for example, if
  87.  * the input file(s) cannot be opened.  If we do
  88.  * eventually produce output, code in edit() makes
  89.  * sure these messages can be seen before they are
  90.  * overwritten or scrolled away.
  91.  */
  92.     public void
  93. flush()
  94. {
  95.     register int n;
  96.     register int fd;
  97.  
  98. #if __MSDOS__
  99.     if (output_mode == 0)
  100.     {
  101.         *ob = '\0';
  102.         cputs(obuf);
  103.         ob = obuf;
  104.         return;
  105.     }
  106. #endif
  107.     n = ob - obuf;
  108.     if (n == 0)
  109.         return;
  110.     fd = (any_display) ? 1 : 2;
  111.     if (write(fd, obuf, n) != n)
  112.         screen_trashed = 1;
  113.     ob = obuf;
  114. }
  115.  
  116. /*
  117.  * Output a character.
  118.  */
  119.     public void
  120. putchr(c)
  121.     int c;
  122. {
  123.     if (ob >= &obuf[sizeof(obuf)])
  124.         flush();
  125.     if (need_clr)
  126.     {
  127.         need_clr = 0;
  128.         lower_left();
  129.         clear_eol();
  130.     }
  131. #if __MSDOS__
  132.     if (c == '\n')
  133.         *ob++ = '\r';
  134. #endif
  135.     *ob++ = c;
  136. }
  137.  
  138. /*
  139.  * Output a string.
  140.  */
  141.     public void
  142. putstr(s)
  143.     register char *s;
  144. {
  145.     while (*s != '\0')
  146.         putchr(*s++);
  147. }
  148.  
  149.  
  150. /*
  151.  * Output an integer in a given radix.
  152.  */
  153.     static int
  154. iprintnum(num, radix)
  155.     int num;
  156.     int radix;
  157. {
  158.     register char *s;
  159.     int r;
  160.     int neg;
  161.     char buf[10];
  162.  
  163.     if (neg = (num < 0))
  164.         num = -num;
  165.  
  166.     s = buf;
  167.     do
  168.     {
  169.         *s++ = (num % radix) + '0';
  170.     } while ((num /= radix) != 0);
  171.  
  172.     if (neg)
  173.         *s++ = '-';
  174.     r = s - buf;
  175.  
  176.     while (s > buf)
  177.         putchr(*--s);
  178.     return (r);
  179. }
  180.  
  181. /*
  182.  * This function implements printf-like functionality
  183.  * using a more portable argument list mechanism than printf's.
  184.  */
  185.     static int
  186. iprintf(fmt, parg)
  187.     register char *fmt;
  188.     PARG *parg;
  189. {
  190.     register char *s;
  191.     register int n;
  192.     register int col;
  193.  
  194.     col = 0;
  195.     while (*fmt != '\0')
  196.     {
  197.         if (*fmt != '%')
  198.         {
  199.             putchr(*fmt++);
  200.             col++;
  201.         } else
  202.         {
  203.             ++fmt;
  204.             switch (*fmt++) {
  205.             case 's':
  206.                 s = parg->p_string;
  207.                 parg++;
  208.                 while (*s != '\0')
  209.                 {
  210.                     putchr(*s++);
  211.                     col++;
  212.                 }
  213.                 break;
  214.             case 'd':
  215.                 n = parg->p_int;
  216.                 parg++;
  217.                 col += iprintnum(n, 10);
  218.                 break;
  219.             }
  220.         }
  221.     }
  222.     return (col);
  223. }
  224.  
  225. /*
  226.  * Output a message in the lower left corner of the screen
  227.  * and wait for carriage return.
  228.  */
  229.     public void
  230. error(fmt, parg)
  231.     char *fmt;
  232.     PARG *parg;
  233. {
  234.     int c;
  235.     int col = 0;
  236.     static char return_to_continue[] = "  (press RETURN)";
  237.  
  238.     errmsgs++;
  239.  
  240.     if (any_display)
  241.     {
  242.         lower_left();
  243.         clear_eol();
  244.         so_enter();
  245.         col += so_s_width;
  246.     }
  247.  
  248.     col += iprintf(fmt, parg);
  249.  
  250.     if (!any_display)
  251.     {
  252.         putchr('\n');
  253.         return;
  254.     }
  255.  
  256.     putstr(return_to_continue);
  257.     so_exit();
  258.     col += sizeof(return_to_continue) + so_e_width;
  259.  
  260. #if ONLY_RETURN
  261.     while ((c = getchr()) != '\n' && c != '\r')
  262.         bell();
  263. #else
  264.     c = getchr();
  265.     if (c != '\n' && c != '\r' && c != ' ' && c != READ_INTR)
  266.         ungetcc(c);
  267. #endif
  268.     lower_left();
  269.  
  270.     if (col >= sc_width)
  271.         /*
  272.          * Printing the message has probably scrolled the screen.
  273.          * {{ Unless the terminal doesn't have auto margins,
  274.          *    in which case we just hammered on the right margin. }}
  275.          */
  276.         screen_trashed = 1;
  277.  
  278.     flush();
  279. }
  280.  
  281. static char intr_to_abort[] = "... (interrupt to abort)";
  282.  
  283. /*
  284.  * Output a message in the lower left corner of the screen
  285.  * and don't wait for carriage return.
  286.  * Usually used to warn that we are beginning a potentially
  287.  * time-consuming operation.
  288.  */
  289.     public void
  290. ierror(fmt, parg)
  291.     char *fmt;
  292.     PARG *parg;
  293. {
  294.     lower_left();
  295.     clear_eol();
  296.     so_enter();
  297.     (void) iprintf(fmt, parg);
  298.     putstr(intr_to_abort);
  299.     so_exit();
  300.     flush();
  301.     need_clr = 1;
  302. }
  303.  
  304. /*
  305.  * Output a message in the lower left corner of the screen
  306.  * and return a single-character response.
  307.  */
  308.     public int
  309. query(fmt, parg)
  310.     char *fmt;
  311.     PARG *parg;
  312. {
  313.     register int c;
  314.     int col = 0;
  315.  
  316.     if (any_display)
  317.     {
  318.         lower_left();
  319.         clear_eol();
  320.     }
  321.  
  322.     (void) iprintf(fmt, parg);
  323.     c = getchr();
  324.  
  325.     if (!any_display)
  326.     {
  327.         putchr('\n');
  328.         return (c);
  329.     }
  330.  
  331.     lower_left();
  332.     if (col >= sc_width)
  333.         screen_trashed = 1;
  334.     flush();
  335.  
  336.     return (c);
  337. }
  338.