#!/bin/bash

XML_USR='/opt/VAIxml'
XML_ETC='/opt/VAIxml/etc'
XML_DOCS='/opt/VAIxml/share/doc'
XML_DOCS_URL='/VAIxml'
XML_PUBLIC_URL='http://www.mekwin.com/vaisala/xml'
COMMON_DIR='/opt/VAIxml/share/vaisala/xml/common'
BUILD_ROOT='/tmp/xml/keyval/install'
SOURCEFORGE_MIRROR='http://umn.dl.sourceforge.net/sourceforge'
CONFIG_FILE='no'
TAG='keyval'
SRCDIR='/tmp/xml/keyval'
DTD='keyval_1_0_0.dtd'
URIROOT='http://www.mekwin.com/vaisala/xml'
URIDTD='http://www.mekwin.com/vaisala/xml/dtd/keyval/keyval_1_0_0.dtd'
PUBLIC_ID='-//VAISALA//DTD KeyValue XML V1.0.0//EN'
PKG_PREFIX='vaisala'
COMMON_DIR='/opt/VAIxml/share/vaisala/xml/common'
TAG='keyval'
VERSION='1.0.0'
VERSION_RELEASE='5'
RPM_REDHAT_ARGS='--config no --usr /usr --etc /etc --docs /var/www/html/vaisala/xml --docs-url http://www.mekwin.com/vaisala/xml --java "java -DproxyHost=172.26.0.232 -DproxyPort=3128" --docbook-xsl "search"'
CATALOG='/opt/VAIxml/share/vaisala/xml/keyval/catalog/keyval_catalog.xml'
CATALOG_OASIS='/opt/VAIxml/share/vaisala/xml/keyval/catalog/keyval_catalog.oasis'
SYSROOT='/opt/VAIxml/share/vaisala/xml/keyval'
XSLROOT='/opt/VAIxml/share/vaisala/xml/keyval/xsl'
BASENAME='/usr/bin/basename'
BASH='/bin/bash'
CAT='/usr/bin/cat'
CHMOD='/usr/bin/chmod'
CP='/usr/bin/cp'
DIRNAME='/usr/bin/dirname'
FIND='/usr/bin/find'
GREP='/usr/bin/grep'
JAVA='java -DproxyHost=172.26.0.232 -DproxyPort=3128'
MKDIR='/usr/bin/mkdir'
RMDIR='/usr/bin/rmdir'
TOUCH='/usr/bin/touch'
TR='/usr/bin/tr'
#
# $Id: support.sh,v 1.6 2006/02/24 19:50:25 pkb Exp $
#
#   Adds supporting script functions - assuming that configuration variables
#   are already defined

# log TEXT
#
#   If the LOG_FILE environment variable is not set to "no" and is
#   pointing at a file which exists, this method will append TEXT
#   information to the end of the file.

log() {

  if [ "${LOG_FILE}" != "no" -a -f "${LOG_FILE}" ]; then
    printf "$1\n" >> "${LOG_FILE}"
  fi

}

# error TEXT [EXIT_CODE]
#
#   Reports error message and optionally exits if a exit_code is passed
#

error() {

  log "***ERROR*** ${1}"

  printf "***ERROR*** ${1}\n"
  if [ "$2" != "" ]; then
    exit "${2}"
  fi

}

# message TEXT
#
#   Reports TEXT message to user (unless QUIET is set to "true") and
#   log file (if enabled).

message() {

  log "$1"
  if [ "$QUIET" != "true" ]; then
    printf "$1\n"
  fi

}

# verify_files [FILE0 [FILE1 ...]]
#
# Verifies that ALL files specified exist and exits with error if not

verify_files() {
  for f in $*; do
    if [ ! -f "$f" ]; then
      error "could not find file: $f"
      exit 2
    fi
  done
}


# query_program PROG [DIR [DIR ... ] ]
#
#  Finds fully qualified path of a executable program.
#
#  On success, the environment variable PROG is set to full location of
#  desired program and we return 0, otherwise, we return 1.
#
#  PROG - name of program to find (we always search user PATH and some
#  other common locations)
#
#  DIR [ DIR ... ] - Optional list of other directories to try

