This is Info file evap.info, produced by Makeinfo-1.55 from the input
file evap.texinfo.

   evap.c \- evaluate C command line parameters in a simple and
consistent manner, type-check parameter values and provide complete
command and parameter help (use in place of getopt and friends).

   Copyright (C) 1990 - 1994 by Stephen O. Lidie and Lehigh University.
All rights reserved.

   ** Acknowledgment **

   Many thanks to Control Data Corporation for pioneering the concept of
     a typed, consistent user interface; an interface used by the
NOS/VE       operating system and ALL its applications; an interface
that has       meaningful command and parameter names instead of short,
cryptic ones.        Control Data invented the concept of first-level
help for ALL commands       with DISPLAY_COMMAND_INFORMATION and
DISPLAY_FUNCTION_INFORMATION,       providing a level of global
consistency not found in any other OS in       the world (well, as I
write this on my Mac I might have to reconsider       (-:)!

   Also, many thanks to Mark 'dog' Miller for coding the alpha version
of       evaluate_parameters.


File: evap.info,  Node: Top,  Next: Introduction,  Prev: (dir),  Up: (dir)



   This package evaluates C, Perl and Tcl command line parameters in a simple
and consistent manner, type-checks parameter values and provides
complete command and parameter help (use in place of getopt and
friends).

* Menu:

* Introduction::        What is evap?
* Guidelines::          Suggestions on a human interface
* PDTs::                Parameter Description Table (PDT) Syntax
* Creating a PDT::      More about PDTs ahd how to use them
* Types::               Further Information on Types
* Required Values::     Special Default Value $required
* Defaults::            Using Environment Variables as Default Values
* Lists::               'list of' Parameters
* Customizing the PDT:: Customization of the PDT Structure

* C and evap::          Using evaluate parameters in a C program
* Perl and evap::       Using evaluate paramters in perl programs

* Installation::        How to install evaluate parameters
* DCI::                 Using the Display_Command_Information command
* MM Syntax::           Message Module (MM) Syntax
* Adding MMs::          Adding New Message Modules
* Controls::            Variables MANPAGER, PAGER and D_EVAP_DO_PAGE

* Notes::               Notes and Cautions
* Acknowledgments::


File: evap.info,  Node: Introduction,  Next: Guidelines,  Prev: Top,  Up: Top

Introduction
============

   Function evaluate_parameters parses a C command line in a simple and
consistent manner, performs type checking of parameter values, and
provides the user with first-level help.  evaluate_parameters handles
command lines in the following format:

       command [-parameters] [file_list]

   where parameters and file_list are all optional.  A typical example
is the C compiler:

       cc -O -o chunk chunk.c

   In this case there are two parameters and a file_list consisting of a
single file name for the cc command.

   There are several advantages to using evaluate_parameters in all your
C programs:

   * Every program calling evaluate_parameters has a -help switch which
     lists all the command line arguments and their aliases, the types
     of parameter values they expect, and their default values.  Many
     Unix commands have no man pages so this first-level help is the
     only help available to a user.  This is provided automatically as
     part of evaluate_parameters; no code is required in your
     application. An optional help Message Module can be defined to
     provide additional help.  (See the section Adding New Message
     Modules.)

   * The command display_command_information is available which
     emulates its NOS/VE counterpart.  This command displays
     information about any command using evaluate_parameters.

   * Because evaluate_parameters allows command line arguments to have
     an alias, parameters can be given meaningful names which a user
     can readily understand. Hackers, on the other hand, can use the
     abbreviation to speed their work.

   * evaluate_parameters verifies that the value specified for a
     command line argument is of the appropriate type. Types currently
     supported are switch, string, real, integer, boolean, file, key,
     application and name. Parameter values are available in two forms;
     unconverted C strings and type-converted values.

   * Your job of developing applications is simplified because you don't
     waste time writing code to process arguments again, and again, and
     again!

   * Automatic man page generation for programs calling
     evaluate_parameters.

   * Automatic X11 Motif Tcl/Tk GUI wrapper code creation.

   * Most importantly, as long as you adhere to the Human Interface
     Guidelines, evaluate_parameters provides for a consistent user
     interface.

   Using evaluate_parameters is extremely easy:

  1. Create a Parameter Description Table, analogous to a C function
     prototype, which names all command line arguments and their types.
     Additionally, a PDT specifies the parameter alias and a default
     value.  (Optionally, a help Message Module can be defined which
     names a text file of additional help information.  See Adding New
     Message Modules for more information.)

  2. Feed the PDT to program generate_pdt, which generates a C
     structure that can be #included into your application.  This
     structure, known as a Parameter Description Table (PDT) assists
     evaluate_parameters in parsing the command line.

  3. Call evaluate_parameters in function main.  Command line
     parameters are scanned and their values are stored in the PDT for
     later use.

  4. (Optionally, add a help Message Module to the Message Module
     archive file.  See Adding New Message Modules for more details.)

   Examine addmm.c for an extremely simple example of using
evaluate_parameters.


File: evap.info,  Node: Guidelines,  Next: PDTs,  Prev: Introduction,  Up: Top

Guidelines
==========

   To make evaluate_parameters successful, you, the application
developer, must follow certain conventions when choosing parameter
names and aliases.

   Parameter names consist of one or more words, separated by
underscores, and describe the parameter (for example, OUTPUT and
TERMINAL_MODEL).

   You can abbreviate parameters:  use the first letter of each word in
the parameter name.  Do not use underscores.  For example, you can
abbreviate Command as C and Delay_Period as DP.

   There are exceptions to this standard:
   * PASSWORD is abbreviated PW.

   * The words MINIMUM and MAXIMUM are abbreviated MIN and MAX.  So, the
     abbreviation for the parameter maximum_byte_count is maxbc.

   * There are no abbreviations for the parameters -usage_help and
     -full_help; I do not want to prevent -uh and -fh from being used as
     valid command line parameters.


File: evap.info,  Node: PDTs,  Next: Creating a PDT,  Prev: Guidelines,  Up: Top

PDTs
====

   Here is the PDT syntax.  Optional constructs are enclosed in [], and
the | character separates possible values in a list.

       PDT [(message_module_name.mm)] [program_name, alias]
         [parameter_name[, alias]: type [ = [default_variable,] default_value]]
       PDTEND [optional_file_list | required_file_list | no_file_list]

   So, the simplest possible PDT would be:

       PDT
       PDTEND

   This PDT would simply define a -help switch for the command, but is
rather useless.

   A typical PDT would look more like this:

       PDT (frog.mm) frog
         number, n: integer = 1
       PDTEND no_file_list

   This PDT, for command frog, defines a help Message Module frog.mm and
a single parameter, number (or n), of type integer with a default value
of 1.  The PDTEND no_file_list indicator indicates that no trailing
file_list can appear on the command line.  Of course, the -help switch
is defined automatically.

   The default_variable is an environment variable - see the section
Using Environment Variables as Default Values for complete details.


File: evap.info,  Node: Creating a PDT,  Next: Types,  Prev: PDTs,  Up: Top

Creating a PDT
==============

   evaluate_parameters requires a Parameter Description Table (PDT) to
guide it in parsing the command line.  The program generate_pdt
interprets a Parameter Description Table (PDT) and generates C
statements that declare and initialize the PDT.  Here is generate_pdt's
PDT; it declares -input (or -i) and -output (or -o) parameters, of type
file, and that default to standard input and standard output,
respectively.  The -qualifier (or -q) parameter, of type string,
defaults to an empty string.

       PDT (genpdt.mm) generate_pdt, genpdt
         input, i: file = stdin
         output, o: file = stdout
         qualifier, q: string = ""
       PDTEND no_file_list

   A PDT for the 'mini' C compiler example described in the Introduction
could be:

       PDT cc
         Optimize, O: switch
         object, o: file
       PDTEND optional_file_list

   The PDT says that the Optimize parameter can have no parameter value;
that is, it must stand alone.  The object parameter is of type file.
An optional file_list can follow the command line parameters.

   If cc used evaluate_parameters with this PDT a user could envoke the
compiler in various ways, some of which are more obvious than others
(of course, the command line parameters could be specified in any
order):

       cc -Optimize -object chunk chunk.c
       cc -Optimize -o chunk chunk.c
       cc -O -object chunk chunk.c
       cc -O -o chunk chunk.c

   A special -help (or -?) parameter is automatically generated.
Executing any command that uses evaluate_parameters and specifying the
-help option produces a display of all command line arguments for that
command, similar to NOS/VE's DISPLAY_COMMAND_INFORMATION.  Continuing
our cc example, the following command:

       cc -help

   would produce this first-level help display:

       Usage: cc [ -? -O -o] [file(s)]
     
       Parameters:
       -help, ?, usage_help, full_help: Display Command Information
       -Optimize, O: switch
       -object, o: file
     
       [file(s)] optionally required by this command

   The first line of a Parameter Description Table declaration must be
PDT (or pdt) and the last line must be PDTEND (or pdtend).  Everything
in between defines one or more command line arguments, one per line.
The synatx is similar to CYBIL, Pascal and C function headers:  a
parameter name followed by an optional alias, a colon followed by the
type of parameter (switch, string, real, integer, boolean, file, key,
application, name) and an equal sign followed by the parameter's
default environment variable and default value.  Note that most of
these items are optional.

   With this information evaluate_parameters can parse a command line in
a consistent manner, perform type checking, and provide first-level
help via the -help parameter, similar to NOS/VE's System Command
Language.

   Here are examples of all the supported types:

       PDT (./samplemm.a/sample.mm) sample
         verbose, v: switch
         command, c: string = D_SAMPLE_COMMAND, "ps -el"
         scale_factor, sf: real = 1.2340896e-1
         millisecond_update_interval, mui: integer = $required
         ignore_output_file_column_one, iofco: boolean = TRUE
         output, o: file = stdout
         queue, q: key plotter, postscript, text, printer, keyend = printer
         destination, d: application = `hostname`
         tty, t: list of name = ("/dev/console", "/dev/tty0", "/dev/tty1")
       PDTEND optional_file_list


File: evap.info,  Node: Types,  Next: Required Values,  Prev: Creating a PDT,  Up: Top

Types
=====

   The switch type is a special type that emulates the typical U*X
standalone switch.  It means that no parameter value can appear after
the switch.  evaluate_parameters treats this type similarly to a
boolean type:  the value in the PDT structure is initialized to FALSE,
and if the switch parameter is specified the value is reset to TRUE.
You can therefore use either of the structure members "specified" or
"value" to test if the parameter was specified on the command line.
The switch type is short int.

   The string type is simply a C string.

   The real type is a floating point number.  Currently, there is no
type checking for this type.  A real number on my machine (a CYBER)
ranges from -5.221944407065762533458763552E+1232 to
5.221944407065762533458763552E+1232.  The real type is long double.

   The integer type is an integer number.  Range is -9223372036854775808
to 9223372036854775807, at least on real machines :-).  The integer
type is int.

   The boolean type is either TRUE/YES/ON/1 or FALSE/NO/OFF/0, any case.
