#!/bin/bash

# http://sourceforge.net/projects/process-getopt
# http://process-getopt.sourceforge.net
# http://bhepple.freeshell.org/oddmuse/wiki.cgi/process-getopt

# Copyright 2008-2009 Bob Hepple
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA

# $Id: command-processor,v 1.6 2009/04/10 22:11:22 bhepple Exp $

# A test script for process-getopt - just echos options and args

# error on first failed command or unreferencing a undefined variable:
set -eu

check_and_process_opts() {
    local NO_OPTS TEMP PG

    PG=$(type process-getopt |cut -d' ' -f 3)
    [ "$PG" ] || exit 1
    source $PG

    # option helper functions:
    SLOT_func() { [ "${1:-""}" ] && SLOT="yes"; }
    add_opt SLOT "boolean option" s "" slot 

    TOKEN_func() { [ "${1:-""}" ] && TOKEN="$2"; }
    add_opt TOKEN "option that takes a value" t n token number

    LONGONLY_func() { [ "${1:-""}" ] && LONGONLY="$2"; }
    add_opt LONGONLY "long option without short option" "" "" "long-only" "value"
    COUNTED_func() {  [ "${1:-""}" ] && (( COUNTED++ )); }
    add_opt COUNTED "an option which increments every time it is given" c

    add_std_opts # define the standard options --help etc
    del_opt QUIET VERBOSE

    TEMP=$(call_getopt "$@") || exit 1
    eval set -- "$TEMP"
    process_opts "$@" || shift "$?"
    NEW_ARGS=( "$@" )
    return 0
}

process_add_options() {
    # option helper functions:
    ADDSLOT_func() { [ "${1:-""}" ] && ADDSLOT="yes"; }
    add_opt ADDSLOT "boolean option" s "" add-slot 

    add_std_opts # define the standard options --help etc

    # Call getopt:
    export STOP_ON_FIRST_NON_OPT="yes"
    TEMP=$(call_getopt "$@") || exit 1
    eval set -- "$TEMP"
    process_opts "$@" || shift "$?"
    NEW_ARGS=( "$@" )
}

##########################
#         M A I N        #
##########################

PROG=$(basename $0)
DIR=$(dirname $0)
VERSION='$Revision: 1.6 $'
VERBOSE=""
ARGUMENTS="add | multiply | frob | bris [ COMMAND_OPTIONS] "
USAGE="echos options and args to stdout"

TMP="/tmp/tmp$$.tmp"
trap "/bin/rm -f $TMP" EXIT 
SLOT=""
TOKEN=""
LONGONLY=""
COUNTED=0

export STOP_ON_FIRST_NON_OPT="yes"
NEW_ARGS=( )
check_and_process_opts "$@" && {
    if [ ${#NEW_ARGS[@]} -gt 0 ]; then
        set -- "${NEW_ARGS[@]}"
    else
        set --
    fi
}

# At this point, all the options have been processed and removed from
# the arg list. We can now process $@ as arguments to the program.

echo "After global option processing we have:"
for i in "$@"; do echo -n "\"$i\" "; done
echo

# $@ now contains only the command and its options

[ "$SLOT" ] && echo "SLOT option (-$(get_opt_letter SLOT), --$(get_opt_string SLOT))"
[ "$TOKEN" ] && echo "TOKEN option (-$(get_opt_letter TOKEN) \"$TOKEN\", --$(get_opt_string TOKEN)=\"$TOKEN\")"
[ "$LONGONLY" ] && echo "LONGONLY option (--$(get_opt_string LONGONLY)=\"$LONGONLY\")"
[ "$COUNTED" -gt 0 ] && echo "COUNTED option (-$(get_opt_letter COUNTED) = $COUNTED)"
[ "$VERBOSE" ] && echo "VERBOSE option (-$(get_opt_letter VERBOSE), --$(get_opt_string VERBOSE))"

# at this point we've processed all the options before the first argument - so 
# now we can set up and process the argument and its options:

clean_process_getopt

COMMAND="${1:-""}"
shift
echo "COMMAND=$COMMAND"

case "$COMMAND" in
    add) 
        NEW_ARGS=( )
        PROG="$PROG add"
        USAGE="do the add thing"
        ADDSLOT=""
        process_add_options "$@" && {
            if [ ${#NEW_ARGS[@]} -gt 0 ]; then
                set -- "${NEW_ARGS[@]}"
            else
                set --
            fi
        }
        echo "After 'add' option processing we have:"
        for i in "$@"; do echo -n "\"$i\" "; done
        echo
        echo "ADDSLOT option (-$(get_opt_letter ADDSLOT), --$(get_opt_string ADDSLOT))"
        ;;
    *)
esac