query_program() {
  local FILE="$1"
  shift

  for d in ${PATH//:/ } $* \
    /usr/local/bin /opt/csw/bin /opt/sfw/bin /opt/bin /usr/bin /bin /lan/bin; do
    PROG="${d}/${FILE}";
    if [ -x "$PROG" ]; then
      return 0;
    fi
  done
  PROG=
  return 1;
}


# find_program PROG [URL] [DIR [DIR ... ] ]
#
#  Finds fully qualified path of a executable program, or prints error message
#  and terminates.
#
#  On success, the environment variable PROG is set to full location of
#  desired program.
#
#  PROG - name of program to find (we always search user PATH)
#
#  URL  - Optional URL to refer user to if we don't find PROG
#
#  DIR [ DIR ... ] - Optional list of other directories to try

find_program() {
  local FILE="$1"
  shift
  local URL="$1"
  shift

  if query_program "${FILE}" $* ; then
    return 0;
  fi

  MISSING=true;
  error "unable to find executable program '${FILE}' on system" "${URL}"
  return 1;
}

# require_program ENV PROG [URL] [DIR [DIR ... ] ]
#
#  Finds fully qualified path of a executable program, or prints error message
#  and terminates.
#
#  On success, the environment variable ENV will have the full location of
#  desired program.
#
#  If ENV already points to a executable program, no search is done (we assume
#  it was already found and set by a prior call to this function.
#
#  ENV - Environment variable to be set
#
#  PROG - name of program to find (we always search user PATH)
#
#  URL  - Optional URL to refer user to if we don't find PROG
#
#  DIR [ DIR ... ] - Optional list of other directories to try

require_program() {
  local ENV="${1}";

  # Nothing to do if already set
  if [ -x "${!ENV}" ]; then
    return 0;
  fi

  shift;

  if find_program $*; then
    eval "export ${ENV}=\"${PROG}\";";
    return 0;
  fi

  eval "export ${ENV}=\"did_not_find_${1}\";";
  return 1;
}

# find_class CLASS [URL] [JAR_URL]
#
#   Determines if CLASS can be found in the current Java environment.
#   Requires that CLASS not implement the static void main(String[]) method
#   as we look for the "NoSuchMethod" error in the output of trying to invoke
#   CLASS (which indicates class does exist). Returns 0 if class exists,
#   1 if not (unless RC is passes as well). NOTE: If you pass the JAR_URL
#   parameter, we will attempt to download the JAR file from the JAR_URL
#   specified using wget and make a second try.
#
#   CLASS   - name of class to look for (like:
#             org.apache.xml.resolver.tools.CatalogResolver)
#
#   URL     - Optional, if passed, we will display a error message pointing
#             user to this URL if we are unable to find the class.
#
#   JAR_URL - Optional, if passed, we will attempt to download the necessary
#             JAR file from this URL. 

find_class() {
  local CLASS="${1}";
  local URL="${2}";
  local JARURL="${3}";

  if ! require_program JAVA java ||
     ! require_program GREP grep ||
     ! require_program BASENAME basename ||
     ! require_program MKDIR mkdir; then
    return 1;
  fi

  if [ "${JARURL}" != "" ]; then
    local JARNAME="$(${BASENAME} "${JARURL}")";

    # See if global install under /var/vaisala/jars

    local JARDIR="/var/vaisala/jars";
    local JARFILE="${JARDIR}/${JARNAME}";

    if [ ! -f "${JARFILE}" ]; then
      JARDIR="${HOME}/tmp/vaisala/jars";
      JARFILE="${JARDIR}/${JARNAME}";
    fi

    if [ ! -f "${JARFILE}" ]; then
      printf "\nAttempting to download: ${JARURL}\n\n";

      if ! require_program WGET wget; then
	return 1;
      fi
    
      #
      # Setup user's JAR cache (if necessary)
      #
      if [ ! -d "${JARDIR}" ] && ! ${MKDIR} -p "${JARDIR}"; then
        error "could not create JAR directory: ${JARDIR}"
        MISSING=true;
        return 1;
      fi

      #
      # Download JAR
      #
      if ! ${WGET} "-O${JARFILE}" "${JARURL}"; then
        error "failed to download: ${JARURL}";
        printf "You may want to check your proxy settings ~/.wgetrc\n"
        printf "or the global proxy settings in /etc/wgetrc. Look for:\n"
        printf "\nhttp_proxy = http://172.26.0.232:3128/\nuse_proxy=on\n\n";
        MISSING=true;
        return 1;
      fi
    fi

    export XML_COMMON_CLASSPATH="${XML_COMMON_CLASSPATH}:${JARFILE}";
#    printf "\nLooking for ${CLASS} in:\n  ${JARFILE}\n\n";

#    if ${JAVA} -cp "${XML_COMMON_CLASSPATH}" "${CLASS}" 2>&1 < /dev/null | \
#       ${GREP} NoSuchMethod > /dev/null; then
#       return 0;
#    fi
     return 0;
  fi

  error "could not find class: ${CLASS}" "${URL}"
  MISSING=true;
  return 1;
}

# build_xml_common_classpath
#
#   Sets XML_COMMON_CLASSPATH to list of JAR files required to apply
#   XSL transformations.

build_xml_common_classpath() {

  if [ ! -r "${COMMON_DIR}/sh/pkg_url.sh" ]; then
    error "failed to find JAR URL list at: ${COMMON_DIR}/sh/pkg_url.sh";
    return 1;
  fi

  . "${COMMON_DIR}/sh/pkg_url.sh";

  if find_class org.apache.xalan.xslt.SecuritySupport \
        "${apache_xalanj_URL}" "${apache_xalanj_jar_URL}" &&
     find_class org.apache.xml.resolver.tools.CatalogResolver\
      "${apache_resolver_URL}" "${apache_resolver_jar_URL}"; then

    return 0;

  fi

}


# apply_xsl XML_IN XSL OUT [MORE]
#
# Function to apply XSL to XML document and generate OUT
#
#   XML_IN - XML file to process
#
#   XSL    - XSL file to perform translation with.
#
#   OUT    - Where to store the results
#
#   [MORE] - Optional extra arguments for Xalan parser

apply_xsl() {
  if [ ! -f "$1" ]; then
    error "$1 not found" 1
  fi

  if [ ! -f "$2" ]; then
    error "$2 not found" 1
  fi

  if [ "$3" = "" ]; then
    error "output file not specified" 1
  fi

  IN="$1"
  shift
  XSL="$1"
  shift
  OUT="$1"
  shift

  JAVA="${XML_COMMON_JAVA:-java}";

  if [ "${XML_COMMON_CLASSPATH}" == "" ]; then
    if ! build_xml_common_classpath; then
      error "failed to find/download/install 1 or more required JARS" 1;
    fi
  fi

  ${JAVA} -cp \
   "${XML_COMMON_CLASSPATH}:${XML_USR}/share/vaisala/xml/keyval/catalog" \
   org.apache.xalan.xslt.Process \
   -UriResolver org.apache.xml.resolver.tools.CatalogResolver \
   -EntityResolver org.apache.xml.resolver.tools.CatalogResolver \
   -IN "${IN}" -XSL "${XSL}" -OUT "${OUT}"

}

# install_query_check
#
# This option allows a user to specify options like --install xsl to
# retrieve information about the package installation. This might be
# useful for making use of the package files OUTSIDE of the
# script. --install help will list all possible.

install_query_check() {
  choices=(catalog catalog-oasis docs dtd public-id public-url url xsl)
  results=("${CATALOG}"\
 "${CATALOG_OASIS}"\
 "${XML_DOCS}/${TAG}"\
 "${SYSROTO}/dtd/${DTD}"\
 "${PUBLIC_ID}"\
 "${URIDTD}"\
 "${URIROOT}/${TAG}"\
 "${XSLROOT}")

  if [ "$INSTALL_QUERY" = "" ]; then
    return 0;
  fi

  n="${#choices[*]}"
  ((i=0))
  while (( i < n )); do
    if [ "$INSTALL_QUERY" = "${choices[$i]}" ]; then
      echo "${results[$i]}"
      exit 0;
    fi
    ((i=i+1))
  done

  echo "Use '--install-query NAME' where NAME is one of:"
  echo "  ${choices[*]}"

  if [ "$INSTALL_QUERY" = "help" ]; then
    exit 0
  fi
  exit 1;

}

#!/bin/bash

#
# AUTOMATICALLY GENERATED - DO NOT EDIT!
#

#
# Assume command line options are OK
#

OK=true

VARNAME_LIST="NAME DOC_TYPE TEMPLATES LOG_FILE INSTALL_QUERY TYPE "

# print_config
#
# Displays current configuration in format suitable for sourcing

print_config() {
    printf "#\n# configuration options for keyval2sh script\n#\n\n"
  for e in ${VARNAME_LIST}; do
    if [ "${e}" != "CONFIG_FILE" ]; then
      printf "${e}=%q\n" "${!e}";
    fi
  done
}

# check_config_file CMD
#
# This function checks the CMD value passed. Following rules are
# imposed:
#
#   "" (unset) or "no"
#     Nothing is done
#   "load" 
#     If file $HOME/.vaisala.xml.keyval.keyval2sh.sh exists it is sourced.
#     If not found error message and exit.
#   "auto" 
#     Similar to "load", but does nothing if default config not found.
#   "save" 
#     Settings are saved to $HOME/.vaisala.xml.keyval.keyval2sh.sh for future load.
#   "show"
#     Current settings are shown
#   FILE
#     We attempt to load config from FILE specified.

check_config_file() {
  local SCFG="/etc/vaisala.xml.keyval.keyval2sh.conf"
  local UCFG="${HOME}/.vaisala.xml.keyval.keyval2sh.conf"
  local CMD="$1"

  if [ "$CMD" = "no" -o "$CMD" = "" ]; then
    return 0;
  elif [ "$CMD" = "show" ]; then
    print_config
    exit 0
  elif [ "${CMD}" = "save" ]; then
    print_config > "${UCFG}"
    echo "Saved configuration as: ${UCFG}";
    echo "Will automatically be loaded at next configure invocation."
    exit
  elif [ "${CMD}" = "auto" ]; then
    for f in "${SCFG}" "${UCFG}"; do
      if [ -f "${f}" ]; then
        . "${f}"
      fi
    done
  elif [ "${CMD}" = "load" ]; then
    if [ -f "${UCFG}" ]; then
      for f in "${SCFG}" "${UCFG}"; do
        if [ -f "${f}" ]; then
          . "${f}"
        fi
      done
    else
      error "unable to read config: ${UCFG}"
      exit 1
    fi
  elif [ -f "${CMD}" ]; then
    for f in "${SCFG}" "${CMD}"; do
      if [ -f "${f}" ]; then
        . "${f}"
      fi
    done
  else
    error "for configuration files, use: --config no|save|load|show|FILE"
    exit 1
  fi
}

# list_options
#
# Displays all options on single line

append_line() {
  LLEN=${#LINE}
  NLEN=$((${LLEN}+${#1}+1))
  if [ "$((${NLEN} > 72))" != "0" ]; then
    printf "${LINE}\n";
    LINE="        ";
  fi
  LINE="${LINE} ${1}"
}

list_options() {
  LINE="  $(basename "$0")";
  append_line "[-n|--name TEXT]"
  append_line "[-d|--doc-type TEXT]"
  append_line "[-t|--templates true|false]"
  append_line "[-l|--log-file FILENAME]"
  append_line "[--install-query TEXT]"
  append_line "[--type TEXT]"

  append_line " [-h|--help]";
  printf "${LINE}\n";
}

# show_usage
#
# Displays help screen

show_usage() {
  printf "\nUsage:\n"
  list_options | fold -s 
  printf "\nWhere:\n"
  printf "  -n|--name"
  printf " TEXT  Currently:[$NAME]\n"
  printf "    Specify the name of the script you will be working on.\n"
  printf "  -d|--doc-type"
  printf " TEXT  Currently:[$DOC_TYPE]\n"
  printf "    Documentation output: none, docbook, or m4.\n"
  printf "  -t|--templates"
  printf " true|false  Currently:[$TEMPLATES]\n"
  printf "    Control whether template files are created.\n"
  printf "  -l|--log-file"
  printf " FILENAME  Currently:[$LOG_FILE]\n"
  printf "    Log of detailed output from processing files.\n"
  printf "  --install-query"
  printf " TEXT  Currently:[$INSTALL_QUERY]\n"
  printf "    Query information about the installed package.\n"
  printf "  --type"
  printf " TEXT  Currently:[$TYPE]\n"
  printf "    Allows you to specify exactly one type of file to produce.\n"
  printf "  -h|--help\n    Displays this usage information.\n"
  printf "\n"
}

# error TEXT
#
# Reports error message to screen and sets OK to false - does NOT exit

error() {
  echo "***ERROR*** $1" 1>&2
  OK=false
}

# error_if_switch TEST
#
# makes sure TEST doesn't start with "-"

error_if_switch() {
  local VAL="${1}";
  if [ "${VAL:0:1}" = "-" ]; then
    error "'${VAL}' is not acceptable after ${2:-switch}";
  fi

}

# get_value_for TYPE FROM CNT OPT [MIN] [MAX]
#
# Sets VALUE to the value parsed from FROM. TYPE indicates the type of value
# we are looking for. CNT is 0 if FROM wasn't available (number of
# arguments left on line). OPT is only used for error reporting (the
# command line switch we are looking for). Current rules (based on
# TYPE):
#
# bool
#   If CNT is 0, then echo "true"
#   If FROM starts with '-', then VALUE="$TRUE"
#   Otherwise, accept and set VALUE=FROM if it is "true" OR "false"
#
# int64/double
#   If CNT is 0, then error
#   Otherwise, we accept anything ('-' might be negative)
#
# OTHER
#   If CNT is 0 or FROM starts with '-' then error
#   Otherwise set VALUE=FROM
#
# returns 1 is FROM was used or 0 if not (use via: shift $?)
#
# Non-Error Examples:
#
#   get_value_for "bool" "" "0" "--enable"   # VALUE=true returns 0
#   get_value_for "bool" "--in" "12" "--enable"  # VALUE=true returns 0
#   get_value_for "bool" "false" "12" "--enable" # VALUE=false returns 1
#   get_value_for "file" "file.txt" "1" "--in" # VALUE=file.txt returns 1
#
# Error Examples:
#
#   get_value_for "bool" "no" "1" "--enable" # no not allowed 
#   get_value_for "file" "" "0" "--in" # missing value (0 count)
#   get_value_for "file" "--out" "12" "--in" # omitted value

get_value_for() {
  local TYPE="${1}"; # Type of value (like "int64")
  local VAL="${2}";  # Value to check (like "7")
  local CNT="${3}";  # Maximum number of values (like "1")
  local OPT="${4}";  # Option name (like "--verbosity")

  if [ "${TYPE}" == "bool" ]; then
                           # if true/false omitted, default to true
    if [ "${CNT}" = "0" -o "${VAL:0:1}" = "-" ]; then
      VALUE="true";
      return 0;
    fi

    if [ "${VAL}" != "true" -a "${VAL}" != "false" ]; then
      error "'${VAL}' is unacceptable (it was not true or false)."
      exit 1;
    fi
    VALUE="${VAL}";
    return 1;
  fi
  
  if [ "${CNT}" = "0" ]; then
    error "missing value for ${OPT} switch"
    exit 1;
  fi

  #
  # Allow leading '-' for number types
  #
  if [ "${TYPE}" = "double" -o "${TYPE}" = "int64" ]; then
    local MIN="${5}";
    local MAX="${6}";
    local VALID="true";

    # We can check min/max values for integers
    if [ "${TYPE}" = "int64" ]; then
      TYPE="integer";
      local IVAL="${VAL}"; # Strip leading "+" if present
      if [ "${VAL:0:1}" = "+" ]; then
        IVAL="${VAL:1}";
      fi

      if [ "$((VAL+0))" != "${IVAL}" ]; then
        VALID="false";
      elif [ "${MIN}" != "" -a "$((VAL < MIN))" == "1" ]; then
        VALID="false";
      elif [ "${MAX}" != "" -a "$((VAL > MAX))" == "1" ]; then
        VALID="false";
      fi
    elif [ "${TYPE}" = "double" ]; then
      TYPE="real number";
      # fix signs for dc
      local DVAL="${VAL//-/_}";
      DVAL="${DVAL//+/}";
      local DMIN="${MIN//-/_}";
      DMIN="${DMIN//+/}";
      local DMAX="${MAX//-/_}";
      DMAX="${DMAX//+/}";

      if [ "$(echo "[0p]sa" "${DVAL}" 0.0 + "${DVAL}" "!=a" | dc 2>&1)" = "0" ]; then
        VALID="false";
      elif [ "${MIN}" != "" -a\
             "$(echo "[0p]sa" "${DVAL}" "${DMIN}" ">a" | dc 2>&1)" = "0" ]; then
        VALID="false";
      elif [ "${MAX}" != "" -a\
             "$(echo "[0p]sa" "${DVAL}" "${DMAX}" "<a" | dc 2>&1)" = "0" ]; then
        VALID="false";
      fi
    fi


    if [ "${VALID}" == "true" ]; then
      VALUE="${VAL}";
      return 1;
    fi

    error "${OPT} requires a ${TYPE} in range [${MIN:--INF},${MAX:-INF}] (${VAL} is bad)."
    exit 1;
  fi

  if [ "${VAL:0:1}" = "-" ]; then
    error "'${VAL}' is not acceptable after ${OPT} switch"
    exit 1;
  fi
  VALUE="${VAL}";
  return 1;
}

#
# Set default values
#

NAME="";
DOC_TYPE="docbook";
TEMPLATES="true";
LOG_FILE="/dev/null";
INSTALL_QUERY="";
TYPE="";

# process_args CMD ARG0 ARG1 ...
#
#   Process command line arguments passed to CMD

process_args() {

  while test $# -gt 0; do

    OPT="$1";
    shift

    case "$OPT" in

    -h | --help)
      check_config_file "$CONFIG_FILE"
      show_usage;
      exit 1;
      ;;

    -n | --name)
      get_value_for std::string "${1}" "$#" "$OPT" "" ""
      shift $?
      NAME="${VALUE}";
      ;;

    -d | --doc-type)
      get_value_for std::string "${1}" "$#" "$OPT" "" ""
      shift $?
      DOC_TYPE="${VALUE}";
      ;;

    -t | --templates)
      get_value_for bool "${1}" "$#" "$OPT" "" ""
      shift $?
      TEMPLATES="${VALUE}";
      ;;

    -l | --log-file)
      get_value_for std::string "${1}" "$#" "$OPT" "" ""
      shift $?
      LOG_FILE="${VALUE}";
      ;;

    --install-query)
      get_value_for std::string "${1}" "$#" "$OPT" "" ""
      shift $?
      INSTALL_QUERY="${VALUE}";
      ;;

    --type)
      get_value_for std::string "${1}" "$#" "$OPT" "" ""
      shift $?
      TYPE="${VALUE}";
      ;;


    *)
      error "'$OPT' is not a valid option!"
    esac
  done

}