The boolean type is short int.

   The file type is a standard U*X file name, which as far as I can tell
can be any random string of characters, as long as its length is less
than 256.  Here is sample C code to process the output file defined
previously (o is a variable of type FILE *):

       if (pvt[P_output].specified) {
         if ((o=fopen(pvt[P_output].value.file_value, "w")) == NULL) {
           printf("Cannot open output file!\n");
           exit(1);
         }
       } else  /* just use standard output */
         o = stdout;

   The key type is a special type that enumerates valid values.  The
queue parameter in a previous example above only recognizes the values
plotter, postscript, text, and printer.  evaluate_parameters will not
accept other values for this parameter.  Currently, a maximum of 32
values can be specified.  The key type is a C string.

   The applicaton type is a special type that is not type checked
because its interpretation is application specific.  This means that
anything can be specified for this type of parameter.

   The name type is a string of characters without embedded spaces.  It
is just like a string except that it can be specified without the
bounding quotes.  If you require a parameter that may included embedded
spaces use a string.


File: evap.info,  Node: Required Values,  Next: Defaults,  Prev: Types,  Up: Top

Required Values
===============

   All parameters can have a special default value $required.  When this
default is specified, evaluate_parameters will ensure that the
parameter is specified and given a valid value.


File: evap.info,  Node: Defaults,  Next: Lists,  Prev: Required Values,  Up: Top

