Index: ThirdParty/mpqc_open/src/lib/util/psi3/libpsio/Makefile
===================================================================
--- ThirdParty/mpqc_open/src/lib/util/psi3/libpsio/Makefile	(revision 860145ede0311b3539e419277d8ca4a3091f40b2)
+++ ThirdParty/mpqc_open/src/lib/util/psi3/libpsio/Makefile	(revision 860145ede0311b3539e419277d8ca4a3091f40b2)
@@ -0,0 +1,68 @@
+#
+# Makefile
+#
+# Copyright (C) 1996 Limit Point Systems, Inc.
+#
+# Author: Curtis Janssen <cljanss@ca.sandia.gov>
+# Maintainer: LPS
+#
+# This file is part of the SC Toolkit.
+#
+# The SC Toolkit is free software; you can redistribute it and/or modify
+# it under the terms of the GNU Library General Public License as published by
+# the Free Software Foundation; either version 2, or (at your option)
+# any later version.
+#
+# The SC Toolkit 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 Library General Public License for more details.
+#
+# You should have received a copy of the GNU Library General Public License
+# along with the SC Toolkit; see the file COPYING.LIB.  If not, write to
+# the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+#
+# The U.S. Government is granted a limited license as per AL 91-7.
+#
+
+TOPDIR=../../../../..
+ifndef SRCDIR
+  SRCDIR=$(shell pwd)
+endif
+include $(SRCDIR)/$(TOPDIR)/lib/GlobalMakefile
+
+CXXSRC = init.cc done.cc open.cc close.cc open_check.cc error.cc \
+rw.cc read.cc write.cc \
+tocwrite.cc tocread.cc tocscan.cc toclast.cc tocdel.cc tocclean.cc tocprint.cc \
+get_filename.cc get_numvols.cc get_volpath.cc volseek.cc get_address.cc get_global_address.cc \
+write_entry.cc read_entry.cc write_block.cc read_block.cc
+
+LIBOBJ = $(CXXSRC:%.cc=%.$(OBJSUF)) $(GENCXXSRC:%.cc=%.$(OBJSUF))
+
+INC = psio.h psio.gbl
+
+DEPENDINCLUDE = $(INC) $(GENINC)
+
+BIN_OR_LIB = LIB
+TARGET_TO_MAKE = libSCpsio
+
+TESTCXXSRC = psiotest.cc
+DISTFILES = $(CXXSRC) $(INC) Makefile LIBS.h $(TESTCXXSRC)
+
+TESTPROGS = psiotest
+
+default:: $(DEPENDINCLUDE)
+
+interface:: $(DEPENDINCLUDE)
+
+# a test program
+LD = $(CXX)
+psiotest: psiotest.$(OBJSUF) libSCpsio.$(LIBSUF) libSCclass.$(LIBSUF) libSCcontainer.$(LIBSUF) libSCref.$(LIBSUF) libSCmisc.$(LIBSUF) libSCstate.$(LIBSUF) libSCkeyval.$(LIBSUF)
+	$(LTLINK) $(LD) $(LDFLAGS) -o psiotest $^ $(SYSLIBS) $(LTLINKBINOPTS)
+
+include $(SRCDIR)/$(TOPDIR)/lib/GlobalRules
+
+$(TESTCXXSRC:%.cc=%.d) $(LIBOBJ:.$(OBJSUF)=.d): $(DEPENDINCLUDE)
+ifneq ($(DODEPEND),no)
+include $(TESTCXXSRC:%.cc=%.d) $(LIBOBJ:.$(OBJSUF)=.d)
+endif
Index: ThirdParty/mpqc_open/src/lib/util/psi3/libpsio/close.cc
===================================================================
--- ThirdParty/mpqc_open/src/lib/util/psi3/libpsio/close.cc	(revision 860145ede0311b3539e419277d8ca4a3091f40b2)
+++ ThirdParty/mpqc_open/src/lib/util/psi3/libpsio/close.cc	(revision 860145ede0311b3539e419277d8ca4a3091f40b2)
@@ -0,0 +1,72 @@
+/*! \defgroup PSIO libpsio: The PSI I/O Library */
+
+/*!
+** \file close.cc
+** \ingroup (PSIO)
+*/
+
+#include <unistd.h>
+#include <string.h>
+#include <stdlib.h>
+#include <util/psi3/libpsio/psio.h>
+
+namespace psi3 {
+namespace libpsio {
+
+/*!
+** \ingroup (PSIO)
+** PSIO_CLOSE(): Closes a multivolume PSI direct access file.
+**
+**  \param unit = The PSI unit number used to identify the file to all read
+**                and write functions.
+**  \param keep = Boolean to indicate if the file should be deleted (0) or
+**                retained (1).
+*/
+
+int psio_close(unsigned int unit, int keep)
+{
+  unsigned int i;
+  psio_ud *this_unit;
+  psio_tocentry *this_entry, *next_entry;
+
+  this_unit = &(psio_unit[unit]);
+
+  /* First check to see if this unit is already closed */
+  if(this_unit->vol[0].stream == -1) psio_error(unit,PSIO_ERROR_RECLOSE);
+
+  /* Dump the current TOC back out to disk */
+  psio_tocwrite(unit);
+
+  /* Free the TOC */
+  this_entry = this_unit->toc;
+  for(i=0; i < this_unit->toclen; i++) {
+      next_entry = this_entry->next;
+      free(this_entry);
+      this_entry = next_entry;
+    }
+
+  /* Close each volume (remove if necessary) and free the path */
+  for(i=0; i < this_unit->numvols; i++) {
+
+      if(close(this_unit->vol[i].stream) == -1)
+	  psio_error(unit,PSIO_ERROR_CLOSE);
+
+      /* Delete the file completely if requested */
+      if(!keep) unlink(this_unit->vol[i].path);
+
+      free(this_unit->vol[i].path);
+      this_unit->vol[i].path = NULL;
+      this_unit->vol[i].stream = -1;
+    }
+
+  /* Reset the global page stats to zero */
+  this_unit->numvols = 0;
+  this_unit->toclen = 0;
+  this_unit->tocaddress.page = 0;
+  this_unit->tocaddress.offset = 0;
+
+  return(0);
+}
+
+}
+}
Index: ThirdParty/mpqc_open/src/lib/util/psi3/libpsio/done.cc
===================================================================
--- ThirdParty/mpqc_open/src/lib/util/psi3/libpsio/done.cc	(revision 860145ede0311b3539e419277d8ca4a3091f40b2)
+++ ThirdParty/mpqc_open/src/lib/util/psi3/libpsio/done.cc	(revision 860145ede0311b3539e419277d8ca4a3091f40b2)
@@ -0,0 +1,63 @@
+/*!
+** \file done.cc
+** \ingroup (PSIO)
+*/
+
+#include <stdlib.h>
+#include <util/psi3/libpsio/psio.h>
+
+#ifdef PSIO_STATS
+#include <time.h>
+#endif
+
+namespace psi3 {
+namespace libpsio {
+
+/*!
+** \ingroup (PSIO)
+**
+** PSIO_DONE(): Frees global data used by the I/O routines.
+**
+** No arguments.
+*/
+
+int psio_done(void)
+{
+#ifdef PSIO_STATS
+  int i;
+  ULI total_read=0, total_write=0;
+  FILE *io_out;
+  time_t my_time;
+  my_time = time(NULL);
+  io_out = fopen("psio.dat", "a+");
+  fprintf(io_out, "\nLIBPSIO Read/Write Statistics\n\n");
+  fprintf(io_out, "Run at: %s\n", ctime(&my_time));
+  fprintf(io_out, "Unit      Read(kB)    Write(kB)\n");
+  fprintf(io_out, "-------------------------------\n");
+  for(i=0; i < PSIO_MAXUNIT; i++) {
+      total_read += psio_readlen[i];
+      total_write += psio_writlen[i];
+      
+      if(psio_readlen[i] || psio_writlen[i])
+	  fprintf(io_out, "%3d   %10.1f   %10.1f\n",i,
+		  ((double) psio_readlen[i])/((double) 1024),
+		  ((double) psio_writlen[i])/((double) 1024));
+    }
+  fprintf(io_out, "-------------------------------\n");
+  fprintf(io_out, "Total %10.1f   %10.1f\n",
+	  ((double) total_read)/((double) 1024),
+	  ((double) total_write)/((double) 1024));
+  fclose(io_out);
+  free(psio_readlen);
+  free(psio_writlen);
+#endif  
+
+  free(psio_unit);
+
+  _psi3_libpsio_state_ = 0;
+
+  return(0);
+}
+
+}
+}
Index: ThirdParty/mpqc_open/src/lib/util/psi3/libpsio/error.cc
===================================================================
--- ThirdParty/mpqc_open/src/lib/util/psi3/libpsio/error.cc	(revision 860145ede0311b3539e419277d8ca4a3091f40b2)
+++ ThirdParty/mpqc_open/src/lib/util/psi3/libpsio/error.cc	(revision 860145ede0311b3539e419277d8ca4a3091f40b2)
@@ -0,0 +1,106 @@
+/*!
+** \file error.cc
+** \ingroup (PSIO)
+*/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <util/psi3/libpsio/psio.h>
+#include <util/psi3/libpsio/psifiles.h>
+
+namespace psi3 {
+namespace libpsio {
+
+/*!
+** \ingroup (PSIO)
+**
+** PSIO_ERROR(): Print out an error message for libpsio.
+**
+** \param unit   = file number
+** \param errval = error code (defined symbolically, PSIO_ERROR_XXX)
+**
+*/
+void psio_error(unsigned int unit, unsigned int errval)
+{
+  int i;
+
+  fprintf(stderr, "PSIO_ERROR: unit = %d\n", unit);
+  /* Try to save the TOCs for all open units */
+  /* psio_tocwrite() does not call psio_error() so this is OK */
+  for(i=0; i < PSIO_MAXUNIT; i++) psio_tocwrite(i);
+
+  switch(errval) {
+  case PSIO_ERROR_INIT:
+      fprintf(stderr, "PSIO_ERROR: %d (I/O inititalization failed)\n",
+	      PSIO_ERROR_INIT);
+      break;
+  case PSIO_ERROR_DONE:
+      fprintf(stderr, "PSIO_ERROR: %d (I/O cleanup failed)\n",
+	      PSIO_ERROR_DONE);
+      break;
+  case PSIO_ERROR_MAXVOL:
+      fprintf(stderr, "PSIO_ERROR: %d (maximum number of volumes exceeded)\n",
+	      PSIO_ERROR_MAXVOL);
+      break;
+  case PSIO_ERROR_NOVOLPATH:
+      fprintf(stderr, "PSIO_ERROR: %d (no volume path given)\n",
+	      PSIO_ERROR_NOVOLPATH);
+      break;
+  case PSIO_ERROR_IDENTVOLPATH:
+      fprintf(stderr, "PSIO_ERROR: %d (two identical volume paths)\n",
+              PSIO_ERROR_IDENTVOLPATH);
+      break;
+  case PSIO_ERROR_OPEN:
+      fprintf(stderr, "PSIO_ERROR: %d (file not open or open call failed)\n",
+	      PSIO_ERROR_OPEN);
+      break;
+  case PSIO_ERROR_REOPEN:
+      fprintf(stderr, "PSIO_ERROR: %d (file is already open)\n",
+	      PSIO_ERROR_REOPEN);
+      break;
+  case PSIO_ERROR_CLOSE:
+      fprintf(stderr, "PSIO_ERROR: %d (file close failed)\n",
+	      PSIO_ERROR_CLOSE);
+      break;
+  case PSIO_ERROR_RECLOSE:
+      fprintf(stderr, "PSIO_ERROR: %d (file is already closed)\n",
+	      PSIO_ERROR_RECLOSE);
+      break;
+  case PSIO_ERROR_OSTAT:
+      fprintf(stderr, "PSIO_ERROR: %d (invalid status flag for file open)\n",
+	      PSIO_ERROR_OSTAT);
+      break;
+  case PSIO_ERROR_LSEEK:
+      fprintf(stderr, "PSIO_ERROR: %d (lseek failed)\n",
+	      PSIO_ERROR_LSEEK);
+      break;
+  case PSIO_ERROR_NOTOCENT:
+      fprintf(stderr, "PSIO_ERROR: %d (no such TOC entry)\n",
+	      PSIO_ERROR_NOTOCENT);
+      break;
+  case PSIO_ERROR_TOCENTSZ:
+      fprintf(stderr, "PSIO_ERROR: %d (TOC entry size mismatch)\n",
+	      PSIO_ERROR_TOCENTSZ);
+      break;
+  case PSIO_ERROR_KEYLEN:
+      fprintf(stderr, "PSIO_ERROR: %d (TOC key too long)\n",
+	      PSIO_ERROR_KEYLEN);
+      break;
+  case PSIO_ERROR_BLKSIZ:
+      fprintf(stderr, "PSIO_ERROR: %d (Requested blocksize invalid)\n",
+	      PSIO_ERROR_BLKSIZ);
+      break;
+  case PSIO_ERROR_BLKSTART:
+      fprintf(stderr, "PSIO_ERROR: %d (Incorrect block start address)\n",
+	      PSIO_ERROR_BLKSTART);
+      break;
+  case PSIO_ERROR_BLKEND:
+      fprintf(stderr, "PSIO_ERROR: %d (Incorrect block end address)\n",
+	      PSIO_ERROR_BLKEND);
+      break;
+    }
+  exit(PSI_RETURN_FAILURE);
+}
+
+}
+}
Index: ThirdParty/mpqc_open/src/lib/util/psi3/libpsio/get_address.cc
===================================================================
--- ThirdParty/mpqc_open/src/lib/util/psi3/libpsio/get_address.cc	(revision 860145ede0311b3539e419277d8ca4a3091f40b2)
+++ ThirdParty/mpqc_open/src/lib/util/psi3/libpsio/get_address.cc	(revision 860145ede0311b3539e419277d8ca4a3091f40b2)
@@ -0,0 +1,38 @@
+/*!
+** \file get_address.c
+** \ingroup (PSIO)
+*/
+ 
+#include <util/psi3/libpsio/psio.h>
+
+namespace psi3 {
+namespace libpsio {
+
+/*!
+** PSIO_GET_ADDRESS(): Given a starting page/offset and a shift length
+** (in bytes), return the page/offset of the next position in the file.
+** \ingroup(PSIO)
+*/
+
+psio_address psio_get_address(psio_address start, ULI shift)
+{
+  psio_address address;
+  ULI bytes_left;
+
+  bytes_left = PSIO_PAGELEN - start.offset; /* Bytes remaining on fpage */
+
+  if(shift >= bytes_left) { /* Shift to later page */
+      address.page = start.page + (shift - bytes_left)/PSIO_PAGELEN + 1;
+      address.offset = shift - bytes_left -
+			(address.page - start.page - 1)*PSIO_PAGELEN;
+    }
+  else {  /* Block starts on current page */
+      address.page = start.page;
+      address.offset = start.offset + shift;
+    }
+
+  return address;
+}
+
+}
+}
Index: ThirdParty/mpqc_open/src/lib/util/psi3/libpsio/get_filename.cc
===================================================================
--- ThirdParty/mpqc_open/src/lib/util/psi3/libpsio/get_filename.cc	(revision 860145ede0311b3539e419277d8ca4a3091f40b2)
+++ ThirdParty/mpqc_open/src/lib/util/psi3/libpsio/get_filename.cc	(revision 860145ede0311b3539e419277d8ca4a3091f40b2)
@@ -0,0 +1,53 @@
+/*!
+   \file get_filename.c
+   \ingroup (PSIO)
+*/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <util/psi3/libpsio/psio.h>
+
+namespace psi3 {
+namespace libpsio {
+
+/*!
+** PSIO_GET_FILENAME(): Get the filename for filenumber 'unit'
+**
+** Returns: 
+**   0 if a user-specified filename was found
+**   1 if the global default will be used
+**
+** \ingroup (PSIO)
+*/
+int psio_get_filename(unsigned int unit, char *name)
+{
+  int errcod;
+  char ip_token[PSIO_MAXSTR];
+
+  sprintf(ip_token,":PSI:FILES:FILE%u:NAME",unit);
+//  errcod = ip_data(ip_token,"%s",name,0);
+//  if(errcod == IPE_OK) return(0);
+
+  sprintf(ip_token,":DEFAULT:FILES:FILE%u:NAME",unit);
+//  errcod = ip_data(ip_token,"%s",name,0);
+//  if(errcod == IPE_OK) return(0);
+
+//  strcpy(name,psi_file_prefix);
+  sprintf(name, "psiotest");
+  return(1);
+}
+
+
+/*!
+** PSIO_GET_FILENAME_DEFAULT(): Get the default filename
+*/
+int psio_get_filename_default(char *name)
+{
+//  strcpy(name,psi_file_prefix);
+  sprintf(name, "psiotest");
+  return(0);
+}
+
+}
+}
Index: ThirdParty/mpqc_open/src/lib/util/psi3/libpsio/get_global_address.cc
===================================================================
--- ThirdParty/mpqc_open/src/lib/util/psi3/libpsio/get_global_address.cc	(revision 860145ede0311b3539e419277d8ca4a3091f40b2)
+++ ThirdParty/mpqc_open/src/lib/util/psi3/libpsio/get_global_address.cc	(revision 860145ede0311b3539e419277d8ca4a3091f40b2)
@@ -0,0 +1,35 @@
+/*!
+   \file get_global_address.c
+   \ingroup (PSIO)
+*/
+
+#include <util/psi3/libpsio/psio.h>
+
+namespace psi3 {
+namespace libpsio {
+
+/*!
+** PSIO_GET_GLOBAL_ADDRESS(): Given the global starting address for a
+** TOC entry and a relative offset within the entry, compute the global
+** address for the offset.
+** 
+** \ingroup (PSIO)
+*/
+
+psio_address psio_get_global_address(psio_address entry_start,
+				     psio_address rel_address)
+{
+  psio_address address;
+
+  address.page = entry_start.page + rel_address.page;
+  address.offset = entry_start.offset + rel_address.offset;
+  if((entry_start.offset + rel_address.offset) >= PSIO_PAGELEN) {
+     address.offset -= PSIO_PAGELEN;
+     address.page++;
+     }
+
+  return(address);
+}
+
+}
+}
Index: ThirdParty/mpqc_open/src/lib/util/psi3/libpsio/get_numvols.cc
===================================================================
--- ThirdParty/mpqc_open/src/lib/util/psi3/libpsio/get_numvols.cc	(revision 860145ede0311b3539e419277d8ca4a3091f40b2)
+++ ThirdParty/mpqc_open/src/lib/util/psi3/libpsio/get_numvols.cc	(revision 860145ede0311b3539e419277d8ca4a3091f40b2)
@@ -0,0 +1,75 @@
+/*!
+   \file get_numvols.c
+   \ingroup (PSIO)
+*/
+ 
+#include <stdio.h>
+#include <string.h>
+#include <util/psi3/libpsio/psio.h>
+
+namespace psi3 {
+namespace libpsio {
+
+/*!
+** PSIO_GET_NUMVOLS(): Get the number of volumes that file number 'unit'
+** is split across.
+**
+** \ingroup (PSIO)
+*/
+unsigned int psio_get_numvols(unsigned int unit)
+{
+  unsigned int num;
+  int errcod;
+  char ip_token[PSIO_MAXSTR];
+
+  num = 0;
+
+  sprintf(ip_token,":PSI:FILES:FILE%u:NVOLUME",unit);
+//  errcod = ip_data(ip_token,"%u",&num,0);
+//  if(errcod == IPE_OK) return(num);
+
+  sprintf(ip_token,":PSI:FILES:DEFAULT:NVOLUME");
+//  errcod = ip_data(ip_token,"%u",&num,0);
+//  if(errcod == IPE_OK) return(num);
+
+  sprintf(ip_token,":DEFAULT:FILES:FILE%u:NVOLUME",unit);
+//  errcod = ip_data(ip_token,"%u",&num,0);
+//  if(errcod == IPE_OK) return(num);
+
+  sprintf(ip_token,":DEFAULT:FILES:DEFAULT:NVOLUME");
+//  errcod = ip_data(ip_token,"%u",&num,0);
+//  if(errcod == IPE_OK) return(num);
+
+  /* default to one volume */
+  return(1);
+}
+
+
+/*!
+** PSIO_GET_NUMVOLS_DEFAULT(): Get the number of volumes that file 
+** number 'unit' is split across.
+**
+** \ingroup (PSIO)
+*/
+unsigned int psio_get_numvols_default(void)
+{
+  unsigned int num;
+  int errcod;
+  char ip_token[PSIO_MAXSTR];
+
+  num = 0;
+
+  sprintf(ip_token,":PSI:FILES:DEFAULT:NVOLUME");
+//  errcod = ip_data(ip_token,"%u",&num,0);
+//  if(errcod == IPE_OK) return(num);
+
+  sprintf(ip_token,":DEFAULT:FILES:DEFAULT:NVOLUME");
+//  errcod = ip_data(ip_token,"%u",&num,0);
+//  if(errcod == IPE_OK) return(num);
+
+  /* default to one volume */
+  return(1);
+}
+
+}
+}
Index: ThirdParty/mpqc_open/src/lib/util/psi3/libpsio/get_volpath.cc
===================================================================
--- ThirdParty/mpqc_open/src/lib/util/psi3/libpsio/get_volpath.cc	(revision 860145ede0311b3539e419277d8ca4a3091f40b2)
+++ ThirdParty/mpqc_open/src/lib/util/psi3/libpsio/get_volpath.cc	(revision 860145ede0311b3539e419277d8ca4a3091f40b2)
@@ -0,0 +1,73 @@
+/*!
+   \file get_volpath.c
+   \ingroup (PSIO)
+*/
+
+#include <stdio.h>
+#include <util/psi3/libpsio/psifiles.h>
+#include <util/psi3/libpsio/psio.h>
+
+namespace psi3 {
+namespace libpsio {
+
+/*
+** PSIO_GET_VOLPATH(): Get the path to a given volume for file number
+** 'unit'.
+**
+** \ingroup (PSIO)
+*/
+int psio_get_volpath(unsigned int unit, unsigned int volume, char *path)
+{
+  int errcod;
+  char ip_token[PSIO_MAXSTR];
+
+  sprintf(ip_token,":PSI:FILES:FILE%u:VOLUME%u",unit,volume+1);
+//  errcod = ip_data(ip_token,"%s",path,0);
+//  if(errcod == IPE_OK) return(0);
+
+  sprintf(ip_token,":PSI:FILES:DEFAULT:VOLUME%u",volume+1);
+//  errcod = ip_data(ip_token,"%s",path,0);
+//  if(errcod == IPE_OK) return(0);
+
+  sprintf(ip_token,":DEFAULT:FILES:FILE%u:VOLUME%u",unit,volume+1);
+//  errcod = ip_data(ip_token,"%s",path,0);
+//  if(errcod == IPE_OK) return(0);
+
+  sprintf(ip_token,":DEFAULT:FILES:DEFAULT:VOLUME%u",volume+1);
+//  errcod = ip_data(ip_token,"%s",path,0);
+//  if(errcod == IPE_OK) return(0);
+
+  /* default to /tmp/ for everything but chkpt */
+  if(unit == PSIF_CHKPT) sprintf(path, "./");
+  else sprintf(path, "/tmp/");
+  return(1);
+}
+
+
+/*
+** PSIO_GET_VOLPATH_DEFAULT(): Get the default path for the nth volume
+** of any file.
+**
+** \ingroup (PSIO)
+*/
+int psio_get_volpath_default(unsigned int volume, char *path)
+{
+  int errcod;
+  char ip_token[PSIO_MAXSTR];
+
+  sprintf(ip_token,":PSI:FILES:DEFAULT:VOLUME%u",volume+1);
+//  errcod = ip_data(ip_token,"%s",path,0);
+//  if(errcod == IPE_OK) return(0);
+
+  sprintf(ip_token,":DEFAULT:FILES:DEFAULT:VOLUME%u",volume+1);
+//  errcod = ip_data(ip_token,"%s",path,0);
+//  if(errcod == IPE_OK) return(0);
+
+  /* default to /tmp/ */
+  sprintf(path, "/tmp/");
+
+  return(1);
+}
+
+}
+}
Index: ThirdParty/mpqc_open/src/lib/util/psi3/libpsio/init.cc
===================================================================
--- ThirdParty/mpqc_open/src/lib/util/psi3/libpsio/init.cc	(revision 860145ede0311b3539e419277d8ca4a3091f40b2)
+++ ThirdParty/mpqc_open/src/lib/util/psi3/libpsio/init.cc	(revision 860145ede0311b3539e419277d8ca4a3091f40b2)
@@ -0,0 +1,101 @@
+/*!
+   \file init.cc
+   \ingroup (PSIO)
+*/
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include <util/psi3/libpsio/psio.h>
+#include <util/psi3/libpsio/psifiles.h>
+
+using namespace psi3::libpsio;
+
+namespace psi3 {
+namespace libpsio {
+
+psio_ud *psio_unit;
+psio_address PSIO_ZERO = {0,0};
+
+/* Library state variable */
+int _psi3_libpsio_state_ = 0;
+
+#ifdef PSIO_STATS
+ULI *psio_readlen;
+ULI *psio_writlen;
+#endif
+
+/*!
+** PSIO_INIT(): Allocates global memory needed by the I/O routines.
+**
+** No arguments.
+**
+** \ingroup (PSIO)
+*/
+
+int psio_init(void)
+{
+  int i,j;
+  char *userhome;
+  char filename[PSIO_MAXSTR];
+  FILE *psirc;
+
+  psio_unit = (psio_ud *) malloc(sizeof(psio_ud)*PSIO_MAXUNIT);
+
+#ifdef PSIO_STATS
+  psio_readlen = (ULI *) malloc(sizeof(ULI) * PSIO_MAXUNIT);
+  psio_writlen = (ULI *) malloc(sizeof(ULI) * PSIO_MAXUNIT);
+#endif
+
+  if(psio_unit == NULL) {
+    fprintf(stderr, "Error in PSIO_INIT()!\n");
+    exit(PSI_RETURN_FAILURE);
+  }
+
+  for(i=0; i < PSIO_MAXUNIT; i++) {
+#ifdef PSIO_STATS
+    psio_readlen[i] = psio_writlen[i] = 0;
+#endif      
+    psio_unit[i].numvols = 0;
+    for(j=0; j < PSIO_MAXVOL; j++) {
+      psio_unit[i].vol[j].path = NULL;
+      psio_unit[i].vol[j].stream = -1;
+    }
+    psio_unit[i].tocaddress.page = 0;
+    psio_unit[i].tocaddress.offset = 0;
+    psio_unit[i].toclen = 0;
+    psio_unit[i].toc = NULL;
+  }
+
+  /* Open user's general .psirc file, if extant */
+  userhome = getenv("HOME");
+  sprintf(filename, "%s%s", userhome, "/.psirc");
+  psirc = fopen(filename, "r");
+  if(psirc != NULL) {
+    // Need to parse the file elsewhere
+    // ip_append(psirc, stdout);
+    fclose(psirc);
+  }
+
+  /* Set library's state variable to initialized value (1) */
+  _psi3_libpsio_state_ = 1;
+
+  return(0);
+}
+
+/*!
+** PSIO_STATE(): Returns state of the library (1=initialized, 0=noninitialized).
+**
+** No arguments.
+**
+** \ingroup (PSIO)
+*/
+
+int psio_state()
+{
+  return _psi3_libpsio_state_;
+}
+
+}
+}
+
Index: ThirdParty/mpqc_open/src/lib/util/psi3/libpsio/open.cc
===================================================================
--- ThirdParty/mpqc_open/src/lib/util/psi3/libpsio/open.cc	(revision 860145ede0311b3539e419277d8ca4a3091f40b2)
+++ ThirdParty/mpqc_open/src/lib/util/psi3/libpsio/open.cc	(revision 860145ede0311b3539e419277d8ca4a3091f40b2)
@@ -0,0 +1,112 @@
+/*!
+   \file open.cc
+   \ingroup (PSIO)
+*/
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <string.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <util/psi3/libpsio/psio.h>
+
+namespace psi3 {
+namespace libpsio {
+
+/*!
+** PSIO_OPEN(): Opens a multivolume PSI direct access file for
+** reading/writing data.
+**
+**  \param unit   = The PSI unit number used to identify the file to all
+**                  read and write functions.
+**  \param status = Indicates if the file is old (PSIO_OPEN_OLD) or new
+**                  (PSIO_OPEN_NEW). 
+**
+** \ingroup (PSIO)
+*/
+
+int psio_open(unsigned int unit, int status)
+{
+  unsigned int i, j;
+  int errcod, stream, tocstat;
+  char name[PSIO_MAXSTR],path[PSIO_MAXSTR],fullpath[PSIO_MAXSTR];
+  psio_ud *this_unit;
+
+  this_unit = &(psio_unit[unit]);
+
+  /* First check to see if this unit is aleady open */
+  if(this_unit->vol[0].stream != -1) psio_error(unit,PSIO_ERROR_REOPEN);
+
+  /* Get number of volumes to stripe across */
+  this_unit->numvols = psio_get_numvols(unit);
+  if(this_unit->numvols > PSIO_MAXVOL) psio_error(unit,PSIO_ERROR_MAXVOL);
+
+  if(!(this_unit->numvols)) this_unit->numvols = 1;
+
+  /* Get the file name prefix */
+  errcod = psio_get_filename(unit,name);
+
+  /* Build the name for each volume and open the file */
+  for(i=0; i < this_unit->numvols; i++) {
+    errcod = psio_get_volpath(unit, i, path);
+
+    if(errcod && this_unit->numvols > 1)
+      psio_error(unit,PSIO_ERROR_NOVOLPATH);
+
+    sprintf(fullpath, "%s%s.%u", path, name, unit);
+    this_unit->vol[i].path = (char *) malloc(strlen(fullpath)+1);
+    strcpy(this_unit->vol[i].path,fullpath);
+
+    /* Check if any previously opened volumes have the same path */
+    for(j=0; j < i; j++)
+      if (!strcmp(this_unit->vol[i].path,this_unit->vol[j].path))
+	psio_error(unit,PSIO_ERROR_IDENTVOLPATH);
+
+    /* Now open the volume */
+    if(status == PSIO_OPEN_OLD) {
+      this_unit->vol[i].stream =
+	open(this_unit->vol[i].path,O_CREAT|O_RDWR,0644);
+      if(this_unit->vol[i].stream == -1)
+	psio_error(unit,PSIO_ERROR_OPEN);
+    }
+    else if(status == PSIO_OPEN_NEW) {
+      this_unit->vol[i].stream =
+	open(this_unit->vol[i].path,O_CREAT|O_RDWR|O_TRUNC,0644);
+      if(this_unit->vol[i].stream == -1)
+	psio_error(unit,PSIO_ERROR_OPEN);
+    }
+    else psio_error(unit,PSIO_ERROR_OSTAT);
+  }
+
+  if (status == PSIO_OPEN_OLD) tocstat = psio_tocread(unit);
+  else if (status == PSIO_OPEN_NEW) {
+      
+    /* Init the TOC stats and write them to disk */
+    this_unit->tocaddress.page = 0;
+    this_unit->tocaddress.offset = 3*sizeof(ULI);
+    this_unit->toclen = 0;
+    this_unit->toc = NULL;
+
+    /* Seek vol[0] to its beginning */
+    stream = this_unit->vol[0].stream;
+    errcod = lseek(stream, 0L, SEEK_SET);
+    if(errcod == -1) psio_error(unit,PSIO_ERROR_LSEEK);
+  
+    errcod = write(stream, (char *) &(this_unit->tocaddress.page),
+		   sizeof(ULI));
+    if(errcod != sizeof(ULI)) psio_error(unit,PSIO_ERROR_WRITE);
+    errcod = write(stream, (char *) &(this_unit->tocaddress.offset),
+		   sizeof(ULI));
+    if(errcod != sizeof(ULI)) psio_error(unit,PSIO_ERROR_WRITE);
+    errcod = write(stream, (char *) &(this_unit->toclen), sizeof(ULI));
+    if(errcod != sizeof(ULI)) psio_error(unit,PSIO_ERROR_WRITE);
+
+  }
+  else psio_error(unit,PSIO_ERROR_OSTAT);
+
+  return(0);
+}
+
+}
+}
Index: ThirdParty/mpqc_open/src/lib/util/psi3/libpsio/open_check.cc
===================================================================
--- ThirdParty/mpqc_open/src/lib/util/psi3/libpsio/open_check.cc	(revision 860145ede0311b3539e419277d8ca4a3091f40b2)
+++ ThirdParty/mpqc_open/src/lib/util/psi3/libpsio/open_check.cc	(revision 860145ede0311b3539e419277d8ca4a3091f40b2)
@@ -0,0 +1,31 @@
+/*!
+   \file open_check.cc
+   \ingroup (PSIO)
+*/
+
+#include <util/psi3/libpsio/psio.h>
+
+namespace psi3 {
+namespace libpsio {
+
+/*!
+** PSIO_OPEN_CHECK(): Check to see if a given PSI direct access file
+** is already open.
+**
+** \param unit = the PSI unit number.
+**
+** \ingroup (PSIO)
+*/
+
+int psio_open_check(unsigned int unit)
+{
+  psio_ud *this_unit;
+
+  this_unit = &(psio_unit[unit]);
+
+  if(this_unit->vol[0].stream != -1) return 1;
+  else return 0;
+}
+
+}
+}
Index: ThirdParty/mpqc_open/src/lib/util/psi3/libpsio/psifiles.h
===================================================================
--- ThirdParty/mpqc_open/src/lib/util/psi3/libpsio/psifiles.h	(revision 860145ede0311b3539e419277d8ca4a3091f40b2)
+++ ThirdParty/mpqc_open/src/lib/util/psi3/libpsio/psifiles.h	(revision 860145ede0311b3539e419277d8ca4a3091f40b2)
@@ -0,0 +1,128 @@
+#ifndef util_class_psi3_libpsio_psifiles_h_
+#define util_class_psi3_libpsio_psifiles_h_
+
+#define PSI_DEFAULT_FILE_PREFIX "psi"
+
+#define PSIF_CHKPT          32 /* new libpsio checkpoint file number */
+
+#define PSIF_OPTKING        1
+#define PSIF_DSCF           31
+#define PSIF_SO_TEI         33
+#define PSIF_OEI            35
+#define PSIF_SO_R12         38
+#define PSIF_SO_R12T1       39
+#define PSIF_DERINFO        40
+#define PSIF_SO_PRESORT     41
+#define PSIF_OLD_CHKPT      42   /* Until we have flexible PSIF_CHKPT this will store previous calculation info */
+#define PSIF_CIVECT         43   /* CI vector from DETCI along with string and determinant info */
+
+#define PSIF_AO_DGDBX       44   /* B-field derivative AO integrals over GIAO Gaussians -- only bra-ket
+                                    permutational symmetry holds */
+#define PSIF_AO_DGDBY       45
+#define PSIF_AO_DGDBZ       46
+
+#define PSIF_MO_R12         79
+#define PSIF_MO_R12T1       80
+
+#define PSIF_SO_PKSUPER1    92
+#define PSIF_SO_PKSUPER2    93
+
+#define PSIF_MO_TEI         72
+#define PSIF_MO_OPDM        73
+#define PSIF_MO_TPDM        74
+#define PSIF_MO_LAG         75
+#define PSIF_AO_OPDM        76   /* PSIF_AO_OPDM also contains AO Lagrangian */
+#define PSIF_AO_TPDM        77
+
+/*
+** MO Hessian File (also contains specialized integral and Fock lists.
+** See programs STABLE and CPHF for more info.
+** -TDC, 7/00
+*/
+#define PSIF_MO_HESS        78
+#define PSIF_CPHF           78
+
+/*
+** Additions for UHF-based transformations.
+** -TDC, 6/01
+*/
+#define PSIF_MO_AA_TEI      81
+#define PSIF_MO_BB_TEI      82
+#define PSIF_MO_AB_TEI      83
+#define PSIF_MO_AA_TPDM     84
+#define PSIF_MO_BB_TPDM     85
+#define PSIF_MO_AB_TPDM     86
+#define PSIF_AA_PRESORT     87   /* AA UHF twopdm presort file */
+#define PSIF_BB_PRESORT     88   /* BB UHF twopdm presort file */
+#define PSIF_AB_PRESORT     89   /* AB UHF twopdm presort file */
+
+/* All of these one-electron quantities have been moved into PSIF_OEI
+   Most integrals are real Hermitian hence only lower triangle of the matrix is written out */
+/* These macros give libpsio TOC strings for easy identification.     */
+#define PSIF_SO_S           "SO-basis Overlap Ints"
+#define PSIF_SO_T           "SO-basis Kinetic Energy Ints"
+#define PSIF_SO_V           "SO-basis Potential Energy Ints"
+#define PSIF_AO_S           "AO-basis Overlap Ints"
+#define PSIF_AO_MX          "AO-basis Mu-X Ints"
+#define PSIF_AO_MY          "AO-basis Mu-Y Ints"
+#define PSIF_AO_MZ          "AO-basis Mu-Z Ints"
+#define PSIF_MO_MX          "MO-basis Mu-X Ints"
+#define PSIF_MO_MY          "MO-basis Mu-Y Ints"
+#define PSIF_MO_MZ          "MO-basis Mu-Z Ints"
+#define PSIF_AO_QXX         "AO-basis Q-XX Ints"    /* Electric quadrupole moment integrals */
+#define PSIF_AO_QXY         "AO-basis Q-XY Ints"
+#define PSIF_AO_QXZ         "AO-basis Q-XZ Ints"
+#define PSIF_AO_QYY         "AO-basis Q-YY Ints"
+#define PSIF_AO_QYZ         "AO-basis Q-YZ Ints"
+#define PSIF_AO_QZZ         "AO-basis Q-ZZ Ints"
+
+/* These integrals are anti-Hermitian -- upper triangle has sign opposite of that of the lower triangle */
+#define PSIF_AO_NablaX      "AO-basis Nabla-X Ints" /* integrals of nabla operator */
+#define PSIF_AO_NablaY      "AO-basis Nabla-Y Ints"
+#define PSIF_AO_NablaZ      "AO-basis Nabla-Z Ints"
+
+/* These integrals are pure imaginary Hermitian. We write the full matrix of the imaginary part of these
+integrals out (i.e. multiply by i=sqrt(-1) to get the integrals) */
+#define PSIF_AO_LX          "AO-basis LX Ints"      /* integrals of angular momentum operator */
+#define PSIF_AO_LY          "AO-basis LY Ints"
+#define PSIF_AO_LZ          "AO-basis LZ Ints"
+#define PSIF_AO_DSDB_X      "AO-basis dS/dBx Ints"      /* Overlap derivative integrals WRT B field */
+#define PSIF_AO_DSDB_Y      "AO-basis dS/dBy Ints"
+#define PSIF_AO_DSDB_Z      "AO-basis dS/dBz Ints"
+#define PSIF_AO_DHDB_X      "AO-basis dh/dBx Ints"      /* One-electron derivative integrals WRT B field */
+#define PSIF_AO_DHDB_Y      "AO-basis dh/dBy Ints"
+#define PSIF_AO_DHDB_Z      "AO-basis dh/dBz Ints"
+#define PSIF_AO_D2HDBDE_XX  "AO-basis d2h/dBxdEx Ints"  /* One-electron derivative integrals WRT E and B fields */
+#define PSIF_AO_D2HDBDE_XY  "AO-basis d2h/dBxdEy Ints"
+#define PSIF_AO_D2HDBDE_XZ  "AO-basis d2h/dBxdEz Ints"
+#define PSIF_AO_D2HDBDE_YX  "AO-basis d2h/dBydEx Ints"
+#define PSIF_AO_D2HDBDE_YY  "AO-basis d2h/dBydEy Ints"
+#define PSIF_AO_D2HDBDE_YZ  "AO-basis d2h/dBydEz Ints"
+#define PSIF_AO_D2HDBDE_ZX  "AO-basis d2h/dBzdEx Ints"
+#define PSIF_AO_D2HDBDE_ZY  "AO-basis d2h/dBzdEy Ints"
+#define PSIF_AO_D2HDBDE_ZZ  "AO-basis d2h/dBzdEz Ints"
+#define PSIF_MO_DFDB_X      "AO-basis dF/dBx Ints"      /* Fock operator derivative integrals WRT B field */
+#define PSIF_MO_DFDB_Y      "AO-basis dF/dBy Ints"
+#define PSIF_MO_DFDB_Z      "AO-basis dF/dBz Ints"
+
+#define PSIF_MO_OEI         "MO-basis One-electron Ints"
+#define PSIF_MO_A_OEI       "MO-basis Alpha One-electron Ints"
+#define PSIF_MO_B_OEI       "MO-basis Beta One-electron Ints"
+#define PSIF_MO_FZC         "MO-basis Frozen-Core Operator"
+#define PSIF_MO_A_FZC       "MO-basis Alpha Frozen-Core Oper"
+#define PSIF_MO_B_FZC       "MO-basis Beta Frozen-Core Oper"
+
+/* More macros */
+#define PSIF_AO_OPDM_TRIANG "AO-basis OPDM triang"
+#define PSIF_AO_LAG_TRIANG  "AO-basis Lagrangian triang"
+#define PSIF_AO_OPDM_SQUARE "AO-basis OPDM square"
+#define PSIF_SO_OPDM        "SO-basis OPDM"
+#define PSIF_SO_OPDM_TRIANG "SO-basis triang"
+
+/* PSI return codes --- for new PSI driver           */
+#define PSI_RETURN_SUCCESS      0
+#define PSI_RETURN_FAILURE      1
+#define PSI_RETURN_ENDLOOP      2
+
+#endif
+
Index: ThirdParty/mpqc_open/src/lib/util/psi3/libpsio/psio.gbl
===================================================================
--- ThirdParty/mpqc_open/src/lib/util/psi3/libpsio/psio.gbl	(revision 860145ede0311b3539e419277d8ca4a3091f40b2)
+++ ThirdParty/mpqc_open/src/lib/util/psi3/libpsio/psio.gbl	(revision 860145ede0311b3539e419277d8ca4a3091f40b2)
@@ -0,0 +1,72 @@
+
+#ifndef util_class_psi3_libpsio_psio_gbl_
+#define util_class_psi3_libpsio_psio_gbl_
+
+namespace psi3 {
+namespace libpsio {
+
+#define PSIO_KEYLEN 80
+#define PSIO_MAXVOL 8
+#define PSIO_MAXUNIT 300
+#define PSIO_MAXSTR 512
+#define PSIO_PAGELEN 65536
+
+typedef unsigned long int ULI;  /* For convenience */
+
+typedef struct {
+    ULI page;   /* First page of entry */
+    ULI offset; /* Starting byte offset on fpage */
+} psio_address;
+
+struct psio_entry {
+    char key[PSIO_KEYLEN];
+    psio_address sadd;
+    psio_address eadd;
+    struct psio_entry *next;
+    struct psio_entry *last;
+};
+
+typedef struct psio_entry psio_tocentry;
+
+typedef struct {
+    char *path;
+    int stream;
+} psio_vol;
+
+typedef struct {
+    ULI numvols;
+    psio_vol vol[PSIO_MAXVOL];
+    psio_address tocaddress;
+    ULI toclen;
+    psio_tocentry *toc;
+} psio_ud;
+
+extern psio_ud *psio_unit;
+
+#define PSIO_ERROR_INIT       1
+#define PSIO_ERROR_DONE       2
+#define PSIO_ERROR_MAXVOL     3
+#define PSIO_ERROR_NOVOLPATH  4
+#define PSIO_ERROR_OPEN       5
+#define PSIO_ERROR_REOPEN     6
+#define PSIO_ERROR_CLOSE      7
+#define PSIO_ERROR_RECLOSE    8
+#define PSIO_ERROR_OSTAT      9
+#define PSIO_ERROR_LSEEK     10
+#define PSIO_ERROR_READ      11
+#define PSIO_ERROR_WRITE     12
+#define PSIO_ERROR_NOTOCENT  13
+#define PSIO_ERROR_TOCENTSZ  14
+#define PSIO_ERROR_KEYLEN    15
+#define PSIO_ERROR_BLKSIZ    16
+#define PSIO_ERROR_BLKSTART  17
+#define PSIO_ERROR_BLKEND    18
+#define PSIO_ERROR_IDENTVOLPATH 19
+
+#define PSIO_OPEN_NEW 0
+#define PSIO_OPEN_OLD 1
+
+}
+}
+
+#endif    /* #ifndef PSIO_GBL */
Index: ThirdParty/mpqc_open/src/lib/util/psi3/libpsio/psio.h
===================================================================
--- ThirdParty/mpqc_open/src/lib/util/psi3/libpsio/psio.h	(revision 860145ede0311b3539e419277d8ca4a3091f40b2)
+++ ThirdParty/mpqc_open/src/lib/util/psi3/libpsio/psio.h	(revision 860145ede0311b3539e419277d8ca4a3091f40b2)
@@ -0,0 +1,68 @@
+#ifndef util_class_psi3_libpsio_psio_h_
+#define util_class_psi3_libpsio_psio_h_
+
+#include <stdio.h>
+#include <util/psi3/libpsio/psio.gbl>
+
+namespace psi3 {
+namespace libpsio {
+
+/* A convenient address initialization struct */
+extern psio_address PSIO_ZERO;
+
+/* Library state variable */
+extern int _psi3_libpsio_state_;
+
+#ifdef PSIO_STATS
+extern ULI *psio_readlen;
+extern ULI *psio_writlen;
+#endif
+
+int psio_init(void);
+int psio_state(void);
+int psio_done(void);
+void psio_error(unsigned int unit, unsigned int errval);
+int psio_open(unsigned int unit, int status);
+int psio_close(unsigned int unit, int keep);
+
+unsigned int psio_get_numvols(unsigned int unit);
+unsigned int psio_get_numvols_default(void);
+int psio_get_volpath(unsigned int unit, unsigned int volume, char *path);
+int psio_get_volpath_default(unsigned int volume, char *path);
+int psio_get_filename(unsigned int unit, char *name);
+int psio_get_filename_default(char *name);
+psio_address psio_get_address(psio_address start, ULI shift);
+psio_address psio_get_global_address(psio_address entry_start,
+                                     psio_address rel_address);
+int psio_volseek(psio_vol *vol, ULI page, ULI offset, ULI numvols);
+ULI psio_get_length(psio_address sadd, psio_address eadd);
+psio_address psio_get_entry_end(unsigned int unit, char *key);
+
+int psio_tocwrite(unsigned int unit);
+int psio_tocread(unsigned int unit);
+void psio_tocprint(unsigned int unit, FILE *output);
+psio_tocentry *psio_tocscan(unsigned int unit, char *key);
+psio_tocentry *psio_toclast(unsigned int unit);
+unsigned int psio_toclen(unsigned int unit);
+int psio_tocdel(unsigned int unit, char *key);
+int psio_tocclean(unsigned int unit, char *key);
+void psio_tocrename(unsigned int unit, char *key, char *newkey);
+
+int psio_write(unsigned int unit, char *key, char *buffer, ULI size,
+	       psio_address sadd, psio_address *eadd);
+int psio_read(unsigned int unit, char *key, char *buffer, ULI size,
+	      psio_address sadd, psio_address *eadd);
+int psio_write_entry(unsigned int unit, char *key, char *buffer, ULI size);
+int psio_read_entry(unsigned int unit, char *key, char *buffer, ULI size);
+int psio_write_block(unsigned int unit, char *key, char *buffer, ULI blksiz,
+		     ULI start_blk, ULI end_blk);
+int psio_read_block(unsigned int unit, char *key, char *buffer, ULI blksiz,
+		    ULI start_blk, ULI end_blk);
+int psio_rw(unsigned int unit, char *buffer, psio_address address, ULI size, int wrt);
+
+int psio_open_check(unsigned int unit);
+
+}
+}
+
+#endif    /* #ifndef PSIO_H */
Index: ThirdParty/mpqc_open/src/lib/util/psi3/libpsio/psiotest.cc
===================================================================
--- ThirdParty/mpqc_open/src/lib/util/psi3/libpsio/psiotest.cc	(revision 860145ede0311b3539e419277d8ca4a3091f40b2)
+++ ThirdParty/mpqc_open/src/lib/util/psi3/libpsio/psiotest.cc	(revision 860145ede0311b3539e419277d8ca4a3091f40b2)
@@ -0,0 +1,62 @@
+//
+// psiotest.cc
+//
+// Copyright (C) 2004 Edward Valeev.
+//
+// Author: Edward Valeev <edward.valeev@chemistry.gatech.edu>
+//
+// This file is part of the SC Toolkit.
+//
+// The SC Toolkit is free software; you can redistribute it and/or modify
+// it under the terms of the GNU Library General Public License as published by
+// the Free Software Foundation; either version 2, or (at your option)
+// any later version.
+//
+// The SC Toolkit 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 Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public License
+// along with the SC Toolkit; see the file COPYING.LIB.  If not, write to
+// the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+//
+// The U.S. Government is granted a limited license as per AL 91-7.
+//
+
+// a simple program to test the class stuff
+
+#include <iostream>
+#include <stdio.h>
+
+#include <util/psi3/libpsio/psio.h>
+
+using namespace std;
+using namespace psi3::libpsio;
+
+main()
+{
+  psio_init();
+  psio_open(32,0);
+
+  double A = .1111;  
+  psio_write_entry(32, ":A", (char *)&A, sizeof(double));
+  cout << "Wrote entry :A : value = " << A << endl;
+  psio_close(32,1);
+
+  psio_open(32,1);
+  psio_read_entry(32, ":A", (char *)&A, sizeof(double));
+  cout << "Read entry :A : value = " << A << endl;
+  cout << "Table of contents of file 32:" << endl;
+  psio_tocprint(32,stdout);
+  psio_close(32,1);
+
+  psio_done();
+}
+
+/////////////////////////////////////////////////////////////////////////////
+
+// Local Variables:
+// mode: c++
+// c-file-style: "CLJ"
+// End:
Index: ThirdParty/mpqc_open/src/lib/util/psi3/libpsio/read.cc
===================================================================
--- ThirdParty/mpqc_open/src/lib/util/psi3/libpsio/read.cc	(revision 860145ede0311b3539e419277d8ca4a3091f40b2)
+++ ThirdParty/mpqc_open/src/lib/util/psi3/libpsio/read.cc	(revision 860145ede0311b3539e419277d8ca4a3091f40b2)
@@ -0,0 +1,78 @@
+/*!
+   \file read.c
+   \ingroup (PSIO)
+*/
+ 
+#include <unistd.h>
+#include <string.h>
+#include <util/psi3/libpsio/psio.h>
+
+namespace psi3 {
+namespace libpsio {
+
+/*!
+** PSIO_READ(): Reads data from within a TOC entry from a PSI file.
+**
+**  \param unit   = The PSI unit number used to identify the file to all
+**                  read and write functions.
+**  \param key    = The TOC keyword identifying the desired entry.
+**  \param buffer = The buffer to store the data as it is read.
+**  \param size   = The number of bytes to read.
+**  \param sadd   = The entry-relative starting page/offset of the desired data.
+**  \param eadd   = A pointer to the entry-relative page/offset for the next
+**                  byte after the end of the read request.
+** 
+** \ingroup (PSIO)
+*/
+
+int psio_read(unsigned int unit, char *key, char *buffer, ULI size,
+	       psio_address sadd, psio_address *eadd)
+{
+  psio_ud *this_unit;
+  psio_address address, end_address;
+  psio_tocentry *this_entry;
+
+  this_unit = &(psio_unit[unit]);
+  
+  /* Find the entry in the TOC */
+  this_entry = psio_tocscan(unit, key);
+
+  if(this_entry == NULL) {
+      fprintf(stderr, "PSIO_ERROR: Can't find TOC Entry %s\n", key);
+      psio_error(unit,PSIO_ERROR_NOTOCENT);
+  }
+  else {
+
+      /* Compute the starting page and offset for the block */
+      address = psio_get_global_address(this_entry->sadd, sadd);
+
+      /* Make sure the block starts and ends within the entry */
+      if(address.page > this_entry->eadd.page)
+	  psio_error(unit,PSIO_ERROR_BLKSTART);
+      else if((address.page == this_entry->eadd.page) &&
+	      (address.offset > this_entry->eadd.offset))
+	  psio_error(unit,PSIO_ERROR_BLKSTART);
+
+      end_address = psio_get_address(address, size);
+      if((end_address.page > this_entry->eadd.page))
+	  psio_error(unit,PSIO_ERROR_BLKEND);
+      else if((end_address.page == this_entry->eadd.page) &&
+	      (end_address.offset > this_entry->eadd.offset))
+	  psio_error(unit,PSIO_ERROR_BLKEND);
+
+      /* Update the eadd argument value for the caller */
+      *eadd = psio_get_address(sadd, size);
+    }
+
+  /* Now read the actual data from the unit */
+  psio_rw(unit, buffer, address, size, 0);
+
+#ifdef PSIO_STATS
+  psio_readlen[unit] += size;
+#endif  
+
+  return(0);
+}
+
+}
+}
Index: ThirdParty/mpqc_open/src/lib/util/psi3/libpsio/read_block.cc
===================================================================
--- ThirdParty/mpqc_open/src/lib/util/psi3/libpsio/read_block.cc	(revision 860145ede0311b3539e419277d8ca4a3091f40b2)
+++ ThirdParty/mpqc_open/src/lib/util/psi3/libpsio/read_block.cc	(revision 860145ede0311b3539e419277d8ca4a3091f40b2)
@@ -0,0 +1,71 @@
+/*!
+   \file read_block.c
+   \ingroup (PSIO)
+*/
+
+#include <unistd.h>
+#include <string.h>
+#include <util/psi3/libpsio/psio.h>
+
+namespace psi3 {
+namespace libpsio {
+
+/*!
+** PSIO_READ_BLOCK(): Read a block of data.
+**
+** \param unit      = file number to read from
+** \param key       = key to search for
+** \param buffer    = where to put data
+** \param blksiz    = ??
+** \param start_blk = ??
+** \param end_blk   = ??
+**
+** \ingroup (PSIO)
+*/
+int psio_read_block(unsigned int unit, char *key, char *buffer, ULI blksiz,
+	            ULI start_blk, ULI end_blk)
+{
+  ULI size, shift;
+  psio_ud *this_unit;
+  psio_address sadd, eadd;
+  psio_tocentry *this_entry;
+
+  this_unit = &(psio_unit[unit]);
+  
+  /* Find the entry in the TOC */
+  this_entry = psio_tocscan(unit, key);
+
+  if(this_entry == NULL) {
+    fprintf(stderr, "PSIO_ERROR: Can't find TOC Entry %s\n", key);
+    psio_error(unit,PSIO_ERROR_NOTOCENT);
+  }
+  else {
+    size = (end_blk - start_blk + 1) * blksiz; /* The total buffer size */
+    shift = start_blk * blksiz; /* Number of bytes to shift from start */
+
+    /* Compute the starting page and offset for the block */
+    sadd = psio_get_address(this_entry->sadd, shift);
+
+    /* Make sure the block starts and ends within the entry */
+    if((sadd.page > this_entry->eadd.page))
+      psio_error(unit,PSIO_ERROR_BLKSTART);
+    else if((sadd.page == this_entry->eadd.page) &&
+	    (sadd.offset > this_entry->eadd.offset))
+      psio_error(unit,PSIO_ERROR_BLKSTART);
+
+    eadd = psio_get_address(sadd, size);
+    if((eadd.page > this_entry->eadd.page))
+      psio_error(unit,PSIO_ERROR_BLKEND);
+    else if((eadd.page == this_entry->eadd.page) &&
+	    (eadd.offset > this_entry->eadd.offset))
+      psio_error(unit,PSIO_ERROR_BLKEND);
+
+    /* Now read the actual data from the unit */
+    psio_rw(unit, buffer, sadd, size, 0);
+  }
+
+  return(0);
+}
+
+}
+}
Index: ThirdParty/mpqc_open/src/lib/util/psi3/libpsio/read_entry.cc
===================================================================
--- ThirdParty/mpqc_open/src/lib/util/psi3/libpsio/read_entry.cc	(revision 860145ede0311b3539e419277d8ca4a3091f40b2)
+++ ThirdParty/mpqc_open/src/lib/util/psi3/libpsio/read_entry.cc	(revision 860145ede0311b3539e419277d8ca4a3091f40b2)
@@ -0,0 +1,34 @@
+/*!
+   \file read_entry.c
+   \ingroup (PSIO)
+*/
+
+#include <util/psi3/libpsio/psio.h>
+
+namespace psi3 {
+namespace libpsio {
+
+/*!
+** PSIO_READ_ENTRY(): Reads an entire TOC entry from a PSI file.
+**
+**  \param unit   = The PSI unit number used to identify the file to all read
+**                  and write functions.
+**  \param key    = The TOC keyword identifying the desired entry.
+**  \param buffer = The buffer to store the data as it is read.
+**  \param size   = The number of bytes to read.
+**
+** Note that the value of size is not directly compared to the actual
+** size of the entry, but care is taken to ensure that the end of the
+** entry is not surpassed.
+**
+** \ingroup (PSIO)
+*/
+
+int psio_read_entry(unsigned int unit, char *key, char *buffer, ULI size)
+{
+  psio_address end;
+  return psio_read(unit, key, buffer, size, PSIO_ZERO, &end);
+}
+
+}
+}
Index: ThirdParty/mpqc_open/src/lib/util/psi3/libpsio/rw.cc
===================================================================
--- ThirdParty/mpqc_open/src/lib/util/psi3/libpsio/rw.cc	(revision 860145ede0311b3539e419277d8ca4a3091f40b2)
+++ ThirdParty/mpqc_open/src/lib/util/psi3/libpsio/rw.cc	(revision 860145ede0311b3539e419277d8ca4a3091f40b2)
@@ -0,0 +1,107 @@
+/*!
+   \file rw.c
+   \ingroup (PSIO)
+*/
+
+#include <stdio.h>
+#include <unistd.h>
+#include <util/psi3/libpsio/psio.h>
+
+namespace psi3 {
+namespace libpsio {
+
+/*!
+** PSIO_RW()
+**
+** \ingroup (PSIO)
+*/
+int psio_rw(unsigned int unit, char *buffer, psio_address address, ULI size, int wrt)
+{
+  int errcod;
+  unsigned int i;
+  ULI errcod_uli;
+  ULI page, offset;
+  ULI buf_offset;
+  ULI this_page, this_page_max, this_page_total;
+  unsigned int first_vol, this_vol, numvols;
+  ULI bytes_left, num_full_pages;
+  psio_ud *this_unit;
+
+  this_unit = &(psio_unit[unit]);
+  numvols = this_unit->numvols;
+  page = address.page;
+  offset = address.offset;
+  
+  /* Seek all volumes to correct starting positions */
+  first_vol = page % numvols;
+  errcod = psio_volseek(&(this_unit->vol[first_vol]), page, offset, numvols);
+  if(errcod == -1) psio_error(unit,PSIO_ERROR_LSEEK);
+  for(i=1,this_page=page+1; i < numvols; i++,this_page++) {
+      this_vol = this_page % numvols;
+      errcod = psio_volseek(&(this_unit->vol[this_vol]), this_page, 
+                            (ULI) 0, numvols);
+      if(errcod == -1) psio_error(unit,PSIO_ERROR_LSEEK);
+    }
+
+  /* Number of bytes left on the first page */
+  this_page_max = PSIO_PAGELEN - offset;
+
+  /* If we have enough room on this page, use it */
+  if(size <= this_page_max)  this_page_total = size;
+  else this_page_total = this_page_max;
+
+  buf_offset = 0;
+  if(wrt) {
+      errcod_uli = write(this_unit->vol[first_vol].stream, &(buffer[buf_offset]),
+		     this_page_total);
+      if(errcod_uli != this_page_total) psio_error(unit,PSIO_ERROR_WRITE);
+    }
+  else {
+      errcod_uli = read(this_unit->vol[first_vol].stream, &(buffer[buf_offset]),
+		    this_page_total);
+      if(errcod_uli != this_page_total) psio_error(unit,PSIO_ERROR_READ);
+    }
+
+  /* Total number of bytes remaining to be read/written */
+  bytes_left = size - this_page_total;
+
+  /* Read/Write all the full pages */
+  num_full_pages = bytes_left/PSIO_PAGELEN;  
+  buf_offset += this_page_total;
+  for(i=0,this_page=page+1; i < num_full_pages; i++,this_page++) {
+      this_vol = this_page % numvols;
+      this_page_total = PSIO_PAGELEN;
+      if(wrt) {
+	  errcod_uli = write(this_unit->vol[this_vol].stream, &(buffer[buf_offset]),
+			 this_page_total);
+	  if(errcod_uli != this_page_total) psio_error(unit,PSIO_ERROR_WRITE);
+	}
+      else {
+	  errcod_uli = read(this_unit->vol[this_vol].stream, &(buffer[buf_offset]),
+			this_page_total);
+	  if(errcod_uli != this_page_total) psio_error(unit,PSIO_ERROR_READ);
+	}
+      buf_offset += this_page_total;
+    }
+
+  /* Read/Write the final partial page */
+  bytes_left -= num_full_pages * PSIO_PAGELEN;
+  this_vol = this_page % numvols;
+  if(bytes_left) {
+      if(wrt) {
+	  errcod_uli = write(this_unit->vol[this_vol].stream, &(buffer[buf_offset]),
+			 bytes_left);
+	  if(errcod_uli != bytes_left) psio_error(unit,PSIO_ERROR_WRITE);
+	}
+      else {
+	  errcod_uli = read(this_unit->vol[this_vol].stream, &(buffer[buf_offset]),
+			 bytes_left);
+	  if(errcod_uli != bytes_left) psio_error(unit,PSIO_ERROR_READ);
+	}
+    }
+
+  return(0);
+}
+
+}
+}
Index: ThirdParty/mpqc_open/src/lib/util/psi3/libpsio/tocclean.cc
===================================================================
--- ThirdParty/mpqc_open/src/lib/util/psi3/libpsio/tocclean.cc	(revision 860145ede0311b3539e419277d8ca4a3091f40b2)
+++ ThirdParty/mpqc_open/src/lib/util/psi3/libpsio/tocclean.cc	(revision 860145ede0311b3539e419277d8ca4a3091f40b2)
@@ -0,0 +1,50 @@
+/*!
+   \file tocclean.c
+   \ingroup (PSIO)
+*/
+
+#include <string.h>
+#include <stdlib.h>
+#include <util/psi3/libpsio/psio.h>
+
+namespace psi3 {
+namespace libpsio {
+
+/*!
+** PSIO_TOCCLEAN(): Delete all TOC entries after the given key.
+** If a blank key is given, the entire TOC will be wiped.
+**
+** \ingroup (PSIO)
+*/
+
+int psio_tocclean(unsigned int unit, char *key)
+{
+  psio_tocentry *this_entry, *last_entry, *prev_entry;
+
+  /* Check the key length first */
+  if((strlen(key)+1) > PSIO_KEYLEN) psio_error(unit,PSIO_ERROR_KEYLEN);
+
+  this_entry = psio_tocscan(unit, key);
+  if(this_entry == NULL) {
+      if(!strcmp(key,"")) this_entry = psio_unit[unit].toc;
+      else {
+          fprintf(stderr, "PSIO_ERROR: Can't find TOC Entry %s\n", key);
+          psio_error(unit,PSIO_ERROR_NOTOCENT);
+      }
+    }
+  else this_entry = this_entry->next;
+
+  /* Get the end of the TOC and work backwards */
+  last_entry = psio_toclast(unit);
+
+  while((last_entry != this_entry) && (last_entry != NULL)) { 
+      /* Now free all the remaining members */
+      prev_entry = last_entry->last;
+      free(last_entry);
+      last_entry = prev_entry;
+    }
+  return(0);
+}
+
+}
+}
Index: ThirdParty/mpqc_open/src/lib/util/psi3/libpsio/tocdel.cc
===================================================================
--- ThirdParty/mpqc_open/src/lib/util/psi3/libpsio/tocdel.cc	(revision 860145ede0311b3539e419277d8ca4a3091f40b2)
+++ ThirdParty/mpqc_open/src/lib/util/psi3/libpsio/tocdel.cc	(revision 860145ede0311b3539e419277d8ca4a3091f40b2)
@@ -0,0 +1,47 @@
+/*!
+   \file tocdel.c
+   \ingroup (PSIO)
+*/
+
+#include <stdlib.h>
+#include <string.h>
+#include <util/psi3/libpsio/psio.h>
+
+namespace psi3 {
+namespace libpsio {
+
+/*!
+** PSIO_TOCDEL(): Delete an entry with identifier key from TOC.
+** 
+** \param unit = file number
+** \param key = entry to delete from TOC
+**
+** \ingroup (PSIO)
+*/
+
+int psio_tocdel(unsigned int unit, char *key)
+{
+  psio_tocentry *this_entry, *last_entry, *next_entry;
+
+  /* Check the key length first */
+  if((strlen(key)+1) > PSIO_KEYLEN) psio_error(unit,PSIO_ERROR_KEYLEN);
+
+  this_entry = psio_tocscan(unit, key);
+  if(this_entry == NULL) {
+      fprintf(stderr, "PSIO_ERROR: Can't find TOC Entry %s\n", key);
+      psio_error(unit,PSIO_ERROR_NOTOCENT);
+  }
+
+  last_entry = this_entry->last;
+  if(last_entry != NULL) last_entry->next = this_entry->next;
+
+  next_entry = this_entry->next;
+  if(next_entry != NULL) next_entry->last = this_entry->last;
+
+  free(this_entry);
+
+  return(0);
+}
+
+}
+}
Index: ThirdParty/mpqc_open/src/lib/util/psi3/libpsio/toclast.cc
===================================================================
--- ThirdParty/mpqc_open/src/lib/util/psi3/libpsio/toclast.cc	(revision 860145ede0311b3539e419277d8ca4a3091f40b2)
+++ ThirdParty/mpqc_open/src/lib/util/psi3/libpsio/toclast.cc	(revision 860145ede0311b3539e419277d8ca4a3091f40b2)
@@ -0,0 +1,29 @@
+/*!
+   \file toclast.c
+   \ingroup (PSIO)
+*/
+
+#include <util/psi3/libpsio/psio.h>
+
+namespace psi3 {
+namespace libpsio {
+
+/*!
+** PSIO_TOCLAST(): Returns the last TOC entry.
+**
+** \ingroup (PSIO)
+*/
+
+psio_tocentry *psio_toclast(unsigned int unit)
+{
+  psio_tocentry *this_entry;
+
+  this_entry = psio_unit[unit].toc;
+
+  while(this_entry->next != NULL) this_entry = this_entry->next;
+
+  return(this_entry);
+}
+
+}
+}
Index: ThirdParty/mpqc_open/src/lib/util/psi3/libpsio/tocprint.cc
===================================================================
--- ThirdParty/mpqc_open/src/lib/util/psi3/libpsio/tocprint.cc	(revision 860145ede0311b3539e419277d8ca4a3091f40b2)
+++ ThirdParty/mpqc_open/src/lib/util/psi3/libpsio/tocprint.cc	(revision 860145ede0311b3539e419277d8ca4a3091f40b2)
@@ -0,0 +1,44 @@
+/*!
+   \file tocprint.c
+   \ingroup (PSIO)
+*/
+
+#include <stdio.h>
+#include <util/psi3/libpsio/psio.h>
+
+namespace psi3 {
+namespace libpsio {
+
+/*!
+** PSIO_TOCPRINT(): Print the table of contents for the given unit
+**
+** \ingroup (PSIO)
+*/
+
+void psio_tocprint(unsigned int unit, FILE *output)
+{
+  psio_tocentry *this_entry;
+
+  this_entry = psio_unit[unit].toc;
+
+  fprintf(output, "\nTable of Contents for Unit %5u\n", unit);
+  fprintf(output,
+"----------------------------------------------------------------------------\n");
+  fprintf(output,
+"Key                                   Spage    Soffset      Epage    Eoffset\n");
+  fprintf(output,
+"----------------------------------------------------------------------------\n");
+
+  while(this_entry != NULL) {
+      fprintf(output, "%-32s %10lu %10lu %10lu %10lu\n",
+	      this_entry->key,
+	      this_entry->sadd.page, this_entry->sadd.offset,
+	      this_entry->eadd.page, this_entry->eadd.offset);
+      this_entry = this_entry->next;
+    }
+  fprintf(output, "\n");
+  fflush(output);
+}
+
+}
+}
Index: ThirdParty/mpqc_open/src/lib/util/psi3/libpsio/tocread.cc
===================================================================
--- ThirdParty/mpqc_open/src/lib/util/psi3/libpsio/tocread.cc	(revision 860145ede0311b3539e419277d8ca4a3091f40b2)
+++ ThirdParty/mpqc_open/src/lib/util/psi3/libpsio/tocread.cc	(revision 860145ede0311b3539e419277d8ca4a3091f40b2)
@@ -0,0 +1,80 @@
+/*!
+   \file tocread.c
+   \ingroup (PSIO)
+*/
+
+#include <unistd.h>
+#include <stdlib.h>
+#include <util/psi3/libpsio/psio.h>
+
+namespace psi3 {
+namespace libpsio {
+
+/*!
+** PSIO_TOCREAD(): Read the table of contents for file number 'unit'.
+** 
+** \ingroup (PSIO)
+*/
+int psio_tocread(unsigned int unit)
+{
+  unsigned int i;
+  int errcod, stream, volume, entry_size;
+  psio_ud *this_unit;
+  psio_tocentry *last_entry, *this_entry; 
+
+  this_unit = &(psio_unit[unit]);
+  entry_size = sizeof(psio_tocentry) - 2*sizeof(psio_tocentry *);
+
+  /* Check that this unit is actually open */
+  if(this_unit->vol[0].stream == -1) return(0);
+
+  /* Seek vol[0] to its beginning */
+  stream = this_unit->vol[0].stream;
+  errcod = lseek(stream, 0L, SEEK_SET);
+  if(errcod == -1) psio_error(unit,PSIO_ERROR_LSEEK);
+
+  /* Read the TOC from disk */
+  errcod = read(stream, (char *) &(this_unit->tocaddress.page),
+                sizeof(ULI));
+  if(errcod != sizeof(ULI)) return(1);
+  errcod = read(stream, (char *) &(this_unit->tocaddress.offset),
+                sizeof(ULI));
+  if(errcod != sizeof(ULI)) return(1);
+  errcod = read(stream, (char *) &(this_unit->toclen), sizeof(ULI));
+  if(errcod != sizeof(ULI)) return(1);
+
+  /* Malloc room for the TOC */
+  this_unit->toc = (psio_tocentry *) malloc(sizeof(psio_tocentry));
+  this_entry = this_unit->toc;
+  this_entry->last = NULL;
+  for(i=1; i < this_unit->toclen; i++) {
+      last_entry = this_entry;
+      this_entry = (psio_tocentry *) malloc(sizeof(psio_tocentry));
+      last_entry->next = this_entry;
+      this_entry->last = last_entry;
+    }
+  this_entry->next = NULL;
+
+  /* Seek the TOC volume to the correct position */
+  volume = (this_unit->tocaddress.page) % (this_unit->numvols);
+  errcod = psio_volseek(&(this_unit->vol[volume]), this_unit->tocaddress.page,
+	                this_unit->tocaddress.offset, this_unit->numvols);
+  if(errcod == -1) psio_error(unit,PSIO_ERROR_LSEEK);
+
+  /* Read the TOC entry-by-entry */
+  this_entry = this_unit->toc;
+  for(i=0; i < this_unit->toclen; i++) {
+
+      /* This read() assumes a fixed ordering on the members of this_entry */
+      errcod = read(this_unit->vol[volume].stream, (char *) this_entry,
+		    entry_size);
+      if(errcod != entry_size) psio_error(unit,PSIO_ERROR_READ);
+
+      this_entry = this_entry->next;
+    }
+
+  return(0);
+}
+
+}
+}
Index: ThirdParty/mpqc_open/src/lib/util/psi3/libpsio/tocscan.cc
===================================================================
--- ThirdParty/mpqc_open/src/lib/util/psi3/libpsio/tocscan.cc	(revision 860145ede0311b3539e419277d8ca4a3091f40b2)
+++ ThirdParty/mpqc_open/src/lib/util/psi3/libpsio/tocscan.cc	(revision 860145ede0311b3539e419277d8ca4a3091f40b2)
@@ -0,0 +1,36 @@
+/*!
+   \file tocscan.c
+   \ingroup (PSIO)
+*/
+
+#include <string.h>
+#include <util/psi3/libpsio/psio.h>
+
+namespace psi3 {
+namespace libpsio {
+
+/*!
+** PSIO_TOCSCAN(): Scans the TOC for a particular keyword and returns either
+** a pointer to the entry or NULL to the caller.
+**
+** \ingroup (PSIO)
+*/
+
+psio_tocentry *psio_tocscan(unsigned int unit, char *key)
+{
+  psio_tocentry *this_entry;
+
+  if(key == NULL) return(NULL);
+
+  this_entry = psio_unit[unit].toc;
+
+  while(this_entry != NULL) {
+      if(!strcmp(this_entry->key,key)) return(this_entry);
+      this_entry = this_entry->next;
+    }
+
+  return(NULL);
+}
+
+}
+}
Index: ThirdParty/mpqc_open/src/lib/util/psi3/libpsio/tocwrite.cc
===================================================================
--- ThirdParty/mpqc_open/src/lib/util/psi3/libpsio/tocwrite.cc	(revision 860145ede0311b3539e419277d8ca4a3091f40b2)
+++ ThirdParty/mpqc_open/src/lib/util/psi3/libpsio/tocwrite.cc	(revision 860145ede0311b3539e419277d8ca4a3091f40b2)
@@ -0,0 +1,84 @@
+/*!
+   \file tocwrite.c
+   \ingroup (PSIO)
+*/
+
+#include <stdlib.h>
+#include <unistd.h>
+#include <util/psi3/libpsio/psio.h>
+#include <util/psi3/libpsio/psifiles.h>
+
+namespace psi3 {
+namespace libpsio {
+
+/*!
+** PSIO_TOCWRITE(): Write the table of contents for file number 'unit'.
+**
+** \ingroup (PSIO)
+*/
+int psio_tocwrite(unsigned int unit)
+{
+  unsigned int i;
+  int errcod, volume, entry_size, stream;
+  psio_ud *this_unit;
+  psio_tocentry *this_entry;
+
+  this_unit = &(psio_unit[unit]);
+  entry_size = sizeof(psio_tocentry) - 2*sizeof(psio_tocentry *);
+
+  /* Check that this unit is actually open */
+  if(this_unit->vol[0].stream == -1) return(0);
+
+  /* Seek vol[0] to its beginning */
+  stream = this_unit->vol[0].stream;
+  errcod = lseek(stream, 0L, SEEK_SET);
+  if(errcod == -1) {
+     fprintf(stderr, "Error in PSIO_TOCWRITE()!\n");
+     exit(PSI_RETURN_FAILURE);
+    }
+
+  /* Dump the TOC stats to disk */
+  errcod = write(stream, (char *) &(this_unit->tocaddress.page), sizeof(ULI));
+  if(errcod != sizeof(ULI)) {
+     fprintf(stderr, "Error in PSIO_TOCWRITE()!\n");
+     exit(PSI_RETURN_FAILURE);
+    }
+  errcod = write(stream, (char *) &(this_unit->tocaddress.offset), sizeof(ULI));
+  if(errcod != sizeof(ULI)) {
+     fprintf(stderr, "Error in PSIO_TOCWRITE()!\n");
+     exit(PSI_RETURN_FAILURE);
+    }
+  errcod = write(stream, (char *) &(this_unit->toclen), sizeof(ULI));
+  if(errcod != sizeof(ULI)) {
+     fprintf(stderr, "Error in PSIO_TOCWRITE()!\n");
+     exit(PSI_RETURN_FAILURE);
+    }
+
+  /* Seek the TOC volume to the correct position */
+  volume = (this_unit->tocaddress.page) % (this_unit->numvols);
+  errcod = psio_volseek(&(this_unit->vol[volume]), this_unit->tocaddress.page,
+	                this_unit->tocaddress.offset,this_unit->numvols);
+  if(errcod == -1) {
+      fprintf(stderr, "Error in PSIO_TOCWRITE()!\n");
+      exit(PSI_RETURN_FAILURE);
+    }
+
+  this_entry = this_unit->toc;
+  for(i=0; i < this_unit->toclen; i++) {
+
+      /* This write() assumes a fixed ordering on the members of this_toc */
+      errcod = write(this_unit->vol[volume].stream, (char *) this_entry,
+		     entry_size);
+      if(errcod != entry_size) {
+      fprintf(stderr, "Error in PSIO_TOCWRITE()!\n");
+      exit(PSI_RETURN_FAILURE);
+        }
+
+      this_entry = this_entry->next;
+    }
+
+  return(0);
+}
+
+}
+}
Index: ThirdParty/mpqc_open/src/lib/util/psi3/libpsio/volseek.cc
===================================================================
--- ThirdParty/mpqc_open/src/lib/util/psi3/libpsio/volseek.cc	(revision 860145ede0311b3539e419277d8ca4a3091f40b2)
+++ ThirdParty/mpqc_open/src/lib/util/psi3/libpsio/volseek.cc	(revision 860145ede0311b3539e419277d8ca4a3091f40b2)
@@ -0,0 +1,51 @@
+/*!
+   \file volseek.c
+   \ingroup (PSIO)
+*/
+
+#include <unistd.h>
+#include <util/psi3/libpsio/psio.h>
+
+namespace psi3 {
+namespace libpsio {
+
+/* This is strictly used to avoid overflow errors on lseek() calls */
+#define PSIO_BIGNUM 10000
+
+/*!
+** PSIO_VOLSEEK()
+**
+** \ingroup (PSIO)
+*/
+int psio_volseek(psio_vol *vol, ULI page, ULI offset, ULI numvols)
+{
+  int stream, errcod;
+  ULI bignum, total_offset;
+
+  bignum = PSIO_BIGNUM*numvols;
+
+  stream = vol->stream;
+
+  /* Set file pointer to beginning of file */
+  errcod = lseek(stream, (ULI) 0, SEEK_SET);
+  if(errcod == -1) return(errcod);
+
+  /* lseek() through large chunks of the file to avoid offset overflows */
+  for(; page > bignum; page -= bignum) {
+      total_offset = PSIO_BIGNUM * PSIO_PAGELEN;
+      errcod = lseek(stream, total_offset, SEEK_CUR);
+      if(errcod == -1) return(errcod);
+    }
+
+  /* Now compute the final offset including the page-relative term */ 
+  total_offset = (ULI) page/numvols; /* This should truncate */
+  total_offset *= PSIO_PAGELEN;
+  total_offset += offset; /* Add the page-relative term */
+  errcod = lseek(stream, total_offset, SEEK_CUR);
+  if(errcod == -1) return(errcod);
+
+  return(0);
+}
+
+}
+}
Index: ThirdParty/mpqc_open/src/lib/util/psi3/libpsio/write.cc
===================================================================
--- ThirdParty/mpqc_open/src/lib/util/psi3/libpsio/write.cc	(revision 860145ede0311b3539e419277d8ca4a3091f40b2)
+++ ThirdParty/mpqc_open/src/lib/util/psi3/libpsio/write.cc	(revision 860145ede0311b3539e419277d8ca4a3091f40b2)
@@ -0,0 +1,127 @@
+/*!
+   \file write.c
+   \ingroup (PSIO)
+*/
+
+#include <stdlib.h>
+#include <string.h>
+#include <util/psi3/libpsio/psio.h>
+
+namespace psi3 {
+namespace libpsio {
+
+/*!
+** PSIO_WRITE(): Writes data to a TOC entry in a PSI file.
+**
+**  \param unit   = The PSI unit number used to identify the file to all read
+**                  and write functions.
+**  \param key    = The TOC keyword identifying the desired entry.
+**  \param buffer = The buffer from which the data is written.
+**  \param size   = The number of bytes to write.
+**  \param sadd   = The entry-relative starting page/offset to write the data.
+**  \param eadd   = A pointer to the entry-relative page/offset for the next
+**                  byte after the end of the write request.
+**
+** \ingroup (PSIO)
+*/
+
+int psio_write(unsigned int unit, char *key, char *buffer, ULI size,
+	       psio_address rel_start, psio_address *rel_end)
+{
+  psio_ud *this_unit;
+  psio_tocentry *this_entry, *last_entry;
+  psio_address address, end_address;
+
+  this_unit = &(psio_unit[unit]);
+
+  /* Find the entry in the TOC */
+  this_entry = psio_tocscan(unit, key);
+
+  if(this_entry == NULL) { /* New TOC entry */
+    if(rel_start.page||rel_start.offset) psio_error(unit,PSIO_ERROR_BLKSTART);
+
+    this_entry = (psio_tocentry *) malloc(sizeof(psio_tocentry));
+    strcpy(this_entry->key,key);
+    this_entry->next = NULL;
+    this_entry->last = NULL;
+
+    /* Compute the address of the entry */
+    if(!(this_unit->toclen)) { /* First TOC entry */
+      this_entry->sadd.page = 0;
+      this_entry->sadd.offset = 3*sizeof(ULI);
+
+      this_unit->toc = this_entry;
+    }
+    else {  /* Use ending address from last TOC entry */
+      last_entry = psio_toclast(unit);
+      this_entry->sadd = last_entry->eadd;
+
+      last_entry->next = this_entry;
+      this_entry->last = last_entry;
+    }
+
+    /* Data for the write call */
+    address = this_entry->sadd;
+
+    /* Set the end address for this_entry */
+    this_entry->eadd = psio_get_address(this_entry->sadd, size);
+
+    /* Update the unit's TOC stats */
+    this_unit->toclen++;
+    this_unit->tocaddress = this_entry->eadd;
+
+    /* Update the rel_end argument value for the caller */
+    *rel_end = psio_get_address(rel_start,size);
+  }
+  else { /* Old TOC entry */
+
+    /* Compute the global starting page and offset for the block */
+    address = psio_get_global_address(this_entry->sadd, rel_start);
+
+    /* Make sure this block doesn't start past the end of the entry */
+    if(address.page > this_entry->eadd.page)
+      psio_error(unit,PSIO_ERROR_BLKSTART);
+    else if((address.page == this_entry->eadd.page) &&
+	    (address.offset > this_entry->eadd.offset))
+      psio_error(unit,PSIO_ERROR_BLKSTART);
+
+    /* Compute the new global ending address for the entry, if necessary */
+    end_address = psio_get_address(address, size);
+    if(end_address.page > this_entry->eadd.page) {
+      if(this_entry->next != NULL) {
+	fprintf(stderr, "PSIO_ERROR: Attempt to write into next entry: %d, %s\n", 
+		unit, key);
+	psio_error(unit, PSIO_ERROR_BLKEND);
+      }
+      this_entry->eadd = end_address;
+      this_unit->tocaddress = end_address;
+	  
+    }
+    else if((end_address.page == this_entry->eadd.page) &&
+	    (end_address.offset > this_entry->eadd.offset))
+      {
+	if(this_entry->next != NULL) {
+	  fprintf(stderr, "PSIO_ERROR: Attempt to write into next entry: %d, %s\n", 
+		  unit, key);
+	  psio_error(unit, PSIO_ERROR_BLKEND);
+	}
+	this_entry->eadd = end_address;
+	this_unit->tocaddress = end_address;
+      }
+
+    /* Update the eadd argument value for the caller */
+    *rel_end = psio_get_address(rel_start, size);
+  }
+
+  /* Now write the actual data to the unit */
+  psio_rw(unit, buffer, address, size, 1);
+
+#ifdef PSIO_STATS
+  psio_writlen[unit] += size;
+#endif
+
+  return(0);
+}
+
+}
+}
Index: ThirdParty/mpqc_open/src/lib/util/psi3/libpsio/write_block.cc
===================================================================
--- ThirdParty/mpqc_open/src/lib/util/psi3/libpsio/write_block.cc	(revision 860145ede0311b3539e419277d8ca4a3091f40b2)
+++ ThirdParty/mpqc_open/src/lib/util/psi3/libpsio/write_block.cc	(revision 860145ede0311b3539e419277d8ca4a3091f40b2)
@@ -0,0 +1,101 @@
+/*!
+   \file write_block.c
+   \ingroup (PSIO)
+*/
+ 
+#include <stdlib.h>
+#include <string.h>
+#include <util/psi3/libpsio/psio.h>
+
+namespace psi3 {
+namespace libpsio {
+
+/*!
+** PSIO_WRITE_BLOCK(): 
+**
+** \ingroup (PSIO)
+*/
+
+int psio_write_block(unsigned int unit, char *key, char *buffer, ULI blksiz,
+  		     ULI start_blk, ULI  end_blk)
+{
+  ULI size, shift;
+  psio_ud *this_unit;
+  psio_tocentry *this_entry, *last_entry;
+  psio_address sadd, eadd;
+
+  this_unit = &(psio_unit[unit]);
+
+  /* Find the entry in the TOC */
+  this_entry = psio_tocscan(unit, key);
+
+  if(this_entry == NULL) { /* New TOC entry */
+      if(start_blk) psio_error(unit,PSIO_ERROR_BLKSTART);
+
+      this_entry = (psio_tocentry *) malloc(sizeof(psio_tocentry));
+      strcpy(this_entry->key,key);
+      this_entry->next = NULL;
+      this_entry->last = NULL;
+
+      /* Compute the address of the entry */
+      if(!(this_unit->toclen)) { /* First TOC entry */
+	  this_entry->sadd.page = 0;
+	  this_entry->sadd.offset = 3*sizeof(ULI);
+
+	  this_unit->toc = this_entry;
+	}
+      else {  /* Use ending address from last TOC entry */
+	  last_entry = psio_toclast(unit);
+	  this_entry->sadd = last_entry->eadd;
+
+	  last_entry->next = this_entry;
+	  this_entry->last = last_entry;
+	}
+
+      /* Data for the write call */
+      size = (end_blk - start_blk + 1)*blksiz;
+      sadd = this_entry->sadd;
+
+      /* Set end address for this_entry */
+      this_entry->eadd = psio_get_address(this_entry->sadd, size);
+
+      /* Update the unit's TOC stats */
+      this_unit->toclen++;
+      this_unit->tocaddress = this_entry->eadd;
+    }
+  else { /* Old TOC entry */
+
+      size = (end_blk - start_blk + 1) * blksiz; /* The total buffer size */
+      shift = start_blk * blksiz; /* Number of bytes to shift from start */
+
+      /* Compute the starting page and offset for the block */
+      sadd = psio_get_address(this_entry->sadd, shift);
+
+      /* Make sure this block doesn't start past the end of the entry */
+      if(sadd.page > this_entry->eadd.page)
+	  psio_error(unit,PSIO_ERROR_BLKSTART);
+      else if((sadd.page == this_entry->eadd.page) &&
+	      (sadd.offset > this_entry->eadd.offset))
+	  psio_error(unit,PSIO_ERROR_BLKSTART);
+
+      /* Compute the new ending address for the entry, if necessary */
+      eadd = psio_get_address(sadd, size);
+      if(eadd.page > this_entry->eadd.page) {
+	  this_entry->eadd = this_unit->tocaddress = eadd;
+	}
+      else if((eadd.page == this_entry->eadd.page) &&
+	      (eadd.offset > this_entry->eadd.offset))
+	  {
+	    this_entry->eadd = eadd;
+	    this_unit->tocaddress = eadd;
+	  }
+    }
+
+  /* Now write the actual data to the unit */
+  psio_rw(unit, buffer, sadd, size, 1);
+
+  return(0);
+}
+
+}
+}
Index: ThirdParty/mpqc_open/src/lib/util/psi3/libpsio/write_entry.cc
===================================================================
--- ThirdParty/mpqc_open/src/lib/util/psi3/libpsio/write_entry.cc	(revision 860145ede0311b3539e419277d8ca4a3091f40b2)
+++ ThirdParty/mpqc_open/src/lib/util/psi3/libpsio/write_entry.cc	(revision 860145ede0311b3539e419277d8ca4a3091f40b2)
@@ -0,0 +1,23 @@
+/*!
+   \file write_entry.c
+   \ingroup (PSIO)
+*/
+
+#include <util/psi3/libpsio/psio.h>
+
+namespace psi3 {
+namespace libpsio {
+
+/*!
+** PSIO_WRITE_ENTRY()
+**
+** \ingroup (PSIO)
+*/
+int psio_write_entry(unsigned int unit, char *key, char *buffer, ULI size)
+{
+  psio_address end;
+  return psio_write(unit, key, buffer, size, PSIO_ZERO, &end);
+}
+
+}
+}