# check_required_args [EXIT_CODE]
#
#   Checks all arguments which have a default value of "REQUIRED". If
#   these arguments have not been specified by the user, then echos a
#   message (and optionally exits with EXIT_CODE).
#
# EXIT_CODE
#   If this argument is passed, we will exit the script if
#   any required arguments are found to be missing.
#
# RETURNS
#   0 if we were not missing any required arguments, 1 if we were (and
#   we didn't exit).

check_required_args() {

  return 0;
}

process_args "$@"

# If configuration files are enabled (CONFIG_FILE set), then check
# user value. Will need to reload command line arguments if "--config
# auto" specified (as it implies different default settings).

if [ "$CONFIG_FILE" != "" ]; then
  check_config_file "$CONFIG_FILE"

  if [ "$CONFIG_FILE" = "auto" ]; then
    process_args "$@"
  fi
fi

#
# If any obvious errors, show the usage and exit now!
#

if [ "$OK" != "true" ]; then
  show_usage 1>&2
  exit 2
fi

#
# END OF SECTION GENERATED BY keyval_to_sh.xsl
#
#
# $Id: keyval2sh.sh,v 1.10 2006/02/24 15:33:41 pkb Exp $
#

#
# Allow user to request information about the install
#

install_query_check

#
# We require the --name option (but that's about all we require)
#

