.NH 1 "VGPARM LIBRARY"
.XS
\s12\*(SN  VGPARM LIBRARY\s0
.XE
.sp 2
.NH 2 "INTRODUCTION TO THE VGPARM LIBRARY"
.XS
      \*(SN  INTRODUCTION
.XE
.sp 2
.PP
The \fIvgparm\fP library contains many useful routines that perform 
miscellaneous tasks, most of which deal with I/O.  The application programmer
is highly encouraged to become familiar with these routines, as they are 
frequently needed, and programmers working under the Khoros system should always
try to avoid "re-inventing the wheel".  In addition, using these utilities 
whenever possible ensures that new programs developed under the Khoros system 
handle I/O in a way which is consistent with the rest of the system. 
In  particular, calls to the routines \fIkhoros_open()\fP and 
\fIkhoros_close()\fP are required in all Khoros programs.  
.PP
In many cases, "smarter" versions of various system calls are provided for the
sake of convenience. These routines serve as front ends to the corresponding 
system calls, but are improved over their system call counterpart in some way.  
Especially encouraged are the use of the Khoros versions of the system string 
manipulation routines, including: \fI VStrcat(), VStr3cat(), VStrcmp(), 
VStrncmp(), VStrcpy(), VStrncpy(),\fP and \fIVStrlen()\fP.  All of these macros 
check for NULL arguments, and allocate space appropriately when necessary.
.PP
The \fIvgparm\fP library also includes routines that must be used as
replacements for their system counterparts when it is desired that 
the calling program be able to take advantage of the Khoros data transport 
and distributed processing capabilities.  It is important to remember that
these routines may \fInot\fP  be intermixed with other system commands.  
For instance, if \fIkopen()\fP was used to open a transport mechanism, then 
you must not use the system \fIread()\fP; instead, use \fIkread()\fP because 
if the shared memory transport is being used, the system \fIread()\fP routine 
will be certain to fail.  
.PP
The routines that must be used by programs that are to take advantage of 
the data transport/distributed processing capabilities include: \fIktempnam(), 
kopen(), kclose(), kread(), kwrite(), kaccess(), kunlink(), kflock(), klseek(),
kfopen(), kfclose(), kfread(), kfwrite(), kfgetc(), kfputc(), kfgets(),
kfputs(), kftell(), kfseek(), krewind(), kfileno(), kmachtype(),
kgethostname(), ksystem(), kdescriptors(),\fP and
\fIkexecvp()\fP.  Routines that have not been implemented as of yet, but will
be provided in future releases of Khoros include: \fIkpopen(), 
kpclose(), kfprintf(), kfscanf(),\fP and \fIkfork()\fP.  Note that the use
of the data transport and distributed processing mechanisms is explained in
Chapter 1 ("Getting Started") of the Khoros User's Manual, and an example of
a program that uses the Khoros system counterparts to take advantage of 
the data transport and distributed processing capabilities of Khoros is 
included in Chapter 1 ("Writing Programs") of the Khoros Programmer's Manual.
.PP
In addition, the \fIvgparm\fP library contains all routines that do the
actual parsing and checking of arguments provided to an application program
via the command line user interface (CLUI).   In general, these routines are
not made by the programmer, but are automatically generated by 
\fBghostwriter\fP (see Chapter 5, "Ghost Routines", of the Khoros Programmer's
Manual);  however, routine definitions are provided here for the curious.
.sp 
ALL programs that utilize these routines MUST include the statement:
.sp
#include "vinclude.h"
.sp 3
.NH 2 "VGPARM UTILITIES"
.XS
      \*(SN  VGPARM UTILITIES
.XE
.sp 4
.NH 3 " khoros_init()"
.XS
              \*(SN   khoros_init()
.XE
.sp 
.LP
A CALL TO THE khoros_init() ROUTINE SHOULD BE THE FIRST THING APPEARING IN
ANY PROGRAM UNDER THE KHOROS SYSTEM.  It sets the environment variables, and
sets things up in order for a program to run properly and consistently
under the Khoros system. It has no arguments.  \fBGhostwriter\fP will 
automatically generate a call to this routine in the main driver of a new
program.
.sp
.LP
=====================================================================
.sp 2
.NH 3 " khoros_close()"
.XS
              \*(SN   khoros_close()
.XE
.sp
.LP
A CALL TO THE khoros_close() ROUTINE SHOULD BE THE LAST THING APPEARING
IN ANY PROGRAM UNDER THE KHOROS SYSTEM.  It will make sure that the program
exits properly, and that it is consistent with the rest of the Khoros system.
It has no arguments.  Note that a call to khoros_close() replaces a call
to exit(). \fBGhostwriter\fP will automatically generate a call to this 
routine in the main driver of a new program.
.sp
.LP
=====================================================================
.bp
.sp 5
.NH 3 " check_args()"
.XS
              \*(SN   check_args()
.XE
.sp
.LP
Each time a command line argument is taken off the command line, it is 
set to NULL in the av (argv) string array.  This routine searches the av (argv) 
array for any arguments that have not been set to NULL after all defined 
command line arguments have been processed. If the  ac (argv) array contains 
any arguments that have not been set to NULL (implying that the user has
entered bogus input on the command line in addition to correct input) 
an error message results.  check_args() has no arguments.  Every routine
that DOES NOT USE the X Toolkit MUST make a call to check_args().
.LP
Note that programs using the \fIxvforms\fP or \fIxvutils\fP 
libraries MUST NOT have this call.
This is because extra arguments may not actually be bogus, but may actually
be in reference to X Toolkit attributes.
.sp
.LP
=====================================================================
.sp 5
.NH 3 " consolidate_args()"
.XS
              \*(SN   consolidate_args()
.XE
.sp
.LP
This routine searches the command and packs all the arguments to the front 
of the av (argv) array. The ac (argc) count is set to the new number of 
arguments. Basically this consolidates arguments by getting rid of all 
NULL arguments.  
.LP
Note that programs using the \fIxvforms\fP libraries will have this call
made for them in \fIxvf_initialize()\fP.  This is necessary because
all remaining arguments must be passed to the X Toolkit, for use by various
routines located there.  consolidate_args() has no arguments.
.sp
.LP
=====================================================================
.bp
.sp 5
.NH 3 " kaccess()"
.XS
              \*(SN   kaccess()
.XE
.sp
.LP
This function is a replacement for the system \fIaccess()\fP call.  The only 
difference is that kaccess() checks all available transport mechanisms.
The routine will check to see if the token specified by the transport 
is either readable (R_OK), writeable (W_OK), or accessible (X_OK), 
or any possible combination by OR'ing the flags together.
.B
.sp
char *kaccess(path, mode)
.br
char *path;
.br
int  mode;
.sp
.R
.LP
-- -- -- -- -- -- -- -- -- -- -- -- -- -- --  explanation of arguments  -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
.IP path:
The string containing the path name of the file to be accessed, as in
the UNIX \fIaccess()\fP command.
.IP mode:
The mode in which kaccess() should test for the transport.  The mode is 
comprised of an OR'ing of the following flags:
.in +5
R_OK - the transport is readable
.br
W_OK - the transport is writeable
.br
X_OK - the transport is executable
.br
F_OK - the directory leading to the file is accessible (if applicable).
.in -5
.sp
.LP
=====================================================================
.sp 5
.NH 3 " kalloca()"
.XS
              \*(SN   kalloca()
.XE
.sp
.LP
Calls alloca() to allocate the size bytes of space in the stack frame of the
caller, and returns a pointer to the allocated block. This temporary space
is automatically freed when the caller returns.  Note that if the allocated
block is beyond the current stack limit, the resulting behavior is undefined.
Checks to make sure that the user doesn't allocate 0 bytes, since
this will fail on certain architectures.  If the user requests 0 bytes, the
request will be changed to allocate a single byte.
.B
.sp
char *kalloca(size)
.br
int size;
.sp
.R
.LP
-- -- -- -- -- -- -- -- -- -- -- -- -- -- --  explanation of arguments  -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
.IP size:
The desired number of bytes to allocate from the frame stack. 
.sp
.LP
=====================================================================
.bp
.sp 5
.NH 3 " kcalloc()"
.XS
              \*(SN   kcalloc()
.XE
.sp
.LP
Calls calloc() to allocate space for an array of num elements of the size
specified, initialize the space to zeros, and return a pointer to the
initialized block. Checks to make sure that the user doesn't allocate 0 bytes,since this will fail on certain architectures.  If the user requests 0 bytes,
the request will be changed to allocate a single byte.
.B
.sp
char *kcalloc(num, size)
.br
size_t num;
.br
size_t size;
.sp
.R
.LP
-- -- -- -- -- -- -- -- -- -- -- -- -- -- --  explanation of arguments  -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
.IP num:
Number of elements in the array to allocate.
.IP size:
Size of each element in the array.
.sp
.LP
=====================================================================
.sp 5
.NH 3 " kclose()"
.XS
              \*(SN   kclose()
.XE
.sp
.LP
This function is a replacement for the system \fIclose()\fP call.  The only 
difference is that \fIkclose()\fP supports supports all available data transport
mechanisms.
.B
.sp
char *kclose(id)
.br
int id;
.sp
.R
.LP
-- -- -- -- -- -- -- -- -- -- -- -- -- -- --  explanation of arguments  -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
.IP id:
File identifier of file which was opened earlier with the use of \fIkopen()\fP.
.sp
.LP
=====================================================================
.bp
.sp 5
.NH 3 " kdescriptors()"
.XS
              \*(SN   kdescriptors()
.XE
.sp
.LP
This function is used to retrieve the input and output file descriptor
associated with a transport.  Note that this routine should not be used without
extreme caution, since certain transports don't have file descriptors (such as
shared memory).  It is sometimes important to be able to have access to a
transports real UNIX file descriptors so that such functions as the X Toolkit's
XtAppAddInput() can be used.  This should be used until the \fIphantom\fP
becomes more advanced and starts to support the concept of threads and parallel
processing.
.B
.sp
int kdescriptors(file, inum, onum)
.br
kfile *file;
.br
int   *inum;
.br
int   *onum;
.sp
.R
.LP
-- -- -- -- -- -- -- -- -- -- -- -- -- -- --  explanation of arguments  -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
.IP id:
File identifier of file which was opened earlier with the use of \fIkopen()\fP.
.IP inum:
The input descriptor if exists (or if non exists -1)
.IP onum:
The output descriptor if exists (or if non exist
.sp
.LP
=====================================================================
.bp
.sp 5
.NH 3 " kexecvp()"
.XS
              \*(SN   kexecvp()
.XE
.sp
.LP
This function is a replacement for the system \fIexecvp()\fP call.  The only 
difference is that \fIkexecvp()\fP supports execution of processes on remote 
machines (distributed processing) enabled by a remote data transport mechanism.
The routine will execute another process (specified by arg0) and replace 
the current core image with the specified core.  For example, the command:
.in +5
vfileinfo -i1 file
.in -5
would be specified as:
.in +5
arg0 = "vfileinfo"
.br
args[0] = "vfileinfo"
.br
args[1] = "-i1"
.br
args[2] = "file"
.br
args[3] = NULL
.br
.in -5
If the command is to be executed on a different machine, for example "borris",
then the same command would look like:
.in +5
vfileinfo@borris -i1 file
.in -5
which would be specified as:
.in +5
arg0 = "vfileinfo@borris"
.br
args[0] = "vfileinfo@borris"
.br
args[1] = "-i1"
.br
args[2] = "file"
.br
args[3] = NULL
.in -5
.br
If the command is to be executed on a different machine, for example "borris", 
and the file to be read is on "natasha", then the command would look like this:
.in +5
vfileinfo@borris -i1 file@natasha
.in -5
which would be specified as:
.br
arg0 = "vfileinfo@borris"
.br
args[0] = "vfileinfo@borris"
.br
args[1] = "-i1"
.br
args[2] = "file@natasha"
.br
args[3] = NULL
.br
.in -5
.B
.sp
kexecvp(arg0, args)
.br
char *arg0;
.br
char *args[];
.sp
.R
.LP
-- -- -- -- -- -- -- -- -- -- -- -- -- -- --  explanation of arguments  -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
.IP arg0:
The routine to be executed
.IP args:
The arguments, including arg0, with which to execute the command
.sp
.LP
=====================================================================
.bp
.sp 5
.NH 3 " kfclose()"
.XS
              \*(SN   kfclose()
.XE
.sp
.LP
This function is a replacement for the system \fIfclose()\fP call.  The only 
difference is that kfclose() supports all available transport mechanisms.
Returns 0 on success, -1 on failure.
.B
.sp
char *kfclose(file)
.br
kfile *file;
.sp
.R
.LP
-- -- -- -- -- -- -- -- -- -- -- -- -- -- --  explanation of arguments  -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
.IP file:
Pointer to the kfile structure, originally returned by \fIkfopen()\fP.
.sp
.LP
=====================================================================
.sp 5
.NH 3 " kfgetc()"
.XS
              \*(SN   kfgetc()
.XE
.sp
.LP
This function is a replacement for the system \fIfgetc\fP call.  The only
difference is that \fIkfgetc()\fP supports all available transport mechanisms.
The routine will get a single character from the specified transport.  If the
character could not be written, EOF is returned; otherwise, the character
that is read is returned.
.B
.sp
int kfgetc(file)
.br
kfile *file;
.sp
.R
.LP
-- -- -- -- -- -- -- -- -- -- -- -- -- -- --  explanation of arguments  -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
.IP file:
Pointer to the kfile structure, originally returned by \fIkfopen()\fP.
.sp
.LP
=====================================================================
.bp
.sp 5
.NH 3 " kfgets()"
.XS
              \*(SN   kfgets()
.XE
.sp
.LP
This function is a replacement for the system \fIfgets\fP call.  The only
difference is that \fIkfgets()\fP supports all available transport mechanisms.
The routine will reads a single line of characters from the specified transport.
If the characters could not be read then NULL is returned, otherwise the input
character array is returned.  \fIkfgets()\fP reads characters from the stream
into the array pointed to by buffer until num-1 characters are read or a '\n'
(newline character) or a EOF is encountered.  The characters read are returned
or if EOF or an error is encountered and no characters have been read then NULL
is returned.
.B
.sp
int kfgets(buffer, num, file)
.br
char    *buffer;
.br
int     num;
.br
kfile *file;
.sp
.R
.LP
-- -- -- -- -- -- -- -- -- -- -- -- -- -- --  explanation of arguments  -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
.IP buffer:
The buffer from which to get the data to be written.
.IP num:
The maximum number of characters (sizeof character array)
.IP file:
Pointer to the kfile structure, originally returned by \fIkfopen()\fP.
.sp
.LP
=====================================================================
.sp 5
.NH 3 " kfileno()"
.XS
              \*(SN   kfileno()
.XE
.sp
.LP
This function is a replacement for the system \fIfileno\fP call.  The only
difference is that \fIkfileno()\fP is used to retrieve the corresponding
kfile entry descriptor, which can be used with the (int fid) routines like,
\fIkread()\fP and \fIkwrite()\fP.  The entry indentifier or descriptor is
returned, otherwise -1 is returned if no such entry exists in the transport
table.
.B
.sp
int kfileno(file)
.br
kfile *file;
.sp
.R
.LP
-- -- -- -- -- -- -- -- -- -- -- -- -- -- --  explanation of arguments  -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
.IP file:
Pointer to the kfile structure, originally returned by \fIkfopen()\fP.
.sp
.LP
=====================================================================
.bp
.sp 5
.NH 3 " kflock()"
.XS
              \*(SN   kflock()
.XE
.sp
.LP
This function is used to lock the transport mechanism. Depending on the 
transport mechanism being used, the behavior of \fIkflock()\fP will be 
different.  For instance, with a file it calls \fIflock()\fP to lock the file;
however,  with shared memory it calls \fIshmctl()\fP to lock & unlock 
the shared memory segment.
.B
.sp
char *kflock(id, operation)
.br
int     id;
.br
int     operation;
.sp
.R
.LP
-- -- -- -- -- -- -- -- -- -- -- -- -- -- --  explanation of arguments  -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
.IP id:
Id of the object to be flock'ed.
.IP operation:
The mode in which kflock() should lock the transport mechanism.  The operation 
is comprised of an OR'ing of the following flags:
.in +5
LOCK_SH - lock transport mechanism shareable (when reading)
.br
LOCK_EX - lock transport mechanism execlusive (when writing)
.br
LOCK_NB - lock transport mechanism for no block (don't block)
.br
LOCK_UN - unlock the transport mechanism (free previous lock)
.in -5
.sp
.LP
=====================================================================
.bp
.sp 5
.NH 3 " kfopen()"
.XS
              \*(SN   kfopen()
.XE
.sp
.LP
This function is a replacement for the system \fIfopen()\fP call.  The only 
difference is that \fIkfopen()\fP supports all available transport mechanisms.
The path should be in the form of an identifier, followed by an equal (=) 
indicator, which is in turn followed by the transport token. For example,
a shared memory path would look like: "shm=1032". If a file was desired 
then either "/usr/tmp/vadd1235" or "file=/usr/tmp/vadd1235" would work.
Returns the kfile structure or NULL upon failure.
.B
.sp
kfile *kfopen(path, type)
.br
char *path;
.br
char *type;
.sp
.R
.LP
-- -- -- -- -- -- -- -- -- -- -- -- -- -- --  explanation of arguments  -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
.IP path:
The string containing the path name to the file to be opened, as in the
regular UNIX fopen() command.
.IP type:
How the file is to be opened; provide one of the following:
.in +5
"r"  - Open file for only reading
.br
"w"  - Open file for only writing
.br
"a"  - apend file for only writing
.br
"A"  - apend file for writing; non overwrite
.br
"r+" - Open file for both reading & writing
.br
"w+" - Open file for both reading & writing
.br
"a+" - apend file for only writing
.br
"A+" - apend file for writing; non overwrite
.in -5
.sp
.LP
=====================================================================
.sp 2
.NH 3 " kfputc()"
.XS
              \*(SN   kfputc()
.XE
.sp
.LP
This function is a replacement for the system \fIfputc\fP call.  The only 
difference is that \fIkfputc()\fP supports all available transport mechanisms.
The routine will write a single character to the specified transport.  If the 
character could not be written, EOF is returned; otherwise, the character
that is written is returned.
.B
.sp
int kfputc(character, file)
.br
int     character;
.br
kfile   *file;
.sp
.R
.LP
-- -- -- -- -- -- -- -- -- -- -- -- -- -- --  explanation of arguments  -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
.IP character:
The character to be written.
.IP file:
The kfile pointer to write to; opened earlier with \fIkfopen()\fP.
.sp
.LP
=====================================================================
.sp 5
.NH 3 " kfputs()"
.XS
              \*(SN   kfputs()
.XE
.sp
.LP
This function is a replacement for the system \fIfputs\fP call.  The only
difference is that \fIkfputc()\fP supports all available transport mechanisms.
The routine will write a single line of characters to the specified transport.  
If the characters could not be written EOF is returned, otherwise the number of
characters is returned.
.B
.sp
int kfputs(buffer, file)
.br
char    *buffer;
.sp
kfile   *file;
.sp
.R
.LP
-- -- -- -- -- -- -- -- -- -- -- -- -- -- --  explanation of arguments  -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
.IP buffer:
Pointer to the array of characters to be written.
.IP file:
Pointer to the kfile structure, originally returned by \fIkfopen()\fP.
.sp
.LP
=====================================================================
.bp
.sp 5
.NH 3 " kfread()"
.XS
              \*(SN   kfread()
.XE
.sp
.LP
This function is a replacement for the system \fIfread()\fP call.  The only 
difference is that \fIkfread()\fP supports all available transport mechanisms.
The routine will read nbytes into the character array "ptr".  If not all 
nitems can be read, then the \fIkfread()\fP routine returns the number of 
items actually read.
.B
.sp
int kfread(ptr, size, nitems, file)
.br
void *ptr;
.br
int size; 
.br
int nitems;
.br
kfile *file;
.sp
.R
.LP
-- -- -- -- -- -- -- -- -- -- -- -- -- -- --  explanation of arguments  -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
.IP ptr: 7
The character pointer into which the data is to be read.
.IP size:
The size of each element to be read.
.IP nitems:
The number of elements to be read.
.IP file:
The kfile pointer to be read from; opened earlier with \fIkfopen()\fP.
.sp
.LP
=====================================================================
.sp 2
.NH 3 " kfseek()"
.XS
              \*(SN   kfseek()
.XE
.sp
.LP
This function is used to go to a particular byte location in the transport. 
Depending on the transport mechanism being used, the behavior of \fIkfseek()\fP
will be different.  For instance, with a file it calls \fIfseek()\fP to seek 
the file, but with shared memory, it it simply resets the internal offset 
pointer.
.B
.sp
char *kfseek(id, offset, whence)
.br
kfile   *file;
.br
int     offset;
.br
int     whence;
.sp
.R
.LP
-- -- -- -- -- -- -- -- -- -- -- -- -- -- --  explanation of arguments  -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
.IP file:
The kfile pointer to be read from; opened earlier with \fIkfopen()\fP.
.IP offset:
The offset in which to seek.
.IP whence:
The control of how the offset will be applied.
.sp
.LP
=====================================================================
.sp 5
.NH 3 " kftell()"
.XS
              \*(SN   kftell()
.XE
.sp
.LP
This function is used to tell the current position within the transport.
The system call returns the offset of the current byte relative to the
beginning of the file associated with the transport identifier.
Depending on the different transport being used the behavior will be
different.  For a file it calls \fItell()\fP to locate the offset within the
file, but for a shared memory segment it it simply indicates the internal
offset.  Returns -1 or the current offset depending on whether the operation
failed or succeeded.
.B
.sp
int kftell(file)
.br
kfile *file;
.sp
.R
.LP
-- -- -- -- -- -- -- -- -- -- -- -- -- -- --  explanation of arguments  -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
.IP file: 8
The kfile pointer to be read from; opened earlier with \fIkfopen()\fP.
.sp
.LP
=====================================================================
.sp 5
.NH 3 " kgethostname()"
.XS
              \*(SN   kgethostname()
.XE
.sp
.LP
This function is a replacement for the system \fIgethostname()\fP call.
The only difference is that \fIkgethostname()\fP supports all available 
transport mechanisms. It returns the standard host name for the current 
processor.  The returned name is NULL-terminated unless insufficient space
is provided.  Returns 0 on success, -1 on failure.
.B
.sp
char *kgethostname(machine, hostname, namelen)
.br
char *machine;
.br
char *hostname;
.br
int  namelen;
.sp
.R
.LP
-- -- -- -- -- -- -- -- -- -- -- -- -- -- --  explanation of arguments  -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
.IP machine: 10
Input name of machine to inquire about.
.IP hostname:
Returns the standard host name for the current processor.
.IP namelen:
Returns the length of the "hostname" string returned.
.sp
.LP
=====================================================================
.bp
.sp 5
.NH 3 " kfwrite()"
.XS
              \*(SN   kfwrite()
.XE
.sp
.LP
This function is a replacement for the system \fIfwrite()\fP call.  The only 
difference is that \fIkfwrite()\fP supports all available transport mechanisms.
The routine will write nitems from the character array "ptr".  If not all 
nitems can be written, then the \fIkfwrite()\fP routine returns the number of 
items actually written.
.B
.sp
int kfwrite(ptr, size, nitems, file)
.br
void  *ptr;
.br
int size; 
.br
int nitems;
.br
kfile *file;
.sp
.R
.LP
-- -- -- -- -- -- -- -- -- -- -- -- -- -- --  explanation of arguments  -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
.IP ptr: 7
The character pointer from which the data is to be written.
.IP size:
The size of each element to be written.
.IP nitems:
The number of elements to be written.
.IP file:
The kfile pointer to be written to; opened earlier with \fIkfopen()\fP.
.sp
.LP
=====================================================================
.sp 2
.NH 3 " klseek()"
.XS
              \*(SN   klseek()
.XE
.sp
.LP
This function is used to go to a particular byte location in the transport. 
Depending on the transport mechanism being used, the behavior of \fIklseek()\fP
will be different.  For instance, with a file it calls \fIlseek()\fP to seek 
the file, but with shared memory, it it simply resets the internal offset 
pointer.
.B
.sp
char *klseek(id, offset, whence)
.br
int     id;
.br
int     offset;
.br
int     whence;
.sp
.R
.LP
-- -- -- -- -- -- -- -- -- -- -- -- -- -- --  explanation of arguments  -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
.IP id: 9
The id of the transport mechanism to be seeked.
.IP offset:
The offset in which to seek.
.IP whence:
The control of how the offset will be applied.
.sp
.LP
=====================================================================
.bp
.sp 5
.NH 3 " kmachtype()"
.XS
              \*(SN   kmachtype()
.XE
.sp
.LP
Same as the Khoros routine \fImachtype()\fP, except that it supports all
machines available for distributed processing.  The machines that are 
currently supported and their identifying #define'd numbers can be found in 
KHOROS_HOME/include/machdefs.h. If the current machine is not defined,
then the value of 255 is returned.  If the "hosttype" parameter is
set to NULL, then the string representation of the host type is not returned. 
If the "hosttype" parameter is passed in as an allocated string, the host type 
name is copied into that string.
.B
.sp
long kmachtype(machine, hosttype)
.br
char    *machine;
.br
char    *hosttype;
.sp
.R
.LP
-- -- -- -- -- -- -- -- -- -- -- -- -- -- --  explanation of arguments  -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
.IP machine: 10
Input name of machine to inquire about.
.IP hosttype:
If not NULL, the string representing the type of machine will be returned.
.sp
.LP
=====================================================================
.sp 2
.NH 3 " kmalloc()"
.XS
              \*(SN   kmalloc()
.XE
.sp
.LP
Calls malloc() to allocate the requested data; returns a pointer to a block of
at least size bytes, appropriately aligned.  Checks
to make sure that the user doesn't allocate 0 bytes, since this will fail
on certain architectures.  If the user requests 0 bytes, the request will
be changed to allocate a single byte.
.B
.sp
char *kmalloc(size)
.br
unsigned int size;
.sp
.R
.LP
-- -- -- -- -- -- -- -- -- -- -- -- -- -- --  explanation of arguments  -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
.IP size:
The number of bytes to allocate. 
.sp
.LP
=====================================================================
.bp
.sp 5
.NH 3 " kopen()"
.XS
              \*(SN   kopen()
.XE
.sp
.LP
This function is a replacement for the system \fIopen()\fP call.  The only 
difference is that \fIkopen()\fP supports all available data transport
mechanisms.  The path should be in the form of an identifier, followed by an 
equal (=) indicator, which is in turn followed by a transport token. For 
example, a shared memory path would look like: "shm=1032".  If a file was 
desired, examples would be: "/usr/tmp/vadd1235", or "file=/usr/tmp/vadd1235".
To find out which transport mechanisms are available on your computer 
architecture, and their associated identifiers, execute:  % transinfo.
.B
.sp
int kopen(path, flags, mode)
.br
char *path;
.br
int  flags;
.br
int  mode;
.sp
.R
.LP
-- -- -- -- -- -- -- -- -- -- -- -- -- -- --  explanation of arguments  -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
.IP path:
The string specifying the name to the file to be opened, as in \fIopen()\fP.
.IP flags:
Mask specifies how the file is to be opened:
.in +5
O_RDONLY - Open file for only reading
.br
O_WRONLY - Open file for only writing
.br
O_RDWR   - Open file for both reading & writing
.br
O_NONBLOCK - POSIX definition of O_NDELAY.
.br
O_NDELAY - Whether to block when reading and writing to the file.
.br
O_APPEND - Append to the file (writing).
.br
O_TRUNC  - Truncate the file for writing.
.br
O_EXCL   - Error if file exists
.in -5
.IP mode:
The permissions to be used when creating a new file.  
.sp
.LP
=====================================================================
.sp 
.NH 3 " kread()"
.XS
              \*(SN   kread()
.XE
.sp
.LP
Replaces for the system \fIread()\fP call.  The only 
difference is that kread() supports all available transport mechanisms.
The routine will read nbytes into the character array "buf".  If not all 
nbytes can be read, then the \fIkread()\fP routine returns the number of 
bytes actually read.
.B
.sp
int kread(id, buf, nbytes)
.br
int     id;
.br
char    *buf;
.br
int     nbytes;
.sp
.R
.LP
-- -- -- -- -- -- -- -- -- -- -- -- -- -- --  explanation of arguments  -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
.IP id: 8
Identifier of the file to be read, where the file was opened earlier with 
the use of \fIkopen()\fP.
.IP buf:
The buffer into which to read the data.
.IP nbytes:
Number of bytes to be read.
.br
.LP
=====================================================================
.bp
.sp 5
.NH 3 " krealloc()"
.XS
              \*(SN   krealloc()
.XE
.sp
.LP
Calls realloc() to re-allocate the requested data; changes the size of the
block referenced by ptr to size bytes and returns a pointer to the (possibly
moved) block.  The contents will be unchanged up to the lesser of the new and
old sizes.  If unable to honor a reallocation request, krealloc() leaves its
first argument unaltered.
.B
.sp
char *krealloc(ptr, size)
.br
char *ptr;
.br
unsigned int size;
.sp
.R
.LP
-- -- -- -- -- -- -- -- -- -- -- -- -- -- --  explanation of arguments  -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
.IP ptr:
Pointer to the original block of data.
.IP size:
The new size of the block of data.
.sp
.LP
=====================================================================
.sp 5
.NH 3 " krewind()"
.XS
              \*(SN   krewind()
.XE
.sp
.LP
This function is used to seek the transport to the beginning of a file.  In
essence it performs a \fIkfseek(file, 0L, 0);\fP.  Depending on the different
transport being used the  behavior will be different.  For a file it calls
fseek() to seek the file, but for a shared memory segment it it simply resets
the internal offset pointer.
.B
.sp
void krewind(file)
.br
kfile *file;
.sp
.R
.LP
-- -- -- -- -- -- -- -- -- -- -- -- -- -- --  explanation of arguments  -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
.IP file:
The kfile pointer to be read from; opened earlier with \fIkfopen()\fP.
.sp
.LP
=====================================================================
.bp
.sp 5
.NH 3 " ksystem()"
.XS
              \*(SN   ksystem()
.XE
.sp
.LP
This function is a replacement for the \fIsystem()\fP library call.  The 
only difference is that \fIksystem()\fP supports all available data transport
mechanisms.
.B
.sp
char *ksystem(command)
.br
char *command;
.sp
.R
.LP
-- -- -- -- -- -- -- -- -- -- -- -- -- -- --  explanation of arguments  -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
.IP command:
The command to be executed.
.sp
.LP
=====================================================================
.bp
.sp 5
.NH 3 " ktempnam()"
.XS
              \*(SN   ktempnam()
.XE
.sp
.LP
A front end for \fIvtempname()\fP, this module is used to create temporary
files for calling programs that support the data transport and distributed
processing mechanisms. \fIKtempnam()\fP is called with a template filename 
which is used to help identify the calling program.  The type of temporary file
created depends on the identifier.  If a unique temporary shared memory key 
is desired, then the template should look like: "shm=XXXX". If a file is 
desired, then either "XXXXXXXXX" or "file=XXXX" will work.  The convention 
should be as follows: an identifier followed by an equals indicator (=),
which is in turn followed by an optional template.  To find out which transport
mechanisms are available on your computer architecture, and their associated
identifiers, execute: { % transinfo }.  
.B
.sp
char *ktempnam(machine, template)
.br
char *machine;
.br
char *template;
.sp
.R
.LP
-- -- -- -- -- -- -- -- -- -- -- -- -- -- --  explanation of arguments  -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
.IP machine:
Optional machine name in which to create the template file.
.IP template:
Template for name of the file to be created.
.sp
.LP
=====================================================================
.bp
.sp 5
.NH 3 " ktell()"
.XS
              \*(SN   ktell()
.XE
.sp
.LP
This function is used to tell the current position within the transport.
The system call returns the offset of the current byte relative to the
beginning of the file associated with the transport identifier.
Depending on the different transport being used the behavior will be
different.  For a file it calls \fItell()\fP to locate the offset within the
file, but for a shared memory segment it it simply indicates the internal
offset.  Returns -1 or the current offset depending on whether the operation
failed or succeeded.
.B
.sp
int ktell(id)
.br
int id;
.sp
.R
.LP
-- -- -- -- -- -- -- -- -- -- -- -- -- -- --  explanation of arguments  -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
.IP id: 8
Identifier of the file which is to be used to return the current offset, where
the file was opened earlier with the use of \fIkopen()\fP.
.sp
.LP
=====================================================================
.sp 5
.NH 3 " kunlink()"
.XS
              \*(SN   kunlink()
.XE
.sp
.LP
This function is used to unlink the transport mechanism.  Depending on the 
transport being used, the behavior of \fIkunlink()\fP will be different.  
For instance, with a file it will unlink the file;  however, with a shared 
memory segment it initializes the memory segment before using a call to
\fIshmctl()\fP to destroy it.  Returns 0 on success, -1 on failure.
.B
.sp
char *kunlink(path)
.br
char *path;
.sp
.R
.LP
-- -- -- -- -- -- -- -- -- -- -- -- -- -- --  explanation of arguments  -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
.IP path:
The path to the tranport to be unlinked.
.sp
.LP
=====================================================================
.bp
.sp 5
.NH 3 " kwrite()"
.XS
              \*(SN   kwrite()
.XE
.sp
.LP
This function is a replacement for the system \fIwrite()\fP call.  The only 
difference is that kwrite() supports all available transport mechanisms.
The routine will write nbytes from the character array "buf" into the 
appropriate transport mechanism specified by id.  If not all nbytes can be 
written, then the \fIkwrite()\fP routine returns the number of bytes actually
written.
.B
.sp
char *kwrite(id, buf, nbytes)
.br
int     id;
.br
char    *buf;
.br
int     nbytes;
.sp
.R
.LP
-- -- -- -- -- -- -- -- -- -- -- -- -- -- --  explanation of arguments  -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
.IP id:
Identifier of the file to be written, where the file was opened earlier with 
the use of \fIkopen()\fP.
.IP buf:
The buffer from which to get the data to be written.
.IP nbytes:
Number of bytes to be written.
.sp
.LP
=====================================================================
.bp
.sp 5
.NH 3 " VStrcat()"
.XS
              \*(SN   VStrcat()
.XE
.sp
.LP
Same as strcat(); appends a copy of string2 to the end of string1.  Improved
in that that it will malloc for you.
.B
.sp
char *VStrcat(string1, string2)
.br
char *string1;
.br
char *string2;
.sp
.R
.LP
-- -- -- -- -- -- -- -- -- -- -- -- -- -- --  explanation of arguments  -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
.IP string1: 9
First string
.IP string2:
Second string, to be appended to the first
.sp
.LP
=====================================================================
.sp 3
.NH 3 " VStr3cat()"
.XS
              \*(SN   VStr3cat()
.XE
.sp
.LP
Appends string3 to string2, and then appends the result to string 1.
Malloc's for you.
.B
.sp
char *VStr3cat(string1, string2, string3)
.br
char *string1; 
.br
char *string2;
.br
char *string3;
.sp
.R
.LP
-- -- -- -- -- -- -- -- -- -- -- -- -- -- --  explanation of arguments  -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
.IP string1: 9
First string
.IP string2:
Second string, to be appended to the first
.IP string3:
Third string, to be appended to the second before the second is appended to
the first.
.sp
.LP
=====================================================================
.bp
.sp 5
.NH 3 " VStrcmp()"
.XS
              \*(SN   VStrcmp()
.XE
.sp
.LP
Improved version of strcmp(); compares the two input strings and returns a
status indicating whether string1 < string2 (-1), string1 = string2 (0),
or string1 > string2 (1).  If either of the strings are NULL, then
the NULL string is considered less than the other.  If both strings are NULL,
they are considered equal (0).
.B
.sp
int VStrcmp(string1, string2)
.br
char *string1; 9
.br
char *string2;
.sp
.R
.LP
-- -- -- -- -- -- -- -- -- -- -- -- -- -- --  explanation of arguments  -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
.IP string1: 9
First string to be compared.
.IP string2:
Second string to be compared.
.sp
.LP
=====================================================================
.sp 5
.NH 3 " VStrncmp()"
.XS
              \*(SN   VStrncmp()
.XE
.sp
.LP
Improved version of strncmp(); compares the two input strings up until the
nth character, and returns a status indicating whether string1 < string2 (-1),
string1 = string2 (0), or string1 > string2 (1).  If either of the strings are
NULL, then the NULL string is considered less than the other. If both strings
are NULL, they are considered equal (0).
.B
.sp
int VStrncmp(string1, string2, n)
.br
char *string1;
.br
char *string2;
.br
int n;
.sp
.R
.LP
-- -- -- -- -- -- -- -- -- -- -- -- -- -- --  explanation of arguments  -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
.IP string1: 9
First string to be compared to nth character.
.IP string2:
Second string to be compared to nth character.
.IP n:
Number of characters in string1 and string2 to compare.
.sp
.LP
=====================================================================
.bp
.sp 5
.NH 3 " VStrcpy()"
.XS
              \*(SN   VStrcpy()
.XE
.sp
.LP
Returns a copy of its string argument, and calloc's for you.
.B
.sp
char *VStrcpy(string)
.br
char *string;
.sp
.R
.LP
-- -- -- -- -- -- -- -- -- -- -- -- -- -- --  explanation of arguments  -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
.IP string: 9
String to be copied.
.sp
.LP
=====================================================================
.sp 5
.NH 3 " VStrncpy()"
.XS
              \*(SN   VStrncpy()
.XE
.sp
.LP
Copies string argument until n characters have been
copied, returns the result.  Improved in that it calloc's for you.
.B
.sp
char *VStrncpy(string, n)
.br
char *string; 
.br
int n;
.sp
.R
.LP
-- -- -- -- -- -- -- -- -- -- -- -- -- -- --  explanation of arguments  -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
.IP string: 9
String to have n characters copied
.IP n:
Number of characters to copy from string
.sp
.LP
=====================================================================
.bp
.sp 5
.NH 3 " VStrlen()"
.XS
              \*(SN   VStrlen()
.XE
.sp
.LP
Same as strlen(); returns the number of characters in its string argument,
not counting the null-terminating character.  Improved in that it checks
for NULL pointers and returns zero if the argument is NULL.
.B
.sp
int *VStrlen(string)
.br
char *string;
.sp
.R
.LP
-- -- -- -- -- -- -- -- -- -- -- -- -- -- --  explanation of arguments  -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
.IP string: 9
String to have characters counted. 
.sp
.LP
=====================================================================
.sp 2
.NH 3 " vbasename()"
.XS
              \*(SN   vbasename()
.XE
.sp
.LP
This function is used to strip the filename off of the path passed in.
This function is the opposite of vdirname().
.B
.sp
char *vbasename(directory_path)
.br
char *directory_path;  
.sp
.R
.LP
-- -- -- -- -- -- -- -- -- -- -- -- -- -- --  explanation of arguments  -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
.sp
.IP directory_path: 15
The directory path from which to strip off the filename.
.sp
.LP
=====================================================================
.sp 3
.LP
\fIEXAMPLE: 
.br
This example uses vbasename() to strip the filename off of a directory path.
\fP
.sp
char *dir_path = "KHOROS_HOME/data/images/ball.xv";
.br
char *filename;
.sp
if (!(filename = vbasename (dir_path)))
.br
    fprintf(stderr, "'%s' does not seem to exist", dir_path);
.sp
else
.br
    fprintf(stderr, "The filename is %s", filename);  /* should be "ball.xv" */
.bp
.sp 2
.NH 3 " vdirname()"
.XS
              \*(SN   vdirname()
.XE
.sp
.LP
This function is used to strip the directory path off of the filename passed in.
This function is the opposite of vbasename().
.B
.sp
char *vdirname(filename)
.br
char *filename;
.R
.sp
.LP
-- -- -- -- -- -- -- -- -- -- -- -- -- -- --  explanation of arguments  -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
.sp
.IP filename: 15
The filename from which to strip off the directory.
.sp
.LP
=====================================================================
.sp 3
.LP
\fIEXAMPLE:
.br
This example uses vdirname() to strip the directory off of a filename.
\fP
.sp
char *filename_path = "KHOROS_HOME/data/images/ball.xv";
.br
char *directory;
.sp
if (!(directory = vdirname (filename_path)))
.br
    fprintf(stderr, "'%s' does not seem to exist", filename_path);
.sp
else
.br
    /* should be "KHOROS_HOME/data/images" */
.br
    fprintf(stderr, "The directory is %s", directory);  
.bp
.sp 3
.NH 3 " veditfile()"
.XS
              \*(SN   veditfile()
.XE
.LP
This routine puts the user into a session with the editor, to edit the file
whose name is specified.
.B
.sp
veditfile(filename)
.br
char *filename;  
.sp
.R 
.LP
-- -- -- -- -- -- -- -- -- -- -- -- -- -- --  explanation of arguments  -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
.sp
.IP filename: 10
Name of the file which the user will be editing once the session with the
editor is begun.
.sp
.LP
=====================================================================
.sp 3
.LP
\fIEXAMPLE: 
.br
This example uses veditfile() to put the user into a session 
with the editor; they will be editing a file called "george".
\fP
.sp
int edit_file = true;
.br
char *filename = "george";
.sp
if (edit_file)
.br
{
.br
    veditfile(filename);
.br
}
.br
.bp
.sp 3
.NH 3 " vexpandpath()"
.XS
              \*(SN   vexpandpath()
.XE
.LP
This function expands any path to an absolute path from the root directory "/".
.B
.sp
vexpandpath(filename, directory, return_file)
.br
char *filename;
.br
char *directory;
.br
char *return_file;
.sp
.R 
.LP
-- -- -- -- -- -- -- -- -- -- -- -- -- -- --  explanation of arguments  -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
.sp
.IP filename: 10
The filename to be expanded
.IP directory:
The directory path to prepend onto the filename. Pass in NULL if not applicable.
.IP return_file:
If \fIreturn_file\fP is not NULL, then this will be where we return the 
full path to the expanded file.  Otherwise, we allocate the necessary space 
and return the expanded path.
.sp
.LP
=====================================================================
.sp 3
.LP
\fIEXAMPLE: 
.br
This example uses vexpandpath() to expand a relative path to a full path.
\fP
.sp
char *panepath;
.br
if ((panepath = vexpandpath("vadd.pane", NULL, NULL)) == NULL)
.br
{
.br
    (void)fprintf(stderr,"Invalid path specified for the vadd.pane file.\n");
.br
    exit(0);
.br
}
.br
.bp
.sp 3
.NH 3 " vfreelist()"
.XS
              \*(SN   vfreelist()
.XE
.sp
.LP
This routine frees a list that was previously created using \fIvlistdir()\fP
or \fIvlistfile()\fP.
.B
.sp
vfreelist(list, num_entries)
.br
char **list;
.br
int num_entries;
.sp
.R
.LP
-- -- -- -- -- -- -- -- -- -- -- -- -- -- --  explanation of arguments  -- -- --
 -- -- -- -- -- -- -- -- -- -- -- --
.sp
.IP list:
The list to be freed (previously created using \fIvlistdir\fP or
\fIvlistfile()\fP.
.IP num_entries:
The number of entries in the list to be freed (previously returned by
\fIvlistdir()\P or \fIvlistfile()\fP.
.sp
.LP
=====================================================================
.sp 3
.LP
\fIEXAMPLE:
.br
See example provided with \fIvlistdir.
\fP
.bp
.B
.sp 3
.bp
.NH 3 " vfullpath()"
.XS
              \*(SN   vfullpath()
.XE
.sp
.LP
This function returns the full, expanded path to the supplied file.  
It will expand the KHOROS_HOME environment variable if this it is currently
set in the user's environment. vfullpath() will also expand a "~".  If desired,
the caller may pass in a directory path which will be prepended to the front of 
the filename.  If it is a directory path, and not a file path that needs to
be expanded, simply provide the directory path to be expanded as the first
argument, and not the second.  WARNING: will return NULL \fIONLY if the filename
cannot be expanded\fP.   For instance, \fIvfullpath() will return NULL if 
the KHOROS_HOME environment variable is used by the application program 
but has not been set by the user.  vfullpath() will allocate the return 
string for you or not, as indicated by the value of \fIreturn_file\fP.
If \fIreturn_file\fP is NULL, vfullpath() will malloc the returned string
for you;  if \fIreturn_file\fP is non-NULL,  vfullpath() will place the return
string in that location.  Note that if the latter method is used, 
\fIreturn_file\fP must be allocated with sufficient space to accomodate the 
output string before this routine is called.
.sp
.B
.sp
char *vfullpath(filename, directory_path, return_file)
.br
char *filename;  
.br
char *directory_path;  
.br
char *return_file;
.sp
.R
.LP
-- -- -- -- -- -- -- -- -- -- -- -- -- -- --  explanation of arguments  -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
.sp
.IP filename: 15
The filename (or directory path) to be expanded.
.IP directory_path: 
The directory path to prepend onto the filename. Pass in NULL if not applicable.
.IP return_file:
If you want vfullpath() to allocate and return the expanded filename to you,
pass in NULL as the \fIreturn_file\fP.  If you wish to allocate your own 
memory in which to have the file expanded, allocate this character pointer first
and pass it in as \fIreturn_file\fP.  In this case, vfullpath will expand the
filename in \fIreturn_file\fP. Note: use the latter method at your own
risk!  It is the caller's responsibility to allocate sufficient space for the
expanded filename when \fIreturn_file\fP is not passed in as NULL.
.sp
.LP
=====================================================================
.sp 3
.LP
\fIEXAMPLE 1: 
.br
This example uses vfullpath() to expand a filename which includes the 
KHOROS_HOME environment variable.
\fP
.sp
char *filename = "KHOROS_HOME/data/images/ball.xv";
.br
char *fullpath;
.sp
fullpath = vfullpath(filename, NULL, NULL);
.sp 3
\fIEXAMPLE 2: 
.br
This example uses vfullpath() to prepend a directory path onto a filename, 
and expand the result.
\fP
.sp
char *filename = "ball.xv";
.br
char *directory = "~khaos/data/images";
.sp
fullpath = vfullpath(filename, directory, NULL);
.sp 3
\fIEXAMPLE 3: 
.br
This example uses vfullpath() to expand a directory path.
\fP
.sp
char *filename = "~khaos/data/images";
.sp
fullpath = vfullpath(filename, NULL, NULL);
.bp
.sp 2
.NH 3 " vget_type()"
.XS
              \*(SN   vget_type()
.XE
.sp
.LP
This utility routine takes a string describing a data type and returns 
the integer that represents it's #define'd name in the Khoros system.
.sp
It takes as input a string that must be one of:
.br
"bit", "byte", "short", "int", "float", "complex" or "double"
.sp
It passes back the corresponding integer which will (respectively) be one of:
.br
VFF_TYP_BIT, 
.br
VFF_TYP_1_BYTE, 
.br
VFF_TYP_2_BYTE, 
.br
VFF_TYP_4_BYTE, 
.br
VFF_TYP_FLOAT, 
.br
VFF_TYP_COMPLEX,
.br
VFF_TYP_DOUBLE,
.br
or VFF_TYP_DCOMPLEX.
.sp
vget_type() will return False (0) if an error occurs, non-zero if it was
successful.
.LP
=====================================================================
.B
.sp
int *vget_type(type, string)
.br
int *type;
.br
char *string;  
.R
.LP
-- -- -- -- -- -- -- -- -- -- -- -- -- -- --  explanation of arguments  -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
.sp
.IP type: 10
The integer representation of the string passed in will be returned to
the caller via this argument.
.IP string:
The string to be interpreted.
.sp
.LP
=====================================================================
.sp 2
.LP
\fIEXAMPLE: 
.br
This example uses vget_type() to assign the proper storage type to 
a Khoros image's data_storage_type field.
\fP
.sp
struct xvimage *image;
.br
int data_type;
.sp
/*
.br
 * assuming we have a valid image,
.br
 * but need to assign it's data storage type.
.br
 * we know that it is an integer image.
.br
 */
.sp
if (vget_type(&data_type, "int")) 
.br
    image->data_storage_type =  data_type;
.sp
.sp 2
.sp 2
.NH 3 " vlistdir()"
.XS
              \*(SN   vlistdir()
.XE
.sp
.LP
This routine is used to create a list of files according to a user supplied 
basename and a initial global directory.  The directory_path field is to be 
used in the same way as the directory_path field in vfullpath().  The basename 
can be either a path or partial path to the directory in which a listing
will be performed.  If the basename is a partial path such as "image", 
in a directory where "image1" and "image2" exists, then vlistdir() will return 
the two filenames and any other files that may match the "image" base.
If the basename is NULL then the entire directory specified by the 
directory_path will be listed.
.LP
The list mode is used to indicate what we are going to list in the directory.  
The possible defines are listed in KHOROS_HOME/include/vdefines.h.  
The following are the current list modes:
.sp
.in +5
XV_PATH - prepend the path to each file
.br
XV_FILE         - list plain text files
.br
XV_DIR          - list directories
.br
XV_DOT          - list dot files
.br
XV_LINK         - list symbolic files
.br
XV_SOCK         - list socket files
.br
XV_READ         - file is readable by caller
.br
XV_WRITE        - file is writable by caller
.br
XV_EXEC         - file is executable by caller
.br
.in -5
.sp
.LP
The selections are or'ed together in order to choose which attribute is desired.For example, (XV_FILE | XV_DIR) will list only files and directories that match
the basename.  The read, write, execute flags should be used when the caller 
wishes to know if they have the correct permissions for the list of files.
For instance,  (XV_FILE | XV_WRITE) will list only files for which the user
has write permissions.
.LP
\fIvlistdir)\fP will return an array of character strings representing
the contents of the desired directory.  The number of entries will be returned
within the num_entries field. If the path to be listed does not exist or no 
files are matched from the basename, then vlistdir() will return
NULL.  Since the list is allocated the programmer should use
the \fIvfreelist()\fP call to free the list (or use the UNIX \fIfree()\fP 
routine).
.B
.sp
char **vlistdir(basename, directory_path, list_mode, format, num_entries)
.br
char *basename;  
.br
char *directory_path;
.br
int list_mode;
.br
int format;
.br
int *num_entries;
.sp
.R
.LP
-- -- -- -- -- -- -- -- -- -- -- -- -- -- --  explanation of arguments  -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
.sp
.IP basename: 15
A path or partial path to the directory in which the listing is to be performed.
.IP directory_path: 15
The directory in which to listing is to be performed.
.IP list_mode: 15
Used to indicate what parts of the directory contents are to be listed 
(see above).
.IP format:
The format field is used to prepend a type to the filename,
similar to the UNIX "ls -F" command.  Directories will have
"/", "@" for symbolic links, and "=" for sockets.  Pass TRUE (1) if you would
like types prepended to the filename, FALSE (0) if you would not.
.IP num_entries: 
Returns the number of entries found in the directory that match the 
requisites specified by \fIlist_mode\fP.
.LP
=====================================================================
.sp 3
.LP
\fIEXAMPLE: 
.br
This example uses vlistdir() to get the entire contents of the 
KHOROS_HOME/data/images directory.
\fP
.sp
char *directory = "KHOROS_HOME/data/images";
.br
char **list;
.br
int mode, num_entries;
.sp
mode = XV_DIR | XV_FILE;
.br
list = vlistdir(NULL, directory, mode, True, &num_entries);
.br
if (list == NULL)
.br
   (void) fprintf(stderr, "Error! Cannot open directory %s", directory);
.sp
/*
.br
 *  use the list for something, and free the list when it is no longer needed
.br
 */
.sp
vfreelist(list, num_entries);
.bp
.sp 2
.NH 3 " vlistfile()"
.XS
              \*(SN   vlistfile()
.XE
.sp
.LP
This routine is used to create a list from the contents of the supplied file.  
It reads the contents of the specified file and returns the words in the file
in an array of strings.  The file may contain a word on each line or several 
words on each line.  Each word will be put into the list separately and the 
list sorted if the sort_list flag is specified.  Note:  All 'sh' and 'C' style 
comments lines will be skipped.  'sh' style comments are delineated by the
\fI#\fP character.  The contents from that point until the end of line will 
be ignored.  A C style comment is delineated by a \fI/*\fP.  The contents of 
the file will be skipped until a \fI*/\fP is encountered; the \fI*/\fP can be 
located on the same or any proceeding line.
.sp
If desired, the caller may pass in a directory path which will be prepended to
the front of the filename.  Most applications set this argument to NULL.
The programmer also has the option of specifying if they want the resulting
strings sorted or not.  If the \fIsort_list\fP field is specified the list
will be sorted into descending order.
.sp
vlistfile() will return an array of character strings and the number of
entries will be returned within the \fInum_entries\fP field.  If the path to
be listed does not exist or the specified file does not exist, then
vlistfile() will return NULL.  The programmer should use the vfreelist() 
call to free the list (or use the UNIX free(3) routine) after it will no
longer be used.
.sp
.B
.sp
char **vlistfile(filename, directory_path, sort_list, num_entries)
.br
char *filename;
.br
char *directory_path;
.br
int sort_list;
.br
int *num_entries;
.sp
.R
.LP
-- -- -- -- -- -- -- -- -- -- -- -- -- -- --  explanation of arguments  -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
.sp
.IP filename: 15
The filename (or directory path) to be expanded.
.IP directory_path: 
The directory path to prepend onto the filename. Pass in NULL if not applicable.
.IP sort_list:
sort_list indicates if vlistfile() is to sort the list into descending order
before passing back the list then.  Pass TRUE (1) if you would like the list
sorted, FALSE (0) if you would not.
.IP num_entries: 
Returns the number of entries in the returned list.
.sp
.LP
=====================================================================
.sp 3
.LP
\fIEXAMPLE: 
.br
This example uses vlistfile() to get the contents of the
KHOROS_HOME/repos/cantata/routines.nolist file.
\fP
.sp
char *filename = "KHOROS_HOME/repos/cantata/routines.nolist";
.br
char **list;
.br
int num_entries;
.sp
list = vlistfile(filename, NULL, True, &num_entries);
.br
if (list == NULL)
.br
   (void) fprintf(stderr, "Error! Cannot open filename %s", filename);
.sp
/*
.br
 *  use the list for something, and free the list when it is no longer needed
.br
 */
.sp
vfreelist(list, num_entries);
.bp
.sp 2
.NH 3 " vread_ascii()"
.XS
              \*(SN   vread_ascii()
.XE
.sp
.LP
This function gets the read device for ascii reading.  
This routine should be used whenever you are reading from an ascii file.
.B
.sp
vread_ascii(input_filename, device)
.br
char *input_filename;  
.br
FILE **device;
.sp
.R
.LP
-- -- -- -- -- -- -- -- -- -- -- -- -- -- --  explanation of arguments  -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
.sp
.IP input_filename: 17
The filename of the ascii file which is to be read from.
.IP device:
Returns the open stream to the ascii file, ready for reading.
.sp
.LP
=====================================================================
.sp 3
.LP
\fIEXAMPLE: 
.br
This example uses vread_ascii() to get the read device to read from an
ascii file named "input_ascii_file".
\fP
.sp
FILE *read_device;
.br
char *input_file = "input_ascii_file";
.br
int array[NumPoints];
.br
int i;
.sp
/*
.br
 * use vread_ascii() to open file for reading
.br
 */
.br
if (! vread_ascii(input_file, &read_device))
.br
{
.br
    (void) fprintf(stderr, "Can't open ascii input file '%s'\n", input_file);
.br
    exit(1);
.br
}
.br
/*
.br
 * read a set of integers into the array
.br
 */
.br
for (i = 0; i < NumPoints; i++)
.br
   fscanf(read_device, "%d", &array[i++]);
.bp
.sp 3
.NH 3 " vlower_string()"
.XS
              \*(SN   vlower_string()
.XE
.LP
This function returns the lower case representation of the 
supplied input string.
.B
.sp
char *vlower_string(input_string, output_string)
.br
char *input_string;
.br
char *output_string;
.sp
.R 
.LP
-- -- -- -- -- -- -- -- -- -- -- -- -- -- --  explanation of arguments  -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
.sp
.IP input_string:
The input string to be put in lower case.
.IP output_string:
If output_string is NULL, vlower_string() will malloc the returned string
for you;  if output_string is non-NULL,  vlower_string will place the return
string in that location.  Note that if the latter method is used, output_string
must be allocated with sufficient space to accomodate the output string before
this routine is called.
.sp
.LP
=====================================================================
.sp 3
.LP
\fIEXAMPLE: 
.br
This example uses vlower_string() to change a string to its lower case
representation, using our own memory allocation. \fP
.sp
char *lower, *upper, *calloc();
.sp
upper = VStrcpy("THIS IS A TEST");
.br
lower = (char *) calloc (1, sizeof(char) * VStrlen(upper));
.br
(void) vlower_string(upper, lower);
.br
fprintf(stderr, "%s\n", lower);  /* should write to stderr: this is a test */
.bp
.sp 3
.NH 3 " vputenv()"
.XS
              \*(SN   vputenv()
.XE
.LP
This module is used to put an environment variable
in the user's environment variable list.  If "PUTENV" is defined, then
we use the system call \fIputenv()\fP; otherwise, we use our own put
environment code.
.B
.sp
vputenv(string)
.br
char *string;  
.sp
.R 
.LP
-- -- -- -- -- -- -- -- -- -- -- -- -- -- --  explanation of arguments  -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
.sp
.IP string: 10
The environment variable string to be added to the user's environment 
variable list. Note that \fIstring\fP must point to a string of the form
"name=value". This subroutine makes the value of the environment variable
\fIname\fP equal to \fIvalue\fP by altering an existing variable or
creating a new one. In either case, the string pointed to by \fIstring\fP
becomes part of the environment, so altering the string will
change the environment.   If your system supports \fIputenv()\fP, you
may obtain more information by doing \f(CW% man putenv\fP.
.sp
.LP
=====================================================================
.sp 3
.LP
\fIEXAMPLE: 
.br
This example uses vputenv() to add or change the DISPLAY environment variable.
\fP
.sp
char *display_name;
.br
char temp[MaxLength];
.sp
display_name = VStrcpy("peabody:0");
.br
(void) sprintf(temp, "DISPLAY=%s", display_name);
.br
vputenv(xvf_strcpy(temp));
.br
.bp
.sp 3
.NH 3 " vtempnam()"
.XS
              \*(SN   vtempnam()
.XE
.sp
.LP
This function creates names for temporary files.  The template filename 
supplied should help to identify the application which created it.  
If no template filename is given, TEMPLATE is used.  If a temporary file 
cannot be created, NULL is returned.  The application should 
remove temporary files after using them.
.LP
.B
.sp
vtempnam(template)
.br
char *template;  
.sp
.R
.LP
-- -- -- -- -- -- -- -- -- -- -- -- -- -- --  explanation of arguments  -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
.sp
.IP template: 10
A string to be used as the template filename for the temporary file, to help
identify the application that created it.
.sp
.LP
=====================================================================
.sp 3
.LP
\fIEXAMPLE: 
.br
This example uses vtempnam() to get a good filename for a temporary file.
It uses "george" as a template, so that everyone will know that it came
from our example.
\fP
.sp
char *tempfile;
.sp
tempfile = vtempnam("george");
.sp
/*
.br
 * do something with the filename - most likely write into
.br
 * it, use the contents, and delete it.
.br
 */
.bp
.sp 3
.NH 3 " vreplace_char()"
.XS
              \*(SN   vreplace_char()
.XE
.LP
This function performs a global change of character on the input string.  It 
returns a string where every occurrence of the scan character is replaced with 
the replacement character.  If output_string is sent in as NULL, the result will
be malloc'ed for you.  If output_string is provided as non-null, the result 
will be stored in output_string.  Note that if the latter use is chosen,
output_string must be previously allocated with a sufficient amount of storage 
space before this routine is called.
.B
.sp
char *vreplace_char(input_string, scan_char, replace_char, output_string)
.br
char *input_string;
.br
char scan_char;
.br
char replace_char;
.br
char *output_string;
.sp
.R 
.LP
-- -- -- -- -- -- -- -- -- -- -- -- -- -- --  explanation of arguments  -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
.sp
.IP input_string:
The input string to be changed.
.IP scan_char:
The character to be replaced
.IP replace_char:
The character to replace with
.IP output_string:
If output_string is NULL, vreplace_char() will malloc the returned string
for you;  if output_string is non-NULL,  replace_char() will place the return
string in that location.  Note that if the latter method is used, output_string
must be allocated with sufficient space to accomodate the output string before
this routine is called.
.sp
.LP
=====================================================================
.sp 3
.LP
\fIEXAMPLE: 
.br
This example uses vreplace_char() to change a string.  It allocates space
in advance for the string, and has vreplace_char() use that space for the
output string. 
\fP
.sp
char *old, *new, *calloc();
.br
char scan, replace;
.sp
old = VStrcpy("Many Fishes");
.br
scan = 'F';
.br
replace = 'W';
.br
new = (char *) calloc(1, sizeof(char) * VStrlen(old));
.br
(void) vreplace_char(old, scan, replace, new);
.br
fprintf(stderr, "%s\n", new);  /* "Many Wishes" */
.br
.bp
.NH 3 " vreplace_string()"
.XS
              \*(SN   vreplace_string()
.XE
.LP
This function performs a global change of text on the input string.  It 
returns a string where every occurrence of the scan text is replaced with 
the replacement text.  If output_string is sent in as NULL, the result will 
be malloc'ed for you.  If output_string is provided as non-null, the result 
will be stored in output_string.  Note that if the latter use is chosen,
output_string must be previously allocated with a sufficient amount of storage 
space before this routine is called.
.B
.sp
char *vreplace_string(input_string, scan_str, replace_str, output_string)
.br
char *input_string;
.br
char *scan_str;
.br
char *replace_str;
.br
char *output_string;
.sp
.R 
.LP
-- -- -- -- -- -- -- -- -- -- -- -- -- -- --  explanation of arguments  -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
.sp
.IP input_string:
The input string to be changed.
.IP scan_str:
The text to be replaced
.IP replace_str:
The text to replace with
.IP output_string:
If output_string is NULL, vreplace_string() will malloc the returned string
for you;  if output_string is non-NULL,  replace_string() will place the return
string in that location.  Note that if the latter method is used, output_string
must be allocated with sufficient space to accomodate the output string before
this routine is called.
.bp
.sp 3
.NH 3 " vstrstr()"
.XS
              \*(SN   vstrstr()
.XE
.LP
.PP
This function
returns a pointer to the first  occurrence  of  the
pattern string sub_string in input_string.   For example, if
input_string is "This is a  string thing" and sub_string is "ing", vstrstr()
returns "ing thing".  If sub_string does not occur in
the input_string, vstrstr() returns NULL
.B
.sp
char *vstrstr(input_string, sub_string)
.br
char *input_string;
.br
char *sub_string;
.sp
.R
.LP
-- -- -- -- -- -- -- -- -- -- -- -- -- -- --  explanation of arguments  -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
.sp
.IP input_string:
The input string to be searched.
.IP sub_string:
The string to search for the occurence of in input_string.
.sp
.LP
=====================================================================
.sp 3
.LP
\fIEXAMPLE: 
.br
This example uses vstrstr() to search for the sub-string "come"
in the input string "Welcome Welcome to Khoros".
.sp
char *input_string, *sub_string, *new;
.sp
input_string = VStrcpy("Welcome, Welcome to Khoros");
.br
sub_string = VStrcpy("come");
.br
new = vstrstr(input_string, sub_string);
.br
fprintf(stderr, "%s\n", new);  /* "come Welcome to Khoros" */
.bp
.sp 3
.NH 3 " vupper_string()"
.XS
              \*(SN   vupper_string()
.XE
.LP
This function returns the upper case representation of the 
supplied input string.
.B
.sp
char *vupper_string(input_string, output_string)
.br
char *input_string;
.br
char *output_string;
.sp
.R 
.LP
-- -- -- -- -- -- -- -- -- -- -- -- -- -- --  explanation of arguments  -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
.sp
.IP input_string:
The input string to be put in upper case.
.IP output_string:
If output_string is NULL, vupper_string() will malloc the returned string
for you;  if output_string is non-NULL,  vupper_string will place the return
string in that location.  Note that if the latter method is used, output_string
must be allocated with sufficient space to accomodate the output string before
this routine is called.
.sp
.LP
=====================================================================
.sp 3
.LP
\fIEXAMPLE: 
.br
This example uses vupper_string() to change a string to its upper case
representation, allowing the routine to malloc for us.\fP
.sp
char *lower, *upper;
.sp
lower = VStrcpy("This is a test");
.br
upper = vupper_string(lower, NULL);
.br
fprintf(stderr, "%s\n", upper);  /* "THIS IS A TEST" */
.bp
.sp 3
.NH 3 " vwait3()"
.XS
              \*(SN   vwait3()
.XE
.LP
This routine emulates the BSD \fIwait3()\fP command.
The wait3 process waits until any child has completed, without hanging
(WNOHANG). If "WAIT3" is defined, we use the system call \fIwait3()\fP;
otherwise, we use our own wait3 code.  If \fIwait3()\fP is not defined on
your machine, the \fIoptions\fP and \fIrusage\fP parameters will not be
used; pass dummy variables if desired.  This new routine is compliments
of Bob Weaver, at Idaho National Labs.  If \fIwait3()\fP is defined on 
your system, do \f(CW% man wait3\fP for more information.
.B
.sp
vwait3(status, options, rusage)
.br
vstatus *status;
.br
int options;
.br
struct  rusage *rusage;
.sp
.R 
.LP
-- -- -- -- -- -- -- -- -- -- -- -- -- -- --  explanation of arguments  -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
.sp
.IP status:
The return status of the process
.IP options:
Options used for wait3 (WUNTRACED, WNOHANG)
.IP rusage:
Ihe resource usage
.sp
.IP Note: the options and rusage are ignored when the system call \fIwait3()\fP
is not defined.  The default value of \fIoptions\fP is WNOHANG.
.sp
.LP
=====================================================================
.sp 3
.LP
\fIEXAMPLE: 
.br
This example uses vwait3() to check to see if any process is finished
running, and perform some operation at that time.\fP
.sp
int          pid;
.br
vstatus      status;
.sp
while ((pid = vwait3(&status, WNOHANG, NULL)) > 0)
.br
{
.br
   /* check status of process for pid and then perform some task. */
.br
}
.br
.bp
.sp 2
.NH 3 " vwrite_ascii()"
.XS
              \*(SN   vwrite_ascii()
.XE
.sp
.LP
This function gets the write device for ascii writing.  
This routine should be used whenever you are writing to an ascii file.
.B
.sp
vwrite_ascii(output_filename, device)
.br
char *output_filename;  
.br
FILE **device;
.sp
.R
.LP
-- -- -- -- -- -- -- -- -- -- -- -- -- -- --  explanation of arguments  -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
.sp
.IP output_filename: 17
The filename of the ascii file which is to be written to.
.IP device:
Returns the open stream to the ascii file, ready for writing.
.sp
.LP
=====================================================================
.sp 3
.LP
\fIEXAMPLE: 
.br
This example uses vwrite_ascii() to get the write device to write to an
ascii file named "output_ascii_file" \fP.
.sp
FILE *write_device;
.br
char *output_file = "output_ascii_file";
.br
int array[NumPoints];
.br
int i;
.sp
/*
.br
 * use vwrite_ascii() to open file for writing
.br
 */
.br
if (! vread_ascii(output_file, &write_device))
.br
{
.br
    (void) fprintf(stderr, "Can't open ascii output file '%s', output_file);
.br
    exit(1);
.br
}
.br
/*
.br
 * write a set of integers into the file (assuming array is set)
.br
 */
.br
for (i = 0; i < NumPoints; i++)
.br
   fprintf(write_device, "%d", array[i++]);
.bp
.bp
.sp 3
.NH 2 "OBTAINING ARGUMENTS FROM THE CLUI"
.XS
      \*(SN  OBTAINING ARGUMENTS FROM THE CLUI
.XE
.sp 2
.PP
Descriptions of the routines in the \fIvgparms\fP library that parse the 
command line user interface for arguments to a program are provided here 
so that the application programmer may gain a more thorough understanding 
of how an application in the Khoros system which uses a command line user 
interface operates.  However, a gw_get_args() routine 
(which will correctly include all calls to the \fIvgparm\fP library
necessary to get all arguments for the application program) can be
automatically generated by the \fIghostwriter\fP automatic code generation 
program.  Novice application programmers are encouraged to read the 
documentation on \fIghostwriter\fP, use the \fIghostwriter\fP program to 
generate a driver for a simple application, and use the generated code to 
look at  while reading this documentation (as opposed to attempting to use 
the descriptions here to create from scratch a routine which will get
command line arguments).
.bp
.sp 2
.NH 3 " vget_infile()"
.XS
              \*(SN   vget_infile()
.XE
.sp
.LP
Gets an input file, and returns it to the caller. May get the input file 
directly from the command line, may use interactive prompting to obtain 
a input filename from the user, or may get the input file from an answer file.
Checks to make sure that the file exists, and that the file is readable by 
the user.  Note that when stdin is to be used in place of an input file on
the command line, a "-" may be substituted for the filename.  Returns a status
of True (1) if the \fIflag_string\fP specified was found; returns False (0) 
otherwise.
.sp
.B
.sp
int vget_infile(fd_ansr, prompt_flag, flag_string, prompt_string, infile_return)
.br
int fd_ansr;  
.br
int prompt_flag;
.br
char *flag_string;
.br
char *prompt_str;
.br
char **infile_return;
.sp
.R
.LP
-- -- -- -- -- -- -- -- -- -- -- -- -- -- --  explanation of arguments  -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
.sp
.IP fd_ansr: 14
If an answer file is used, this is the file descriptor of the answer file.
If no answer file is used, pass (-1).
.sp
.IP prompt_flag:
True (1) if interactive prompting is to be used; False (0) if input file is
to be obtained directly from the command line.
.sp
.IP flag_string:
The "-flag" that is to be searched for on the command line to precede the
input file value.  For example, if [-i1 {infile} ] is expected, flag_string
should be specified as "-i1". 
.sp
.IP prompt_string:
An appropriate prompt string should be specified here, for use with 
interactive prompting.  If interactive prompting is not used, pass "noprompt".  
.sp
.IP infile_return:
Allocates and returns the input filename provided by the user.  
.sp
.LP
=====================================================================
.bp
.sp 3
.LP
\fIEXAMPLE: 
.br
This example gets an input file from the command line.  
An answer file is not used, nor is interactive prompting.
In this example, we look for [-i1 {input filename}].
\fP
.sp
int infile_specified, fd_ansr, prompting;
.br
char *input_filename;
.sp
fd_ansr = -1; /* no answer file will be used */
.br
prompting = False; /* no interactive prompting to be used */
.sp
infile_specified = vget_infile(fd_ansr, prompting, "-i1", "noprompt", &input_filename);
.sp
if (infile_specified)
.br
{
.br
	/* 
.br
	 *  use \fIinput_filename\fP to read in a file; 
.br
	 *  take into account the fact that the user
.br
	 *  might have specified "-", and in that case, read from stdin.
.br
	 * 
.br
	 */
.br
}
.bp
.sp 2
.NH 3 " vget_outfile()"
.XS
              \*(SN   vget_outfile()
.XE
.sp
.LP
Gets an output file, and returns it to the caller. May get the output file 
directly from the command line, may use interactive prompting to obtain 
a output filename from the user, or may get the output file from an answer file.
Checks to make sure that the directory referenced exists, and that the 
directory is writable by the user.  Note that when stdout is to be used in 
place of an output file on the command line, a "-" may be substituted for 
the filename.  Returns a status of True (1) if the \fIflag_string\fP 
specified was found; returns False (0) otherwise.
.sp
.B
.sp
int vget_outfile(fd_ansr, prompt_flag, flag_string, prompt_string, outfile_return)
.br
int fd_ansr;  
.br
int prompt_flag;
.br
char *flag_string;
.br
char *prompt_str;
.br
char **outfile_return;
.sp
.R
.LP
-- -- -- -- -- -- -- -- -- -- -- -- -- -- --  explanation of arguments  -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
.sp
.IP fd_ansr: 14
If an answer file is used, this is the file descriptor of the answer file.
If no answer file is used, pass (-1).
.sp
.IP prompt_flag:
True (1) if interactive prompting is to be used; False (0) if output file is
to be obtained directly from the command line.
.sp
.IP flag_string:
The "-flag" that is to be searched for on the command line to precede the
input file value.  For example, if [-o1 {outfile} ] is expected, flag_string
should be specified as "-o1". 
.sp
.IP prompt_string:
An appropriate prompt string should be specified here, for use with 
interactive prompting.  If interactive prompting is not used, pass "noprompt".  
.sp
.IP outfile_return:
Allocates and returns the output filename provided by the user.  
.sp
.LP
=====================================================================
.bp
.sp 3
.LP
\fIEXAMPLE: 
.br
This example uses interactive prompting to get an output filename from the user.
An answer file is not used. In this example, we prompt for the equivalent of
[-o1 {output filename}] appearing on the command line.
\fP
.sp
int outfile_specified, fd_ansr, prompting;
.br
char *output_filename;
.br
char *prompt = "Please enter the desired name for the output file"
.sp
fd_ansr = -1; /* no answer file will be used */
.br
prompting = True; /* interactive prompting is to be used */
.sp
outfile_specified = vget_outfile(fd_ansr, prompting, "-o1", prompt, &output_filename);
.sp
if (outfile_specified)
.br
{
.br
	/* 
.br
	 *  use \fIoutput_filename\fP to write out a file; 
.br
	 *  take into account the fact that the user
.br
	 *  might have specified "-", and in that case, write to stdout.
.br
	 * 
.br
	 */
.br
}
.bp
.sp 3
.sp 2
.NH 3 " vget_int()"
.XS
              \*(SN   vget_int()
.XE
.sp
.LP
Gets an integer, and returns it to the caller. May get the integer 
directly from the command line, may use interactive prompting to obtain 
the integer from the user, or may get the integer from an answer file.
Checks to make sure that the input is a proper integer, and that the 
integer is within given bounds, if bounds are specified. Returns a status
of True (1) if the \fIflag_string\fP specified was found;
returns False (0) otherwise. If the \fIflag_string\fP specified could not 
be found, vget_int() will return the value of the integer default specified.
.sp
.B
.sp
int vget_int(fd_ansr, prompt_flag, flag_string, prompt_string, 
.br
			int_return, int_default, int_min, int_max); 
.br
int fd_ansr;  
.br
int prompt_flag;
.br
char *flag_string;
.br
char *prompt_str;
.br
int *int_return;
.br
int int_default;
.br
int int_min, int_max;
.sp
.R
.LP
-- -- -- -- -- -- -- -- -- -- -- -- -- -- --  explanation of arguments  -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
.sp
.IP fd_ansr: 13
If an answer file is used, this is the file descriptor of the answer file.
If no answer file is used, pass (-1).
.sp
.IP prompt_flag:
True (1) if interactive prompting is to be used; False (0) if integer is
to be obtained directly from the command line.
.sp
.IP flag_string:
The "-flag" that is to be searched for on the command line to precede the
integer value.  For example, if [-int_value {integer} ] is expected, flag_string
should be specified as "-int_value". 
.sp
.IP prompt_string:
An appropriate prompt string should be specified here, for use with 
interactive prompting.  If interactive prompting is not used, pass "noprompt".  
.sp
.IP int_return:
Returns the integer.  If the flag string could not be found, this will be
equal to the value passed in for \fIint_default\fP.
.sp
.IP int_default:
Default for the integer, in case the user neglects to specify \fIflag_string\fP.
Must be consistent with \fIint_min\fP and \fIint_max\fP.
.bp
.sp 3
.IP "int_min, int_max;"
The minimum and maximum values of the integer.  With these values,
you may also specify \fIbounds\fP for the integer specified.  Here are the 
possible values for \fIint_min\fP and \fIint_max\fP:
.sp
.in +1i
int_min = int_max = -2 {legal values  < 0}
.br
int_min = int_max = -1 {legal values <= 0}
.br
int_min = int_max =  1 {legal values >= 0}
.br
int_min = int_max =  2 {legal values >  0}
.br
int_min = int_max =  X {no range checking}
.br
int_min = X;  int_max = Y  { X <= legal value <= Y}
.in -1i
.sp
.LP
=====================================================================
.sp 2
.LP
\fIEXAMPLE: 
.br
This example gets an integer that is strictly less than zero. The default
value for this integer is (-10).  An answer file is not used, nor is 
interactive prompting.  In this example, we look for [-x {integer}].
\fP
.sp
int int_specified, fd_ansr, prompting;
.br
int int_def = -2, int_min = -2, int_max = -2;
.br
int int_value;
.sp
fd_ansr = -1; /* no answer file will be used */
.br
prompting = False; /* no interactive prompting to be used */
.sp
int_specified = vget_int(fd_ansr, prompting, "-i1", "noprompt", &int_value,
.br
			int_def, int_min, int_max);
.sp
.br
/* 
.br
 *  use the integer for something. if \fIint_specified\fP is false,
.br
 *  we can still use \fIint_value\fP, as it takes on the default value of -2.
.br
 */
.br
.bp
.sp 2
.NH 3 " vget_float()"
.XS
              \*(SN   vget_float()
.XE
.sp
.LP
Gets a float, and returns it to the caller. May get the float 
directly from the command line, may use interactive prompting to obtain 
the float from the user, or may get the float from an answer file.
Checks to make sure that the input is a proper float, and that the 
float is within given bounds, if bounds are specified. Returns a status
of True (1) if the \fIflag_string\fP specified was found;
returns False (0) otherwise. If the \fIflag_string\fP specified could not 
be found, vget_float() will return the value of the float default specified.
.sp
.B
.sp
int vget_float(fd_ansr, prompt_flag, flag_string, prompt_string, 
.br
			float_return, float_default, float_min, float_max); 
.br
int fd_ansr;  
.br
int prompt_flag;
.br
char *flag_string;
.br
char *prompt_str;
.br
float *float_return;
.br
float float_default;
.br
float float_min, float_max;
.sp
.R
.LP
-- -- -- -- -- -- -- -- -- -- -- -- -- -- --  explanation of arguments  -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
.sp
.IP fd_ansr: 14
If an answer file is used, this is the file descriptor of the answer file.
If no answer file is used, pass (-1).
.sp
.IP prompt_flag:
True (1) if interactive prompting is to be used; False (0) if float is
to be obtained directly from the command line.
.sp
.IP flag_string:
The "-flag" that is to be searched for on the command line to precede the
float value.  For example, if [-float_value {float} ] is expected, flag_string
should be specified as "-float_value". 
.sp
.IP prompt_string:
An appropriate prompt string should be specified here, for use with 
interactive prompting.  If interactive prompting is not used, pass "noprompt".  
.sp
.IP float_return:
Returns the float.  If the flag string could not be found, this will be
equal to the value passed in for \fIfloat_default\fP.
.sp
.IP float_default:
Default for the float, in case the user neglects to specify \fIflag_string\fP.
Must be consistent with \fIfloat_min\fP and \fIfloat_max\fP.
.bp
.sp 3
.IP "float_min, float_max;"
The minimum and maximum values of the float.  With these values,
you may also specify \fIbounds\fP for the float specified.  Here are the 
possible values for \fIfloat_min\fP and \fIfloat_max\fP:
.sp
.in +1i
float_min = float_max = -2.0 {legal values  < 0.0}
.br
float_min = float_max = -1.0 {legal values <= 0.0}
.br
float_min = float_max =  1.0 {legal values >= 0.0}
.br
float_min = float_max =  2.0 {legal values >  0.0}
.br
float_min = float_max =  X {no range checking}
.br
float_min = X;  float_max = Y  { X <= legal value <= Y}
.in -1i
.sp
.LP
=====================================================================
.sp 3
.LP
\fIEXAMPLE: 
.br
This example gets an float that is between the values of -5.0 and 5.0, 
inclusive. The default value for this float is (0.0).  An answer file 
is not used, nor is interactive prompting.  In this example, we look for 
[-scale {float}].
\fP
.sp
int float_specified, fd_ansr, prompting;
.br
int float_def = 0.0, float_min = -5.0, float_max = 5.0;
.br
int scale_value;
.sp
fd_ansr = -1; /* no answer file will be used */
.br
prompting = False; /* no interactive prompting to be used */
.sp
float_specified = vget_float(fd_ansr, prompting, "-scale", "noprompt", &scale_value,
.br
			float_def, float_min, float_max);
.sp
.br
/* 
.br
 *  use the float for something. if \fIfloat_specified\fP is false,
.br
 *  we can still use \fIfloat_value\fP, as it takes on the default value of 0.0.
.br
 */
.br
.bp
.sp 2
.NH 3 " vget_logic()"
.XS
              \*(SN   vget_logic()
.XE
.sp
.LP
Gets a logical (boolean) value, and returns it to the caller. May get the 
boolean directly from the command line, may use interactive prompting to obtain 
the boolean from the user, or may get the boolean from an answer file.
Checks to make sure that the input is a proper boolean, 
Returns a status of True (1) if the \fIflag_string\fP specified was found; 
returns False (0) otherwise. If the \fIflag_string\fP
specified could not be found, vget_logic() will return the value of the 
boolean default specified.
.sp
Note that vget_logic will only accept proper boolean values from the user.
These include: 
.in +1.0i
.br
1 and 0, 
.br
"yes" and "no", "Yes" and "No", "YES" and "NO"
.br
"y" and "n", "Y" and "N"
.br
"true" and "false", "True" and "False", "TRUE" and "FALSE"
.br
"t" and "f", "T" and "F".  
.sp
.in -1.0i
Where, in each of the above pairs, the first entry has a value of 1, and
the second entry has a value of 0.
.LP
.B
.sp 2
int vget_logic(fd_ansr, prompt_flag, flag_string, prompt_string, 
.br
			logic_return, logic_default); 
.br
int fd_ansr;  
.br
int prompt_flag;
.br
char *flag_string;
.br
char *prompt_str;
.br
int *logic_return;
.br
int logic_default;
.sp
.R
.LP
-- -- -- -- -- -- -- -- -- -- -- -- -- -- --  explanation of arguments  -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
.sp
.IP fd_ansr: 14
If an answer file is used, this is the file descriptor of the answer file.
If no answer file is used, pass (-1).
.sp
.IP prompt_flag:
True (1) if interactive prompting is to be used; False (0) if logical is
to be obtained directly from the command line.
.sp
.IP flag_string:
The "-flag" that is to be searched for on the command line to precede the
logical value.  For example, if [-install {boolean value} ] is expected, 
flag_string should be specified as "-install". 
.sp
.IP prompt_string:
An appropriate prompt string should be specified here, for use with 
interactive prompting.  If interactive prompting is not used, pass "noprompt".  
.sp
.IP logic_return:
Returns the logical value.  If the flag string could not be found, this will be
equal to the value passed in for \fIlogic_default\fP.
.bp
.sp 3
.IP logic_default:
Default for the logical, in case the user neglects to specify \fIflag_string\fP.
Must be 0 (False) or 1 (True).
.sp
.LP
=====================================================================
.sp 3
.LP
\fIEXAMPLE: 
.br
This example gets a logical value from the user interactively. The default
value for this logical is False (0).  An answer file is not used.
In this example, we look for the equivalent of [-install {boolean value}]
appearing on the command line.
\fP
.sp
int specified, fd_ansr, prompting;
.br
int logical_def = False; 
.br
int logical_value;
.br
char *prompt = "Install the source files?";
.sp
fd_ansr = -1; /* no answer file will be used */
.br
prompting = True; /* interactive prompting will be used */
.sp
specified = vget_logical(fd_ansr, prompting, "-install", prompt, &logical_value, logical_def);
.sp
if (logical_value)
.br
{
.br
	/* 
.br
	 *  install source files, since user indicated that
.br
	 *  this was the desired action.
.br
	 */
.br
}
.bp
.sp 2
.NH 3 " vget_string()"
.XS
              \*(SN   vget_string()
.XE
.sp
.LP
Gets a string, and returns it to the caller. May get the string
directly from the command line, may use interactive prompting to obtain 
a string from the user, or may get the string from an answer file.
Returns a status of True (1) if the flag_string specified was found;
returns False (0) otherwise.  If the flag_string cannot be found, the string
returned will take on the value of the default string provided.
.sp
.B
.sp
int vget_string(fd_ansr, prompt_flag, flag_string, prompt_string, 
.br
			string_return, string_default)
.br
int fd_ansr;  
.br
int prompt_flag;
.br
char *flag_string;
.br
char *prompt_str;
.br
char **string_return;
.br
char *string_default;
.sp
.R
.LP
-- -- -- -- -- -- -- -- -- -- -- -- -- -- --  explanation of arguments  -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
.sp
.IP fd_ansr: 14
If an answer file is used, this is the file descriptor of the answer file.
If no answer file is used, pass (-1).
.sp
.IP prompt_flag:
True (1) if interactive prompting is to be used; False (0) if input file is
to be obtained directly from the command line.
.sp
.IP flag_string:
The "-flag" that is to be searched for on the command line to precede the
string value.  For example, if [-name {string} ] is expected, flag_string
should be specified as "-name". 
.sp
.IP prompt_string:
An appropriate prompt string should be specified here, for use with 
interactive prompting.  If interactive prompting is not used, pass "noprompt".  
.sp
.IP string_return:
Allocates and returns the string provided by the user.  
.sp
.IP string_default:
If the \fIflag_string\fP specified is not found, \fIstring_return\fP takes on
this value.
.sp
.LP
=====================================================================
.bp
.sp 3
.LP
\fIEXAMPLE: 
.br
This example gets a string from the command line.  
An answer file is not used, nor is interactive prompting.
In this example, we look for [-name {string}].
\fP
.sp
int name_specified, fd_ansr, prompting;
.br
char *name;
.br
char *default_name = "Harry";
.sp
fd_ansr = -1; /* no answer file will be used */
.br
prompting = False; /* no interactive prompting to be used */
.sp
name_specified = vget_string(fd_ansr, prompting, "-name", "noprompt", &name, default_name);
.sp
.br
/* 
.br
 *  use \fIname\fP for something - if "-name {string}" was not found on the
.br
 *  command line, \fIname\fP will take on the value of "Harry".
.br
 * 
.br
 */
.br
}
