
#--------------------------------CUT HERE-------------------------------------
#! /bin/sh
#
# This is a shell archive. Save this into a file, edit it
# and delete all lines above this comment.  Then give this
# file to sh by executing the command 'sh file'. The files
# will be extracted into the current directory owned by
# you with default permissions.

echo 'x - myenv.h'
sed 's/^X//' << '________This_Is_The_END________' > myenv.h
X// This may look like C code, but it is really -*- C++ -*-
X//************************************************************************
X//
X//			A standard environment
X//			  I am accustomed to
X
X#pragma once
X#pragma interface
X
X				/* Strings of symbols			*/
X				/* They may be used as a delimiting lines*/
Xextern const char _Minuses [];
Xextern const char _Asteriscs [];
Xextern const char _Equals [];
X
X				/* Print an error message at stderr and	*/
X				/* abort				*/
Xvolatile void _error(
X	const char * message,		/* Message to be printed	*/
X	...                             /* Additional args to printf	*/
X	   );
X
X				/* Print a message at stderr 		*/
Xvoid message(
X	const char * text,		/* Message to be printed	*/
X	...                             /* Additional args to printf	*/
X	   );
X
X
X//------------------------------------------------------------------------
X//			Verify the assertion
X
X#if 0
X  					/* Print a message and abort*/
Xextern volatile void _error( const char * message,... ); 
X#endif
X
X#define assert(ex) \
X        (void)((ex) ? 1 : \
X              (_error("Failed assertion " #ex " at line %d of `%s'.\n", \
X               __LINE__, __FILE__), 0))
X#define assertval(ex) assert(ex)
X
X#define assure(expr,message)				\
X	if	(expr) ;				\
X	else _error("%s\n at line %d of '%s'.",message,__LINE__, __FILE__);
X
X
________This_Is_The_END________
if test `wc -l < myenv.h` -ne 48; then
echo 'shar: myenv.h was damaged during transit (should have had 48 lines)'
fi


echo 'x - myenv.cc'
sed 's/^X//' << '________This_Is_The_END________' > myenv.cc
X// This may look like C code, but it is really -*- C++ -*-
X/*
X ************************************************************************
X *			Service C++ functions 
X *	     that support the standard environment for me
X */
X
X#pragma implementation
X
X#include "myenv.h"
X#include <builtin.h>
X#include <stdarg.h>
X
X			// The following line is needed only for
X			// the stupid BSD 4.3
X#define vfprintf(fp,format,arg) _doprnt(format,arg,fp)
X
X/*
X *-----------------------------------------------------------------------
X *		Some global constant pertaining to input/output
X */
X
Xconst char _Minuses [] = "\
X-------------------------------------------------------------------------------";
X
Xconst char _Asteriscs [] = "\
X*******************************************************************************";
X
Xconst char _Equals [] = "\
X===============================================================================";
X
X
X/*
X *------------------------------------------------------------------------
X *	        Print an error message at stderr and abort
X * Synopsis
X *	volatile void _error(const char * message,... );
X *	Message may contain format control sequences %x. Items to print 
X *	with the control sequences are to be passed as additional arguments to
X *	the function call.
X */
X
Xvolatile void _error(const char * message,...)
X{
X  va_list args;
X  va_start(args,message);		/* Init 'args' to the beginning of */
X					/* the variable length list of args*/
X  fprintf(stderr,"\n_error:\n"); 	
X  vfprintf(stderr,message,args);
X  fputs("\n",stderr);
X  abort();
X}
X
X
X/*
X *------------------------------------------------------------------------
X *	       		 Print a message at stderr
X * Synopsis
X *	void message(const char * text,... );
X *	Message may contain format control sequences %x. Items to print 
X *	with the control sequences are to be passed as additional arguments to
X *	the function call.
X */
X
Xvoid message(const char * text,...)
X{
X  va_list args;
X  va_start(args,text);		/* Init 'args' to the beginning of */
X					/* the variable length list of args*/
X  vfprintf(stderr,text,args);
X}
X
________This_Is_The_END________
if test `wc -l < myenv.cc` -ne 72; then
echo 'shar: myenv.cc was damaged during transit (should have had 72 lines)'
fi


