[comp.unix.xenix] Monitor source Part 4 of 9

jct@jct.UUCP (jct) (07/11/89)

#! /bin/sh
# This is a shell archive.  Remove anything before this line, then unpack
# it by saving it into a file and typing "sh file".  To overwrite existing
# files, type "sh file -c".  You can also feed this as standard input via
# unshar, or by typing "sh <file", e.g..  If this archive is complete, you
# will see the following message at the end:
#		"End of archive 4 (of 9)."
# Contents:  include/km/scrio.h lib/rdspec.c lib/scrout5.c
# Wrapped by jct@ on Mon Jul 10 22:48:15 1989
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f 'include/km/scrio.h' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'include/km/scrio.h'\"
else
echo shar: Extracting \"'include/km/scrio.h'\" \(8592 characters\)
sed "s/^X//" >'include/km/scrio.h' <<'END_OF_FILE'
X/* Include file for screen io */
X
X/*
X*/
X
X/*
X   Created May 5, 1987 by JCT
X*/
X
X#include <km/termcap.h>
X
X#define TAB_STOP	8
X
X/*
X   The following are flags for directory operations
X*/
X
X#define ALL_FILES	0x00
X#define NO_DIR		0x01
X#define ONLY_DIR	0x02
X#define NO_PERIOD	0x04
X
X/*
X   The following are window flags, 16 bits available
X*/
X
X#define BOX_FLAG	0x0001
X#define SCROLL_FLAG	0x0002
X#define FLUSH_FLAG	0x0004
X#define CLEAR_FLAG	0x0008
X#define LEAVE_FLAG	0x0010
X#define NO_CHANGE	0x0020
X#define FULLWINDOW	0x0040
X#define TSTCLRTOEOL	0x0080
X#define SET_COLOR	0x0100
X
X/*
X   The following are color flags, 8 bits available
X*/
X
X#define BLACK		0x0000
X#define RED		0x0001
X#define GREEN		0x0002
X#define YELLOW		0x0003
X#define BLUE		0x0004
X#define MAGENTA		0x0005
X#define CYAN 		0x0006
X#define WHITE		0x0007
X#define COLOR_8		0x0008
X#define COLOR_9 	0x0009
X#define COLOR_10	0x000a
X#define COLOR_11	0x000b
X#define COLOR_12	0x000c
X#define COLOR_13	0x000d
X#define COLOR_14	0x000e
X#define COLOR_15	0x000f
X
X/*
X   The following are character attribute flags, 8 bits available
X*/
X
X#define NORMAL		0x0000
X#define STANDOUT	0x0001
X#define BLINK		0x0002
X#define BOLD		0x0004
X#define UNDERLINE	0x0008
X#define GRAPHIC		0x0010
X
X/*
X   The following are character flags, 8 bits available
X*/
X
X#define REVERSED_COLOR	0x0001
X
X/*
X   The following are chars to represent the graphic line drawing set
X   The GRAPHIC bit should be turned on for each char as well
X*/
X
X#define G_H		'A'
X#define G_V		'B'
X#define G_C		'C'
X#define G_UL		'D'
X#define G_DT		'E'
X#define G_UR		'F'
X#define G_LT		'G'
X#define G_LR		'H'
X#define G_UT		'I'
X#define G_LL		'J'
X#define G_RT		'K'
X
X/*
X   Flags for cpwin()
X*/
X
X#define CW_NOBLANK	0x01
X#define CW_WRAP		0x02
X#define CW_JOIN		0x04
X
typedef struct
X  {
X    int  ch;
X    int  insert;
X    char *str;
X    char *curr;
X    char *end;
X  } IN_STAT;
X
typedef struct
X  {
X    char ch;
X    char color;
X    char attrib;
X    char ch_flags;
X  } YX_ELEMENT;
X
typedef struct win_struct
X  {
X    short 	      y_org, x_org;
X    short 	      y_max, x_max;
X    short 	      y_cur, x_cur;
X    YX_ELEMENT	      *ch_cur;
X    YX_ELEMENT        *ch_first;
X    YX_ELEMENT	      *ch_last;
X    YX_ELEMENT	      *buf;
X    short 	      buf_len;
X    short 	      flags;
X    short	      color;
X    short	      attrib;
X    short             ch_flags;
X    struct win_struct *prev, *next;
X  } WINDOW;
X
X#define WIN_NULL (WINDOW*)NULL
X
X/*
X   General public data
X*/
X
extern int     LINES, COLS;
extern int     have_standout, have_blink, have_underline, have_bold;
extern int     have_color, have_graphic, rev_color;
extern int     def_fg, def_bg;
extern WINDOW  *stdscr, *curscr;
extern char    *scr_hf, *scr_hs;
extern int     scr_key_curr, scr_esc_enable, scr_print_enable;
extern int     key_tbl_index;
X#ifdef UNIX
extern KEY_TBL key_tbl[];
X#endif
X
extern int    box();
extern int    mvwin();
extern int    cpwin();
extern int    delwin();
extern int    endwin();
extern WINDOW *initscr();
extern char   *longname();
extern int    mvcur();
extern WINDOW *newwin();
extern int    printw();
extern int    scroll();
extern int    setterm();
extern WINDOW *superwin();
extern WINDOW *subwin();
extern int    touchwin();
extern int    waddch();
extern int    waddstr();
extern int    waddtext();
extern int    wclear();
extern int    wclrtobot();
extern int    wclrtoeol();
extern int    wdelch();
extern int    wdeleteln();
extern int    werase();
extern int    winch();
extern int    winsch();
extern int    winsertln();
extern int    wmove();
extern int    wprintw();
extern int    wrefresh();
extern int    wstandend();
extern int    wstandout();
extern int    keypad();
extern int    keypadend();
extern int    winattrib();
extern int    wincolor();
extern int    wendattrib();
extern int    wclrattrib();
extern int    wsetattrib();
extern int    waddattrib();
extern int    fg_bits();
extern int    bg_bits();
extern int    wsetcolor();
extern int    waddgraphic();
extern int    draw_box();
extern int    unbox();
extern int    tgetchar();
extern char   *getcap();
extern char   *tgetstr();
extern char   *tgoto();
extern int    tgetint();
extern int    tgetnum();
extern int    tgetflag();
extern void   tputs();
extern int    sdo_help();
extern int    wdo_help();
extern char   *dir_pick();
extern int    wget_scr();
extern int    get_color();
extern int    wgetch();
extern int    get_key();
extern int    unget_key();
extern char   *wget_input();
extern char   *wget_str();
extern int    wget_int();
X#ifdef MMAPPED
extern void   ini_mmscr();
extern void   put_mmscr();
extern void   pos_mmscr();
X#endif
X
X#define getch()			(wgetch(stdscr))
X#define getstr(s)		(wgetstr(stdscr,s))
X#define addch(c)	        (waddch(stdscr,c))
X#define addstr(s)		(waddstr(stdscr,s))
X#define addtext(s)		(waddtext(stdscr,s))
X#define clear()			(wclear(stdscr))
X#define clrtobot()		(wclrtobot(stdscr))
X#define clrtoeol()		(wclrtoeol(stdscr))
X#define delch()			(wdelch(stdscr))
X#define deleteln()		(wdeleteln(stdscr))
X#define erase()			(werase(stdscr))
X#define inch()			(winch(stdscr))
X#define insch(c)		(winsch(stdscr,c))
X#define insertln()		(winsertln(stdscr))
X#define move(y,x)		(wmove(stdscr,y,x))
X#define refresh()		(wrefresh(stdscr))
X#define standend()		(wstandend(stdscr))
X#define standout()		(wstandout(stdscr))
X#define inattrib()		(winattrib(stdscr))
X#define incolor()		(wincolor(stdscr))
X#define endattrib()		(wendattrib(stdscr))
X#define clrattrib(a)		(wclrattrib(stdscr,a))
X#define setattrib(a)		(wsetattrib(stdscr,a))
X#define addattrib(a)		(waddattrib(stdscr,a))
X#define setcolor(f,b)		(wsetcolor(stdscr,f,b))
X#define addgraphic(c)		(waddgraphic(stdscr,c))
X#define get_scr(f,s)		(wget_scr(stdscr,f,s))
X#define overlay(w1,w2)		(cpwin(w1,w2,CW_NOBLANK))
X#define overwrite(w1,w2)	(cpwin(w1,w2,0))
X#define get_str(p,n,h)          (wget_str(stdscr,p,n,h))
X
X#define	mvwaddch(win,y,x,c)	(wmove(win,y,x) == FALSE ? FALSE : waddch(win,c))
X#define	mvwgetch(win,y,x)	(wmove(win,y,x) == FALSE ? FALSE : wgetch(win))
X#define	mvwaddstr(win,y,x,s)	(wmove(win,y,x) == FALSE ? FALSE : waddstr(win,s))
X#define mvwgetstr(win,y,x,s)  	(wmove(win,y,x) == FALSE ? FALSE : wgetstr(win,s))
X#define	mvwinch(win,y,x)	(wmove(win,y,x) == FALSE ? FALSE : winch(win))
X#define	mvwdelch(win,y,x)	(wmove(win,y,x) == FALSE ? FALSE : wdelch(win))
X#define	mvwinsch(win,y,x,c)	(wmove(win,y,x) == FALSE ? FALSE : winsch(win,c))
X#define	mvaddch(y,x,c)		mvwaddch(stdscr,y,x,c)
X#define	mvgetch(y,x)		mvwgetch(stdscr,y,x)
X#define	mvaddstr(y,x,s)		mvwaddstr(stdscr,y,x,s)
X#define mvgetstr(y,x,s)		mvwgetstr(stdscr,y,x,s)
X#define	mvinch(y,x)		mvwinch(stdscr,y,x)
X#define	mvdelch(y,x)		mvwdelch(stdscr,y,x)
X#define	mvinsch(y,x,c)		mvwinsch(stdscr,y,x,c)
X
X#define	clearok(win,bf)  (bf ? (win->flags |= CLEAR_FLAG) : (win->flags &= ~CLEAR_FLAG))
X#define	leaveok(win,bf)  (bf ? (win->flags |= LEAVE_FLAG) : (win->flags &= ~LEAVE_FLAG))
X#define	scrollok(win,bf) (bf ? (win->flags |= SCROLL_FLAG) : (win->flags &= ~SCROLL_FLAG))
X#define flushok(win,bf)	 (bf ? (win->flags |= FLUSH_FLAG) : (win->flags &= ~FLUSH_FLAG))
X#define	getyx(win,y,x)	 y = win->y_cur, x = win->x_cur
X
X#ifdef UNIX
X
X#define raw()      (_tty.c_cc[VMIN] = 1, _tty.c_cc[VTIME] = 0, _tty.c_oflag &= ~OPOST, _tty.c_lflag &= ~(ICANON | ISIG), ioctl(_tty_ch, TCSETAW, &_tty))
X#define noraw()    (_tty.c_cc[VEOF] = CEOF, _tty.c_cc[VEOL] = CNUL, _tty.c_oflag |= OPOST, _tty.c_lflag |= (ICANON | ISIG), ioctl(_tty_ch, TCSETAW, &_tty))
X#define crmode()   (_tty.c_cc[VMIN] = 1, _tty.c_cc[VTIME] = 0, _tty.c_lflag &= ~ICANON, ioctl(_tty_ch, TCSETAW, &_tty))
X#define nocrmode() (_tty.c_cc[VEOF] = CEOF, _tty.c_cc[VEOL] = CNUL, _tty.c_lflag |= ICANON, ioctl(_tty_ch, TCSETAW, &_tty))
X#define echo()     (_tty.c_lflag |= ECHO, ioctl(_tty_ch, TCSETAW, &_tty))
X#define noecho()   (_tty.c_lflag &= ~ECHO, ioctl(_tty_ch, TCSETAW, &_tty))
X#define nl()       (_tty.c_iflag |= ICRNL, _tty.c_oflag |= (ONLCR | OCRNL), ioctl(_tty_ch, TCSETAW, &_tty))
X#define nonl()     (_tty.c_iflag &= ~ICRNL, _tty.c_oflag &= ~(ONLCR | OCRNL), ioctl(_tty_ch, TCSETAW, &_tty))
X#define savetty()  (ioctl(_tty_ch, TCGETA, &_tty), _stty = _tty)
X#define resetty()  (_tty = _stty, ioctl(_tty_ch, TCSETAW, &_tty))
X
X#else
X
X#define TC_RAW		0x0001
X#define TC_CRMODE	0x0002
X#define TC_ECHO		0x0004
X#define TC_NL		0x0008
X
X#define raw()		(_tty |= TC_RAW)
X#define noraw()		(_tty &= ~TC_RAW)
X#define crmode()	(_tty |= TC_CRMODE)
X#define nocrmode()	(_tty &= ~TC_CRMODE)
X#define echo()		(_tty |= TC_ECHO)
X#define noecho()	(_tty &= ~TC_ECHO)
X#define nl()		(_tty |= TC_NL)
X#define nonl()		(_tty &= ~TC_NL)
X#define savetty()	(_stty = _tty)
X#define resetty()	(_tty = _stty)
X
X#endif
END_OF_FILE
if test 8592 -ne `wc -c <'include/km/scrio.h'`; then
    echo shar: \"'include/km/scrio.h'\" unpacked with wrong size!