Using Environment Variables as Default Values
=============================================

   Consider the following PDT:

       PDT (frog.mm) frog
         number, n: integer = D_FROG_NUMBER, 1
       PDTEND no_file_list

   The integer parameter number (or n) has a default value of 1.
However, if the environment variable D_FROG_NUMBER is defined AND if
number is not specified on the command line, evaluate_parameters will
use the value of the environment variable as the parameter's default
value.  With this feature users can easily customize command parameters
to their liking.

   Although the name of the environment variable can be whatever you
choose, the following scheme is suggested for consistency and to avoid
conflicts in names:

   * Use all uppercase characters.

   * Begin the variable name with D_, to suggest a default variable.

   * Continue with the name of the command or its alias followed by an
     underscore.

   * Complete the variable name with the name of the parameter or its
     alias.

     So, for example, D_DISCI_DO would name a default variable for the
     display_option (do) parameter of the display_command_information
     (disci) command.


File: evap.info,  Node: Lists,  Next: Customizing the PDT,  Prev: Defaults,  Up: Top

Lists
=====

   The PVT structure member "list" is the 'list of' indicator.  If
"list" is NULL then the command line parameter is a scalar and its
value is found in the members "unconverted_value" and "value", as we've
seen in many previous examples.

   A non-NULL value for the "list" member means that the command line
parameter is a list and that the value of the pointer points to the
head of an array of structures of type evap_List_Value (the array of
course may consist of only a single element).  Each evap_List_Value
itself consists of the members "unconverted_value" and "value".  Your
application simply passes through the list until an "unconverted_value"
member is NULL - the tail of the list.


File: evap.info,  Node: Customizing the PDT,  Next: C and evap,  Prev: Lists,  Up: Top

Customizing the PDT
===================

   The PDT structure evap_Parameter_Value is defined below, and,
although initialized by generate_pdt, can be customized in the
following ways:

   * You can change the description as displayed by -help.

   * You can change the changeable member to -1 so that a parameter is
     not advertised in response to a -help, although it can still be
     changed by the user, similar to the NOS/VE HIDDEN attribute.


File: evap.info,  Node: Installation,  Next: DCI,  Prev: Perl and evap,  Up: Top

Installation
============

   You need an ANSI C compiler for the basic evaluate_parameters
installation.  A complete installation requires two other public domain
packages - Perl 4.035 by Larry Wall, and Tcl 7.0 and Tk 3.3 by John
Ousterhout.

   Inspect the Makefile and follow the instructions to make any needed
path name changes.  Then simply:

       make; make install


File: evap.info,  Node: DCI,  Next: MM Syntax,  Prev: Installation,  Up: Top

   Besides evap.c, genpdt.c and addmm.c, this package includes the
special command display_command_information (disci).  disci does just
what it says:  it displays information about any evap-compliant command
(that is, any application that uses evaluate_parameters to parse its
command line).  There are usage, brief and full display options on the
command.  For example, try disci on itself:

       display_command_information -command disci

   This will give brief command information.  Then examine the full
display:

       disci -c disci -do f

   Try disci on generate_pdt and add_message_modules too.


File: evap.info,  Node: MM Syntax,  Next: Adding MMs,  Prev: DCI,  Up: Top

   A Message Module is a simple text file describing a command and its
parameters.  There is one thing special about the file:  a period (.)
in column one is the leadin character for a parameter description
(similar to an nroff directive line).

   All text until the first dot leadin character or end-of-file is
copied to standard output by evaluate_parameters when the -help command
line parameter is specified by a user.

   When evaluate_parameters encounters a dot, the following characters
on the line are taken as the full spelling of the command line
parameter, and all text from the following line until the next dot
leadin character or end-of-file is saved (in memory).
evaluate_parameters continues reading the Message Module file
collecting (in memory) all the parameters' help text.

   Finally, as evaluate_parameters is listing the individual command
line parameters on standard output, any additional parameter help
previously read from the Message Module is itself copied to standard
output for the benefit of the user (only with -full_help).


File: evap.info,  Node: Adding MMs,  Next: Controls,  Prev: MM Syntax,  Up: Top

   A Message Module is simply a text file of additional information used