echo 'x - task_env.h'
sed 's/^X//' << '________This_Is_The_END________' > task_env.h
X// This may look like C code, but it is really -*- C++ -*-
X/*
X ************************************************************************
X *
X *			Task environment handling
X *
X *
X * Task environment area is a set of global (common) data. Any procedure
X * within the active task can deposit a piece of information to be used
X * by other procedure. And any procedure can request to retrieve information
X * having been deposited under a given name.
X *
X * The present service is assumed to be used as task customization tool.
X * Root module of the task reads the configuration file and deposits
X * data into the task environment area (e.g. the no. of grids, the output
X * file name etc.). Other modules that need such a parameter request it from 
X * the present service.
X *
X ************************************************************************
X */
X
X#pragma once
X#pragma interface
X
X//	The following is the declaration of routines dealing with
X//			the task environment
X 
X				// Deposit a string at the env area
X				// Parameter string must be of the form
Xvoid task_env_deposit(		//	"name = value ;other comment"
X	const char * str
X	    );
X
X				// Retrieve the value of the parameter
X				// string by its name
Xconst char * task_env_retrieve(
X	const char * name			// Param. name
X                        );
X
X				// Write the environment area in the
X				// specified file
Xvoid task_env_write(
X	const char * file_name 		// File to write to
X		   );
X
X 				// Print the contents of the environment
X				// area
Xvoid task_env_print(void);
X
X				// Read the environment area from the
X				// file specified from the current
X				// record to either specified termina-
X				// ting string or EOF (whichever comes
X				// first
Xvoid task_env_read(
X	const char * file_name,		// File to read from
X	const char * terminator		// String terminating the output
X                  );
X
________This_Is_The_END________
if test `wc -l < task_env.h` -ne 59; then
echo 'shar: task_env.h was damaged during transit (should have had 59 lines)'
fi


