.ds f. vgparm.sec
.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. 
.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). 
.PP
.sp 1
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 15
.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 15
.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 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.
.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
or VFF_TYP_DOUBLE.
.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 " 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.
.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 " 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.
.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
}
