Mercurial > hg > octave-lyh
view src/pager.cc @ 2103:30e2b1c4ffd9
[project @ 1996-04-28 12:19:45 by jwe]
author | jwe |
---|---|
date | Sun, 28 Apr 1996 12:22:22 +0000 |
parents | 8a40a2a677fa |
children | dece5cc39e00 |
line wrap: on
line source
/* Copyright (C) 1996 John W. Eaton This file is part of Octave. Octave is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. Octave is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Octave; see the file COPYING. If not, write to the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #ifdef HAVE_CONFIG_H #include <config.h> #endif #include <csignal> #include <string> #include <fstream.h> #include "oct-term.h" #include "procstream.h" #include "defaults.h" #include "defun.h" #include "error.h" #include "help.h" #include "oct-obj.h" #include "pager.h" #include "sighandlers.h" #include "unwind-prot.h" #include "user-prefs.h" pid_t octave_pager_pid = -1; // Our actual connection to the external pager. static oprocstream *external_pager = 0; // Nonzero means we write to the diary file. static int write_to_diary_file = 0; // The name of the current diary file. static string diary_file; // The diary file. static ofstream external_diary_file; static sig_handler *saved_sigint_handler = 0; static int really_flush_to_pager = 0; static void do_sync (const char *msg, bool bypass_pager) { if (! error_state) { if (msg && *msg) { if (bypass_pager) cout << msg; else { if (! external_pager) { string pgr = user_pref.pager_binary; if (! pgr.empty ()) { saved_sigint_handler = octave_set_signal_handler (SIGINT, SIG_IGN); external_pager = new oprocstream (pgr.c_str ()); if (external_pager) octave_pager_pid = external_pager->pid (); } } if (external_pager) { *external_pager << msg; if (external_pager->fail ()) { octave_pager_pid = -1; delete external_pager; external_pager = 0; if (saved_sigint_handler) { octave_set_signal_handler (SIGINT, saved_sigint_handler); saved_sigint_handler = 0; } } else external_pager->flush (); } else cout << msg; } } } } static bool more_than_a_screenful (const char *s) { if (s) { int available_rows = terminal_rows () - 2; int count = 0; char c; while ((c = *s++) != '\0') if (c == '\n') { count++; if (count > available_rows) return true; } } return false; } int octave_pager_buf::sync (void) { if (really_flush_to_pager || (user_pref.page_screen_output && user_pref.page_output_immediately) || ! user_pref.page_screen_output) { sputc ('\0'); char *buf = eback (); bool bypass_pager = (really_flush_to_pager && user_pref.page_screen_output && ! user_pref.page_output_immediately && ! more_than_a_screenful (buf)); do_sync (buf, bypass_pager); octave_diary << buf; seekoff (0, ios::beg); } return 0; } int octave_diary_buf::sync (void) { sputc ('\0'); if (write_to_diary_file && external_diary_file) external_diary_file << eback (); seekoff (0, ios::beg); return 0; } octave_pager_stream *octave_pager_stream::instance = 0; octave_pager_stream::octave_pager_stream (void) : ostream (), pb (0) { pb = new octave_pager_buf; rdbuf (pb); setf (unitbuf); } octave_pager_stream::~octave_pager_stream (void) { flush (); delete pb; } octave_pager_stream& octave_pager_stream::stream (void) { if (! instance) instance = new octave_pager_stream (); return *instance; } octave_diary_stream *octave_diary_stream::instance = 0; octave_diary_stream::octave_diary_stream (void) : ostream (), db (0) { db = new octave_diary_buf; rdbuf (db); setf (unitbuf); } octave_diary_stream::~octave_diary_stream (void) { flush (); delete db; } octave_diary_stream& octave_diary_stream::stream (void) { if (! instance) instance = new octave_diary_stream (); return *instance; } void flush_octave_stdout (void) { begin_unwind_frame ("flush_octave_stdout"); unwind_protect_int (really_flush_to_pager); really_flush_to_pager = 1; octave_stdout.flush (); if (external_pager) { octave_pager_pid = -1; delete external_pager; external_pager = 0; if (saved_sigint_handler) { octave_set_signal_handler (SIGINT, saved_sigint_handler); saved_sigint_handler = 0; } } run_unwind_frame ("flush_octave_stdout"); } static void close_diary_file (void) { if (external_diary_file.is_open ()) { octave_diary.flush (); external_diary_file.close (); } } static void open_diary_file (void) { close_diary_file (); external_diary_file.open (diary_file.c_str (), ios::app); if (! external_diary_file) error ("diary: can't open diary file `%s'", diary_file.c_str ()); } DEFUN_TEXT (diary, args, , "diary [on|off]\n\ diary [file]\n\ \n\ redirect all input and screen output to a file.") { octave_value_list retval; int argc = args.length () + 1; string_vector argv = args.make_argv ("diary"); if (error_state) return retval; if (diary_file.empty ()) diary_file = "diary"; switch (argc) { case 1: write_to_diary_file = ! write_to_diary_file; open_diary_file (); break; case 2: { string arg = argv[1]; if (arg == "on") { write_to_diary_file = 1; open_diary_file (); } else if (arg == "off") { close_diary_file (); write_to_diary_file = 0; } else { diary_file = arg; open_diary_file (); } } break; default: print_usage ("diary"); break; } return retval; } DEFUN_TEXT (more, args, , "more on\n\ more off\n\ \n\ Turn output pagination on or off.") { octave_value_list retval; int argc = args.length () + 1; string_vector argv = args.make_argv ("more"); if (error_state) return retval; if (argc == 2) { string arg = argv[1]; if (arg == "on") bind_builtin_variable ("page_screen_output", "true"); else if (arg == "off") bind_builtin_variable ("page_screen_output", "false"); else error ("more: unrecognized argument `%s'", arg.c_str ()); } else print_usage ("more"); return retval; } static string default_pager (void) { string pager_binary; char *pgr = getenv ("PAGER"); if (pgr) pager_binary = string (pgr); #ifdef DEFAULT_PAGER else { pager_binary = string (DEFAULT_PAGER); if (pager_binary == "less") { pager_binary.append (" -e"); if (! getenv ("LESS")) pager_binary.append (" -P'-- less ?pB(%pB\\%):--. (f)orward, (b)ack, (q)uit$'"); } } #endif return pager_binary; } void symbols_of_pager (void) { DEFVAR (PAGER, default_pager (), 0, sv_pager_binary, "path to pager binary"); DEFVAR (page_output_immediately, 1.0, 0, page_output_immediately, "if paging output, start sending it as soon as it is available"); DEFVAR (page_screen_output, 1.0, 0, page_screen_output, "if possible, send output intended for the screen through the pager"); } /* ;;; Local Variables: *** ;;; mode: C++ *** ;;; End: *** */