echo 'x - task_env.cc'
sed 's/^X//' << '________This_Is_The_END________' > task_env.cc
X// This may look like C code, but it is really -*- C++ -*-
X/*
X ************************************************************************
X *
X *			Task environment handling
X *
X *			      Package body
X *
X ************************************************************************
X */
X
X#include "task_env.h"
X
X#include "myenv.h"
X#include <ctype.h>
X#include <std.h>
X#include <stream.h>
X
X#pragma implementation
X
X//------------------------------------------------------------------------
X//	    Data structures that represent the task environment
X
Xstruct ENV_ELEMENT {			// Environment area element
X  const char * name;			// Name
X  const char * value;			// Value
X  ENV_ELEMENT * next;			// Ptr to the next element
X};
X
X					// Ptr to the list of elements
Xstatic ENV_ELEMENT * Task_Environment_Area;
Xstatic ENV_ELEMENT * Last_env_element;
X
X/*
X *-----------------------------------------------------------------------
X *			Some service functions
X */
X
X				// Try to locate the element by its name
X				// Return 0 if the element isn't found
Xstatic ENV_ELEMENT * find_element_by_name(const char * name)
X{
X  register ENV_ELEMENT * p = Task_Environment_Area;
X
X  while( p != 0 )
X     if( strcmp(p->name,name) == 0 )
X       return p;			/* Name has been found		*/
X     else
X       p = p->next;			/* Else try the next element	*/
X  return 0;				/* No element was found		*/
X}
X
X
X			/* Create a new element and append it to the	*/
X                        /* environment list				*/
Xstatic void create_element(const char * name, const char * value)
X{
X  register ENV_ELEMENT * new_el = new ENV_ELEMENT;
X
X  new_el->name  = name;
X  new_el->value = value;
X  new_el->next  = 0;
X
X  if( Last_env_element == 0 )		// If the task env is empty
X  {
X    assert(Task_Environment_Area == 0);
X    Task_Environment_Area = new_el;
X  }
X  else					// Append it to the list
X    Last_env_element->next = new_el;
X
X  Last_env_element = new_el;
X}
X
X
X
X/*
X *-----------------------------------------------------------------------
X *	    Deposit a parameter string in the task environment area
X * 
X * Format of the string
X *	"name = value ;other comment"
X */
X
Xvoid task_env_deposit(const char * str)
X{
X  register char *p, *q;
X  register int i;
X  
X			// Separate and analyze the name
X  if( (p=strchr(str,'=')) == 0 )
X    _error("Equal sign was not found where expected in the string '%s'",
X	   str);
X
X  while( --p >= str && *p == ' ' )      // Delete blanks between the name
X     ;					// and the equal sign
X     
X  if( (i= (++p - str)) <= 0 )		// i is the name length
X    _error("No name found in string '%s'",str);
X
X  char * name = strncpy(new char[i+1],str,i);
X  name[i] = '\0';
X
X			// Separate and analyze the value
X  assert( (q=strchr(str,'=')) );
X  while( *++q == ' ' && *q != '\0' )	// Find out where the value starts
X     ;
X  if( *q == '\0' ) 
X    _error("No value found in string '%s'",str);
X
X  if( (p=strchr(q,';')) == 0 )  	/* Locate p at the '\0' or	*/
X    p = q + strlen(q);		        /* at the beginning of comment	*/
X
X  while( --p >= q && *p == ' ' )        /* Delete padding blanks	*/
X     ;			       
X     
X  if( (i= (++p - q)) <= 0 )		// i is the size of the value
X    _error("No value found in string '%s'",str);
X
X  char * value = strncpy(new char[i+1],q,i);
X  value[i] = '\0';
X
X                        // Create a new ENV_ELEMENT
X  if( find_element_by_name(name) )
X    _error("Element '%s' is already in the task environment area",name);
X
X  create_element(name,value);
X}
X
X
X   
X/*
X *-----------------------------------------------------------------------
X *	    Retrive the value of a parameter string by its name
X * 
X */
X
Xconst char * task_env_retrieve(const char * name)
X{
X  register ENV_ELEMENT * p;
X
X  if( (p=find_element_by_name(name)) == 0 )
X    _error("No env string with the name '%s' was found",name);
X
X  return p->value;
X}
X
X
X
X/*
X *-----------------------------------------------------------------------
X *	      Print/Write/Read the contents of the environment area
X * 
X */
X
Xvoid task_env_print(void)
X{
X  message("\n\n\t\t\tTask environment area\n\nName\t\t\tValue\n");
X  task_env_write("/dev/tty");
X  message("\n");
X}
X
X				/* Write the environment area in the	*/
X				/* specified file			*/
Xvoid task_env_write(const char * file_name)
X{
X  register ENV_ELEMENT * p = Task_Environment_Area;
X
X  if( p == 0 )
X  {
X     message("\nTask environment area is empty\n\n");
X     return;
X  }
X
X  ostream outf(file_name,"w");
X
X  while( p != 0 )
X  {
X     outf << p->name << " = " << p->value << "\n";
X     p = p->next;
X  }
X}
X
X				/* Read the environment area from the	*/
X				/* file specified from the current 	*/
X				/* record to either specified termina-	*/
X				/* ting string or EOF (whichever comes	*/
X				/* first				*/
Xvoid task_env_read(const char * file_name, const char * terminator)
X{
X  char buffer [100];
X  register char *p;
X
X  File inp(file_name,"r");
X
X  for(;;)
X  {
X    inp.getline(buffer,sizeof(buffer)-2,'\n');
X    if( inp.eof() )
X      break;	     			/* Exit on EOF			*/
X
X    if( buffer[0] == ';' )
X      continue;				/* Bypass the comment string	*/
X    if( (p=strchr(buffer,'\n')) == 0 )
X      _error("Too long string has been read\n\"%s\" ",buffer);
X    *p = '\0';				/* Replace \n by \0		*/
X
X    if( strcmp(buffer,terminator) == 0 )/* Exit on terminator		*/
X      break;
X    task_env_deposit(buffer);
X  }
X
X}
X
X
________This_Is_The_END________
if test `wc -l < task_env.cc` -ne 215; then
echo 'shar: task_env.cc was damaged during transit (should have had 215 lines)'
fi