[ "$NAME" = "" ] && error "the --name NAME option was not set properly" 2

#
# Determine types of files to generate
#

if [ "$TYPE" != "" ]; then
  if [ ! -f "${XSL_DIR}/keyval2${TYPE}.xsl" ]; then
    error "'$TYPE' is not valid for the --type option - see man page"
    exit 1;
  fi
  TYPES="$TYPE"
  TEMPLATES="false"
else
  TYPES="sh"
  if [ "$DOC_TYPE" = "m4" ]; then
    TYPES="sh sh_m4i"
  elif [ "$DOC_TYPE" = "docbook" ]; then
    TYPES="sh docbook_synopsis docbook_options"
  elif [ "$DOC_TYPE" != "none" ]; then
    error "invalid document type '$DOC_TYPE' specified" 1
  fi
fi

#
# Create a template file if it doesn't exist
#

XML_FILE="${NAME}_config.xml"

if [ ! -f "${XML_FILE}" ]; then
  [ "$TEMPLATES" != "true" ] && error "missing file: ${XML_FILE}" 2

  message "creating template file: ${XML_FILE}"

  cat >| "${XML_FILE}" <<EOF
<?xml version="1.0"?>

<!-- $Id: keyval2sh.sh,v 1.10 2006/02/24 15:33:41 pkb Exp $

  Initial template definition of command line arguments for ${NAME}.sh

