#! /bin/ksh
#
# config - interactively configure a file
#
# Version 1.1
# 
# Stuart Herbert
# Academic Computing Services
# University of Sheffield
#
# Copyright (c) 1994.  All rights reserved
#
############################################################################
#
# Modifications
#
#	v1.0	SLH	04 Jan 95	First version
#	v1.1	SLH	19 Jan 95	--new and --old added
#	v1.2	SLH	05 Apr 95	User prompts made clearer
#
############################################################################
#
# Functions for use in config files
#
# Boolean <prompt> <variable> <y|n>
# Comment <comment>
# Integer <prompt> <variable> <default value>
# String  <prompt> <variable> <default value>
#
############################################################################
# Boolean() - select yes or no
# $1 - prompt for the user
# $2 - define to set
# $3 - boolean value

Boolean ()
{
  local x
  
  sm_last="Boolean"
  
  GetString "$1" "x" "$3" "$2"
  if [ "$x" = "Y" ]; then
    x="y"
  elif [ "$x" != "y" ]; then
    x="n"
  fi
  
  case "$x" in
    'y')
      Define "$2" "y"
      ;;
    'n')
      Undefine "$2"
      ;;
    *)
      echo "PANIC: This line should not be reached!!!"
      exit 1
      ;;
  esac
  UpdateConfig "\"$1\" $2 $3" "\"$1\" $2 $x"
}

############################################################################
# CleanSlate - delete all existing generated files
# $1 - part we're configuring

CleanSlate ()
{
  local x
  
  for x in $szOutputHeader ; do
    if [ -f $x ]; then
      rm -f $x
    fi
  done
  
  if [ -n "$szOutputHeader" ]; then
    echo "#ifndef __${szConfigOrig}_CONFIG_HEADER"	>  $szOutputHeader
    echo "#define __${szConfigOrig}_CONFIG_HEADER"	>> $szOutputHeader
    echo						>> $szOutputHeader
    echo "/*"						>> $szOutputHeader
    echo " * This is an automatically-generated file,"	>> $szOutputHeader
    echo " * which is included by the C source code."	>> $szOutputHeader
    echo " *"						>> $szOutputHeader
    echo " * Edit at your own risk."			>> $szOutputHeader
    echo " */"						>> $szOutputHeader
    echo						>> $szOutputHeader
  fi
}

############################################################################
# CleanStateDef() - start a clean definitions file
# no parameters

CleanStateDef ()
{
  echo "#"						>  $szConfig.def
  echo "# This is an automatically-generated file,"	>> $szConfig.def
  echo "# which is included by config,sh and make"	>> $szConfig.def
  echo "#"						>> $szConfig.def
  echo "# Edit at your own risk."			>> $szConfig.def
  echo "#"						>> $szConfig.def
  echo							>> $szConfig.def
  sm_last="Comment"
}

############################################################################
# Comment() - Put a comment into the header
# $@ - the comment

Comment ()
{
  if [ -n "$szOutputHeader" ]; then
    if [ "$sm_last" != "Comment" ]; then
      echo						>> $szOutputHeader
    fi
    echo "/*"						>> $szOutputHeader
    for x in "$@" ; do
      echo " * $x"					>> $szOutputHeader
    done
    echo " */"						>> $szOutputHeader
    echo 						>> $szOutputHeader
  fi
  
  if [ "$sm_last" != "Comment" ]; then
    echo						>> $szConfig.def
  fi
  for x in "$@" ; do
    echo "# $x"						>> $szConfig.def
  done
  echo 							>> $szConfig.def
  
  if [ "$sm_last" != "Comment" ]; then
    echo
  fi
  echo "#"
  for x in "$@" ; do
    echo "# $x"
  done
  echo "#"
  echo

  sm_last="Comment"
}

############################################################################
# Define() - define a variable in the header
# $1 - variable to define
# $2 - value of variable in header

Define ()
{
  if [ -n "$szOutputHeader" ]; then
    echo "#define $1 $2" 				>> $szOutputHeader
  fi
  
  echo "$1=\"$2\""					>> $szConfig.def
  eval "$1=\"`eval echo \"$2\"`\""
}

############################################################################
# FinishOff() - add any extra bumphf to the header
# no parameters

