		Notes on the structure and design of the driver
		-----------------------------------------------

The primary goals of the new driver are maintainability and
expandibility.  Specifically, we would like it to be easy to 
add options or languages, and to change the behavior of options.
For this reason, we try to localize information about options
as much as possible.  The primary way that we achieve this is
by using a table of information about options.  This table is
read by a separate program which then generates several routines
that are compiled and linked into the driver.  It would be 
possible to read the table at run-time, but so far there has
not been a need for such dynamic behavior, and the statically
compiled routines provide better performance.

Below is a quick synopsis of each of the source files in the driver,
including the table-generated files:

DESIGN_DOC	- This document.

OPTIONS		- The table of option information.  This gives, for each
		  option, the name, 
		  an action to be done upon reading the option, 
		  what languages accept the option, 
		  what phases accept the option, 
		  what other options are implied by the option,
		  and a help message for the option.  See the comments
		  at the beginning of the file to understand the syntax
		  of the information.

table.c		- Reads the OPTIONS table and generates several C files
		  that are compiled into the driver.  It generates:
		  get_option.i, opt_action.i, init_options.i, check_combos.c,
		  implicits.c, and option_names.h

basic.h		- Common global typedefs, like boolean and string.

check_combos.c	- Generated by table program, it has routines to check for
		  combinations of options that have different behavior when
		  combined than when used individually.

errors.{c,h}	- Error handling routines.  There are different types of
		  errors, e.g. internal errors, parsing errors, warnings, etc.
		  Most of them take a variable number of arguments, to provide 
		  better flexibility.  Someday it would be good to create a
		  separate list of error messages which could then be easily
		  internationalized.

file_utils.{c,h}- Utilities for handling temp files and checking the
		  existence of files.

get_options.{c,h}-Routines for reading and adding options.
		  This includes the generated file get_option.i.
		
get_option.i	- Generated by table program; it parses the command-line
		  arguments into driver options.  This driver is compatible
		  with svr4 syntax, which means that single-letter options
		  can be combined into one argument, e.g. -cv is the same
		  as -c -v.

lang_defs.{c,h}	- Contains lists of languages, phases, and source suffixes,
		  and routines for getting information about those values.

main.c		- main program, which consists of parsing all the command
		  line options and file names, then checking for option
		  duplicates and combinations, adding implicit options,
		  adding environment and default options, plus adding any
		  options not handled by the table. 
		  Then we build the phase commands and invoke the compiler.
		  The help message handling is also done in this file.

objects.{c,h}	- Utilities for handling objects and libraries.

opt_actions.{c,h}- Action routines like toggle, that are done upon reading
		   certain options.  Includes opt_action.i.

opt_action.i	- Generated by table program, it invokes an action 
		  for a given option.

option_names.h	- Generated by table program, it defines an integer
		  value for each option.

option_seen.{c,h}- Maintains an ordered list of the options that are seen,
		   and routines for traversing and modifying that list.

options.{c,h}	- Maintains a table of predefined options and user-defined
		  options, with routines to add and get information about
		  options.  Includes init_option.i.  Uses the option_names
		  values to index the table.

init_options.i	- Generated by table program, it initializes the list of
		  predefined options.

phases.{c,h}	- Routines to determine which phases to run for a compile,
		  and then to create the argument lists for each phase.
		  What happens is that we initially have (from main) a
		  list of all valid options, which we then iterate over
		  for each phase to find the options that apply to that 
		  particular phase.  The list of phases to run is decided
		  by some hand-coded rules in determine_phase_order.

run.{c,h}	- The run_phase routine actually execs the phase.
		  We also have code here to catch and handle signals.

implicits.c	- Generated by table program, it has a routine to handle
		  the toggle actions of implicit options.

sort_options.{awk,csh} - The table program requires that the OPTIONS table
		  be sorted, so this shell script does that.  The sorted
		  order is needed for get_option to correctly parse options
		  that begin with the same prefix.

special_options.{c,h} - Routines for handling options that are not simple
		  enough for the table (they must be defined in the table,
		  but properties like when they are used can be adjusted
		  here).  Also defines when options are set by default.

string_utils.{c,h}- Utilities for manipulating strings and lists of strings.

