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 >
Wrap
C/C++ Source or Header
|
1996-09-28
|
5KB
|
247 lines
// pager.cc -*- C++ -*-
/*
Copyright (C) 1992, 1993, 1994, 1995 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, 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <signal.h>
#include <iostream.h>
#include <strstream.h>
#include <fstream.h>
#include <stdlib.h>
#include "procstream.h"
#include "sighandlers.h"
#include "user-prefs.h"
#include "oct-obj.h"
#include "error.h"
#include "defun.h"
#include "input.h"
#include "pager.h"
#include "utils.h"
#include "help.h"
// Where we stash output headed for the screen.
static ostrstream *pager_buf = 0;
// Nonzero means we write to the diary file.
static int write_to_diary_file = 0;
// The name of the current diary file.
static char *diary_file = "diary";
// The diary file.
static ofstream diary_stream;
static int
line_count (char *s)
{
int count = 0;
if (s)
{
char c;
while ((c = *s++) != '\0')
if (c == '\n')
count++;
}
return count;
}
// For now, use the variables from readline. It already handles
// SIGWINCH, so these values have a good chance of being correct even
// if the window changes size (they will be wrong if, for example, the
// luser changes the window size while the pager is running, and the
// signal is handled by the pager instead of us.
int
terminal_columns (void)
{
extern int screenwidth;
return screenwidth > 0 ? screenwidth : 80;
}
int
terminal_rows (void)
{
extern int screenheight;
return screenheight > 0 ? screenheight : 24;
}
void
initialize_pager (void)
{
delete pager_buf;
pager_buf = new ostrstream ();
}
void
maybe_page_output (ostrstream& msg_buf)
{
msg_buf << ends;
char *message = msg_buf.str ();
if (interactive
&& user_pref.page_screen_output
&& user_pref.pager_binary)
{
*pager_buf << message;
delete [] message;
}
else
{
cout << message;
cout.flush ();
delete [] message;
}
}
void
flush_output_to_pager (void)
{
// Extract message from buffer, then delete the buffer so that any
// new messages get sent separately.
*pager_buf << ends;
char *message = pager_buf->str ();
initialize_pager ();
if (! message || ! *message)
{
delete [] message;
return;
}
maybe_write_to_diary_file (message);
int nlines = line_count (message);
if (nlines > terminal_rows () - 2)
{
char *pgr = user_pref.pager_binary;
if (pgr)
{
oprocstream pager_stream (pgr);
if (pager_stream)
{
volatile sig_handler *old_sigint_handler;
old_sigint_handler = signal (SIGINT, SIG_IGN);
pager_stream << message;
delete [] message;
pager_stream.flush ();
pager_stream.close ();
signal (SIGINT, old_sigint_handler);
return;
}
}
}
cout << message;
delete [] message;
cout.flush ();
}
static void
open_diary_file (void)
{
if (diary_stream.is_open ())
diary_stream.close ();
diary_stream.open (diary_file, ios::app);
if (! diary_stream)
error ("diary: can't open diary file `%s'", diary_file);
}
void
close_diary_file (void)
{
if (diary_stream)
diary_stream.close ();
}
void
maybe_write_to_diary_file (const char *s)
{
if (write_to_diary_file && diary_stream)
diary_stream << s;
}
DEFUN_TEXT ("diary", Fdiary, Sdiary, -1, 1,
"diary [on|off]\n\
diary [file]\n\
\n\
redirect all input and screen output to a file.")
{
Octave_object retval;
DEFINE_ARGV("diary");
switch (argc)
{
case 1:
write_to_diary_file = ! write_to_diary_file;
open_diary_file ();
break;
case 2:
{
char *arg = argv[1];
if (strcmp (arg, "on") == 0)
{
write_to_diary_file = 1;
open_diary_file ();
}
else if (strcmp (arg, "off") == 0)
write_to_diary_file = 0;
else
{
delete [] diary_file;
diary_file = strsave (arg);
open_diary_file ();
}
}
break;
default:
print_usage ("diary");
break;
}
DELETE_ARGV;
return retval;
}
/*
;;; Local Variables: ***
;;; mode: C++ ***
;;; page-delimiter: "^/\\*" ***
;;; End: ***
*/