eval 'exec perl -w -S $0 ${1+"$@"}'
  if 0;

#
# Copyright 1998, University of California.  All Rights reserved.
#

if ( ( $#ARGV < 0 ) ||
     ( $ARGV[0] ne "go" ) &&
     ( $ARGV[0] ne "print" ) )
  {
    print <<'EOF';
#............................................................................
#...configure.pl                                                          ...
#...                                                                      ...
#...Usage: configure.pl <go|print> <argument(s)>                          ...
#...                                                                      ...
#...Description:                                                          ...
#...                                                                      ...
#...   go:            create make.inc                                     ...
#...   print:         just print the variables to stdout                  ...
#...   <argument(s)>: modify settings derived from the datafile           ...
#...                  <+option>: add to       configure.dat options       ...
#...                  <-option>: remove from  configure.dat options       ...
#...                  <option> : assign new   configure.dat options       ...
#...                  <MAKE_VARIABLE=VALUE>:  assign gmake variable       ...
#...                  <MAKE_VARIABLE+=VALUE>: add to gmake variable       ...
#...                                                                      ...
#...   1) make.inc variables                                              ...
#...      These variables are created from reading configure.dat.         ...
#...      See configure.dat for a description on that file.               ...
#...                                                                      ...
#...   2) command line arguments are evaluated in sorted order.           ...
#...        configure.pl go AA+=a AA=a                                    ...
#...       -is the same as:                                               ...
#...        configure.pl go AA=a                                          ...
#...       since AA=a is evaluated last                                   ...
#...                                                                      ...
#...   3) Additions (+=) to variable values will be separated by 1 space. ...
#...                                                                      ...
#...Flow:                                                                 ...
#...   1) read configure.dat                                              ...
#...   2) get defined options                                             ...
#...   3) foreach variable group,                                         ...
#...   3a)  make list of which variables are satisfied from the defined   ...
#...        options                                                       ...
#...   3b)  from this list of satisfied variables, pick the first one     ...
#...        that has the largest set of requirements                      ...
#...   4) create default variables                                        ...
#...   4a) for UPS, change VERSION in master_ups.h if dictated by         ...
#...       cvs status -v README                                           ...
#...   6) print to screen or print to file depending upon command line    ...
#...      option                                                          ...
#...                                                                      ...
#............................................................................
EOF
    exit;

  }

my(
   @all_requirements, # array of all meaningful options
   $assignment, # if directive (:) or variable (=)
   $change_option, # option to be changed (+ or -)
   $command_line_options, # options given on command line
   $command_line_arg, # foreach @command_line_arg...
   @command_line_args, # command line args
   @command_line_args_unique, # @ARGV that modifies configure.dat
   %command_line_variable, # foreach %command_line_variables
   %command_line_variables, # command line assignments for make.inc variables
   $computer_name, # COMPUTER_NAME set to this
   $continuation_line, # the line continued by a "\" on previous line
   $create_file, # whether to print output to file or screen
   $current_working_directory, # ROOT_DIR set to this
   $datafile_options, # options defined by the input file
   $date, # todays date
   $done, # whether done with a task
   $done_continuation, # whether on a continuation line
   $edited_options, # whether or not command line options had "+" or "-"
   @file_lines, # lines of the input file
   $i, # loop variable
   $ierr, # error return value
   $input_file, # configure.dat
   $line, # printed line in error messages
   $line_number, # current 1 based line number being parsed
   $max_name_length, # for lining up variable in output file
   $new_version, # new version dictated by cvs status -v README
   $option, # current predefined option
   $options, # set of all defined options
   $output_file, # make.inc
   $predefined_option_name, # current name of predefined option
   $predefined_options, # whitespace list of options automatically defined
   %predefined_options_all, # {$predefined_option_name} = all possibilities
   $requirement, # one requirement of variable in input file
   %requirement_list, # {$requirement} = true (hash for printing)
   $requirements, # all requirements of a variable in input file
   $requirements_total, # get all possible options
   %seen, # used for finding unique items in list
   $start_verbatim, # line number where "begin verbatim:" was
   $temp_output, # output from system calls
   $this_line, # current file_lines to be modified
   $total_output, # output to be printed to output file
   $value, # value of variable in input file
   $variable, # variable in input file
   %variable_group, # {variable} = "$requirement=$value\n(another pair)\n..."
   %variable_group_temp, # variable_group with temporary group
   %variable_output, # {variable} = $value (printed to output file)
   $variable_results, # final output for variables
   $verbatim, # verbatim string to go in output file
  );

print "\n  $0 ", join( " ", @ARGV ),"\n";

#............................................................................
#....................assign default variables................................
#............................................................................
$current_working_directory = `pwd`;
$current_working_directory =~ s/\s*$//;
if ( $current_working_directory !~ /\S/ )
  {
    $ierr = -1;
    &print_error( "Cannot find pwd", $ierr );
    exit( $ierr );
  }

$computer_name = `uname -n`;
$computer_name =~ s/[^a-zA-Z_0-9]/_/g;
chop( $computer_name );

#...........................
#...where to print output...
#...........................
$create_file = "";
if ( $ARGV[0] ne "print" )
  {
    $create_file = "true";
  }

#.......................................................
#...get command line args that modifies configure.dat...
#.......................................................
@command_line_args = @ARGV;
shift ( @command_line_args );

#..............
#...get date...
#..............
$date = `date '+%y%m%d %H%M%S'`;
chop ( $date );

#.......................
#...input/output file...
#.......................
$input_file = 'configure.dat';
$output_file = 'make.inc';

#...............
#...init vars...
#...............
$requirements_total = "";
$verbatim = "";

#...............................
#...assign predefined options...
#...............................
$predefined_options = "";

#......................
#...set architecture...
#......................
$option = "";
$predefined_option_name =
  "architecture";
$predefined_options_all{"$predefined_option_name"} =
  "aix alpha irix linux tflop";
$temp_output = `uname -a`;
if ( $temp_output =~ /\bAIX/ )
  {
    $option = "aix";
  }
elsif ( $temp_output =~ /\balpha/ )
  {
    $option = "alpha";
  }
elsif ( $temp_output =~ /\bIRIX/ )
  {
    $option = "irix";
  }
elsif ( $temp_output =~ /\bLinux\b/ )
  {
    $option = "linux";
  }
elsif ( $temp_output =~ /\b(janus|sasn100|sasn101)\b/ )
  {
    $option = "tflop";
  }

if ( $option !~ /\S/ )
  {
    $ierr = -1;
    &print_error( "Cannot determine [$predefined_option_name].",
                  "Possibilities: [$predefined_options_all{$predefined_option_name}]",
                  $ierr
                );
    exit( $ierr );
  }
$predefined_options .= " $option ";
#............................
#...DONE: set architecture...
#............................

#.......................
#...set computer name...
#.......................
$option = "";
$predefined_option_name =
  "computer_name";
$predefined_options_all{"$predefined_option_name"} =
  "from uname -n";
$option = $computer_name;
if ( $option !~ /^\S+$/ )
  {
    $ierr = -1;
    &print_error( "Cannot determine [$predefined_option_name].",
                  "Possibilities: [$predefined_options_all{$predefined_option_name}]",
                  $ierr
                );
    exit( $ierr );
  }
$predefined_options .= " $option ";
#.............................
#...DONE: set computer name...
#.............................

#.......................................................
#...have 1 space between options and unique-sort list...
#.......................................................
$predefined_options =~ s/\s+/ /g;
$predefined_options =~ s/^\s+//;
$predefined_options =~ s/\s+$//;
#......................
#...unique-sort list...
#......................
%seen = ();
$predefined_options = join( " ", 
                            sort grep{ ! $seen{$_}++ } 
                            split( /\s+/, $predefined_options ) );

#.....................................
#...DONE: assign predefined options...
#.....................................

#............................
#...read in configure file...
#............................
print "    Parsing  input  file [$input_file]\n";
if ( ! open (FILE, $input_file) )
  {
    $ierr = -1;
    &print_error( "Cannot open input file [$input_file]", $ierr );
    exit( $ierr );
  }
@file_lines = <FILE>;
close ( FILE );

#.......................................................................
#...parse the lines of the file into the variables and the directives...
#.......................................................................
$done = "false";
$i = 0;
undef( %variable_group );
while ( $done eq "false" )
  {

    #.......................
    #...stop at last line...
    #.......................
    if ( $i > $#file_lines )
      {
        $done = "true";
        last;
      }

    #...................................................
    #...create copy of this line that can be modified...
    #...................................................
    $this_line = $file_lines[$i];

    #.............................
    #...join continuation lines...
    #.............................
    if ( $this_line =~ /\\\s*$/ )
      {
        #...............................................
        #...remove continuation marker and whitespace...
        #...............................................
        $this_line =~ s/\\\s*$//;
        
        #...................................................
        #...process the entire continuation for this line...
        #...................................................
        $done_continuation = "false";
        while ( $done_continuation eq "false" )
          {
            #............................
            #...increment to next line...
            #............................
            $i++;
            
            #..........................
            #...stop if at last line...
            #..........................
            if ( $i > $#file_lines )
              {
                $done_continuation = "true";
                $done = "true";
                last;
              }
            
            #...........................................................
            #...remove beginning whitespace and add line to this_line...
            #...........................................................
            $continuation_line = $file_lines[$i];
            $continuation_line =~ s/^\s*//;
            $this_line .= $continuation_line;
              
            #...............................................
            #...note if you continue on this line as well...
            #...and remove continuation marker/whitespace...
            #...............................................
            if ( $this_line =~ /\\\s*$/ )
                {
                  $done_continuation = "false";
                  $this_line =~ s/\\\s*$//;
                }
            #...............................................
            #...if this is last continuation, note it and...
            #...remove trailing whitespace               ...
            #...............................................
            else
              {
                $done_continuation = "true";
                $this_line =~ s/\s*$//;
              }
          }
        #.........................................................
        #...DONE: process the entire continuation for this line...
        #.........................................................
      }
    #...................................
    #...DONE: join continuation lines...
    #...................................

    #..................................
    #...skip blank and comment lines...
    #..................................
    if ( $this_line =~ /^\s*$/ || $this_line =~ /^\s*\#/ )
      {
        $i++;
        next;
      }

    #.........................................
    #...if you get to a variable definition...
    #.........................................
    if ( $this_line =~ 
         /
         ^\s*                 # beginning plus whitespace
         ([\w\-]+)            # variable (word characters or a dash)
         \s*                  # whitespace
         \(\s*([\w\- ]*)\s*\) # ( <whitespace requirements list> )
         \s*(\+?=)\s*          # += or =
         (.*)                 # <value>
         \s*$                 # whitespace plus ending
         /x )
      {
        #.....................................................
        #...assign variable, its requirement, and the value...
        #.....................................................
        $variable = $1;
        $requirements = $2;
        $assignment = $3;
        $value = $4;
        #.......................................
        #...strip leading and trailing blanks...
        #.......................................
        $variable =~ s/^\s*//;
        $variable =~ s/\s*$//;
        $requirements =~ s/^\s*//;
        $requirements =~ s/\s*$//;
        $value =~ s/^\s*//;
        $value =~ s/\s*$//;
        #...............................................................
        #...add to the requirements_total variable for a print option...
        #...............................................................
        $requirements_total .= " $requirements ";
        #....................................
        #...add variable to variable group...
        #....................................
        if ( ! defined $variable_group{"$variable"} )
          {
            $variable_group{"$variable"} = "";
          }
        $variable_group{"$variable"} .= 
          "$requirements$assignment$value\n";
      }
    #...........................................
    #...DONE: processed a variable definition...
    #...........................................

    #.........................................
    #...otherwise, must be a directive line...
    #.........................................
    else
      {
        #......................................................
        #...verbatim block:                                 ...
        #...    things that should directly go into make.inc...
        #......................................................
        if ( $this_line =~ /^\s*begin\s+verbatim\s*:\s*$/i )
          {
            
            #.......................................
            #...process the entire verbatim block...
            #.......................................
            $start_verbatim = $i+1;
            $done_verbatim = "false";
            while ( $done_verbatim eq "false" )
              {
                
                #...................................
                #...increment to next line       ...
                #...................................
                $i++;
                
                #..........................
                #...stop if at last line...
                #..........................
                if ( $i > $#file_lines )
                  {
                    $ierr = -1;
                    $line_number = $i + 1;
                    &print_error( "$input_file:$line_number",
                                  "Cannot find [end verbatim:].",
                                  "Begin varbatim on line".
                                  "$input_file:$start_verbatim",
                                  $ierr
                                );
                    exit( $ierr );
                  }
                
                #.............................................
                #...if you hit "end verbatim:" you are done...
                #...with this verbatim block               ...
                #...............................................
                if ( $file_lines[$i] =~ /^\s*end\s+verbatim\s*:\s*$/i )
                  {
                    $done_verbatim = "true";
                    $verbatim .= "\n";
                    last;
                  }
                
                #..............................
                #...tack on this to verbatim...
                #..............................
                $verbatim .= $file_lines[$i];
              }
            #....................................................
            #...DONE: entire verbatim block has been processed...
            #....................................................
          }
        #.................................................................
        #...Done: we hit the start of a verbatim block and processed it...
        #.................................................................
        
        #.......................
        #...unknown directive...
        #....................... 
        else
          {
            $ierr = -1;
            $line_number = $i + 1;
            $line = $file_lines[$i];
            chop( $line );
            &print_error( "$input_file:$line_number",
                          "[$line]",
                          "Unknown directive",
                          "Possible missing continuation character on line $i.",
                          $ierr
                        );
            exit( $ierr );
          }
      }
    #.................................
    #...DONE: processed a directive...
    #.................................

    #.....................
    #...go to next line...
    #.....................
    $i++;
  }
#...................................................................
#...DONE: each variable line (with continuations) has been placed...
#...      inside a variable_group                                ...
#...................................................................

#........................................................................
#...get CONFIGURE_OPTIONS/datafile_options based on predefined options...
#........................................................................
undef( %variable_output );
if ( defined $variable_group{CONFIGURE_OPTIONS} )
  {
    %variable_group_temp = (
                            "CONFIGURE_OPTIONS" => 
                            "$variable_group{CONFIGURE_OPTIONS}"
                           );
    $ierr = &get_variable_output(
                                 \%variable_group_temp,
                                 $predefined_options,
                                 \%variable_output
                                );
    if ( $ierr )
      {
        &print_error( "get_variable_output", $ierr );
        exit( $ierr );
      }
    $datafile_options = $variable_output{"CONFIGURE_OPTIONS"};
    undef( $variable_output{"CONFIGURE_OPTIONS"} );
    #......................
    #...unique-sort list...
    #......................
    %seen = ();
    $datafile_options = join( " ", 
                              sort grep{ ! $seen{$_}++ } 
                              split( /\s+/, $datafile_options ) );
  }
else
  {
    $datafile_options = "";
  }
#..............................................................................
#...DONE: get CONFIGURE_OPTIONS/datafile_options based on predefined options...
#..............................................................................

#...........................
#...set options/variables...
#...........................
$options = $datafile_options;
$edited_options = "false";
$command_line_options = "";
%command_line_variables = ();
#......................
#...unique-sort list...
#......................
%seen = ();
@command_line_args_unique = 
  sort grep{ ! $seen{$_}++ } @command_line_args;
foreach $command_line_arg ( @command_line_args_unique )
  {
    if ( $command_line_arg =~ /^\+([^=\s]\S*)$/ )
      {
        $change_option = $1;
        $options .= " $change_option";
        $edited_options = "true";
        $command_line_options .= " $command_line_arg";
      }
    elsif ( $command_line_arg =~ /^\-([^=\s]\S*)$/ )
      {
        $change_option = $1;
        $options =~ s/(\b)$change_option(\b)/$1$2/g;
        $edited_options = "true";
        $command_line_options .= " $command_line_arg";
      }
    elsif ( $command_line_arg =~ /^([\w]+)(\+?=.*)$/ )
      {
        $command_line_variables{$1} = $2;
      }
    else
      {
        if ( "$edited_options" eq "true" )
          {
            $ierr = -1;
            &print_error( "Cannot have both absolute and ".
                          "relative (+|-) options.",
                          "[$command_line_arg]",
                          $ierr
                        );
            exit( $ierr );
          }
        $command_line_options .= " $command_line_arg";
      }
  }
#..........................................................
#...create unique-sort list for command_line_options and...
#...redefine options if needed                          ...
#..........................................................
if ( $command_line_options =~ /\S/ )
  {
    $command_line_options =~ s/\s+/ /g;
    $command_line_options =~ s/^\s+//;
    $command_line_options =~ s/\s+$//;
    #......................
    #...unique-sort list...
    #......................
    %seen = ();
    $command_line_options = join( " ", sort grep{ ! $seen{$_}++ } 
                                  split( /\s+/, $command_line_options ) );
    if ( $edited_options ne "true" )
      {
        $options = $command_line_options;
      }
  }
$options .= " $predefined_options";
$options =~ s/\s+/ /g;
$options =~ s/^\s*//;
$options =~ s/\s*$//;
#......................
#...unique-sort list...
#......................
%seen = ();
$options = join( " ", 
                 sort grep{ ! $seen{$_}++ } split( /\s+/, $options ) );
#.................................
#...DONE: set options/variables...
#.................................

#.........................................
#...get variables with complete options...
#.........................................
undef( %variable_output );
$ierr = &get_variable_output(
                             \%variable_group,
                             $options,
                             \%variable_output
                            );
if ( $ierr )
  {
    &print_error( "get_variable_output", $ierr );
    exit( $ierr );
  }
#..........................................................
#...undefine here so the predefined checking below works...
#..........................................................
undef( $variable_output{"CONFIGURE_OPTIONS"} );

#...............................................................
#...assign command line variables.                           ...
#...Do before default variables in case they are used there. ...
#...............................................................
foreach $command_line_variable ( sort keys %command_line_variables )
  {
    #................
    #...assignment...
    #................
    if ( $command_line_variables{$command_line_variable} =~ 
         /^=(.*)$/ )
      {
        $variable_output{$command_line_variable} = $1;
      }
    #..............
    #...addition...
    #..............
    elsif ( $command_line_variables{$command_line_variable} =~ 
            /^\+=(.*)$/ )
      {
        if ( ! defined( $variable_output{$command_line_variable} ) )
          {
            $variable_output{$command_line_variable} = $1;
          }
        else
          {
            $variable_output{$command_line_variable} .= " $1";
          }
      }
    else
      {
        $ierr = -1;
        &print_error( "Unrecognized command line argument:",
                      "[$command_line_variable$command_line_variables{$command_line_variable}]",
                      $ierr
                    );
        exit( $ierr );
      }
  }
#.........................................
#...DONE: assign command line variables...
#.........................................
#..............................
#...assign default variables...
#..............................
#..............
#...ROOT_DIR...
#..............
$variable = "ROOT_DIR";
if ( defined( $variable_output{$variable} ) )
  {
    $ierr = -1;
    &print_error( "Redefining predefined variable:", "[$variable]", $ierr );
    exit( $ierr );
  }
$variable_output{$variable} = $current_working_directory;
#.......................
#...CONFIGURE_OPTIONS...
#.......................
$variable = "CONFIGURE_OPTIONS";
if ( defined( $variable_output{$variable} ) )
  {
    $ierr = -1;
    &print_error( "Redefining predefined variable:", "[$variable]", $ierr );
    exit( $ierr );
  }
$variable_output{$variable} = $options;
#...................
#...COMPUTER_NAME...
#...................
$variable = "COMPUTER_NAME";
if ( defined( $variable_output{$variable} ) )
  {
    $ierr = -1;
    &print_error( "Redefining predefined variable:", "[$variable]", $ierr );
    exit( $ierr );
  }
$variable_output{$variable} = $computer_name;
#....................
#...CVS_ACCESSIBLE...
#....................
$variable = "CVS_ACCESSIBLE";
if ( defined( $variable_output{$variable} ) )
  {
    $ierr = -1;
    &print_error( "Redefining predefined variable:", "[$variable]", $ierr );
    exit( $ierr );
  }
$variable_output{$variable} = "";
if ( -d "CVS" )
  {
    $output = `cvs status -v README`;
    if ( ! defined( $output ) )
      {
        $output = "";
      }
    if ( $output =~ /\nFile: README/ )
      {
        $variable_output{$variable} = "true";
      }
  }
#.....................................................................
#...VERSION_CVS                                                    ...
#...Not defined if not CVS_ACCESSIBLE or using a CVS sticky version...
#.....................................................................
$variable = "VERSION_CVS";
if ( defined( $variable_output{$variable} ) )
  {
    $ierr = -1;
    &print_error( "Redefining predefined variable:", "[$variable]", $ierr );
    exit( $ierr );
  }
if ( $variable_output{'CVS_ACCESSIBLE'} eq "true" )
  {
    #................................................
    #...grab VERSION from cvs status -v README    ...
    #................................................
    $output = `cvs status -v README`;
    if ( ! defined( $output ) )
      {
        $output = "";
      }
    if ( ( $output =~ 
           /
           \n\s*                    # beginning of line plus whitespace
           Sticky\ Tag:\s*\(none\)  # no sticky tag
           /xi ) &&
         ( $output =~
           /
           \n\s*                    # beginning of line plus whitespace
           Sticky\ Date:\s*\(none\) # no sticky data
           /xi ) &&
         ( $output =~
           /
           \n\s*             # beginning of line plus whitespace
           (v-[0-9]{2}-[0-9]{2}-[0-9]{2}) # the version format
           \s+               # end word -> official release (no v-02-02-03_foo)
           /xi ) )
      {
        $variable_output{$variable} = $1;
        $variable_output{$variable} =~ s/[^0-9]//g;
        $variable_output{$variable} =~ s/^0+//g;
        $variable_output{$variable}++;
        $variable_output{$variable} =
          substr( "000000", 0, 6-length( $variable_output{$variable} ) ) .
            $variable_output{$variable};
        $variable_output{$variable} =~ 
          s/([0-9][0-9])([0-9][0-9])([0-9][0-9])/v-$1-$2-$3/;
      }
  }
#.............
#...VERSION...
#.............
$variable = "VERSION";
if ( defined( $variable_output{$variable} ) )
  {
    $ierr = -1;
    &print_error( "Redefining predefined variable:", "[$variable]", $ierr );
    exit( $ierr );
  }
#........................................
#...UPS gets version from master_ups.h...
#........................................
if ( open( FILE, "include/master_ups.h" ) )
  {
    while ( <FILE> )
      {
        if ( /UPS_VERSION\s*=\s*([0-9]+)\s*\n/ )
          {
            $variable_output{$variable} = $1;
            $variable_output{$variable} =~ 
              s/([0-9][0-9]?)([0-9][0-9])([0-9][0-9])/v-$1-$2-$3/;
            $variable_output{$variable} =~ 
              s/v-([0-9])-/v-0$1-/;
            last;
          }
      }
    close( FILE );
    if ( ! defined( $variable_output{$variable} ) )
      {
        $ierr = -1;
        &print_error( "Cannot find: UPS_VERSION\\s*=\\s*([0-9]+)\\s",
                      "file:        include/master_ups.h",
                      $ierr
                    );
        exit( $ierr );
      }
    #..................................................................
    #...modify include/master_ups.h if a new version has been tagged...
    #...and you are not working with a cvs sticky version of product...
    #..................................................................
    if ( $variable_output{'CVS_ACCESSIBLE'} eq "true" &&
         defined( $variable_output{'VERSION_CVS'} ) &&
         $variable_output{$variable} ne $variable_output{'VERSION_CVS'} &&
         $create_file eq "true" )
      {
        print "    Updating UPS_VERSION in include/master_ups.h.\n";
        #...............................
        #...get numerical new_version...
        #...............................
        $new_version = $variable_output{'VERSION_CVS'};
        $new_version =~ s/[^0-9]//g;
        $new_version =~ s/^0+//g;
        #..........................................................
        #...read in include/master_ups.h and replace new_version...
        #..........................................................
        if ( ! open( FILE, "include/master_ups.h" ) )
          {
            $ierr = -1;
            &print_error( "Cannot open VERSION file [include/master_ups.h]",
                          $ierr );
            exit( $ierr );
          }
        @file_lines = <FILE>;
        close( FILE );
        grep ( s/          # replace
               UPS_VERSION # UPS_VERSION
               \s*=\s*     # equal and surrounding whitespace
               [0-9]+\s*   # digits and whitespace 
               /UPS_VERSION = $new_version\n/x,
               @file_lines );
        #.........................................
        #...print new include/master_ups.h file...
        #.........................................
        if ( ! open( FILE, ">include/master_ups.h" ) )
          {
            $ierr = -1;
            &print_error( "Cannot open VERSION file [include/master_ups.h]",
                          $ierr );
            exit( $ierr );
          }
        print FILE @file_lines;
        close( FILE );
        #...................
        #...reset VERSION...
        #...................
        $variable_output{$variable} = $variable_output{'VERSION_CVS'};
      }
    #........................................................................
    #...DONE: modify include/master_ups.h if a new version has been tagged...
    #........................................................................
  }
#..............................................
#...DONE: UPS gets version from master_ups.h...
#..............................................
else
  {
    $variable_output{$variable} = $variable_output{'VERSION_CVS'};
  }
#...................
#...DONE: VERSION...
#...................
#....................................
#...DONE: assign default variables...
#....................................

#......................................................
#...for lining up columns, get longest variable name...
#......................................................
$max_name_length = 0;
foreach $variable ( keys %variable_output )
  {
    #.................................
    #...and get maximum name length...
    #.................................
    if ( length ($variable) > $max_name_length )
      {
        $max_name_length = length ($variable);
      }
  }

#........................................
#...prepare output string for printing...
#........................................
$total_output = "";

#..................
#...print header...
#..................
$total_output .= 
  "#................................................................\n".
  "#...$output_file                                                  ...\n".
  "#...  Creation date: $date                            ...\n".
  "#...  This file is automatically generated by $0. ...\n".
  "#...  Permanent changes should be made to:                    ...\n".
  "#...       $0 or $input_file                    ...\n".
  "#................................................................\n";

#................................
#...print variable information...
#................................
@all_requirements = split ( /\s+/, $requirements_total );
foreach $requirement ( @all_requirements )
  {
    if ( $requirement =~ /\S/ )
      {
        $requirement_list {"$requirement"} = "true";
      }
  }
$total_output .= "\n#......................................................\n";
$total_output .= "#...All Valid Options:   ";
foreach $requirement ( sort keys %requirement_list )
  {
    $total_output .= "$requirement ";
  }
$total_output .= "\n#...\n#...Used Options: $options";
$total_output .= "\n#...\n#...Command Line Args: $command_line_options";
foreach $command_line_variable ( sort keys %command_line_variables )
  {
    $total_output .= " \'$command_line_variable$command_line_variables{$command_line_variable}\'";
  }
$total_output .= "\n#...\n#...$input_file Options: $datafile_options";
$total_output .= "\n#...\n#...$0 Predefined Options: $predefined_options";
$total_output .= "\n#...\n#...All Possible Predefined Options:\n";
foreach $key ( sort keys %predefined_options_all )
  {
    $total_output .= "#...   predefined $key: $predefined_options_all{$key}\n";
  }
$total_output .= "#......................................................\n";
# Check if TAU is defined
foreach $command_line_arg ( @command_line_args_unique )
  {
    if ( $command_line_arg eq "+tau" )
      {
	print "Please set the TAU_MAKEFILE environment variable before compiling\n";
        print ".................................................................\n";
        $total_output .= "\n#......................................................";
        $total_output .= "\n#... include TAU stub Makefile";
        $total_output .= "\ninclude \$(TAU_MAKEFILE)";
        $total_output .= "\n#......................................................\n";
        $total_output .= "\n#......................................................\n";
        $total_output .= "PDTCPARSE        = \$(PDTDIR)/\$(CONFIG_ARCH)/bin/cparse\n";
	$total_output .= "TAUINSTR        = \$(TAUROOT)/\$(CONFIG_ARCH)/bin/tau_instrumentor";
        $total_output .= "\n#......................................................\n";

      }
  }

#..............................................
#...format variable output into nice columns...
#..............................................
$variable_results = "";
foreach $variable ( sort keys %variable_output )
  {
    $variable_results .= "$variable ";
    for ( $i = 0; $i < $max_name_length - length ( $variable ); $i++ )
      {
        $variable_results .= " ";
      }
    $variable_results .= "= $variable_output{$variable}\n";
  }

$total_output .= "\n\n".
  "#.....................\n".
  "#...variable output...\n".
  "#.....................\n\n";
$total_output .= $variable_results;

#...............................
#...print the verbatim things...
#...............................
$total_output .= "\n\n".
  "#.....................\n".
  "#...verbatim output...\n".
  "#.....................\n\n";
$total_output .= $verbatim;

#................................
#...if printing to file, do so...
#................................
if ( $create_file eq "true" )
  {
    print "    Creating output file [$output_file: $options]\n\n";
    if ( ! open ( FILE, ">$output_file" ) )
      {
        $ierr = -1;
        &print_error( "Cannot open output file [$input_file]", $ierr );
        exit( $ierr );
      }
    print FILE $total_output;
    close FILE;
  }

#.............................................................
#...otherwise, print to screen and print info about options...
#.............................................................
else
  {
    print $total_output;
  }

#.........
#...end...
#.........
exit( 0 );

#.........................................................................
#...Name
#...====
#... get_variable_output
#...
#...Purpose
#...=======
#... get list of variables that are maximally satisfied by the options
#...
#...Arguments
#...=========
#... variable_group_ref    Intent: in
#...                       Perl type: hash_ref
#...                       hash containing {variable}="req=value\n<repeat>"
#...
#... options               Intent: in
#...                       Perl type: scalar
#...                       options set for this variable group
#...
#... variable_output_ref   Intent: out
#...                       Perl type: hash_ref
#...                       hash containing {variable}="value"
#...
#...Program Flow
#...============
#... 1) get hash of variables that are satisfied
#... 2) get maximally satisfied list from satisfied variables
#.........................................................................
sub get_variable_output
  {
    my(
       $variable_group_ref,
       $options,
       $variable_output_ref
      ) = @_;

    #........................
    #...Local Declarations...
    #........................
    
    my(
       $assignment, # =/+=
       %additional_value, # if given a +=
       $requirement_number, # current number of reqs for satisfied variable
       $requirements, # all requirements of a variable in input file
       $requirements_array, # array of $requirements
       $satisfied, # whether this variable(requirements)=value is satisfied
       %seen, # for unique-sort list
       $value, # value of variable in input file
       %variable_satisfied, # satisfied %variable_group
       $variable, # variable in input file
       $variable_line, # one variable_lines
       @variable_lines, # list of requirement=value pairs for a variable
      );

    #...........................
    #...Executable Statements...
    #...........................

    #..........
    #...init...
    #..........
    undef ( %variable_satisfied );
    undef ( %additional_value );

    #..............................................
    #...get hash of variables that are satisfied...
    #..............................................
    foreach $variable ( sort keys %$variable_group_ref )
      {
        #..................................
        #...init so no additional values...
        #..................................
        $additional_value{"$variable"} = "";
        #..............................................
        #...check all possibilities of this variable...
        #..............................................
        @variable_lines = split ( /\n/, $$variable_group_ref{"$variable"} );
        foreach $variable_line ( @variable_lines )
          {
            #.....................................................
            #...get the requirements and the value of this line...
            #.....................................................
            ( $requirements = $variable_line ) =~ s/^([\w\- ]*)(\+?=)(.*)$/$1/;
            $assignment = $2;
            $value = $3;
            
            #.......................................................
            #...search each requirement to see if it is satisfied...
            #.......................................................
            $satisfied = "true";
            foreach $requirement ( split ( /\s+/, $requirements ) )
              {
                if ( " $options " !~ /\b$requirement\b/ )
                  {
                    $satisfied = "false";
                  }
              }
            if ( $satisfied eq "true" )
              {
                if ( "$assignment" eq "=" )
                  {
                    if ( ! defined $variable_satisfied{"$variable"} )
                      {
                        $variable_satisfied{"$variable"} = "";
                      }
                    $variable_satisfied{"$variable"} .= "$variable_line\n"; 
                  }
                elsif ( "$assignment" eq "+=" )
                  {
                    $additional_value{"$variable"} .= " $value";
                  }
              }
            #.............................................................
            #...DONE: search each requirement to see if it is satisfied...
            #.............................................................
          }
        #....................................................
        #...DONE: check all possibilities of this variable...
        #....................................................
      }
    #....................................................
    #...DONE: get hash of variables that are satisfied...
    #....................................................

    #...........................................................
    #...get maximally satisfied list from satisfied variables...
    #...........................................................
    foreach $variable ( sort keys %variable_satisfied )
      {
        @variable_lines = split ( /\n/, $variable_satisfied{"$variable"} );
        #.................................................................
        #...find the variable line with the largest set of requirements...
        #.................................................................
        $requirement_number = -2;
        foreach $variable_line ( @variable_lines )
          {
            #.....................................................
            #...get the requirements and the value of this line...
            #.....................................................
            ( $requirements = $variable_line ) =~ s/^([^=]*)=(.*)$/$1/;
            $value = $2;
            
            #.....................................................
            #...if you have a larger number of requirements for...
            #...that variable, remember it                     ...
            #.....................................................
            %seen = ();
            @requirements_array = 
              sort grep{ ! $seen{$_}++ } 
              split ( /\s+/, $requirements );
            if ( $#requirements_array > $requirement_number )
              {
                $$variable_output_ref{"$variable"} = "$value";
                $requirement_number = $#requirements_array;
              }
          }
        #................................................................
        #...DONE: found the largest set of requirements for a variable...
        #................................................................
      }
    #.................................................................
    #...DONE: get maximally satisfied list from satisfied variables...
    #.................................................................
    #.............................
    #...add on additional_value...
    #.............................
    foreach $variable ( sort keys %additional_value )
      {
        if ( $additional_value{"$variable"} =~ /\S/ )
          {
            if ( defined( $$variable_output_ref{"$variable"} ) )
              {
                $$variable_output_ref{"$variable"} .= 
                  $additional_value{"$variable"};
              }
            else
              {
                $$variable_output_ref{"$variable"}  = 
                  $additional_value{"$variable"};
                $$variable_output_ref{"$variable"} =~ s/^ //;
              }
          }
      }

    #............
    #...return...
    #............
    return( 0 );
  }

#............................................................................
#...Name
#...====
#... print_error
#...
#...Purpose
#...=======
#... Print a standard error message.
#...
#...Arguments
#...=========
#... error_lines  Intent: in
#...              Perl type: array
#...              0: cause of error (file_name:line_number)
#...              1: explanation/fix (if there is one)
#...              2: error value
#...
#...Program Flow
#...============
#... 1) see if warning or error (last argument is 0 or not)
#... 2) Line up error lines by column
#... 3) find out who was calling this routine and the line number
#... 4) print out info
#............................................................................
sub print_error
  {
    my( 
       @error_lines # what emitted the error
      ) = @_;

    my(
       $error_level,  # what is printed (eg WARNING or ERROR)
       $error_line,   # each line of input argument
       @routine_info, # var from caller
       $routine_name, # routine name
       $spaces        # spaces for lining up columns
      );

    #......................................................
    #...assign WARNING or ERROR depending on error value...
    #......................................................
    if ( "$error_lines[$#error_lines]" eq "0" )
      {
        $error_level = "**WARNING**";
        $spaces      = "           ";
      }
    else
      {
        $error_level = "**ERROR**";
        $spaces      = "         ";
      }

    #............................................................
    #...DONE: assign WARNING or ERROR depending on error value...
    #............................................................

    #.......................................
    #...init error and add argument lines...
    #.......................................
    $error_line = shift( @error_lines );
    $error_message = "\n$error_level $error_line\n";
    foreach $error_line ( @error_lines )
      {
        $error_message .= "$spaces $error_line\n";
      }

    #............................................................
    #...get routine name (special if called from main program)...
    #............................................................
    @routine_info = caller(1);
    if ( $#routine_info < 3 )
      {
        $routine_name = $0;
      }
    else
      {
        $routine_name = (caller(1))[3];
      }
    $routine_name = $routine_name.":".(caller(0))[2];

    #.........................
    #...append routine name...
    #.........................
    $error_message .= "$spaces $routine_name\n";

    #.................
    #...print error...
    #.................
    print STDERR $error_message;

  }