fi
# end of 'include/km/scrio.h'
fi
if test -f 'lib/rdspec.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'lib/rdspec.c'\"
else
echo shar: Extracting \"'lib/rdspec.c'\" \(16010 characters\)
sed "s/^X//" >'lib/rdspec.c' <<'END_OF_FILE'
X/* Read file tokens */
X
X/*
X   This module provides a set of functions to read a line oriented
X   specification data file. These functions may be used as is or to create
X   higher level tools.
X*/
X
X/*
X   Created August 1, 1986 by JCT
X
X   March 3, 1987 JCT : Modified to no longer ignore '_' in get_sstr()
X   changed \b to \s for space (blank) characters. \b is the C convention
X   for backspace.
X
X   March 29, 1987 JCT : Modified to add rs_line_mode boolean. If FALSE, on
X   eol condition a space is returned and a new line is automatically read.
X   If FALSE, it works as before, a \0 is returned and the user must read
X   a new line. Defaults on startup to TRUE.
X
X   June 15, 1987 JCT : Changed comment character from ";" to eol, to regular C
X   language comments.
X
X   August 20, 1987 JCT : Made ";" a string spec delimiter unless escaped.
X   Also, changed get_sspec so that the pointer returned is only valid until the
X   next get_sspec, it used to be valid until the next get_lspec. This makes
X   some things inconvient but is more reliable since rs_line_mode may be false.
X   Finally, added rs_raw_mode, which is FALSE by default, that when TRUE
X   prevents conversion of tabs to spaces, striping of leading and trailing
X   blanks and printable char check in get_sline();
X*/
X
X/*
X *	Copyright (c) John C. Tompkins 1989
X *	All rights reserved.
X *
X *	Permission is granted to use this for any personal, noncommercial use.
X *	You may not distribute source or executable code for profit, nor
X *	may you distribute it with a commercial product without the prior
X *      written consent of the author.  Please send modifications to the 
X *      author for inclusion in updates to the program.
X */
X
X#include <stdio.h>
X#include <ctype.h>
X
X#include <km/ascii.h>
X#include <km/defs.h>
X#include <km/rdspec.h>
X
X#define MAX_COUNT 150		/* maximum spec line size, also spec string */
X
static int  line_cnt, line_index, line_len; 
static int  sstr_cnt, sstr_max, sstr_case;
static int  get_new_line = FALSE;
static FILE *fd;
static char sstr[MAX_COUNT], line_spec[MAX_COUNT], *sstr_ptr;
X
char   cspec, *sspec, *lspec, *espec;
double fspec;
long   lispec, dspec, tspec;
int    ispec, rs_abort, rs_eol, rs_eof, rs_errs, rs_stdin, rs_rd_decimal;
int    rs_raw_mode = FALSE;
int    rs_line_mode = TRUE;		/* TRUE, user application must call */
X					/* get_lspec(), else its automatic */
X
int sline_cnt()
X{
X  return(line_cnt);
X}
X
int sline_index()
X{
X  return(line_index);
X}
X
int get_sline(line, max)
X  char line[];
X  int  max;
X{
X
X/*
X   Reads a specification line into a standard line buffer, all subsequent
X   reads are from this line buffer. All leading and trailing blanks are
X   ignored. Tab characters are converted into spaces on a one for one basis.
X   The standatd C comment sequence is used to open and close comments. The 
X   beginning and ending sequences for comments must each be on a single line.
X   All information in a comment is ignored. Nesting of comments is not allowed.
X   The comment start and stop sequence may be escaped by "\\".
X   Any non-visible characters, other than tabs, are ignored.
X*/
X
X  int character, temp;
X  int done = FALSE, started = FALSE;
X  static int have_comment = FALSE;
X
X  if (rs_abort)
X    return(FALSE);
X  lspec = line;
X  line_len = 0;
X  while (((character = getc(fd)) != '\n') &&
X	 !(rs_eof = (character == EOF)) &&
X	 !done &&
X	 (line_len < (max - 2)))
X    {
X      if (!have_comment)
X        {
X          if (character == '\\')
X	    {
X	      if (((character = getc(fd)) != '\n') && (character != EOF))
X	        {
X	          switch (tolower(character))
X		    {
X		      case '/' :
X		        line[line_len++] = '/';
X			started = TRUE;
X			break;
X		      default :
X			line[line_len++] = '\\';
X		  	if ((line_len < (max - 2)) && (rs_raw_mode || isprint(character)))
X			  line[line_len++] = character;
X			started = TRUE;
X			break;
X		    }
X	        }
X	      else
X		line[line_len++] = '\\';
X	      started = TRUE;
X	    }
X          else
X	    {
X	      switch (character)
X		{
X                  case '/' :
X		    if ((temp = getc(fd)) == '*')
X		      {
X			done = TRUE;
X			have_comment = TRUE;
X		      }
X		    else
X		      {
X			ungetc(temp, fd);
X			line[line_len++] = character;
X			started = TRUE;
X		      }
X		    break;
X	          case '\t' :
X		    if (!rs_raw_mode)
X		      character = ' ';		/* fall thru to space case */
X	          case ' ' :
X		    if (!rs_raw_mode && !started)
X		      break;
X	          default :
X		    if (rs_raw_mode || isprint(character))
X                      line[line_len++] = character;
X	            started = TRUE;
X		    break;
X	        }
X	    }
X	}
X      else					/* in comment */
X	{
X	  if (character == '\\')		/* escape close comment? */
X	    {
X	      if ((temp = getc(fd)) == '*')
X	        ;
X	      else
X		ungetc(temp, fd);
X	    }
X	  if (character == '*')
X	    {
X	      if ((temp = getc(fd)) == '/')
X	        have_comment = FALSE;
X	      else
X		ungetc(temp, fd);
X	    }
X	}
X    }
X  line[line_len] = '\0';
X  if (!rs_raw_mode)
X    {
X      while ((line_len > 0) && (line[line_len - 1] == ' '))
X        line[--line_len] = '\0';
X    }
X  line_cnt++;
X  line_index = 0;
X  rs_eol = (line_len == 0);
X  get_new_line = FALSE;
X  return(line_len > 0);
X}
X
int get_lspec()
X{
X
X/*
X   Reads a line at the default lspec buffer
X*/
X
X  if (rs_abort)
X    return(FALSE);
X  while (!rs_abort && !get_sline(line_spec, sizeof(line_spec)) && !rs_eof)
X    ;
X  return(line_len > 0);
X}
X
int get_schar(character)
X  char *character;
X{
X
X/*
X   Gets a single character from the line buffer, stores it where the
X   passed pointer tells it and advances the line buffer position. 
X   Returns TRUE if got a character, FALSE if at the end of the
X   buffer line. Sets the rs_eol variable as required.
X
X   If rs_line_mode is FALSE, then on eol condition, a new line is
X   automatically read and characters returned from that line. The eol of
X   the current line returns as a space and rs_eol is set TRUE. If at eof,
X   then 0 is returned and no new line read is attempted.
X*/
X
X  if (rs_abort)
X    return(FALSE);
X  if (line_index < line_len)
X    {
X      *character = lspec[line_index++];
X      return(TRUE);
X    }
X  else
X    {
X      if (rs_line_mode)			/* as before */
X	{
X          *character = '\0';
X          rs_eol = TRUE;
X          return(FALSE);
X        }
X      else				/* auto read line mode */
X	{
X	  if (get_new_line)
X	    {
X	      if (get_lspec())		/* get_lspec() sets rs_eol */
X		{
X		  *character = lspec[line_index++];
X		  return(TRUE);
X		}
X	      else
X		{
X		  *character = '\0';
X		  return(FALSE);
X		}
X	    }
X	  else
X	    {
X	      rs_eol = TRUE;
X	      if (!rs_eof)
X		{
X		  if (line_len > 0)	/* already read a line? */
X		    {
X	              get_new_line = TRUE;	/* next time around */
X	              *character = ' ';	/* return blank for eol */
X	              return(TRUE);
X		    }
X		  else			/* must be beginning of file */
X		    {			/* so skip returning a blank */
X	      	      if (get_lspec())	/* get_lspec() sets rs_eol */
X		        {
X		          *character = lspec[line_index++];
X		          return(TRUE);
X		        }
X	              else
X		        {
X		          *character = '\0';
X		          return(FALSE);
X		        }
X		    }
X		}
X	      else
X		{
X		  *character = '\0';	/* return 0 on eof */
X		  return(FALSE);
X		}
X	    }
X	}
X    }
X}
X
int put_schar()
X{
X
X/*
X   Backs up the line buffer position in order to re-read characters
X   NOTE: Even if rs_line_mode is FALSE, it will NOT backup chars before
X   current line.
X*/
X
X  if (rs_abort)
X    return(FALSE);
X  if (line_index > 0)
X    {
X      if (--line_index < line_len)
X	rs_eol = FALSE;
X      return(TRUE);
X    }
X  else
X    return(FALSE);
X}
X
int get_rspec()
X{
X
X/*
X   Reads a "raw" character and stores it in the standard character 
X   specification buffer, cspec. Does no interpretation on the character.
X*/
X
X  if (rs_abort)
X    return(FALSE);
X  return(get_schar(&cspec));
X}
X
int put_rspec()
X{
X
X/*
X   Backs up one "raw" character in the specification line
X   NOTE: Even if rs_line_mode is FALSE, it will NOT backup chars before
X   current line.
X*/
X
X  if (rs_abort)
X    return(FALSE);
X  return(put_schar());
X}
X
int get_cspec()
X{
X
X/*
X   Reads one "interpreted" character into cspec. The "^" character signifies
X   that the next character is the equivilent control character, thus "^j" is
X   a single linefeed character. The "^" may be escaped by "\", "\e" is
X   interpretted as an escape character, "\d" is delete, "\s" is a space and
X   "\\" is a single "\".
X*/
X
X  char character;
X
X  if (rs_abort)
X    return(FALSE);
X  cspec = '\0';
X  if (get_schar(&character))
X    {
X      if (character == '\\')
X        {
X	  if (get_schar(&character))
X	    {
X	      switch (tolower(character))
X	        {
X	          case 'e' :
X		    cspec = ESC;
X		    break;
X	          case 'd' :
X		    cspec = DEL;
X		    break;
X	          case 's' :
X		    cspec = ' ';
X		    break;
X	          case 'n' :
X		    cspec = LF;
X		    break;
X	          case 'r' :
X		    cspec = CR;
X		    break;
X	          case 'b' :
X		    cspec = BS;
X		    break;
X	          case 't' :
X		    cspec = HT;
X		    break;
X	          case '\\' :
X		    cspec = '\\';
X		    break;
X	          case '^' :
X		    cspec = '^';
X		    break;
X	          default :
X		    cspec = '\\';
X		    put_schar();
X		    break;
X		}
X            }
X          else
X	    cspec = '\\';
X        }
X      else if (character == '^')
X        {
X          if (get_schar(&character))
X	    {
X	      if (((character = toupper(character)) >= '@') &&
X		  (character <= '_'))
X                cspec = character - 0x40;
X	      else
X		{
X		  cspec = '^';
X		  put_schar();
X		}
X	    }
X          else
X            cspec = '^';
X        }
X      else
X        cspec = character;
X      return(TRUE);
X    }
X  else
X    return(FALSE);
X}
X
int put_cspec()
X{
X
X/*
X   Backs up one "interpreted" character in the specification line
X   NOTE: Even if rs_line_mode is FALSE, it will NOT backup chars before
X   current line.
X*/
X
X  if (rs_abort)
X    return(FALSE);
X  if (((cspec >= 0x00) && (cspec <= 0x1f)) || (cspec == DEL) || (cspec == '^'))
X    return(put_schar() && put_schar());
X  else if (cspec == ' ')
X    {
X      put_rspec();
X      get_rspec();
X      if (cspec == ' ')
X        return(put_schar());
X      else
X	return(put_schar() && put_schar());
X    }
X  else if (cspec == '\\')
X    {
X      put_rspec();
X      get_rspec();
X      if (cspec == '\\')
X        return(put_schar());
X      else
X	return(put_schar() && put_schar());
X    }
X  else
X    return(put_schar());
X}
X
int eat_sspc()
X{
X
X/*
X   Reads space characters until non-space found, then backs up to
X   re-read that non-space character.
X*/
X
X  if (rs_abort)
X    return(FALSE);
X  while (get_cspec() && (cspec == ' '))
X    ;
X  if (cspec)
X    put_cspec();
X  return(cspec != '\0');
X}
X
int get_sspc()
X{
X
X/*
X   Reads non-space characters until a space is found, then backs up to
X   re-read that space character.
X*/
X
X  if (rs_abort)
X    return(FALSE);
X  while (get_cspec() && (cspec != ' '))
X    ;
X  if (cspec)
X    put_cspec();
X  return(cspec == ' ');
X}
X
int test_number()
X{
X
X/*
X   Reads to the firsts non-space character, tests to see if it is numeric
X   and backs up so that character can be re-read.
X*/
X
X  int temp1, temp2;
X
X  if (rs_abort)
X    return(FALSE);
X  eat_sspc();
X  get_cspec();
X  temp1 = cspec;
X  if ((temp1 == '-') || (temp1 == '+'))
X    {
X      get_cspec();
X      temp2 = cspec;
X      put_cspec();
X      cspec = temp1;
X      put_cspec();
X      return(isdigit(temp2));
X    }
X  put_cspec();
X  return(isdigit(temp1));
X}
X
int get_sint(intp)
X  int *intp;
X{
X
X/*
X   Reads until character is not valid numeric for current base. Default 
X   is base 10, 0x lead-in is base 16, 0b is base 2, 0 lead-in is base 8.
X   Leading negative sign is valid for base 10 numbers.
X*/
X
X  int started = FALSE, value = 0, neg = FALSE;
X
X  if (rs_abort)
X    return(FALSE);
X  eat_sspc();
X  get_cspec();
X  if ((cspec == '0') && !rs_rd_decimal)
X    {
X      started = TRUE;
X      if (cspec == '0')
X	{
X	  if (get_cspec())
X	    {
X	      switch (tolower(cspec))
X	        {
X	          case 'x' :
X		    while (get_cspec() && isxdigit(cspec))
X	  	      {
X		        if (isdigit(cspec))
X		          value = (value * 16) + cspec - '0';
X		        else
X		          value = (value * 16) + toupper(cspec) - '0' - 'A' + '9' + 1;
X		      }
X		    break;
X	          case 'b' :
X		    while (get_cspec() && ((cspec >= '0') && (cspec <= '1')))
X		      value = (value * 2) + cspec - '0';
X		    break;
X	          default :
X		    while ((cspec >= '0') && (cspec <= '7'))
X		      {
X		        value = (value * 8) + cspec - '0';
X			get_cspec();
X		      }
X		    break;
X		}
X	    }
X	}
X    }
X  else
X    {
X      if (cspec == '-')
X        {
X          neg = TRUE;
X	  get_cspec();
X	}
X      else if (cspec == '+')
X	get_cspec();
X      while (isdigit(cspec))
X        {
X	  value = (value * 10) + cspec - '0';
X	  started = TRUE;
X	  get_cspec();
X	}
X      if (neg)
X	value = -value;
X    }
X  *intp = value;
X  return(started);
X}
X
int get_ispec()
X{
X
X/*
X   Reads an integer into the standard integer buffer, ispec.
X*/
X
X  return(get_sint(&ispec));
X}
X
static int store_sstr(character)
X  int  character;
X{
X  if (sstr_cnt < sstr_max)
X    {
X      switch (sstr_case)
X        {
X	  case LOWER_CASE :
X	    sstr_ptr[sstr_cnt++] = tolower(character);
X	    break;
X	  case UPPER_CASE :
X	    sstr_ptr[sstr_cnt++] = toupper(character);
X	    break;
X	  default :
X	    sstr_ptr[sstr_cnt++] = character;
X	    break;
X        }
X      return(TRUE);
X    }
X  else
X    return(FALSE);
X}
X
int get_sstr(strp, max, what_case)
X  char *strp;
X  int  max;
X  int  what_case;
X{
X
X/*
X   Reads into a string buffer of specified maximum size with optional
X   case conversion. Strings are normally terminated by blanks. Spaces can be 
X   escaped by a leading "\" character. A """ character can also be used to 
X   enclose a string without blank termination, the next " terminates the string.
X   The """ can be escaped by "\". An unquoted and unescaped ";" will also
X   terminate the string.
X*/
X
X  int done = FALSE, started = FALSE, in_quote = FALSE;
X
X  if (rs_abort)
X    return(FALSE);
X  sstr_ptr = strp;
X  sstr_max = max - 2;
X  sstr_case = what_case;
X  sstr_cnt = 0;
X  eat_sspc();
X  while (!done && get_cspec())
X    {
X      if (cspec == '\\')
X	{
X	  if (get_cspec())
X	    {
X	      switch (cspec)
X		{
X		  case ' ' :
X		  case '"' :
X		  case ';' :
X		    done = !store_sstr(cspec);
X		    break;
X		  default :
X		    store_sstr('\\');
X		    done = !store_sstr(cspec);
X		    break;
X		}
X	    }
X	  else
X	    {
X	      store_sstr('\\');
X	      done = TRUE;
X	    }
X  	  started = TRUE;
X	}
X      else if (cspec == '"')
X        {
X	  if (in_quote)
X	    {
X	      done = TRUE;
X	      in_quote = FALSE;
X	    }
X	  else if (!started)
X	    in_quote = TRUE;
X	  else
X	    done = !store_sstr(cspec);
X	  started = TRUE;
X	}
X      else if (((cspec == ' ') || (cspec == ';')) && !in_quote)
X	done = TRUE;
X      else
X        {
X	  done = !store_sstr(cspec);
X          started = TRUE;
X        }
X    }
X  sstr_ptr[sstr_cnt] = '\0';
X  return(started);
X}
X
int get_sspec()
X{
X
X/*
X   Stores a string at the default sspec pointer. 
X*/
X
X  sspec = sstr;
X  return(get_sstr(sstr, sizeof(sstr), NONE));
X}
X
static void rs_reset_var()
X{
X  line_cnt = 0;
X  line_index = 0;
X  line_len = 0;
X  rs_eol = TRUE;
X  rs_eof = FALSE;
X  rs_abort = FALSE;
X  rs_errs = 0;
X  rs_stdin = FALSE;
X  rs_rd_decimal = FALSE;
X}
X
int open_stdin()
X{
X
X/*
X   Opens standard input as the current spec file
X*/
X
X  rs_reset_var();
X  fd = stdin;
X  rs_stdin = TRUE;
X  return(TRUE);
X}
X
int open_spec(filename)
X  char *filename;
X{
X
X/*
X   Opens the specified file as the current spec file
X*/
X
X  if ((fd = fopen(filename, "r")) != (FILE*)NULL)
X    {
X      rs_reset_var();
X      return(TRUE);
X    }
X  else
X    return(FALSE);
X}
X
int rewind_spec()
X{
X
X/*
X   Rewinds the spec file to re-read lines from the beginning
X*/
X
X  if (fseek(fd, (long)0, 0) != ERROR)
X    {
X      rs_reset_var();
X      return(TRUE);
X    }
X  else
X    return(FALSE);
X}
X
int close_spec()
X{
X
X/*
X   Closes the current spec file
X*/
X
X  if (fclose(fd))
X    {
X      rs_reset_var();
X      rs_eof = TRUE;
X      return(TRUE);
X    }
X  else
X    return(FALSE);
X}
END_OF_FILE
if test 16010 -ne `wc -c <'lib/rdspec.c'`; then
    echo shar: \"'lib/rdspec.c'\" unpacked with wrong size!
