Manual for some of the many useful PSI routines found in the C input
parsing library LIBIPV1

Documentation created by
Brian Kellogg, August 1994

Last updated 11/9/95 by D. Sherrill
             04/24/96 CBK

==========================================================================
  Routines for initializing and cleaning up the ip library
==========================================================================
 IP_INITIALIZE

void ip_initialize(FILE *infile, FILE *outfile);

parameters:
  infile = the input file to be parsed. (i.e. input.dat)
  outfile = the output file (i.e. output.dat)

returns:
  none.

===========================================================================
IP_APPEND

void ip_append(FILE *infile, FILE *outfile)

        Adds to the ip tree which was initially formed by ip_initialize.
        Can only be called after ip_initialize.  Multiple calls to
        ip_append with different input files are possible.

parameters:
  infile = the input file to be parsed. (i.e. input.dat)
  outfile = the output file (i.e. output.dat)

returns:
  none.

===========================================================================
IP_SET_UPPERCASE

void ip_set_uppercase(int uc)

parameters:
   uc = if uc is one, ip_uppercase is set to 1, and all letters in the
        input are converted to the uppercase. N.B.- Strings which
        are contained in quotes are "protected" and will remain
        as they are within the input deck.

returns:
   none.

===========================================================================
IP_DONE

void ip_done()

       Frees all of the data.  If ip_initialize has already been called,
       this function must be called before it can be called again.

parameters:
   none

returns:
   none

===========================================================================
  Routines that control the order and heirarchy of keyword searches
===========================================================================
IP_CWK_ROOT

void ip_cwk_root()

       Sets the current working keyword list to the the root of the input
       tree.  

parameters:
   none

returns:
   none

===========================================================================
IP_CWK_CLEAR

void ip_cwk_clear()

        sets the current working keyword path list to NULL.

returns:
   none.

===========================================================================
IP_CWK_ADD

void ip_cwk_add(char *keywd)

        Adds a new keyword to the current working keyword path.  n.b. the
        last path to be searched should be added first.  Ifa keyword has
        multiple assignments, only the first value read will be retained.

parameters:
   keyword = title of section which should be read.  In PSI 2.0 input
        style, the keywords for sections are preceded by a colon.
        (i.e. to read the scf section, use ":SCF").  Any keyword added
        which is not prepended by a colon will be assumed to be at a level
        beneath the section heading (i.e., to read the docc array in the
        default section, use "DOCC").

returns:
   none.

===========================================================================
IP_CWK_DESCEND_TREE

ip_keyword_tree_t *ip_cwk_descend_tree(char *keywd)

        Descend the keyword tree using the cwk and obtain a new keyword
        tree.  If keywd is an absolute path (prepended by a colon) it 
        will simply descend into the first instance of that keyword.  If
        keywd is a relative path (no colon), it will descend all the way to
        the first instance of keywd in the cwk list.

parameters:
   keyword = keyword of interest.  i.e. if we want to only scan the 
        files section of the default section, we would use "FILES" then
        read data in from the appropriate keywords

returns:
   ip_keyword_tree_t *kt;  a pointer to the top of the new keyword tree

===========================================================================
  Routines that return ip data
===========================================================================
IP_EXIST

int ip_exist(char *keyword, int n)

        Tells weather or not the particular keyword was picked up by the
        parser.

parameters:
   keyword = keyword of interest.
   n = 0;(should always be zero for this version of parser)

returns:
   1 if keyword is in ip tree, 0 if it is not.

===========================================================================
 IP_COUNT

int ip_count(char *keyword, int *count, int n, int m ...)

        assigns to count the number of arguments assigned to the keyword.

parameters:
   keyword = keyword of interest.
   count = integer where ip_count will store the size of the array.
   n = number of variable arguments to be given. (see bottom of document)
     
returns:
   Errorcode.

===========================================================================
 IP_BOOLEAN

int ip_boolean(char *keyword, int *boolean, int n)

        Figures out the value of a boolean variable and assigns that value
        to the variable boolean.

parameters:
   keyword = keyword of interest.
   boolean = storage spot for boolean value (assigned 1 or 0).
   n = number of variable arguments to be given. (see bottom of document)

returns:
   Errorcode


===========================================================================
IP_DATA

int ip_data(char *keyword, char *conv, VOID *value, int n, int m...)

        assigns to value the value located in the keyword field and
        specified by the integers n, m, etc..

parameters:
   keyword = keyword of interest.
   value = where ip_data will store the specified value.
   conv = conversion specifier string (i.e. "%c" or "%d").
   n = number of variable arguments to be given. (see bottom of document)

returns:
   Errorcode.

===========================================================================
IP_INT_ARRAY

int ip_int_array(char *keyword, int *arr, int len)

        Reads an integer array using the PSI input parser.  It
        checks for errors at all stages and makes sure tha the
        array has the proper length.

