home *** CD-ROM | disk | FTP | other *** search
/ Geek Gadgets 1 / ADE-1.bin / ade-dist / octave-1.1.1p1-src.tgz / tar.out / fsf / octave / src / pager.cc < prev    next >
C/C++ Source or Header  |  1996-09-28  |  5KB  |  247 lines

  1. // pager.cc                                               -*- C++ -*-
  2. /*
  3.  
  4. Copyright (C) 1992, 1993, 1994, 1995 John W. Eaton
  5.  
  6. This file is part of Octave.
  7.  
  8. Octave is free software; you can redistribute it and/or modify it
  9. under the terms of the GNU General Public License as published by the
  10. Free Software Foundation; either version 2, or (at your option) any
  11. later version.
  12.  
  13. Octave is distributed in the hope that it will be useful, but WITHOUT
  14. ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  15. FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  16. for more details.
  17.  
  18. You should have received a copy of the GNU General Public License
  19. along with Octave; see the file COPYING.  If not, write to the Free
  20. Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
  21.  
  22. */
  23.  
  24. #ifdef HAVE_CONFIG_H
  25. #include "config.h"
  26. #endif
  27.  
  28. #include <signal.h>
  29. #include <iostream.h>
  30. #include <strstream.h>
  31. #include <fstream.h>
  32. #include <stdlib.h>
  33.  
  34. #include "procstream.h"
  35.  
  36. #include "sighandlers.h"
  37. #include "user-prefs.h"
  38. #include "oct-obj.h"
  39. #include "error.h"
  40. #include "defun.h"
  41. #include "input.h"
  42. #include "pager.h"
  43. #include "utils.h"
  44. #include "help.h"
  45.  
  46. // Where we stash output headed for the screen.
  47. static ostrstream *pager_buf = 0;
  48.  
  49. // Nonzero means we write to the diary file.
  50. static int write_to_diary_file = 0;
  51.  
  52. // The name of the current diary file.
  53. static char *diary_file = "diary";
  54.  
  55. // The diary file.
  56. static ofstream diary_stream;
  57.  
  58. static int
  59. line_count (char *s)
  60. {
  61.   int count = 0;
  62.   if (s)
  63.     {
  64.       char c;
  65.       while ((c = *s++) != '\0')
  66.     if (c == '\n')
  67.       count++;
  68.     }
  69.   return count;
  70. }
  71.  
  72. // For now, use the variables from readline.  It already handles
  73. // SIGWINCH, so these values have a good chance of being correct even
  74. // if the window changes size (they will be wrong if, for example, the
  75. // luser changes the window size while the pager is running, and the
  76. // signal is handled by the pager instead of us.
  77.  
  78. int
  79. terminal_columns (void)
  80. {
  81.   extern int screenwidth;
  82.   return screenwidth > 0 ? screenwidth : 80;
  83. }
  84.  
  85. int
  86. terminal_rows (void)
  87. {
  88.   extern int screenheight;
  89.   return screenheight > 0 ? screenheight : 24;
  90. }
  91.  
  92. void
  93. initialize_pager (void)
  94. {
  95.   delete pager_buf;
  96.   pager_buf = new ostrstream ();
  97. }
  98.  
  99. void
  100. maybe_page_output (ostrstream& msg_buf)
  101. {
  102.   msg_buf << ends;
  103.  
  104.   char *message = msg_buf.str ();
  105.  
  106.   if (interactive
  107.       && user_pref.page_screen_output
  108.       && user_pref.pager_binary)
  109.     {
  110.       *pager_buf << message;
  111.       delete [] message;
  112.     }
  113.   else
  114.     {
  115.       cout << message;
  116.       cout.flush ();
  117.       delete [] message;
  118.     }
  119. }
  120.  
  121. void
  122. flush_output_to_pager (void)
  123. {
  124.  // Extract message from buffer, then delete the buffer so that any
  125.  // new messages get sent separately.
  126.  
  127.   *pager_buf << ends;
  128.   char *message = pager_buf->str ();
  129.   initialize_pager ();
  130.  
  131.   if (! message || ! *message)
  132.     {
  133.       delete [] message;
  134.       return;
  135.     }
  136.  
  137.   maybe_write_to_diary_file (message);
  138.  
  139.   int nlines = line_count (message);
  140.  
  141.   if (nlines > terminal_rows () - 2)
  142.     {
  143.       char *pgr = user_pref.pager_binary;
  144.       if (pgr)
  145.     {
  146.       oprocstream pager_stream (pgr);
  147.       if (pager_stream)
  148.         {
  149.           volatile sig_handler *old_sigint_handler;
  150.           old_sigint_handler = signal (SIGINT, SIG_IGN);
  151.  
  152.           pager_stream << message;
  153.           delete [] message;
  154.           pager_stream.flush ();
  155.           pager_stream.close ();
  156.  
  157.           signal (SIGINT, old_sigint_handler);
  158.  
  159.           return;
  160.         }
  161.     }
  162.     }
  163.  
  164.   cout << message;
  165.   delete [] message;
  166.   cout.flush ();
  167. }
  168.  
  169. static void
  170. open_diary_file (void)
  171. {
  172.   if (diary_stream.is_open ())
  173.     diary_stream.close ();
  174.  
  175.   diary_stream.open (diary_file, ios::app);
  176.  
  177.   if (! diary_stream)
  178.     error ("diary: can't open diary file `%s'", diary_file);
  179. }
  180.  
  181. void
  182. close_diary_file (void)
  183. {
  184.   if (diary_stream)
  185.     diary_stream.close ();
  186. }
  187.  
  188. void
  189. maybe_write_to_diary_file (const char *s)
  190. {
  191.   if (write_to_diary_file && diary_stream)
  192.     diary_stream << s;
  193. }
  194.  
  195. DEFUN_TEXT ("diary", Fdiary, Sdiary, -1, 1,
  196.   "diary [on|off]\n\
  197. diary [file]\n\
  198. \n\
  199. redirect all input and screen output to a file.")
  200. {
  201.   Octave_object retval;
  202.  
  203.   DEFINE_ARGV("diary");
  204.  
  205.   switch (argc)
  206.     {
  207.     case 1:
  208.       write_to_diary_file = ! write_to_diary_file;
  209.       open_diary_file ();
  210.       break;
  211.  
  212.     case 2:
  213.       {
  214.     char *arg = argv[1];
  215.     if (strcmp (arg, "on") == 0)
  216.       {
  217.         write_to_diary_file = 1;
  218.         open_diary_file ();
  219.       }    
  220.     else if (strcmp (arg, "off") == 0)
  221.       write_to_diary_file = 0;
  222.     else
  223.       {
  224.         delete [] diary_file;
  225.         diary_file = strsave (arg);
  226.         open_diary_file ();
  227.       }
  228.       }
  229.       break;
  230.  
  231.     default:
  232.       print_usage ("diary");
  233.       break;
  234.     }
  235.  
  236.   DELETE_ARGV;
  237.  
  238.   return retval;
  239. }
  240.  
  241. /*
  242. ;;; Local Variables: ***
  243. ;;; mode: C++ ***
  244. ;;; page-delimiter: "^/\\*" ***
  245. ;;; End: ***
  246. */
  247.