fi
# end of 'lib/rdspec.c'
fi
if test -f 'lib/scrout5.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'lib/scrout5.c'\"
else
echo shar: Extracting \"'lib/scrout5.c'\" \(12372 characters\)
sed "s/^X//" >'lib/scrout5.c' <<'END_OF_FILE'
X/* module screen output */
X
X/*
X   provides UNIX "curses" type routines
X*/
X
X/*
X   created May 5, 1987 by JCT
X*/
X
X/*
X *	Copyright (c) John C. Tompkins 1989
X *	All rights reserved.
X *
X *	Permission is granted to use this for any personal, noncommercial use.
X *	You may not distribute source or executable code for profit, nor
X *	may you distribute it with a commercial product without the prior
X *      written consent of the author.  Please send modifications to the 
X *      author for inclusion in updates to the program.
X */
X
X#include <stdio.h>
X#include <string.h>
X
X#include <km/defs.h>
X#include <km/ascii.h>
X#include <km/scrio.h>
X#include <km/string1.h>
X
int waddch(win, ch)			/* add char to window */
X  REGISTER WINDOW *win;
X  int		  ch;
X{
X  int                 y_cur, x_cur, spaces, wrapped;
X  REGISTER YX_ELEMENT *datap;
X  YX_ELEMENT          *start;
X
X  y_cur = win->y_cur;
X  x_cur = win->x_cur;
X  wrapped = FALSE;
X  datap = win->ch_cur;
X  start = datap;
X  switch (ch)
X    {
X      case BS :
X        if (win->flags & BOX_FLAG)
X	  {
X            if (x_cur > 1)
X	      {
X	        datap--;
X	        x_cur--;
X	      }
X	  }
X        else
X	  {
X            if (x_cur > 0)
X	      {
X	        datap--;
X	        x_cur--;
X	      }
X	  }
X	break;
X      case HT :
X        spaces = TAB_STOP - x_cur % TAB_STOP;
X        while (spaces)
X	  {
X	    if (!waddch(win, ' '))
X	      return(FALSE);
X	    spaces--;
X	  }
X        return(TRUE);
X      case LF :
X        if (win->flags & BOX_FLAG)
X	  {
X            datap += (win->x_max - x_cur + 1);
X            x_cur = 1;
X            y_cur++;
X            if (y_cur >= (win->y_max - 1))
X	      {
X		wrapped = TRUE;
X	        datap -= win->x_max;
X	        y_cur--;
X	      }
X	  }
X        else
X	  {
X            datap += (win->x_max - x_cur);
X            x_cur = 0;
X            y_cur++;
X            if (y_cur >= win->y_max)
X	      {
X		wrapped = TRUE;
X	        datap -= win->x_max;
X	        y_cur--;
X	      }
X	  }
X	break;
X      case CR :
X        if (win->flags & BOX_FLAG)
X	  {
X	    datap -= (x_cur - 1);
X            x_cur = 1;
X	  }
X        else
X	  {
X	    datap -= x_cur;
X            x_cur = 0;
X	  }
X	break;
X      default :
X        datap->ch = ch;
X        datap->color = win->color;
X        datap->attrib = win->attrib;
X        datap->ch_flags = 0;
X        datap++;
X        x_cur++;
X        if (win->flags & BOX_FLAG)
X	  {
X            if (x_cur >= (win->x_max - 1))
X	      {
X	        x_cur = 1;
X	        y_cur++;
X	        datap += 2;
X	        if (y_cur >= (win->y_max - 1))
X		  {
X		    wrapped = TRUE;
X		    datap -= win->x_max;
X	            y_cur--;
X		  }
X	      }
X	  }
X        else
X	  {
X            if (x_cur >= win->x_max)
X	      {
X	        x_cur = 0;
X	        y_cur++;
X	        if (y_cur >= win->y_max)
X		  {
X		    wrapped = TRUE;
X		    datap -= win->x_max;
X	            y_cur--;
X		  }
X	      }
X	  }
X	break;
X    }
X  if (start < win->ch_first)
X    win->ch_first = start;
X  else if (start > win->ch_last)
X    win->ch_last = start;
X  if (datap < win->ch_first)
X    win->ch_first = datap;
X  else if (datap > win->ch_last)
X    win->ch_last = datap;
X  win->ch_cur = datap;
X  if (wrapped)
X    {
X      if (win->flags & BOX_FLAG)
X	datap = win->buf + ((win->y_max - 1) * win->x_max) - 2;
X      else
X	datap = win->buf + (win->y_max * win->x_max) - 1;
X      if (datap > win->ch_last)
X	win->ch_last = datap;
X    }
X  win->y_cur = y_cur;
X  win->x_cur = x_cur;
X  win->flags &= ~NO_CHANGE;
X  return(TRUE);
X}
X 
int waddstr(win, str)			/* add string to window */
X  REGISTER WINDOW *win;
X  char		  *str;
X{
X  int        	      color, attrib, y_cur, x_cur, spaces, count, wrapped;
X  REGISTER YX_ELEMENT *datap;
X  YX_ELEMENT 	      *start;
X
X  y_cur = win->y_cur;
X  x_cur = win->x_cur;
X  datap = win->ch_cur;
X  start = datap;
X  color = win->color;
X  attrib = win->attrib;
X  count = 0;
X  wrapped = FALSE;
X  while (*str)
X    {
X      switch (*str)
X	{
X          case BS :
X            if (win->flags & BOX_FLAG)
X	      {
X                if (x_cur > 1)
X		  {
X		    datap--;
X	            x_cur--;
X		  }
X	      }
X            else
X	      {
X                if (x_cur > 0)
X		  {
X		    datap--;
X	            x_cur--;
X		  }
X	      }
X	    break;
X	  case HT :
X            spaces = TAB_STOP - (x_cur % TAB_STOP);
X            while (spaces)
X	      {
X                datap->ch = ' ';
X                datap->color = color;
X                datap->attrib = attrib;
X                datap->ch_flags = 0;
X	        datap++;
X                x_cur++;
X	        if (win->flags & BOX_FLAG)
X		  {
X                    if (x_cur >= (win->x_max - 1))
X	              {
X	                x_cur = 1;
X	                y_cur++;
X		        datap += 2;
X	                if (y_cur >= (win->y_max - 1))
X		          {
X		    	    wrapped = TRUE;
X		            datap -= win->x_max;
X	                    y_cur--;
X		          }
X		      }
X		  }
X	        else
X		  {
X                    if (x_cur >= win->x_max)
X	              {
X	                x_cur = 0;
X	                y_cur++;
X	                if (y_cur >= win->y_max)
X		          {
X		    	    wrapped = TRUE;
X		            datap -= win->x_max;
X	                    y_cur--;
X		          }
X		      }
X	          }
X	        spaces--;
X	      }
X	    break;
X	  case LF :
X	    if (win->flags & BOX_FLAG)
X	      {
X	        datap += (win->x_max - x_cur + 1);
X                x_cur = 1;
X                y_cur++;
X                if (y_cur >= (win->y_max - 1))
X	          {
X		    wrapped = TRUE;
X	            datap -= win->x_max;
X	            y_cur--;
X	          }
X	      }
X	    else
X	      {
X	        datap += (win->x_max - x_cur);
X                x_cur = 0;
X                y_cur++;
X                if (y_cur >= win->y_max)
X	          {
X		    wrapped = TRUE;
X	            datap -= win->x_max;
X	            y_cur--;
X	          }
X	      }
X	    break;
X	  case CR :
X	    if (win->flags & BOX_FLAG)
X	      {
X	        datap -= (x_cur - 1);
X                x_cur = 1;
X	      }
X	    else
X	      {
X	        datap -= x_cur;
X                x_cur = 0;
X	      }
X	    break;
X	  default :
X            datap->ch = *str;
X            datap->color = color;
X            datap->attrib = attrib;
X            datap->ch_flags = 0;
X	    datap++;
X            x_cur++;
X	    if (win->flags & BOX_FLAG)
X	      {
X                if (x_cur >= (win->x_max - 1))
X	          {
X	            x_cur = 1;
X	            y_cur++;
X		    datap += 2;
X	            if (y_cur >= (win->y_max - 1))
X		      {
X			wrapped = TRUE;
X		        datap -= win->x_max;
X	                y_cur--;
X		      }
X	          }
X	      }
X	    else
X	      {
X                if (x_cur >= win->x_max)
X	          {
X	            x_cur = 0;
X	            y_cur++;
X	            if (y_cur >= win->y_max)
X		      {
X			wrapped = TRUE;
X		        datap -= win->x_max;
X	                y_cur--;
X		      }
X	          }
X	      }
X	    break;
X	}
X      str++;
X      count++;
X    }
X  if (start < win->ch_first)
X    win->ch_first = start;
X  else if (start > win->ch_last)
X    win->ch_last = start;
X  if (datap < win->ch_first)
X    win->ch_first = datap;
X  else if (datap > win->ch_last)
X    win->ch_last = datap;
X  win->ch_cur = datap;
X  if (wrapped)
X    {
X      if (win->flags & BOX_FLAG)
X	datap = win->buf + ((win->y_max - 1) * win->x_max) - 2;
X      else
X	datap = win->buf + (win->y_max * win->x_max) - 1;
X      if (datap > win->ch_last)
X	win->ch_last = datap;
X    }
X  win->y_cur = y_cur;
X  win->x_cur = x_cur;
X  win->flags &= ~NO_CHANGE;
X  return(count);
X}
X
int waddtext(win, text, format, flags)
X  WINDOW *win;
X  char   *text;
X  char   *format;
X  int    flags;
X{
X
X/*
X   Add string text to window line up to the end of the current line.
X   Skip leading and trailing blanks on a line. Add newline only if newline
X   is only character, ie blank line, otherwise newline is space. Tabs are
X   single space character. Do not add partial word at end of line unless
X   single line is too short for a single long word. If fills out current line,
X   forces to first column of newline, even on last line of window. Return
X   number of characters read (which may not have all been output because of
X   formatting).
X*/
X
X  int  count, max, temp, start_of_line, y_cur, x_cur, full_line;
X  int  tlen, flen, ch, effect, have_eff;
X  char *tend, *fend, *eff_ptr;;
X
X  count = 0;
X  y_cur = win->y_cur;
X
X/*
X   If flags are set allow stripping of leading blanks
X*/
X
X  if (flags)
X    {
X      while (((*text == ' ') || (*text == '\t')) &&
X	     (format ? (*format == ' ') : TRUE))
X        {
X          text++;
X          if (format && *format)
X	    format++;
X          count++;
X        }
X    }
X  if (*text)					/* any text left to output ? */
X    {
X      temp = count;
X
X/*
X   Find lengths and end pointers for text and format strings
X*/
X
X      tlen = strlen(text);
X      tend = text + tlen;
X      if (substr((tend - 3), "@@\n", TRUE))	/* effect marker ? */
X	{
X	  have_eff = TRUE;			/* clear it */
X	  eff_ptr = tend - 3;
X	  tlen -= 3;
X	  tend -= 3;
X	  count += 3;
X	}
X      else
X	{
X	  have_eff = FALSE;
X	  eff_ptr = NULL;
X	}
X      if (format)
X	{
X          flen = strlen(format);
X	  if (flen <= tlen)
X            fend = format + flen;
X	  else
X	    {
X	      fend = format + tlen;
X	      flen = tlen;
X	    }
X	  if (have_eff && substr((fend - 1), "\n", TRUE))
X	    {
X	      flen--;
X	      fend--;
X	    }
X	}
X
X/*
X   If flags allow, find last non-blank character, if any
X*/
X
X      if (flags)
X	{
X	  while (tlen && ((*(tend - 1) == ' ') || (*(tend - 1) == '\t')) &&
X	        (format ? ((flen == tlen) ?
X	        ((*(fend - 1) == ' ')  || (*(fend - 1) == '\t')) : TRUE) : TRUE))
X	    {
X	      if (format && (flen == tlen))
X	        {
X	          flen--;
X	          fend--;
X	        }
X	      tlen--;
X	      tend--;
X	      count++;
X	    }
X	}
X
X/*
X   If flags allow and current text is only a newline, output newline.
X   Note that normally if flags are set and the newline is not on an empty
X   line, a space is substituted for the newline. This is word wrap.
X*/
X
X      if (flags && (have_eff ? (tlen == 0) : ((tlen == 1) && (*text == '\n'))))
X        {
X	  if ((win->flags & BOX_FLAG) ? (win->x_cur > 1) : (win->x_cur > 0))
X            waddch(win, '\n');				/* end curr line */
X          waddch(win, '\n');				/* make blank line */
X	  count++;
X        }
X      else						/* proceed normally */
X	{
X	  count = temp;
X          max = win->x_max - win->x_cur;		/* room left on line */
X          if (win->flags & BOX_FLAG)
X            max--;
X
X/*
X   If text to output is longer than room left on line, find last "word"
X   that will fit in remaining space. A word is any sequence ended by a blank
X*/
X
X	  if (tlen >= max)
X	    {
X	      full_line = TRUE;
X	      tend = text + max;
X	      tlen = max;
X              while (tlen && (*(tend - 1) != ' '))	/* find blank */
X		{
X		  tlen--;
X                  tend--;
X		}
X	      while (tlen && (*(tend - 1) == ' '))	/* find non-blank */
X		{
X		  tlen--;
X                  tend--;
X		}
X	      start_of_line = (win->x_cur == ((win->flags & BOX_FLAG) ? 1 : 0));
X	      if (!tlen && start_of_line)		/* word too long ? */
X	        tlen = max;				/* do partial word */
X	    }
X	  else
X	    full_line = FALSE;
X
X/*
X   Finally, output the text
X   Substiute blank for newline if flags allow (word wrap)
X*/
X
X	  while ((have_eff ? (tlen >= 0) : tlen))
X	    {
X	      if ((have_eff && (tlen == 0)) || (*text == '\n'))
X		{
X		  if (flags)
X		    ch = ' ';
X		  else
X		    ch = '\n';
X		  effect = ' ';
X		}
X	      else
X		{
X 		  if (*text == HT)
X		    ch = ' ';
X		  else
X		    ch = *text;
X		  if (format)
X		    {
X		      if (*format)
X			{
X		          if (*format == '\n')
X			    effect = ' ';
X			  else
X			    effect = *format;
X			}
X		      else
X			effect = ' ';
X		    }
X		  else
X		    effect = 0;
X		}
X	      if (!effect)
X		waddch(win, ch);
X	      else if (effect == ' ')
X		{
X		  if (win->attrib)
X		    wendattrib(win);
X		  waddch(win, ch);
X		}
X	      else if (effect == '[')
X		{
X		  if (win->attrib)
X		    wendattrib(win);
X		  waddgraphic(win, ch);
X		}
X	      else
X		{
X		  if (!(win->attrib & STANDOUT))
X		    wsetattrib(win, STANDOUT);
X	          waddch(win, ch);
X		}
X	      text++;
X	      count++;
X	      if (format && *format)
X	        format++;
X	      tlen--;
X	    }
X	  if (have_eff && (text == (eff_ptr + 1)))
X	    count += 2;					/* only 2, not 3 */
X	  if (full_line)
X	    {
X	      max = win->y_max - 1;
X	      if (win->flags & BOX_FLAG)
X		{
X		  max--;
X		  x_cur = 1;
X		}
X	      else
X		x_cur = 0;
X	      if (y_cur < max)
X		y_cur++;
X	      wmove(win, y_cur, x_cur);
X	    }
X	}
X    }
X  return(count);
X}
X
END_OF_FILE
if test 12372 -ne `wc -c <'lib/scrout5.c'`; then
    echo shar: \"'lib/scrout5.c'\" unpacked with wrong size!
fi
# end of 'lib/scrout5.c'
fi
echo shar: End of archive 4 \(of 9\).
cp /dev/null ark4isdone
MISSING=""
for I in 1 2 3 4 5 6 7 8 9 ; do
    if test ! -f ark${I}isdone ; then
	MISSING="${MISSING} ${I}"
    fi
done
if test "${MISSING}" = "" ; then
    echo You have unpacked all 9 archives.
    rm -f ark[1-9]isdone ark[1-9][0-9]isdone
else
    echo You still need to unpack the following archives:
    echo "        " ${MISSING}
fi
##  End of shell archive.
exit 0