by disci (in reality evaluate_parameters).  Message Modules for
applications using evaluate_parameters are maintained in an archive
file named libevapmm.a, typically in the catalog /usr/local/lib.  The
name of the Message Module associated with a command is stored in the
command's PDT. Please examine the files in the directory mm for
examples.  So, to create a Message Module for your command you must do
two things:

  1. Use the add_message_modules (addmm) command to add your help text
     to the ar Message Module database. Use a text editor and create
     your file, with a name of the form hhhh.mm, where hhhh is the name
     of your application (the .mm 'extension' implies a Message
     Module).  The file name cannot exceed 14 characters, a limit
     imposed by some ar utilities.  Then:

                 add_message_modules hhhh.mm

  2. Modify the command's PDT to include the name of this file.  Either
     manually change the pdt_header structure member help_module_name
     from NULL to "hhhh.mm" (not recommended), or re-create your PDT
     using generate_pdt (highly recommended).  The Message Module name
     is specified on the PDT statement:

                 PDT (hhhh.mm) command_hhhh
                   parameter declarations ...
                 PDTEND required_file_list

   Examine the sample PDTs in the catalog pdt. Then simply re-compile.

   You can maintain a private Message Module too.  If the Message Module
name specified in the PDT header has one or more slashes in it, then
the Message Module name specifies BOTH a path name to the Message
Module archive file and the name of the Message Module contained in
that library.  For instance, in the following PDT declaration the
Message Module name is again hhhh.mm, but this time it resides in the
archive file my_mm_library rather than in libevapmm.a in the
installation catalog:

          PDT (my_mm_library/hhhh.mm) command_hhhh
            parameter declarations ...
          PDTEND required_file_list

   Now use add_message_modules:

          addmm -mml my_mm_library hhhh.mm

   Use display_command_information -command add_message_modules
-display_option full (disci -c addmm -do f) to see further information.


File: evap.info,  Node: Controls,  Next: Notes,  Prev: Adding MMs,  Up: Top

   The environment variable MANPAGER (or PAGER) is used to control the
display of help information generated by evaluate_parameters.  If
defined and non-null, the value of the environment variable is taken as
the name of the program to pipe the help output through.  If no paging
program is defined then the program `more' is used.

   The boolean environment variable D_EVAP_DO_PAGE can be set to
FALSE/NO/OFF/0, any case, to disable this automatic paging feature (or
you can set your paging program to `cat').


File: evap.info,  Node: Notes,  Next: Acknowledgments,  Prev: Controls,  Up: Top

   The PDT parsing code in genpdt.c is really pretty stupid.  Although
most of the PDT declaration is free-form there is one contruct that
must be entered in a particular fashion: A key type declaration MUST be
entered such that a trailing comma separates all the valid keywords, as
in this example:

            display_option, do: key brief, b, full, f, keyend = brief

   The following key declaration would not parse properly:

            display_option, do: key brief b full f keyend = brief


File: evap.info,  Node: Acknowledgments,  Prev: Notes,  Up: Top

   Many thanks to Control Data Corporation for pioneering the concept of