echo 'x - File.cc'
sed 's/^X//' << '________This_Is_The_END________' > File.cc
X// This may look like C code, but it is really -*- C++ -*-
X//************************************************************************
X/* 
XCopyright (C) 1988 Free Software Foundation
X    written by Doug Lea (dl@rocky.oswego.edu)
X
XThis file is part of GNU CC.
X
XGNU CC is distributed in the hope that it will be useful,
Xbut WITHOUT ANY WARRANTY.  No author or distributor
Xaccepts responsibility to anyone for the consequences of using it
Xor for whether it serves any particular purpose or works at all,
Xunless he says so in writing.  Refer to the GNU CC General Public
XLicense for full details.
X
XEveryone is granted permission to copy, modify and redistribute
XGNU CC, but only under the conditions described in the
XGNU CC General Public License.   A copy of this license is
Xsupposed to have been given to you along with GNU CC so you
Xcan know your rights and responsibilities.  It should be in a
Xfile named COPYING.  Among other things, the copyright notice
Xand this notice must be preserved on all copies.  
X
XUpdate history
XNov-15, 1991	Replace 'abort()' for 'exit(1)' into the 
X		fatal_File_error_handler and make it default error
X		handler
X
XDec-26, 1991	File name to open may be specified now as
X		"| command" or "command |", i.e. as a pipe.
X		The command is launched with popen() and
X		its standard input/output is arranged to be
X		the file being open.
X		Note, in the field File::rw, bit 0x08 is 
X		used to specify the popen() was used to open
X		the file. The function pclose() is should be
X		called to close the file in this case.
X*/
X
X#ifdef __GNUG__
X#pragma implementation
X#endif
X#include <File.h>
X#include <std.h>
X#include <stdarg.h>
X#include <values.h>
X#include <sys/file.h>           // needed to determine values of O_RDONLY...
X
X
X#ifdef VMS
X#include <errno.h>	// needed to get the psect magic loaded
X#define	FP	(*fp)
X#else
X#define	FP	fp
X#endif
X
X// error handlers
X
Xvoid verbose_File_error_handler(const char* msg)
X{
X  perror(msg);
X  errno = 0;
X}
X
Xvoid quiet_File_error_handler(const char*)
X{
X  errno = 0;
X}
X
Xvoid fatal_File_error_handler(const char* msg)
X{
X  perror(msg);
X  abort();
X}
X
Xone_arg_error_handler_t File_error_handler = fatal_File_error_handler;
X
X
Xone_arg_error_handler_t set_File_error_handler(one_arg_error_handler_t f)
X{
X  one_arg_error_handler_t old = File_error_handler;
X  File_error_handler = f;
X  return old;
X}
X
X
X/*
X
X Opening files. 
X
X open(filename, io_mode, access_mode) is done via system open 
X command since fopen doesn't handle all of the cases possible 
X with sys open. After a successful open, fdopen is called to 
X attach an _iobuf to the file descriptor.
X
X All this requires a few decoding routines that can translate among our
X enumerated types, system flags, and fopen modes.
X
X*/
X
X
Xenum sys_open_cmd_io_mode  // These should be correct for most systems
X{                        
X  sio_read      = O_RDONLY,
X  sio_write     = O_WRONLY,
X  sio_readwrite = O_RDWR,
X  sio_append    = O_APPEND
X};
X
Xenum sys_open_cmd_access_mode
X{
X  sa_create     = O_CREAT,
X  sa_truncate   = O_TRUNC,
X  sa_createonly = O_EXCL | O_CREAT
X};
X
X  
Xstatic int open_cmd_arg(io_mode i, access_mode a) // decode modes
X{
X  int arg;
X  switch(i)
X  {
X  case io_readonly:   arg = sio_read;                   break;
X  case io_writeonly:  arg = sio_write;                  break;
X  case io_readwrite:  arg = sio_readwrite;              break;
X  case io_appendonly: arg = sio_append | sio_write;     break;
X  case io_append:     arg = sio_append | sio_readwrite; break;
X  default:            return -1;
X  };
X  switch(a)
X  {
X  case a_createonly:  return arg | sa_createonly;
X  case a_create:      return arg | sa_create | sa_truncate;
X  case a_useonly:     return arg;
X  case a_use:         return arg | sa_create;
X  default:            return -1;
X  }
X}
X
Xstatic char* fopen_cmd_arg(io_mode i)
X{
X  switch(i)
X  {
X  case io_readonly:  return "r";
X  case io_writeonly: return "w";
X  case io_readwrite: return "r+";
X  case io_appendonly:return "a";
X  case io_append:    return "a+";
X  default:           return 0;
X  }
X}
X
X
Xvoid File::initialize() 
X{ 
X  fp = 0; nm = 0; stat = 0; state = _bad; rw = 0;
X}
X
X// reset class vars after open
X// fp->_flag inspection is isolated here
X
Xvoid File::reinitialize(const char* filename)
X{
X  if (filename != 0)     setname(filename);
X  else if (fp == stdin)  setname("(stdin)");
X  else if (fp == stdout) setname("(stdout)");
X  else if (fp == stderr) setname("(stderr)");
X  else if (rw & 4)       setname("(string)");
X  else setname(0);
X
X  if (fp != 0)
X  {
X    state = _good;
X    if (FP->_flag & (_IOREAD|_IORW))
X      rw |= 01;
X    if (FP->_flag & (_IOWRT|_IORW|_IOAPPEND))
X      rw |= 02;
X    check_state();
X  }
X  else
X  {
X    set(_fail); set(_bad);
X    error();
X  }
X}
X
X
XFile& File::open(const char* filename, io_mode m, access_mode a)
X{                                   
X  close();
X  int open_arg = open_cmd_arg(m, a);
X  if (open_arg != -1)
X  {
X    int fd = ::open(filename, open_arg, 0666);
X    if (fd >= 0)
X      fp = fdopen(fd, fopen_cmd_arg(m));
X  }
X  reinitialize(filename);
X  return *this;
X}
X
XFile& File::open(const char* filename, const char* m)
X{                                   
X  close();
X  register char *p = index(filename,'|');
X
X  if( p == 0 )			// No pipes were specified
X    fp = fopen(filename, m);
X  else if( p == strspn(filename," ") + filename )     // '|' is the 1st non-bl
X  {				// Create the pipe to write to
X    if( m[0] != 'w' )
X      (*File_error_handler)
X	("File name looks like the pipe to write to, but the open mode "
X	 "is not \"w\" ");
X    fp = popen(p+1,m);		// p+1 points to the name right after the '|'
X    rw |= 8;			// File has been open with popen()
X  }
X  else if( *(p+1) == '\0' )		// '|' is the last char of the filename
X  {				// Create the pipe to read from
X    char tempname[strlen(filename)+1];		// Copy the file name up to
X    strncpy(tempname,filename,p-filename);	// (but not including) '|'
X    if( m[0] != 'r' )
X      (*File_error_handler)
X	("File name looks like the pipe to read from, but the open mode "
X	 "is not \"r\" ");
X    fp = popen(tempname,m);
X    rw |= 8;			// File has been open with popen()
X  }
X  else
X    (*File_error_handler)
X      ("Pipe char in the file name occured in the wrong place");
X
X  reinitialize(filename);
X  return *this;
X}
X
XFile& File::open(FILE* fileptr)
X{
X  close();
X  fp = fileptr;
X  reinitialize(0);
X  return *this;
X}
X
XFile& File::open(int filedesc, io_mode m)
X{
X  close();
X  fp = fdopen(filedesc, fopen_cmd_arg(m));
X  reinitialize(0);
X  return *this;
X}
X
XFile& File::close()
X{
X  if (fp != 0)
X  {
X#ifdef VMS
X    if (rw & 4)                 // we own the iobuf, kill it
X      delete(*fp);	// kill the _iobuf
X#endif
X    if (rw & 4)                 // we own the iobuf, kill it
X      delete fp;
X    else if (rw & 8)		// fp has been opened as a pipe with popen()
X    {
X      flush();
X      pclose(fp);
X    }
X    else if (fp == stdin || fp == stdout || fp == stderr)
X      flush();
X    else
X      fclose(fp);
X  }
X  fp = 0;
X  rw = 0;
X  set(_bad);
X  return *this;
X}
X
XFile& File::remove()
X{
X  close();
X  return failif (nm == 0 || unlink(nm) != 0);
X}
X
X
XFile::File()
X{ 
X  initialize(); 
X}
X
XFile::File(const char* filename, io_mode m, access_mode a)   
X{ 
X  initialize(); 
X  open(filename, m, a); 
X}
X
XFile::File(const char* filename, const char* m)   
X{ 
X  initialize(); 
X  open(filename, m); 
X}
X
XFile::File(int filedesc, io_mode m)
X{ 
X  initialize(); 
X  open(filedesc, m); 
X}
X
XFile::File(FILE* fileptr)
X{ 
X  initialize(); 
X  open(fileptr); 
X}
X
XFile::File(int sz, char* buf, io_mode m)
X{
X  if (m != io_readonly && m != io_writeonly)
X    (*File_error_handler) ("invalid io_mode for string IO");
X  initialize();
X  rw = 4;
X#ifdef VMS
X  _iobuf	*iob;
X  FILE		*f;
X
X  iob = new _iobuf;
X  f = new(FILE);
X  *f = iob;
X  fp = f;
X#else
X  fp = new _iobuf;
X#endif
X#ifndef _NFILE
X  FP->_file = 255;          // any illegal value
X#else
X  FP->_file = _NFILE-1;       // The last filedescriptor...
X#ifdef BUFEND_ENTRY_TYPE
X  _bufendtab[FP->_file] = (BUFEND_ENTRY_TYPE)buf+sz-1;
X#endif
X#endif
X  FP->_ptr = FP->_base = buf;
X#ifdef HAVE_BUFSIZ
X  FP->_bufsiz = sz;
X#endif
X  if (m == io_readonly)
X  {
X    int len = 0;
X    while (len < sz && buf[len] != 0) ++len;
X    if (len == sz)
X      buf[sz - 1] = 0;            // force null-termination!
X    FP->_cnt = len;
X    FP->_flag = _IOREAD | _IOSTRG | _IOMYBUF;
X  }
X  else
X  {
X    bzero(buf, sz);             // so any result will be null-terminated
X    FP->_cnt = sz - 1;          // leave at least one null at end
X    FP->_flag = _IOWRT | _IOSTRG | _IOMYBUF;
X  }
X  reinitialize(0);
X}
X
XFile::~File()
X{
X  delete(nm);
X  close();
X}
X
Xvoid File::setname(const char* newname)
X{
X  if (nm == newname) return;
X
X  if (nm != 0)
X    delete(nm);
X  if (newname != 0)
X  {
X    nm = new char[strlen(newname) + 1];
X    strcpy(nm, newname);
X  }
X  else
X    nm = 0;
X}
X
X
XFile& File::setbuf(int buffer_kind)
X{                  
X  if (!is_open())
X  {
X    set(_fail);
X    return *this;
X  }
X  switch(buffer_kind)
X  {
X  case _IOFBF:       
X#ifdef HAVE_SETVBUF
X    setvbuf(fp, 0, _IOFBF, 0);
X#endif
X    break;           
X  case _IONBF:       
X    ::setbuf(fp, 0); 
X    break;
X  case _IOLBF:
X#ifdef HAVE_SETLINEBUF
X    setlinebuf(fp);
X#else
X#ifdef HAVE_SETVBUF
X    setvbuf(fp, 0, _IOLBF, 0);
X#endif
X#endif    
X    break;
X  default:
X    break;
X  }
X  return *this;
X}
X
XFile& File::setbuf(int size, char* buf)
X{
X  if (!is_open())
X  {
X    set(_fail);
X    return *this;
X  }
X#ifdef HAVE_SETVBUF
X  setvbuf(fp, buf, _IOFBF, size);
X#else
X  setbuffer(fp, buf, size);
X#endif
X  return *this;
X}
X
Xvoid File::error()
X{
X  check_state();
X  set(_fail);
X  if (errno != 0)
X  {
X    char error_string[400];
X    strcpy(error_string, "\nerror in File ");
X    if (nm != 0)
X      strcat(error_string, nm);
X    (*File_error_handler)(error_string);
X  }
X}
X
X
X//------------------------------------------------------------------
X
Xvoid File::check_state() // ensure fp & state agree about eof
X{
X  if (fp != 0)
X  {
X    if (feof(fp))
X      set(_eof);
X    else
X      unset(_eof);
X    if (ferror(fp))
X      set(_bad);
X  }
X}
X
XFile& File::put(const char* s)
X{ 
X  return failif(!writable() || fputs(s, fp) == EOF);
X}
X
XFile& File::get(char* s, int n, char terminator)
X{
X  if (!readable())
X  {
X    set(_fail);
X    return *this;
X  }
X
X  char ch;
X  stat = --n;
X
X  if (n > 0 && (get(ch)))
X  {
X    if (ch == terminator) {
X      unget(ch);
X      stat= 0;	// This is not an error condition !
X    }
X    else
X    {
X      *s++ = ch; --n;
X      while (n > 0 && (get(ch)))
X      {
X        if (ch == terminator)
X        {
X          unget(ch);
X          break;
X        }
X        else
X        {
X          *s++ = ch; --n;
X        }
X      }
X    }
X  }
X
X  *s = 0;
X  return failif((stat != 0) && ((stat -= n) == 0));
X}
X
XFile& File::getline(char* s, int n, char terminator)
X{
X  if (!readable())
X  {
X    set(_fail);
X    return *this;
X  }
X
X  char ch;
X  stat = --n;
X
X  while (n > 0 && (get(ch)))
X  {
X    --n;
X    if ((*s++ = ch) == terminator)
X      break;
X  }
X
X  *s = 0;
X  return failif((stat != 0) && ((stat -= n) == 0));
X}
X
X// from Doug Schmidt
X
X// This should probably be a page size....
X#define CHUNK_SIZE 512
X
X/* Reads an arbitrarily long input line terminated by a user-specified
X   TERMINATOR.  Super-nifty trick using recursion avoids unnecessary calls
X   to NEW! */
X
Xchar *File::readline (int chunk_number, char terminator) 
X{
X  char buf[CHUNK_SIZE];
X  register char *bufptr = buf;
X  register char *ptr;
X  char ch;
X  int continu;
X
X  while ((continu = !!get(ch)) && ch != terminator) /* fill the current buffer */
X    {
X      *bufptr++ = ch;
X      if (bufptr - buf >= CHUNK_SIZE) /* prepend remainder to ptr buffer */
X        {
X          if (ptr = readline (chunk_number + 1, terminator))
X
X            for (; bufptr != buf; *--ptr = *--bufptr);
X
X          return ptr;
X        }
X    }
X  if (!continu && bufptr == buf)
X    return NULL;
X
X  int size = (chunk_number * CHUNK_SIZE + bufptr - buf) + 1;
X
X  if (ptr = new char[stat = size])
X    {
X
X      for (*(ptr += (size - 1)) = '\0'; bufptr != buf; *--ptr = *--bufptr)
X        ;
X
X      return ptr;
X    } 
X  else 
X    return NULL;
X}
X
X/* Reads an arbitrarily long input line terminated by TERMINATOR.
X   This routine allocates its own memory, so the user should
X   only supply the address of a (char *). */
X
XFile& File::gets(char **s, char terminator)
X{
X  if (!readable())
X  {
X    set(_fail);
X    return *this;
X  }
X
X  return failif(!(*s = readline (0, terminator)));
X}
X  
X#ifndef VMS
XFile& File::scan(const char* fmt ...)
X{
X  if (readable())
X  {
X    va_list args;
X    va_start(args, fmt);
X#ifndef HAVE_VSCANF
X    stat = _doscan(fp, fmt, args);
X#else
X    stat = vfscanf(fp, fmt, args);
X#endif
X    va_end(args);
X    failif(stat <= 0);
X  }
X  return *this;
X}
X#endif
X
XFile& File::form(const char* fmt ...)
X{
X  va_list args;
X  va_start(args, fmt);
X#ifndef HAVE_VPRINTF
X  stat = _doprnt(fmt, args, fp);
X#ifdef HAVE_VOID_DOPRNT
X  stat = ferror(fp) ? -1 : 0;
X#endif
X#else
X  stat = vfprintf(fp, fmt, args);
X#endif
X  va_end(args);
X  failif(stat < 0);
X  return *this;
X}
X
X#ifdef VMS
Xextern "C" {
X    unlink(const char *s)
X    {
X        int remove(const char *);
X
X    	return remove(s);
X    }
X}
X#endif
________This_Is_The_END________
if test `wc -l < File.cc` -ne 633; then
echo 'shar: File.cc was damaged during transit (should have had 633 lines)'
fi