-->

<!DOCTYPE keyval PUBLIC
   "-//VAISALA//DTD KeyValue XML V1.0.0//EN"
   "http://www.mekwin.com/vaisala/xml/dtd/keyval/keyval_1_0_0.dtd">

<keyval class="${NAME}">

  <!-- If you are using emacs, try putting your cursor below this
  comment and then press C-c C-e (and check out the menu's above) -->

  <file default="-" varname="IN">
    <key short="i">in</key>
    <summary>The name of the input file to process.</summary>

    <description>This argument is used to specify the name of the
    input file to be processed by <command>${NAME}</command>. If
    omitted, it defaults to '-' indicating that
    <command>${NAME}</command> should read its input from the
    console.</description>
  </file>

  <file default="-" varname="OUT">
    <key short="o">out</key>
    <summary>The name of the output file to produce.</summary>

    <description>This argument is used to specify the name of the
    output file to be produced by <command>${THIS}</command>. If
    omitted, it defaults to '-' indicating that
    <command>${NAME}</command> should write its input to the
    console.</description>
  </file>

  <boolean default="false" varname="VERBOSE">
    <key short="v">verbose</key>
    <summary>Produce verbose output.</summary>

    <description>When you set this option to true,
    <command>${NAME}</command> will produce additional output. This is
    typically used for diagnostic purposes to help track down when
    things go wrong.</description>
  </boolean>

  <file default="/dev/null" varname="LOG_FILE">
    <key short="l">log-file</key>
    <summary>Used to log diagnositic output to a file.</summary>

    <description>If you are encountering errors when running
    <command>${NAME}</command>, try using this option and examine
    the log file after running <command>${NAME}</command>. It may
    provide useful clues as to what went wrong.</description>
  </file>

</keyval>
EOF
fi

#
# Generate files by applying XSL templates to XML document
#

OK="true"

for TYPE in $TYPES; do
  verify_files ${XSLROOT}/keyval2${TYPE}.xsl
  CMD="apply_xsl ${XML_FILE} ${XSLROOT}/keyval2${TYPE}.xsl ${NAME}_config.${TYPE}"
  message "$(printf "Generating: ${NAME}_config.${TYPE}\n")"
  $CMD >> "${LOG_FILE:-/dev/null}" 2>&1
  if [ "$?" != "0" ]; then 
    OK="false";
  fi
done

if [ "$OK" != "true" ]; then
  error "one or more XSL translations failed (rc:${OK}) - stopping!";
  exit 1;
fi

#
# If templates have been disabled, then we're done, otherwise stub in
# some starter code
#

if [ "$TEMPLATES" != "true" ]; then
  exit "$OK"
fi

#
# Stub in template shell script
#

TEMPLATE="${NAME}.sh"

if [ ! -f "${TEMPLATE}" ]; then
  message "$(printf "Creating Template: ${TEMPLATE}\n")"
  cat >| ${TEMPLATE} <<EOF
#
# Template file - you should edit/replace with your REAL code
#

show_config() {
  for e in \${VARNAME_LIST}; do
    VAL="\${!e}";
    if [ "\${VAL}" == "REQUIRED" ]; then
      printf "# \${e}=\"YOU NEED TO SET THIS VALUE\"\n";
    else
      printf "\${e}=\"\${!e}\"\n";
    fi
  done
}

printf "PLEASE INSERT YOUR OWN CODE!\n\n\
Available settings for the ${NAME} script:\n"

show_config
EOF
fi

#
# Stub in template makefile
#

TEMPLATE="${NAME}.mk"

if [ ! -f "${TEMPLATE}" ]; then
  message "$(printf "Creating Template: ${TEMPLATE}\n")"
cat >| ${TEMPLATE} <<EOF
#
# Template file - you replace this, or merge it into a bigger makefile
#
# Use via: make -f ${NAME}.mk

$(if [ "${DOC_TYPE}" = "m4" ]; then cat <<MEOF
NAME=${NAME}
ALL.APPS=
ALL.LIB=
ALL.M4.DOCS=
ALL.SCRIPTS=${NAME}
ALL.MAN=\$(ALL.SCRIPTS)
ALL.CFLAGS=
ALL.CCFLAGS=

#
# Make help the default target
#

help::
	@printf "The following targets are available:\n\n"
	@printf "  ${NAME}\n\tHandy script for washing dishes.\n"

#
# Include standard rules
#

include ../../include/make/default.mk

MEOF
else cat <<MEOF
#
# You should probably adjust these corresponding to some top level makefile
#

BINDIR=.
MANDIR=.
MANSECTION=l
HTMLDIR=.

JAVA=${XML_COMMON_JAVA:-java} -cp "${XML_COMMON_CLASSPATH}"

DOCBOOK_XSL=${XML_COMMON_DOCBOOK:-http://docbook.sourceforge.net/release/xsl/current}
KEYVAL_XSL=${XSLROOT}
MEOF
fi)

#
# Targets
#

all::

#
# Rules for parts that can be generated (we'll just apply XSL directly)
#

${NAME}_config.sh:	${NAME}_config.xml
	\$(JAVA) org.apache.xalan.xslt.Process -IN "${NAME}_config.xml" \
	    -out "\$(@)" -xsl "\$(KEYVAL_XSL)/keyval2sh.xsl"

${NAME}_config.sh_m4i:		${NAME}_config.xml
	\$(JAVA) org.apache.xalan.xslt.Process -IN "${NAME}_config.xml" \
	    -out "\$(@)" -xsl "\$(KEYVAL_XSL)/keyval2sh_m4i.xsl"

${NAME}_config.docbook_synopsis:	${NAME}_config.xml
	\$(JAVA) org.apache.xalan.xslt.Process -IN "${NAME}_config.xml" \
	    -out "\$(@)" -xsl "\$(KEYVAL_XSL)/keyval2docbook_synopsis.xsl"

${NAME}_config.docbook_options:	${NAME}_config.xml
	\$(JAVA) org.apache.xalan.xslt.Process -IN "${NAME}_config.xml" \
	    -out "\$(@)" -xsl "\$(KEYVAL_XSL)/keyval2docbook_options.xsl"

#
# Rule to build the actual script
#

\$(BINDIR)/${NAME}:: ${NAME}_config.sh ${NAME}.sh
	cat "${NAME}_config.sh" "${NAME}.sh" >| "\$(@)"
	chmod +x "\$(@)"

all::	\$(BINDIR)/${NAME}

$(if [ "${DOC_TYPE}" = "docbook" ]; then cat <<MEOF
#
# Build man page
#

\$(MANDIR)/${NAME}.\$(MANSECTION)::	${NAME}.docbook \
	${NAME}_config.docbook_options ${NAME}_config.docbook_synopsis
	\$(JAVA) org.apache.xalan.xslt.Process -IN "${NAME}.docbook"\
		-XSL "\$(DOCBOOK_XSL)/manpages/docbook.xsl" -OUT "\$(@)"

all::	\$(MANDIR)/${NAME}.\$(MANSECTION)

#
# Build HTML version of man page
#

\$(MANDIR)/${NAME}.man.html::	${NAME}.docbook \
	${NAME}_config.docbook_options ${NAME}_config.docbook_synopsis
	\$(JAVA) org.apache.xalan.xslt.Process -IN "${NAME}.docbook"\
		-XSL "\$(DOCBOOK_XSL)/html/docbook.xsl" -OUT "\$(@)"

all::	\$(MANDIR)/${NAME}.man.html

#
# Clean up temporary files
#

clean_${NAME}::
	@for f in ${NAME}_config.sh ${NAME}_config.docbook_options \
	    ${NAME}_config.docbook_synopsis ${NAME}_config.sh_m4i; do \
	  if [ -f "\$\$f" ]; then rm "\$\$f"; fi; \
	done

clean::	clean_${NAME}

#
# Clear out build area as well
#

clear_name::
	@for f in \$(BINDIR)/${NAME} \$(MANDIR)/${NAME}.\$(MANSECTION) \
	    \$(HTMLDIR)/${NAME}.man.html; do \
	  if [ -f "\$\$f" ]; then rm "\$\$f"; fi; \
	done

clear::	clean_${NAME} clear_${NAME}
MEOF
fi)
EOF
fi

#
# Stub in template docbook
#

if [ "$DOC_TYPE" = "docbook" ]; then

  TEMPLATE="${NAME}.docbook"

  if [ ! -f "${TEMPLATE}" ]; then
    message "$(printf "Creating Template: ${TEMPLATE}\n")"

    cat >| ${TEMPLATE} <<EOF
<?xml version="1.0" standalone="no" ?>

<!-- \$$(printf "Id")\$ 

  Man page for ${NAME} script.

-->

<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN" 
 "http://www.oasis-open.org/docbook/xml/4.0/docbookx.dtd" [

<!--
	Entity definitions, which help with consistency throughout this
	document 
-->

<!ENTITY name '${NAME}'>
<!ENTITY name.app '<application>&name;</application>'>

<!ENTITY author.name.first "Joe">
<!ENTITY author.name.last "Blow">
<!ENTITY author.email "joe.blow@vaisala.com">

<!ENTITY load.synopsis SYSTEM "${NAME}_config.docbook_synopsis">
<!ENTITY load.options SYSTEM "${NAME}_config.docbook_options">

<!-- Example of loading shared entities - adjust or delete
<!ENTITY % load.entities SYSTEM "../../include/sgml/entities.sgml">
%load.entities;
-->

]>

<refentry id="&name;">
  <refentryinfo>
    <author>
      <firstname>&author.name.first;</firstname>
      <surname>&author.name.last;</surname>
      <affiliation>
        <address><email>&author.email;</email></address>
      </affiliation>
    </author>
    <copyright>
      <year>$(date +%Y)</year>
      <holder>&author.name.first; &author.name.last;</holder>
    </copyright>
  </refentryinfo>
  <refmeta>
    <refentrytitle>&name;</refentrytitle>
    <manvolnum>l</manvolnum>
  </refmeta>
      
  <refnamediv>
    <refname>&name;</refname>
    <refpurpose>Used to wash dishes.</refpurpose>
  </refnamediv>
      
  &load.synopsis;

  <refsect1>
    <title>Description</title>

    <para>The <command>&name;</command> is pretty darn handy when it
    comes to washing dishes. It can:</para>

    <itemizedlist>

      <listitem><para>Scrub them clean.</para></listitem>

      <listitem><para>Dry them dry.</para></listitem>

    </itemizedlist>

  </refsect1>

  &load.options;

  <refsect1>
    <title>Files</title>

    <variablelist>

      <varlistentry>
	<term><filename>\${HOME}/.etc/&name;.conf</filename></term>

	<listitem><para>When run, we will search for this file and
	use the settings contained as our defaults.</para> </listitem>

      </varlistentry>

    </variablelist>
  </refsect1>

  <refsect1>
    <title>Environment</title>

    <variablelist>

      <varlistentry>
	<term><envar>XML_COMMON_JAVA</envar></term>

	<listitem><para>When translating <acronym>XML</acronym>
	documents with <acronym>XSL</acronym>,
	the <command>${NAME}</command> will make use of
	the <acronym>XSLT</acronym> processor found in the 1.4.2 version
	of the Java run time environment. If
	the <command>java</command> interpreter found in your path is not
	version 1.4.2 or later, you can use this environment variable
	to specify the location of the appropriate <command>java</command>
	interpreter. In addition, you can also
	use it to specify <acronym>HTTP</acronym> proxy information
	for your <command>java</command> environment. For
	example, a setting
	of <literal>/liz3/pkb/usr/j2re1.4.2_03/bin/java 
	-DproxyHost=172.26.0.232 -DproxyPort=3128</literal> would specify
	a path to a particular <command>java</command> interpreter and set
	the <acronym>HTTP</acronym> proxy settings.</para></listitem>

      </varlistentry>

    </variablelist>
  </refsect1>

  <refsect1>
    <title>Authors</title>

    <para>&author.name.first; &author.name.last; created initial
    version.</para>

  </refsect1>

  <refsect1>
    <title>See Also</title>

    <para>

      <!-- Example man page reference -->

      <citerefentry>
        <refentrytitle>keyval2cc</refentrytitle>
	<manvolnum>l</manvolnum>
      </citerefentry>,

      <!-- Example URL reference -->

      <ulink url="http://www.google.com/">Google</ulink>

    </para>
  </refsect1>

</refentry>
EOF
  fi
fi

#
# Stub in template docbook
#

if [ "$DOC_TYPE" = "m4" ]; then

  TEMPLATE="${NAME}.man.m4"

  if [ ! -f "${TEMPLATE}" ]; then
    message "$(printf "Creating Template: ${TEMPLATE}\n")"

    cat >| ${TEMPLATE} <<EOF
_BEG_COMMENT
_RCS_ID_INFO(["\$$(printf "Id")\$"])
_COPYRIGHT(["$(date +%b,%d,%Y)"],["Vaisala, Tuscon"])

The following line is useful to use easily reference the programs
created by _COMPANY

m4_include(../package/package.m4)
m4_include(man.common.m4)
m4_include(${NAME}_config.sh_m4i)
_END_COMMENT
_DOCUMENT(["${NAME}"],["_AUTHOR_${USER}"],
["_COMPANY_ADDR"],["Used to wash dishes."])
_GLOBAL_INDEX(Man Pages)

_SCRIPT_COMMAND_LINE

_DESCRIPTION

_PARA(["The _THIS is pretty darn handy when it comes to washing
dishes. It can:"])

_BEG_LIST

_LIST_ITEM(["Scrub them clean."])

_LIST_ITEM(["Dry them dry."])

_END_LIST

_SCRIPT_OPTIONS

_FILES

_BEG_FILE_DEF
_FILE_DEF(_ROOTFILE(man/_CAT(man,_DEF_SECTION)/_PROG_NAME._DEF_SECTION),["File
containing this man page."])

_END_FILE_DEF

_HEADING(["Environment"])

_BEG_DESCRIPTION

_DESCRIBE(["_ENV_VAR(["XML_COMMON_JAVA"])"],["When translating
_LIT(["XML"]) documents with _LIT(["XSL"]), the _THIS will make use of
the _LIT(["XSLT"]) processor found in the 1.4.2 version of the Java
run time environment. If the _JAVA interpreter found in your path is
not version 1.4.2 or later, you can use this environment variable to
specify the location of the appropriate _JAVA interpreter. In
addition, you can also use it to specify _LIT(["HTTP"]) proxy
information for your _JAVA environment. For example, a setting of
_LIT(["/liz3/pkb/usr/j2re1.4.2_03/bin/java -DproxyHost=172.26.0.232
-DproxyPort=3128"]) would specify a path to a particular
<command>java</command> interpreter and set the _LIT(["HTTP"]) proxy
settings."])

_END_DESCRIPTION

_ALSO_SEE

_PARA(["_SEE(["_URL(["http://www.google.com/"],["Google"])"])"])

_BEG_COMMENT
_DIAGNOSTICS

_PARA(["Describe terminating error messages application may produce"])

_BUGS

_PARA(["None reported."])
_END_COMMENT

_NOTES

_GENERAL_NOTES
EOF
  fi
fi

#
# Finally done
#

EDIT_FILES="${NAME}.sh and ${NAME}_config.xml"
if [ "$DOC_TYPE" = "docbook" ]; then
  EDIT_FILES="${NAME}.docbook, ${EDIT_FILES}"
elif [ "$DOC_TYPE" = "m4" ]; then
  EDIT_FILES="${NAME}.man.m4, ${EDIT_FILES}"
fi

message "Finished - finally!\n"\
"STEP 1: Try invoking:\n  make -f ${NAME}.mk; ./${NAME} --help\n"\
"STEP 2: Then edit files:\n  ${EDIT_FILES}\n"\
"STEP 3: Repeat steps 1 and 2 until life is good."