a typed, consistent user interface; an interface used by the NOS/VE
operating system and ALL its applications; an interface that has
meaningful command and parameter names instead of short, cryptic ones.
Control Data invented the concept of first-level help for ALL commands
with DISPLAY_COMMAND_INFORMATION and DISPLAY_FUNCTION_INFORMATION,
providing a level of global consistency not found in any other OS in
the world (well, as I write this on my Mac I might have to reconsider
(-:)!

   Also, many thanks to Mark 'dog' Miller for coding the alpha version
of evaluate_parameters.


File: evap.info,  Node: C and evap,  Next: Perl and evap,  Prev: Customizing the PDT,  Up: Top

* Menu:

* C Usage Notes::       How to use evap in your C program
* genpdt::              Generated C code from a parameter description table
* Multiple Files::      Evap and Separately Compiled Modules
* Linking::             Linking Your Program With evaluate_parameters
* C Help Output::       Customization of evap's Help Output
* XGetDefault::         Interface to X11 XGetDefault
* XtAppInitialize::     Interface to X11 XtAppInitialize


File: evap.info,  Node: C Usage Notes,  Next: genpdt,  Up: C and evap

   An extremely simple example program, named "sample", follows.  Two
slightly more complex examples, "sample1" and "sample2", can be found
in the src directory of this distribution.

   These programs simply print the envoking command's name, command line
arguments as described by the PDT, and all file names.  They are
essentially identical, although "sample" uses a "brute force" approach
and prints the type-converted values (stored as a type appropriate for
the parameter) and knows about 'list of' parameters, "sample1" uses an
array approach, prints the unconverted values but doesn't know about
lists, while "sample2" uses pointer code to process parameters and
lists.  These programs are patterned after the examples in K&R, page
115, second edition.  There are a few items worth noting in each:

  1. The first executable statement in your C application must be a
     call to evaluate_parameters. NOTE: Because of variations in U*X
     implementations, the actual name of evaluate_parameters is evap.
     This unobvious name was chosen simply because it was short enough
     to prevent problems with C compilers, loaders and archive
     programs. The real name, evaluate_parameters, will continue to be
     used everywhere except in actual examples.

  2. evaluate_parameters increments argv and decrements argc as it
     parses the command line, leaving argv pointing to just before the
     file names (if any).  The net result is that argc will be >= 1.
     If it is one, there are no trailing file names.  This is analogous
     to the situation where a command, not using evaluate_parameters,
     is envoked with no parameters; argc = 1 and argv simply points to
     the envoking program's name.

  3. Parameter values are stored in the Parameter Value Table structure
     (pvt) in a format appropriate for the type (string for string,
     long double for real, int for integer, short for boolean,
     etcetera).  The unconverted parameter value is also available as a
     C string.

  4. Because of item #2 above, the name of the program in argv[0] is no
     longer available.  Therefore, evaluate_parameters stores it in the
     PDT structure pvt[P_HELP].unconverted_value just in case you need
     it.

   Assume that the file sample_pdt contains the PDT described at the end
of the section Creating a PDT.  First use the command generate_pdt to
convert the file sample_pdt into a C structure declaration for use by
your application and evaluate_parameters:

         generate_pdt -input sample_pdt -output sample_pdt_out

   The resulting PDT declaration on file sample_pdt_out can be included
in main:

   Sample 'brute force' main using arrays:

       #include <stdio.h>
       #include <evap.h>
       #include "pdt/sample_pdt_out"
     
       int main(int argc,
                char *argv[]);
       int main (int argc, char *argv[])
     
       /* evap - a typical example, type-converted values, types, lists */
     
       {
         int i;
         evap_List_Value *lve;
     
         evap ( &argc, &argv, pdt, NULL, pvt );
         printf( "\nProgram name:\n  %s\n\n", pvt[P_HELP].unconverted_value );
     
         if ( pvt[P_verbose].specified ) {
           printf( "verbose = %d\n", pvt[P_verbose].value.switch_value );
         }
         printf( "command = \"%s\"\n", pvt[P_command].value.string_value );
         printf( "scale_factor = %f\n",
                pvt[P_scale_factor].value.real_value );
         printf( "millisecond_update_interval = %d\n",
                pvt[P_millisecond_update_interval].value.integer_value );
         printf( "ignore_output_file_column_one = %d\n",
                pvt[P_ignore_output_file_column_one].value.boolean_value );
         printf( "output = %s\n", pvt[P_output].value.file_value );
         printf( "queue = %s\n", pvt[P_queue].value.key_value );
         printf( "destination = %s\n",
                pvt[P_destination].value.application_value );
     
         printf( "'list of' tty = ");
         lve = pvt[P_tty].list;
         while ( lve->unconverted_value != NULL ) {
           printf( "\"%s\"", lve->value.name_value );
           lve++;
           printf( "%s", lve->unconverted_value !=NULL ? ", " : "" );
         }
         printf( "\n");
     
         if (argc > 1) {
           printf( "\nFile names:\n  " );
           for(i=1; i < argc; i++)
             printf( "%s%s", argv[i], (i < argc-1) ? " " : "" );
           printf( "\n" );
         }
     
       exit( 0 );
     
       }

   Parameter names and their aliases can be at most 31 characters long.

   The values for parameters are stored in a format appropriate for
their type.  Please examine the pvt structure in evap.h for complete
details.  Parameter values are also available, as a C string, exactly
as they appeared on the command line.

   Each parameter has a structure of type evap_Parameter_Value, defined
in evap.h.  All the parameter structures are grouped together in a
Parameter Value Table array named pvt, which is an array of elements of
type evap_Parameter_Value.  An application indexes into the pvt array
using a defined symbol of the form P_FULL_PARAMETER_NAME.  So, to
access the evap_Parameter_Value structure for the scale_factor
parameter, references of the following form would be used:

       sf = pvt[P_scale_factor].value.real_value;

   After calling evaluate_parameters, a program accesses the PDT
structure for information on what parameters were specified and their
values.  To determine if the verbose switch in the example above was
specified code such as the following could be used:

       if(pvt[P_verbose].specified)
           ... do verbose stuff ...
       else
           ... do quiet stuff ...

   Of course, there are numerous examples of PDT code in the C source
files genpdt.c, disci.c and addmm.c.


File: evap.info,  Node: genpdt,  Next: Multiple Files,  Prev: C Usage Notes,  Up: C and evap

Generating C Code from the PDT
==============================

   The program generate_pdt (a.k.a. genpdt) interprets a PDT declaration
and generates C statements that declare and initialize a PDT.  The
command line parser routine evaluate_parameters uses the PDT to scan a
command line for parameters and to display help information about the
command.

   Examples:

       genpdt -i pdt_in -o pdt_out
     
       genpdt <pdt_in >pdt_out

   In the last example note that since the genpdt input and output files
default to stdin and stdout, respectively, normal I/O redirection can be
used.

   OPTIONS
   * -help, ?, usage_help, full_help: Display Command Information

     Display information about this command, which includes a command
     description with examples, plus a synopsis of the command line
     parameters.  If you specify -full_help rather than -help complete
     parameter help is displayed if it's available.

   * -input, i: file = stdin

     Specifies the name of the input file containing a command's
     Parameter Description Table.  The PDT describes the names,
     aliases, types and default values of all the command's command
     line parameters, as well as the path name of the ar message module
     archive file containing help text for the command and its
     parameters.

   * -output, o: file = stdout

     Specifies the name of the generate_pdt output file.  This file
     contains C language statements that are typically included in the
     source of your C application.  You then call the procedure
     evaluate_parameters, passing the PDT and the user's command line
     string; the command line is parsed and the results of the
     evaluation stored in the PDT.

   * -qualifier, q: string = ""

     Specifies a qualifying string that uniquely identifies this PDT.
     By default the C statements created by generate_pdt define the
     symbols pdt and pvt to be used by your application, which point to
     the results of the evaluation of the user's command line input.
     Some C applications support 'multiple entry points'; that is, the
     same C module acts as more than one user program.  And typically
     these 'multiple programs' accept different command line arguments.
     So, there is a requirement that multiple instances of the pdt/pvt
     symbols be defined.

   The value of the qualifier parameter is thus prepended to the name
pdt/pvt.  Therefore if -quailier = "OQ_" the symbols OQ_pdt and OQ_pvt
would be defined.


File: evap.info,  Node: Multiple Files,  Next: Linking,  Prev: genpdt,  Up: C and evap

   evaluate_parameters can be used when you compile C functions
separately from main.  Include <evap.h> as usual and include the PDT
structure created by generate_pdt too.  Define the symbol P_EVAP_EXTERN
somewhere before the include for the PDT structure.  This will declare
the Parameter Value Table (pvt) as an external and will not allocate
storage.  For example:

       #include <evap.h>
       #define P_EVAP_EXTERN
       #include "sample_pdt_out"
     
       void test_func()
       {
         printf("Program name is %s\n", pvt[P_HELP].unconverted_value);
       }


File: evap.info,  Node: Linking,  Next: C Help Output,  Prev: Multiple Files,  Up: C and evap

   Assuming evaluate_parameters is installed properly you link it with
your C application in the standard manner:

       cc -o myprog -I/usr/local/include -L/usr/local/lib myprog.c -levap

   Here the header file evap.h resides in /usr/local/include and the
library file libevap.a resides in usr/local/lib.


File: evap.info,  Node: C Help Output,  Next: XGetDefault,  Prev: Linking,  Up: C and evap

   There are several `Help Hook' strings that can be altered to
customize evap's help output.  Currently there is only one general area
that can be customized: usage and error text dealing with the trailing
file_list.  For instance, if a command requires one or more trailing
file names after all the command line switches, the default -help text
is:

   file(s) required by this command

   Some commands do not want trailing "file names", but rather some
other type of information.  An example is `display_command_information'
where a single Program_Name is expected.  The following code snippet
shows how to do this:

       evap_Help_Hooks[P_HHURFL] = " Program_Name\n";
       evap_Help_Hooks[P_HHBRFL] =
             "\nA Program_Name is required by this command.\n\n";
       evap_Help_Hooks[P_HHERFL] =
             "A trailing Program_Name is required by this command.\n";
       evap (&argc, &argv, pdt, NULL, pvt);

   As you can see, the array of string `evap_Help_Hooks' is indexed by a
simple ordinal.  The ordinals can be found in the evap header file
evap.h and are mostly self-explanatory.  In case you don't have access
to the source for evaluate_parameters, here are the default values of
the Help Hook strings, in a one-to-one correspondence with their
ordinals:

     char   *evap_Help_Hooks[P_MAXIMUM_HELP_HOOKS] = {
       " file(s)\n",
       " [file(s)]\n",
       "\n",
       "\nfile(s) required by this command\n\n",
       "\n[file(s)] optionally required by this command\n\n",
       "\n",
       "Trailing file name(s) required.\n",
       "Trailing file name(s) not permitted.\n",
     };

   The Help Hooks naming convention is rather simple:

       P_HHtf
     
         where:
     
           P_HH  implies an evaluate_parameters Help Hook
           t     type:
                   U=Usage Help
                   B=Brief and Full Help
                   E=error message
           f     file_list:
                   RFL=required_file_list
                   OFL=optional_file_list
                   NFL=no_file_list

   Note to `gentkp' users:  using these Help Hooks may cause `gentkp' to
generate an unuseable Tcl/Tk script.  This happens because `gentkp'
looks for the strings "required by this command" and "optionally
required by this command" in order to generate the file_list Entry
widget - if they are missing the widget is not created.  An easy
solution is to ensure that your Help Hook text contains said string,
just like the code snippet above.  Otherwise you must manually add the
required Tcl/Tk code yourself.


File: evap.info,  Node: XGetDefault,  Next: XtAppInitialize,  Prev: C Help Output,  Up: C and evap

   For X11 Xlib applications call evaluate_parameters as usual then open
the X display.  You can then use code similar to the following to
establish default X values for all unspecified command line parameters:

   /*    For all unspecified parameters see if there is an X default
value.     Variable "i" is type integer and "X_default" is type char *.

   Since there is no concept of a 'list of' X resource we ignore list
parameters.  */

     for ( i = 0 ; i < P_NUMBER_OF_PARAMETERS; i++ ) {
       if ( (! pvt[i].specified) && (pvt[i].list == NULL) ) {
         X_default = XGetDefault( theDisplay, ProgramName, pvt[i].parameter );
         if ( X_default != NULL ) {
           pvt[i].unconverted_value = X_default;
           pvt[i].specified = 1;
           evap_type_conversion( &pvt[i] ); /* convert string to proper type */
         } /* ifend non-null X default for this parameter */
       } /* ifend unspecified scalar parameter */
     } /* forend all evaluate_parameters parameters */


File: evap.info,  Node: XtAppInitialize,  Prev: XGetDefault,  Up: C and evap

   For X11 Xt applications call XtAppInitialize as usual, followed by a
call to evaluate_parameters to process non-standard command line
parameters.

     extern char *evap_X11;
     XtAppContext AppContext;
     Widget TopLevel;
     
     TopLevel = XtAppInitialize(&AppContext, "XOdo", NULL, 0, &argc, argv,
         NULL, NULL, 0);
     evap_X11 = "\nAll standard X11 Toolkit options are also accepted.\n";
     evap( &argc, &argv, pdt, NULL, pvt ); /* evaluate remaining parameters */


File: evap.info,  Node: Perl and evap,  Next: Installation,  Prev: C and evap,  Up: Top

   * Menu

   Function evaluate_parameters parses a Perl command line in a simple
and consistent manner, performs type checking of parameter values, and
provides the user with first-level help.  evaluate_parameters handles
command lines in the following format:

       command [-parameters] [file_list]

   where parameters and file_list are all optional.  A typical example
is the C compiler:

       cc -O -o chunk chunk.c

   In this case there are two parameters and a file_list consisting of a
single file name for the cc command.

* Menu:

* Perl Usage Notes::    How to use evap in your perl programs
* Perl Help Output::    Customizing help output of perl programs


File: evap.info,  Node: Perl Usage Notes,  Next: Perl Help Output,  Up: Perl and evap

   Usage is similar to getopt/getopts/newgetopt:  define a Parameter
Description Table declaring a list of command line parameters, their
aliases, types and default values.  The command line parameter `-help'
(alias `-?') is automatically included by evaluate_parameters.  After
the evaluation the values of the command line parameters are stored in
variable names of the form `$opt_parameter', except for lists which are
returned as `@opt_parameter', where 'parameter' is the full spelling of
the command line parameter. NOTE:  values are also returned in the
associative arrays %options and %Options, with lists being passed as:

   * Perl 4: a single string `joined' with the multi-dimensional array
     emulation character `$;'

   * Perl 5: a reference to a list

   An optional PDT line can be included that tells evaluate_parameters
whether or not trailing file names can appear on the command line after
all the parameters.  It can read `no_file_list, `optional_file_list' or
`required_file_list' and, if not specified, defaults to optional.
Although placement is not important, this line is by convention the
last line of the PDT declaration.

   Additionally a Message Module is declared that describes the command
and provides examples.  Following the main help text an optional series
of help text messages can be specified for individual command line
parameters.  In the following  sample program all the parameters have
this additional text which describes that parameter's type.  The leadin
character is a dot in column one followed by the full spelling of the
command line parameter.  Use `-full_help' rather than `-help' to see
this supplemental information.

   This sample program illustrates the various types and how to use
evap.  The `key' type is a special type that enumerates valid values
for the command line parameter.  The boolean type may be specified as
TRUE/FALSE, YES/NO, ON/OFF or 1/0.  Parameters of type `file' have ~
and $HOME expanded, and default values `stdin' and `stdout' converted
to `-' and `>-', respectively.  Of special note is the default value
'$required':  when specified, evaluate_parameters will ensure a value
is specified for that command line parameter.

   All types except `switch' may be `list of', like the `tty' parameter
below.  A list parameter can be specified multiple times on the command
line.  NOTE: in general you should ALWAYS quote components of your
lists, even if they're not type string, since evaluate_parameters uses
eval to parse them.  Doing this prevents eval from evaluating
expressions that it shouldn't, such as file name shortcuts like $HOME,
and backticked items like `hostname`.  Although the resulting PDT looks
cluttered, evaluate_parameters knows what to do and eliminates
superfluous quotes appropriately.

   Finally, you can specify a default value via an environment variable.
If a command line parameter is not specified and there is a
corresponding environment variable defined then evaluate_parameters
will use the value of the environment variable.  Examine the `command'
parameter for the syntax.  With this feature users can easily customize
command parameters to their liking.   Although the name of the
environment variable can be whatever you choose,  the following scheme
is suggested for consistency and to avoid conflicts in names:

   . Use all uppercase characters.    . Begin the variable name with
D_, to suggest     a default variable.    . Continue with the name of
the command or its     alias followed by an underscore.    . Complete
the variable name with the name of     the parameter or its alias.

   So, for example, D_DISCI_DO would name a default variable for the
display_option (do) parameter of the display_command_information
(disci) command.  Works for MS-DOS and Unix.

   Example:

     #!/usr/local/bin/perl
     
     require "evap.pl";
     
     eval 'BEGIN {}';
     $Perl_version_major = $ ? 4 : 5;
     
     $PDT =<<'end-of-PDT';
     PDT (./samplemm.a/sample.mm) sample
       verbose, v: switch
       command, c: string = D_SAMPLE_COMMAND, "ps -el"
       scale_factor, sf: real = 1.2340896e-1
       millisecond_update_interval, mui: integer = $required
       ignore_output_file_column_one, iofco: boolean = TRUE
       output, o: file = stdout
       queue, q: key plotter, postscript, text, printer, keyend = printer
       destination, d: application = `hostname`
       tty, t: list of name = ("/dev/console", "/dev/tty0", "/dev/tty1")
     PDTEND optional_file_list
     end-of-PDT
     
     $MM =<<'end-of-MM';
     sample
     
             A sample program demonstrating typical evaluate_parameters
             usage.
     
             Examples:
     
               sample
               sample -usage_help
               sample -help
               sample -full_help
               sample -mui 1234
      .verbose
             A 'switch' type parameter emulates a typical standalone
             switch. If the switch is specified evaluate_parameters
             returns a '1'.
      .command
             A 'string' type parameter is just a list of characters,
             which must be quoted if it contains whitespace.
             NOTE:  for this parameter you can also create and
             initialize the environment variable D_SAMPLE_COMMAND to
             override the standard default value for this command
             line parameter.  All types except 'switch' may have a
             default environment variable for easy user customization.
      .scale_factor
             A 'real' type parameter must be a real number that may
             contain a leading sign, a decimal point and an exponent.
      .millisecond_update_interval
             An 'integer' type parameter must consist of all digits
             with an optional leading sign.  NOTE: this parameter's
             default value is '$required', meaning that
             evaluate_parameters ensures that this parameter is
             specified and given a valid value.  All types except
             'switch' may have a default value of '$required'.
      .ignore_output_file_column_one
             A 'boolean' type parameter may be TRUE/YES/ON/1 or
             FALSE/NO/OFF/0, either upper or lower case.  If TRUE,
             evaluate_parameters returns a value of '1', else '0'.
      .output
             A 'file' type parameter expects a filename.  For Unix
             $HOME and ~ are expanded.  For evap/Perl 'stdin' and
             'stdout' are converted to '-' and '>-' so they can be
             used in a Perl 'open' function.
      .queue
             A 'key' type parameter enumerates valid values.  Only the
             specified keywords can be entered on the command line.
      .destination
             An 'application' type parameter is not type-checked in
             any - the treatment of this type of parameter is
             application specific.  NOTE:  this parameter' default
             value is enclosed in grave accents (or "backticks").
             evaluate_parameters executes the command and uses it's
             standard output as the default value for the parameter.
      .tty
             A 'name' type parameter is similar to a string except
             that embedded white-space is not allowed.  NOTE: this
             parameter is also a LIST, meaning that it can be
             specified multiple times and that each value is pushed
             onto a Perl LIST variable.  In general you should quote
             all list elements.  All types except 'switch' may be
             'list of'.
     end-of-MM
     
     @PDT = split( /\n/, $PDT );
     @MM = split( /\n/, $MM );
     
     &evap( *PDT, *MM );      # evaluate parameters
     print "\nProgram name:\n  $Options{'help'}\n\n";
     
     if ( defined( $Options{'verbose'}) ) { print "\nverbose = $Options{'verbose'}\n"; }
     print "command = \"$Options{'command'}\"\n";
     print "scale_factor  = $Options{'scale_factor'}\n";
     print "millisecond_update_interval = $Options{'millisecond_update_interval'}\n";
     print "ignore_output_file_column_one = $Options{'ignore_output_file_column_one'}\n";
     print "output = $Options{'output'}\n";
     print "queue = $Options{'queue'}\n";
     print "destination = $Options{'destination'}\n";
     if ( $Perl_version_major == 5 ) {
         eval q[$tty_list = $Options{'tty'}; print "Perl 5 'list of' tty = \"",
          join( '", "', @$tty_list ), "\"\n";];
     } else {
         print "Perl 4 'list of' tty = \"", join( '", "',
          split( $;, $Options{'tty'} ) ), "\"\n";
     }
     
     print "\nFile names:\n  ", join( ' ', @ARGV ), "\n" if @ARGV;

   Using the PDT as a guide, evaluate_parameters parses a user's command
line, returning the results of the evaluation to global variables of
the form '$opt_parameter' or '@opt_parameter', where 'parameter' is the
full spelling of the command line parameter.  Types which are 'list of'
return a LIST, otherwise a SCALAR.  NOTE:  values are also returned in
the associative arrays %options and %Options, with lists being passed
as:

   * Perl 4: a single string `joined' with the multi-dimensional array
     emulation character `$;'

   * Perl 5:  a reference to a list

   Every command using evaluate_parameters automatically has a -help
switch which displays parameter help; no special code is required in
your application.


File: evap.info,  Node: Perl Help Output,  Prev: Perl Usage Notes,  Up: Perl and evap

   There are several `Help Hook' strings that can be altered to
customize evap's help output.  Currently there is only one general area
that can be customized: usage and error text dealing with the trailing
file_list.  For instance, if a command requires one or more trailing
file names after all the command line switches, the default -help text
is:

     file(s) required by this command

   Some commands do not want trailing "file names", but rather some
other type of information.  An example is `display_command_information'
where a single Program_Name is expected.  The following code snippet
shows how to do this:

       $evap'evap_Help_Hooks{'P_HHURFL'} = " Program_Name\n";
       $evap'evap_Help_Hooks{'P_HHBRFL'} =
             "\nA Program_Name is required by this command.\n\n";
       $evap'evap_Help_Hooks{'P_HHERFL'} =
             "A trailing Program_Name is required by this command.\n";
       &evap( *PDT, *MM );

   As you can see, the array of string `evap_Help_Hooks' is indexed by a
simple ordinal.  The ordinals are shown below and are mostly self-
explanatory.  In case you don't have access to the source for
evaluate_parameters, here are the default values of the Help Hook
strings.

       $evap_Help_Hooks{'P_HHURFL'} = " file(s)\n";
       $evap_Help_Hooks{'P_HHUOFL'} = " [file(s)]\n";
       $evap_Help_Hooks{'P_HHUNFL'} = "\n";
       $evap_Help_Hooks{'P_HHBRFL'} =
              "\nfile(s) required by this command\n\n";
       $evap_Help_Hooks{'P_HHBOFL'} =
             "\n[file(s)] optionally required by this command\n\n";
       $evap_Help_Hooks{'P_HHBNFL'} = "\n";
       $evap_Help_Hooks{'P_HHERFL'} =
             "Trailing file name(s) required.\n";
       $evap_Help_Hooks{'P_HHENFL'} =
             "Trailing file name(s) not permitted.\n";

   The Help Hooks naming convention is rather simple:

       P_HHtf
     
         where:
     
           P_HH  implies an evaluate_parameters Help Hook
           t     type:
                   U=Usage Help
                   B=Brief and Full Help
                   E=error message
           f     file_list:
                   RFL=required_file_list
                   OFL=optional_file_list
                   NFL=no_file_list

   Note to `gentkp' users:  using these Help Hooks may cause `gentkp' to
generate an unuseable Tcl/Tk script.  This happens because `gentkp'
looks for the strings "required by this command" and "optionally
required by this command" in order to generate the file_list Entry
widget - if they are missing the widget is not created.  An easy
solution is to ensure that your Help Hook text contains said string,
just like the code snippet above.  Otherwise you must manually add the
required Tcl/Tk code yourself.



Tag Table:
Node: Top1118
Node: Introduction2421
Node: Guidelines5995
Node: PDTs6976
Node: Creating a PDT8147
Node: Types11720
Node: Required Values14162
Node: Defaults14464
Node: Lists15740
Node: Customizing the PDT16537
Node: Installation17080
Node: DCI17541
Node: MM Syntax18232
Node: Adding MMs19371
Node: Controls21744
Node: Notes22336
Node: Acknowledgments22919
Node: C and evap23643
Node: C Usage Notes24186
Node: genpdt30094
Node: Multiple Files32690
Node: Linking33357
Node: C Help Output33763
Node: XGetDefault36424
Node: XtAppInitialize37528
Node: Perl and evap38099
Node: Perl Usage Notes38865
Node: Perl Help Output48354

End Tag Table