echo 'x - Makefile'
sed 's/^X//' << '________This_Is_The_END________' > Makefile
XCC=./c++
XCCL=./c++l
XTOUCH=/usr/att/bin/touch
X.SUFFIXES: .cc
XMODULES=File.cc myenv.cc task_env.cc
XLAMODULES=matrix1.cc matrix2.cc vector.cc determinant.cc ali.cc \
X	  fft_init.cc fft_input.cc fft_output.cc hjmin.cc zeroin.cc fminbr.cc
X
X#	Rules
X.cc.o: 
X	$(CC) $*.cc
X
X.cc:	$*.cc libla.a
X	$(CC) $*.cc
X	$(CCL) $*.o libla.a -o $*
X	./$*
X	
X.o:	$*.o libla.a
X	$(CCL) $*.o libla.a -o $*
X	./$*
X	
X# Primary goal
X
Xlibserv.a:    $(MODULES)
X	$(CC) $*.cc
X	ar rv libserv.a $*.o
X	rm $*.o
X	ranlib libserv.a
X
X# Linear Algebra Library
X
Xlalib:	libla.a
X
Xlibla.a::	LinAlg.h
X# 					Make the library very obsolete
X	$(TOUCH) 0101010180 $@
X
Xlibla.a::	$(LAMODULES)
X
X# 			Compile the source files that have been changed 
X	$(CC) $?
X	listobj=`echo $? | sed s/.cc/.o/g` ; \
X	ar rv libla.a $$listobj &&	\
X	rm $$listobj
X	ranlib libla.a
X
X
X# Verification routines
Xvvector:	vvector.o libla.a
X	$(CCL) vvector.o libla.a -o vvector
X	./vvector
X
X
X# Specific dependent goals
X
X
X# Dependence rules
X
X
________This_Is_The_END________
if test `wc -l < Makefile` -ne 59; then
echo 'shar: Makefile was damaged during transit (should have had 59 lines)'
fi


echo 'x - c++'
sed 's/^X//' << '________This_Is_The_END________' > c++
X#!/bin/csh
X#	GNU C++ compilation
Xg++ -c -O -pipe -W -Wall -Wpointer-arith -finline-functions  -fforce-mem \
X-fforce-addr -fstrict-prototype -felide-constructors \
X-I. -I{$HOME}/croot/c++-include/ -I- $*
________This_Is_The_END________
if test `wc -l < c++` -ne 5; then
echo 'shar: c++ was damaged during transit (should have had 5 lines)'
fi


echo 'x - c++l'
sed 's/^X//' << '________This_Is_The_END________' > c++l
X#!/bin/csh
X#	GNU C++ linking
Xg++ -O -pipe -W -Wall -Wpointer-arith -finline-functions  -fforce-mem \
X-fforce-addr -fstrict-prototype -felide-constructors \
X-L{$HOME}/croot/c++serv $* -lserv -lg++ -lm
________This_Is_The_END________
if test `wc -l < c++l` -ne 5; then
echo 'shar: c++l was damaged during transit (should have had 5 lines)'
fi