FinishOff ()
{
  if [ -n "$szOutputHeader" ]; then
    echo 						>> $szOutputHeader
    echo "#endif /* __${szConfigOrig}_CONFIG_HEADER */"	>> $szOutputHeader
  fi
}

############################################################################
# GetString() - handle keyboard input

GetString ()
{
  if [ "$SILENT" = "TRUE" ]; then
    eval "$2=\"`eval echo \"$3\"`\""
    echo "$1 ($4) [$3] : $3"
  else
    ReadLine "$1" "$2" "$3" "$4"
  fi
}

############################################################################
# Integer() - define an integer in the header
# $1 - message to print
# $2 - variable
# $3 - default value

Integer ()
{
  local x
  
  GetString "$1" "x" "$3" "$2"

  Define "$2" "$x"
  UpdateConfig '"$1" $2 $3' '"$1" $2 $x'
  sm_last="Integer"
}

############################################################################
# ShowUsage() - show command line options
# no parameters

ShowUsage ()
{
  cat << EOF

config - Interactive File Configuration Tool

Version 1.0, by Stuart Herbert
Copyright (c) 1994 The University of Sheffield

usage:

  --output-header <file>
      Instruct config(1) to generate a C readable header, and to store it
      in the file <file>.

  --input <file>
      Use <file> as the input file to parse.  To have config(1) parse many
      files, separate the filesnames by whitespace, and surround the list of
      files in quotes.
  
  --new | --old
      With --new, the default values are used in prompting.  With --old,
      if the default values are stored in a file which is newer than the
      main input file, then no prompting occurs.

EOF

}

############################################################################
# String() - define a string in the header
# $1 - message to print
# $2 - variable
# $3 - default string

String ()
{
  local x
  
  GetString "$1" "x" "$3" "$2"

  Define "$2" "\"$x\""
  UpdateConfig "$2 \"$3\"" "$2 \"$x\""
  
  sm_last="String"
}

############################################################################
# Undefine - undef a variable in the header
# $1 - variable to undef

Undefine ()
{
  echo "#undef $1" 					>> $szOutputHeader
  echo "$1=n"						>> $szConfig.def
  eval "$1=n"
}

############################################################################
# UpdateConfig - record the user's selection
# $1 - old config line
# $2 - new config line

UpdateConfig ()
{
# This routine should be needed no more, but is left in for now

echo > /dev/null			# NO-OP

#  if [ "$1" != "$2" ]; then
#   sed "/$1/s//$2/" $szConfig > $szConfig.new
#    mv $szConfig.new $szConfig
#  fi
}

############################################################################
# main - the action starts here
# $@ - command line parameters

main ()
{
  if [ -z "$1" ]; then
    ShowUsage
    exit 1
  fi

  # we create and parse $tmpfile because bash(1) loses the value of any
  # variable you set inside a while loop ;-(
  
  AUTO=FALSE
  
  while [ -n "$1" ]; do
    case "$1" in
      '--output-header')
        echo "szOutputHeader=$2" >> $tmpfile
        shift 2
        ;;
      '--input')
        echo "szInput=$2" >> $tmpfile
        shift 2
        ;;
      '--new')
        echo "AUTO=FALSE" >> $tmpfile
	shift
        ;;
      '--old')
        echo "AUTO=TRUE" >> $tmpfile
	shift
        ;;
      *)
        ShowUsage
        exit 1
        ;;
    esac
  done
  
  . $tmpfile
  
  if [ -z "$szInput" ]; then
    echo "No input specified."
    exit 1
  fi
  
  CleanSlate
  
  szCwd="`pwd`"
  szConfigOrig=`basename $szCwd`
  
  for szConfig in $szInput ; do
    if [ -f "$szConfig" ]; then
      if [ -f "$szConfig.def" ]; then
        . $szConfig.def
      fi
      CleanStateDef
      if [ "$AUTO" = "TRUE" -a "$szConfig" -ot "$szConfig.def" ]; then
        SILENT=TRUE
      else
        SILENT=FALSE
      fi
      . $szConfig
    else
      echo "Configure.sh:ERROR:File $szConfig not found."
      exit 1
    fi
  done
  
  FinishOff
  
  if [ -f $tmpfile ]; then
    rm -f $tmpfile
  fi
}

############################################################################

. ../tools/scripts/libsh.0

main $@
