#!/bin/bash

function msg_done {
  echo -e "\033[1m$1\033[m"
}

function msg_failed {
  echo -e "\033[1m\033[31m$1\033[m"
}

function getoptsPOSIX {
# usage: getoptsPOSIX OPTSTRING S_A_OPT1 [S_A_OPT2] ARGS [NO_MORE_OPTS]
#
# OPTSTRING  options string to be parsed
# S_A_OPT1   <-> name of an array of the valid option #1's properties, where
#            S_A_OPT1[0]     --> short option name (case-sensitive)
#            S_A_OPT1[1]     --> long option name (case-insensitive)
#            S_A_OPT1[2]     --> 1 if this option accepts OPT_END as parameter
#            S_A_OPT1[3]     <-- 1 if option present, 0 otherwise
#            S_A_OPT1[4..n]  <-- first and (n-2)th parameter of the option
# S_A_OPT2   <-> [...]
# ARGS[...]  <-- array if arguments that remain after parsing all options
# OPT_END    --> string that defines that no more options are following.
#                If not present or empty, every argument beginning with
#                - is considered an option.
#
# --> means that the function is reading from that field,
# <-- that the function is writing to that field,
# <-> performs both actions on that field.
#
# example:
#
# help[0]="?"
# help[1]="-help"
# flash[0]="F"
# flash[1]="-flash"
# getoptsPOSIX $* help flash
#
# Parsing all command-line arguments, the function will return in
#
# help[2]   1 if -? or --help was present, otherwise 0
# flash[2]  1 if -F or --flash was present, otherwise 0
# flash[3]  first parameter of -F or --flash, a null-string if not present
# flash[4]  second parameter of -F or --flash, a null-string if not present
#
# According to POSIX conformance, an option is also considered present,
# if it's the short option name and within an option string, where in
#
#   -ABDEF /usr/local/bin
#
# the options A to F are present, with /usr/local/bin as the parameter of
# the -F option. Thus it is identical to
#
#   -ABCDE --flash /usr/local/bin
#
# where the long name of the -F option (--flash) is used instead.
#
# Additionally, an option can be defined to specify that all following
# options are only arguments of the program, even if they match a valid
# option. Thus, one may define that the - option alone specifies this
# parsing behavior, where
#
#   -ABDEF /usr/local/bin - -ABCDEF
#
# would say that the second -ABCDEF is not a collection of options but
# a string argument for itself, possibly specifying an odd-named file.

echo "getopts $*"
local aa=$1
echo "args = ${$1}"

  options=1
  for i in $*; do
    if [ $options -eq 1 ] && [ "`echo $i | cut -c 1`" = "-" ]; then
      echo "option(s): $i"
      k=2
      if [ -z "`echo $i | cut -c $k`" ]; then
        options=0
        echo "  end of options"
      else
        if [ "`echo $i | cut -c $k`" = "-" ]; then
          j=$i
          echo "  long option: $j"
        else
          while [ -n "`echo $i | cut -c $k`" ]; do
            j=`echo $i | cut -c $k`
            echo "  $j"
            let k=k+1
          done
        fi
      fi
    else
      if [ $options -eq 1 ] && [ -n "$j" ]; then
        echo -n "    "
      fi
      echo -n "argument"
      if [ $options -eq 1 ] && [ -n "$j" ]; then
        echo -n " to option -$j"
      fi
      echo ": $i"
      j=""
    fi
  done
}

echo
echo Demo Program To Show How To Parse POSIX-Conform Command-Line Arguments
echo
echo "command-line arguments: $*"

echo -n "checking for cut... "
chk=`which cut 2> /dev/null`
if [ -z "$chk" ]; then
  msg_failed missing
  echo
  echo "GNU textutils are required for this program."
  echo
  exit 1
else
  echo "$chk"
fi

# copy[0]="C"
# copy[1]="-copy"
# args=$*
# getoptsPOSIX 'args' 'copy'
# echo ${copy[2]}
# echo ${copy[3]}

echo

  options=1
  for i in $*; do
    if [ $options -eq 1 ] && [ "`echo $i | cut -c 1`" = "-" ]; then
      echo "option(s): $i"
      k=2
      if [ -z "`echo $i | cut -c $k`" ]; then
        options=0
        echo "  end of options"
      else
        if [ "`echo $i | cut -c $k`" = "-" ]; then
          j=$i
          echo "  long option: $j"
        else
          while [ -n "`echo $i | cut -c $k`" ]; do
            j=`echo $i | cut -c $k`
            echo "  $j"
            let k=k+1
          done
        fi
      fi
    else
      if [ $options -eq 1 ] && [ -n "$j" ]; then
        echo -n "    "
      fi
      echo -n "argument"
      if [ $options -eq 1 ] && [ -n "$j" ]; then
        echo -n " to option $j"
      fi
      echo ": $i"
      j=""
    fi
  done

echo