parameters:
   keyword = string containing the keyword for the input parser
   arr     = array to hold results
   len     = length of array

returns:
   Errorcode.

note: keyword should ordinarily be an uppercase string.

===========================================================================
IP_STRING

int ip_string(char *keyword, char **value, int n)

        reads a string from the field of the keyword into value.

parameters:
   keyword = keyword of interest.
   value = where string is stored.
   n = number of variable arguments to be given. (see bottom of document)

returns:
   Errorcode.

===========================================================================
  Routines that deal with keywords
===========================================================================
IP_KARRAY_COUNT

int ip_karray_count(char *keywd, int *karray_count, int n, ...)

	places the count of the the subarray of the specified keyword array
	into karray_count.

parameters:
   keyword = keyword of interest.
   karray_count = address of int in which to store the keyword array count
   n = number of variable arguments to be given. (see bottom of document)

returns:
   none.   
  
===========================================================================
  Routines that deal with errors
===========================================================================
IP_ERROR

char *ip_error_message(int errcod)

	returns text which is specific to the value of errcod, and should
	shed some light on the nature of the ip_error.

parameters:
   errcod = an integer which has a range of values specified in ip_error.h

returns:
   ip_error_message = a string containing error messages.

==========================================================================
  Routines which return or print internal IP data
==========================================================================
IP_KEY_VALUE

ip_value_t *ip_key_value(char *keywd)

	returns a pointer to the struct which contains all the information
	associated with the keywd of interest.

parameters:
   keywd = keyword of interest;

returns: 
   ip_value_t * = pointer to a struct which is created in ip_types.h
==========================================================================
IP_VALUE

int ip_value(char *keywd, ip_value_t **val, int n, ...)

	assigns a pointer to a particular section of a multidimensional
	array of values under keyword.

parameters:
   keywd = keyword of interest;
   val = address of a pointer to ip_value_t, it is where the pointer to the
	subsection will be placed.  
   n = number of variable arguments to be given. (see bottom of document)

returns:
   errcode.

==========================================================================
IP_PRINT_VALUE

void ip_print_value(FILE *fp, ip_value_t *value) 

	prints out the information stored in value to fp.

parameters: 
   fp = file to print out to
   value = ip data structure to print out.

returns:
   none.

==========================================================================
IP_PRINT_KEYWORD

void ip_print_keyword(FILE *fp, ip_keyword_tree_t *st) 

	prints out the keyword  corresponding to the keyword tree st 
        and the path leading to it out to fp.

parameters: 
   fp = file to print out to
   st = the keyword tree of interest

returns:
   none.

==========================================================================
IP_PRINT_TREE

void ip_print_keyword(FILE *fp, ip_keyword_tree_t *tree)

        prints out a symbolic representation of the keyword tree under tree.

parameters:
   fp = file to print out to
   st = tree of interest.  If it is null, the whole tree is printed out.

returns:
   none.


==========================================================================
  Some notes on using variable argument functions
==========================================================================

	Many of the functions in libipv1 take a variable number of
arguments.  An example of such a routine in the standard C libraries is the
printf function, which takes a format string to print as its first argument,
and any number of arguments (including zero) can follow to give printf the
variables it will need to execute the formated output requested by the first
argument ( i.e. printf(" ii = %d  jj = %d",ii,jj) ).  The functions in
libipv1 which allow for variable numbers of arguments usually do so in order
to allow the programmer to probe different layers of the nested information
vectors which are used by the input parser.  The use of these functions is
most easily explained with an example.  Consider the geometry information as
it is stored in input.dat (this is for a methane-like molecule):

geometry = (
  (         .0000000000         .0000000000         .0000000007)
  (        1.6726189235         .0000000000        1.1827202187)
  (       -1.6726189235         .0000000000        1.1827202187)
  (         .0000000000        1.6726189219       -1.1827202193)
  (         .0000000000       -1.6726189219       -1.1827202193)
 )

It is written as a vector, each element of which is a vector of length two.
Using the ip_data routine as an example, we examine the call that we would
have to make in order to read the third coordinate (z-coordinate) of the
fourth atom:  

   ip_data("GEOMETRY","%lf",&geom,2,3,2);

The first integer argument tells the routine how many dimentions in which 
we will consider our search object.  The next integer focuses our inquiry on
only the fourth vector of the geometry object (recall: C ordering).
The final integer focuses the inquiry further to just the third element of
that array.  This is the way that  ip_data(), ip_boolean(), ip_string() and
other such routines work.

One potentially confusing situation is the use of variable
arguments in ip_count.  If we were to use ip_count on the geometry array
above with the following call:

   ip_count("GEOMETRY",&i,0);

it would store a value of five in the variable i.  If, instead, we made the
call:

   ip_count("GEOMETRY",&i,1,3);

a value of 3 would be stored in the variable i.  A call of

   ip_count("GEOMETRY",&i,2,0,0);

would return an error code, but will not change i.
==========================================================================
