Daniele Maccari wrote:
Hi all,
attached you'll find the patch for the commented OptionParser script.
I fixed some little things we discussed with Jonas and Michael (thanks
to both for the help, and their patience). I hope this to be
"definitive", mainly because this way we'll have a default style which
to adhere to.
Bye
A little update to fix some errors, nothing really important though.
Anyway, here comes the patch :)
P.S.: could you please tell me whether attachments are actually attached
in the right manner now? Thanks
--- trunk/Scripts/Functions/OptionParser 2008-04-13 19:15:44.000000000
+0200
+++ trunk.new/Scripts/Functions/OptionParser 2008-04-14 18:49:07.000000000
+0200
@@ -1,32 +1,31 @@
#!/bin/bash (source)
-#######################################################################
-#
-# File:
+###############################################################################
+# File:
# OptionParser
# Description:
-# This file contains a bunch of shell functions used by gobo
-# tools to handle and parse command line options and in a
-# convenient way.
-#
-# A linguistic precision: we call options the -<something> and
-# --<something> parameters you encounter in virtually every command
-# line program, while arguments are the remaining parameters
-# following options, that is, the actual arguments on which the
-# program works. So for example:
+# This file contains a bunch of shell functions used by gobo tools to
+# handle and parse command line options and in a convenient way.
+# Notes:
+# A linguistic clarification: we call options the -<something> and
+# --<something> parameters you encounter in virtually every command line
+# program, while arguments are the remaining parameters,that is, the
+# actual arguments on which the program works. For example:
#
-# MakeRecipe --no-web Foo 1.0 http://foo.bar
+# MakeRecipe --no-web Foo 1.0 http://foo.bar
#
# has one option and three arguments.
+# Also note that options and arguments can come in any order.
# Usage:
# See each function's header for a detailed description of its
# usage.
-#
-#######################################################################
+###############################################################################
Import String # strings handling
-declare -a savedOptions # only used in Parse_Options
+# An array to contain options passed when calling the script, only used in
+# Parse_Options.
+declare -a savedOptions
#declare -a optionsShortList
#declare -a optionsLongList
#declare -a optionsDescriptionList
@@ -37,32 +36,23 @@
argumentsListSize=0
parsedArguments=0
-#######################################################################
-#
+###############################################################################
# Name:
# Add_Option
# Description:
# Adds an option, updating options arrays accordingly.
+# Options are stored using a number of arrays, one for every option's
+# attribute. Every array has dimension equal to the number of options
+# defined for the current script. Options' attributes are as follows:
+#
+# -type = {"Boolean", "Entry", "List"}
+# -short form
+# -long form
+# -description
+# -default value
+# -possible values
#
-# Options are stored using a number of arrays, one for every
-# option's attribute. Every array has dimension equal to the
-# number of options defined for the current script. Options'
-# attributes are:
-#
-# - type
-# - short form
-# - long form
-# - description
-# - default value
-# - possible values
-#
-# Also, an option can be of basically three types:
-#
-# - Boolean
-# - Entry
-# - List
-#
-# See each option's Add_ function header for a more detailed
+# See each option's Add_Option_* function header for a more detailed
# description.
# Arguments:
# type -- string : Option's type
@@ -79,8 +69,7 @@
# Add_Option <type> <default> <short> <long> <description> [<values>]
# Example:
# Add_Option "Entry" "ask" "s" "same" "What to do when unpackaging over
the same version." "keep remove ask cancel"
-#
-#######################################################################
+###############################################################################
function Add_Option() {
# Some debug code
@@ -89,14 +78,15 @@
then
for i in `seq $optionsListSize`
do
+ # Check whether shortening or full name conflict with already present
+ # ones.
if [ "$3" = "${optionsShortList[i]}" -o "$4" =
"${optionsLongList[i]}" ]
then Die "Script internal error: option name -$3 --$4 conflicts with
-${optionsShortList[i]} --${optionsLongList[i]}."
fi
done
fi
-
+
optionsListSize=$[optionsListSize+1]
-
# Add the option's attributes to our arrays.
optionsTypeList[$optionsListSize]="$1" # type
optionsStateList[$optionsListSize]="$2" # default value
@@ -106,20 +96,17 @@
optionsValidStateList[$optionsListSize]="$6" # possible values
}
-#######################################################################
-#
+###############################################################################
# Name:
# Add_Option_Boolean
# Description:
# Adds an option of type boolean.
-#
-# A boolean option has only two possible values: 'on' and 'off',
-# which respectively map to 'true' and 'false'. In fact, everything
-# else than 'on' means 'false'.
-# Since its values are fixed, there is no need to specify a list
-# of possible values. Furthermore, they don't have a default value
-# because they're evaluated at 'false' by default.
-# They should be set using the dedicated function Set_Boolean.
+# A boolean option has only two possible values: 'on' and 'off', which
+# respectively map to 'true' and 'false'. In fact, anything else than
+# 'on' means 'false'.
+# Since its values are fixed, there is no need to specify a list of
+# possible values. Furthermore, they don't have a default value because
+# they're evaluated at 'false' by default.
# Arguments:
# short -- char : Option's shortening
# long -- string : Option's full name
@@ -128,26 +115,26 @@
# none.
# Return:
# none.
+# Notes:
+# Please note that Boolean options should be set using the dedicated
+# function Set_Boolean.
# Usage:
# Add_Option_Boolean <short> <long> <description>
# Example:
# Add_Option_Boolean "d" "display" "Informative output only. Do not
actually kill any process."
-#
-#######################################################################
+###############################################################################
function Add_Option_Boolean() {
Add_Option "Boolean" "" "$@"
}
-#######################################################################
-#
+###############################################################################
# Name:
# Add_Option_Entry
# Description:
# Adds a full option entry.
-#
-# An option of this type can assume only one value at a time,
-# chosen among the pool of possible values.
+# An option of this type can assume only one value at a time, chosen
+# among the pool of possible values.
# Arguments:
# short -- char : Option's shortening
# long -- string : Option's full name
@@ -159,33 +146,28 @@
# Return:
# none.
# Usage:
-# Add_Option_Entry <short> <long> <description> [<default> [<values>]]
+# Add_Option_Entry <short> <long> <description> [<default> <values>]
# Example:
# Add_Option_Entry "s" "same" "What to do when unpackaging over the same
version." "ask" "keep remove ask cancel"
-#
-#######################################################################
+###############################################################################
function Add_Option_Entry() {
- # We can add entry options without a default value, in which case
- # they don't have a list of possible values either.
+ # We can add entry options without a default value, in which case they don't
+ # have a list of possible values either.
if [ "$4" ]
then Add_Option "Entry" "$4" "$1" "$2" "$3" "$5"
else Add_Option "Entry" "[EMAIL PROTECTED]@#" "$1" "$2" "$3"
fi
}
-#######################################################################
-#
+###############################################################################
# Name:
# Add_Option_List
# Description:
# Adds an option of type list.
-#
-# This is an option which can take a list of values instead of
-# a single one.
-# Note that list options are free to be anything, so they don't
-# have any possible value defined.
+# This is an option which can take a list of values instead of a single
+# one.
# Arguments:
# short -- char : Option's shortening
# long -- string : Option's full name
@@ -195,12 +177,14 @@
# none.
# Return:
# none.
+# Notes:
+# Note that list options are free to be anything, so they don't have any
+# possible value defined.
# Usage:
# Add_Option_List <shor> <long> <description> [<default>]
# Example:
# Add_Option_List "s" "sandbox" "Colon-separated list of areas where the
restricted user has write access to." "."
-#
-#######################################################################
+###############################################################################
function Add_Option_List() {
@@ -211,8 +195,7 @@
fi
}
-#######################################################################
-#
+###############################################################################
# Name:
# Add_Argument
# Description:
@@ -227,30 +210,27 @@
# Add_Argument <value>
# Example:
# Add Argument
-#
-#######################################################################
+###############################################################################
function Add_Argument() {
argumentsList[$argumentsListSize]="$1"
argumentsListSize=$[argumentsListSize+1]
}
-#######################################################################
-#
+###############################################################################
# Name:
# Args_To_Array
# Description:
# Converts a space separated string of arguments to a bash array.
-#
-# If the start (end) position is not specified, the array will
-# start at the first (will end at the last) one.
+# If the start (end) position is not specified, the array will start at
+# the first (end at the last) one.
# Arguments:
# name -- string : Array's name
# from -- number : The argument to start from
# to -- number : The argument to end to
# Output:
# array : A bash array, starting from <from> and ending at <to>,
-# in the format <name>=("arg<from>" "arg2" ... "arg<to>").
+# in the format <name>=("arg<from>" "arg<from>+1" ... "arg<to>").
# Return:
# none.
# Notes:
@@ -266,8 +246,7 @@
# Example:
# eval `Args_To_Array myArray`
# Returns an array called myArray with all non-option arguments.
-#
-#######################################################################
+###############################################################################
function Args_To_Array() {
name="$1"
@@ -291,8 +270,7 @@
echo ")"
}
-#######################################################################
-#
+###############################################################################
# Name:
# Arg
# Description:
@@ -300,16 +278,15 @@
# Arguments:
# position -- number : Argument's position
# Output:
-# string : The argument at <position>, if in bounds, or an empty
-# string otherwise.
+# string : The argument at <position>, if in bounds, or an empty string
+# otherwise.
# Return:
# none.
# Usage:
# Arg <position>
# Example:
# Arg 3
-#
-#######################################################################
+###############################################################################
function Arg() {
if [ -z "$1" ]
@@ -323,8 +300,7 @@
fi
}
-#######################################################################
-#
+###############################################################################
# Name:
# Number_Of_Arguments
# Description:
@@ -337,16 +313,14 @@
# none.
# Usage:
# Number_Of_Arguments
-#
-#######################################################################
+###############################################################################
function Number_Of_Arguments() {
- # $0 isn't considered an argument
+ # $0 isn't considered an argument.
echo $[$argumentsListSize-1]
}
-#######################################################################
-#
+###############################################################################
# Name:
# Entry
# Description:
@@ -356,7 +330,7 @@
# Output:
# string : The option's value.
# Return:
-# 0 : The option exists.
+# 0 : The option exists with a value.
# 1 : The option exists without a value.
# 2 : The option doesn't exist.
# Usage:
@@ -365,21 +339,18 @@
# Entry "same"
# Example:
# Entry "s"
-#
-#######################################################################
+###############################################################################
function Entry() {
local i
-
- # Loop through options.
+ # Loop through available options.
for i in `seq $optionsListSize`
do
if [ "$1" = "${optionsShortList[i]}" -o "$1" = "${optionsLongList[i]}" ]
then
- # We've found the option we're looking for, either its
- # shortening or its full name.
- value="${optionsStateList[i]}"
-
+ # We've found the option we're looking for, either its shortening or
+ # its full name.
+ value="${optionsStateList[i]}"
if [ "$value" = "[EMAIL PROTECTED]@#" ]
then return 1
else
@@ -392,8 +363,7 @@
return 2
}
-#######################################################################
-#
+###############################################################################
# Name:
# Is_Entry_Set
# Description:
@@ -412,22 +382,19 @@
# Is_Entry_Set "same"
# Example:
# Is_Entry_Set "s"
-#
-#######################################################################
+###############################################################################
function Is_Entry_Set() {
- # Quiet suppresses output.
Quiet Entry "$@"
}
-#######################################################################
-#
+###############################################################################
# Name:
# Is_Entry
# Description:
-# Checks whether it exists an Entry option with the specified
-# name-value pair. The value can also be empty, in which case
-# the option just has to exist.
+# Checks whether it exists an Entry option with the specified name-value
+# pair. The value can also be empty, in which case the option just has
+# to exist.
# Arguments:
# option -- string : Option's name
# compare -- string : Option's value
@@ -443,34 +410,30 @@
# Is_Entry <option> [<compare>]
# Example:
# Is_Entry "same" "ask"
-#
# Example:
# Is_Entry "s" "ask"
-#
-#######################################################################
+###############################################################################
function Is_Entry() {
# Name the first two parameters 'option' and 'compare'.
Parameters "$@" option compare
-
+
local i
if Is_Empty "$compare"
then
- # We don't want the option's value to be compared. Just search
- # for an option with that name.
+ # We don't want the option's value to be compared. Just search for an
+ # option with that name.
Quiet Entry "$1"
return $?
fi
-
- # Loop through options.
+ # Loop through available options.
for i in `seq $optionsListSize`
do
if [ "$option" = "${optionsShortList[i]}" -o "$option" =
"${optionsLongList[i]}" ]
then
- # We've found the option we're looking for, either its
- # shortening or its full name.
- value="${optionsStateList[i]}"
-
+ # We've found the option we're looking for, either its shortening or
its
+ # full name.
+ value="${optionsStateList[i]}"
if [ "$value" = "$compare" ]
then return 0
else return 1
@@ -492,12 +455,11 @@
fi
}
-#######################################################################
-#
+###############################################################################
# Name:
# Boolean
# Description:
-# Checks if the specified boolean option exists and is active.
+# Checks if the specified Boolean option exists and is active.
# Arguments:
# name -- char/string : Option's shortening/full name
# Ouput:
@@ -510,19 +472,17 @@
# Boolean <name>
# Example:
# Boolean "no-web"
-#
-#######################################################################
+###############################################################################
function Boolean() {
local i
-
- # Loop through options.
+ # Loop through available options.
for i in `seq $optionsListSize`
do
if [ "$1" = "${optionsShortList[i]}" -o "$1" = "${optionsLongList[i]}" ]
then
- # We've found the option we're looking for, either its
- # shortening or its full name.
+ # We've found the option we're looking for, either its shortening or
+ # its full name.
if [ "${optionsStateList[i]}" = "on" ]
then return 0
else return 1
@@ -533,8 +493,7 @@
return 2
}
-#######################################################################
-#
+###############################################################################
# Name:
# Set_Boolean
# Description:
@@ -549,27 +508,25 @@
# 0 : The option was set correctly.
# 2 : The option doesn't exist.
# Notes:
-# Note that, in fact, every other string other than 'on' will be
-# interpreted as false by scripts.
+# Note that, in fact, every string other than 'on' will be interpreted as
+# false by scripts.
# Usage:
-# Set_Boolean [<value>]
+# Set_Boolean <name> [<value>]
# Example:
# Set_Boolean "batch" "on"
# Example:
# Set_Boolean "batch"
-#
-#######################################################################
+###############################################################################
function Set_Boolean() {
local i
-
- # Loop through options.
+ # Loop through available options.
for i in `seq $optionsListSize`
do
if [ "$1" = "${optionsShortList[i]}" -o "$1" = "${optionsLongList[i]}" ]
then
- # We've found the option we're looking for, either its
- # shortening or its full name.
+ # We've found the option we're looking for, either its shortening or
+ # its full name.
if [ "$2" ]
then optionsStateList[i]="$2"
else optionsStateList[i]="on"
@@ -581,8 +538,7 @@
return 2
}
-#######################################################################
-#
+###############################################################################
# Name:
# Show_Version
# Description:
@@ -590,25 +546,25 @@
# Arguments:
# none.
# Output:
-# string : A short "version" message, consisting of name, version
-# and credits for the script.
+# string : A short "version" message, consisting of name, version and
+# credits for the script.
# Return:
# none.
+# Notes:
+# Note that calling this function will cause the script to exit after
+# having printed the version message.
# Usage:
# Show_Version
-#
-#######################################################################
+###############################################################################
function Show_Version() {
echo "$scriptName $scriptVersion"
echo
- # Credits might not exist.
[ "$scriptCredits" ] && echo "$scriptCredits"
exit 0
}
-#######################################################################
-#
+###############################################################################
# Name:
# Show_Help
# Description:
@@ -619,19 +575,19 @@
# string : The script's help.
# Return:
# 0 : Everything went fine.
+# Notes:
+# Note that calling this function will cause the script to exit after
+# having printed the help message.
# Usage:
# Show_Help
-#
-#######################################################################
+###############################################################################
function Show_Help() {
{
local i
-
- # Use the right commands and format when the help must be
- # converted to man.
if [ "$HELP2MAN" ]
then
+ # Use the right formatting when the help must be converted to man.
local H2Mn=-n
local H2Mecho=echo
else
@@ -639,44 +595,36 @@
local H2Mtab=" "
local H2Mnotes="Notes:"
fi
-
- # Print out a little description for the script,
- # together with the usage.
+ # Print out a little description for the script, together with the usage.
[ "$scriptDescription" ] && echo "$scriptDescription"
echo
echo -e "Usage: $scriptName $scriptUsage"
echo
echo "Options:"
-
- # Loop through options.
+ # Loop through available options.
for i in `seq $optionsListSize`
do
- # Indent and print the shortening, if any.
echo -n " "
if [ ! -z "${optionsShortList[i]}" ]
then
echo -n " -${optionsShortList[i]}"
fi
-
# Put a comma to separate shortening and full name, if any.
if [ ! -z "${optionsShortList[i]}" -a ! -z "${optionsLongList[i]}" ]
then
echo -n ","
fi
-
- # Print the full name, if any.
+
if [ ! -z "${optionsLongList[i]}" ]
then
echo -n " --${optionsLongList[i]}"
fi
-
- # Different formats for different types of options.
+ # Different formatting for different types of options.
case "${optionsTypeList[i]}" in
"Entry")
echo $H2Mn " <entry>" # synopsis
echo -e " ${optionsDescriptionList[i]}" # description
-
- # Print out possible values, if any.
+
if [ -n "${optionsValidStateList[i]}" ]
then
echo -n " Valid entries are:"
@@ -686,8 +634,7 @@
done
echo
fi
-
- # Print out default value, if any.
+
if [ "${optionsStateList[i]}" != "[EMAIL PROTECTED]@#" ]
then
echo " The default value is '${optionsStateList[i]}'."
@@ -697,8 +644,7 @@
"List")
echo $H2Mn " <entry>[:<entry>...]" # synopsis
echo -e " ${optionsDescriptionList[i]}" # description
-
- # Print out default value, if any.
+
if [ "${optionsStateList[i]}" != "[EMAIL PROTECTED]@#" ]
then
echo " The default value is '${optionsStateList[i]}'."
@@ -713,16 +659,14 @@
esac # esac is ridiculous.
done
echo
-
- # Print out notes for this script, if any.
+
if [ "$scriptNotes" ]
then
echo "$H2Mnotes"
- echo "$H2Mtab$scriptNotes" # indentation
+ echo "$H2Mtab$scriptNotes"
echo
fi
-
- # Print out examples for this script, if any.
+
if [ "$scriptExample" ]
then
echo "Examples:"
@@ -731,12 +675,11 @@
echo -e "$scriptExample" | while read line; do echo -e
"$H2Mtab$scriptName $line"; done
echo
fi
- } | fmt -sw "$COLUMNS" # format the help to be displayed inside $COLUMNS
columns.
+ } | fmt -sw "$COLUMNS" # format the help to be displayed inside $COLUMNS
columns
exit 0
}
-#######################################################################
-#
+###############################################################################
# Name:
# List_Options
# Description:
@@ -748,10 +691,12 @@
# string : A list of the script's options.
# Return:
# 0 : Everything went fine.
+# Notes:
+# Note that calling this function will cause the script to exit after
+# having printed the list of options.
# Usage:
# List_Options
-#
-#######################################################################
+###############################################################################
function List_Options() {
local i
@@ -764,8 +709,7 @@
exit 0
}
-#######################################################################
-#
+###############################################################################
# Name:
# Get_Parsed_Options
# Description:
@@ -778,42 +722,46 @@
# none.
# Usage:
# Get_Parsed_Options
-#
-#######################################################################
+###############################################################################
function Get_Parsed_Options() {
echo "[EMAIL PROTECTED]"
}
-#######################################################################
-#
+###############################################################################
# Name:
# Parse_Options
# Description:
-# The actual parser. It parses options and arguments
-# passed when invoking a script.
+# The actual parser. It parses options and arguments passed when invoking
+# the script.
# Arguments:
-# $@ -- list : The list of parameters to be parsed, as passed to
-# the script.
+# <parameters> -- list : The list of parameters to be parsed, as passed
+# to the script. Normally you would pass [EMAIL PROTECTED]
# Output:
# none.
# Return:
-# 0 : Everything went fine.
-# 1 : Unknown option.
-# Usage:
-# Parse_Options "$@"
+# none.
+# Notes:
+# This function updates our arrays accordingly with the so far parsed
+# parameters, being they actual options or arguments. It doesn't hence
+# output or return anything.
+# However, some exit error codes can be passed over, in particular:
+#
+# 1, the option is not valid.
+# 2, the value assigned to the option is not valid.
#
-#######################################################################
+# Also note that every time an argument is found, the number of arguments
+# is exported.
+# Usage:
+# Parse_Options <parameters>
+###############################################################################
function Parse_Options() {
- # Make our array of arguments consistent with bash arrays numbering,
- # which starts from 0.
- # Otherwise parsedArguments[0] would be $1.
+ # Make our array of arguments consistent with bash arrays numbering, which
+ # starts from 0. Otherwise parsedArguments[0] would be $1.
Add_Argument "$0"
-
# Initially save all parameters as options.
savedOptions=("$@")
-
# Loop through parameters.
for (( i = 1; i <= $# ; i++ ))
do
@@ -821,15 +769,15 @@
eval option=\${${i}}
unknownOption=true
if [ "${option:0:1}" = "-" ]
- # We have a possible option (-<something>)
then
+ # We have a possible option (-<something>).
if [ "${option:1:1}" = "-" ]
- # A double dash, so it should be a long option (--<something>)
then
+ # A double dash, so it should be a long option (--<something>).
if [ -z "${option:2:1}" ]
then
- # It's a lonely double dash '--'. Take the rest as
- # arguments and stop parsing.
+ # It's a lonely double dash '--'. Take the rest as arguments
+ # and stop parsing.
for (( j = i+1; j <= $# ; j++ ))
do
eval option=\${${j}}
@@ -845,13 +793,12 @@
opt=${option}
fi
export parsedArguments=$[parsedArguments+1]
-
- # Loop through options.
+ # Loop through available options.
for j in `seq $optionsListSize`
do
if [ "$opt" = "--${optionsLongList[j]}" ]
then
- # We've found a valid (known) option
+ # We've found a valid (known) option.
unknownOption=false
case "${optionsTypeList[j]}" in
"Boolean")
@@ -886,30 +833,31 @@
Log_Error "Unknown entry '${val}' for option ${opt}"
exit 2
else
- # Whichever value is ok
+ # Whichever value is ok.
optionsStateList[j]="${val}"
fi
;;
esac
break
fi # valid option
- done # loop through options
-
+ done # loop through available options
+
if $unknownOption
then
Log_Error "Unknown option: $opt"
exit 1
fi
- else # double dash
-
+ else # short option
# This is basically the same as before.
-
- # Loop through short options.
+ # Loop through option's characters. This is needed to support
compressed
+ # options.
+ # Think of it working like `tar -xjvf file.tar.bz2`; x,j,v are
Boolean
+ # options that are enabled, f is an Entry item that eats the next
+ # parameter (and breaks from the loop over characters).
for (( k = 1; k < ${#option} ; k++ ))
do
unknownOption=true
opt=${option:$k:1} # the k-th character in the string
-
# Loop through available options.
for j in `seq $optionsListSize`
do
@@ -943,23 +891,27 @@
do
if [ "${avail}" == "${val}" ]
then
- # The value is valid, add it to the array.
+ # The value is valid, add it to the array and
+ # pass to the next parameter to be parsed.
optionsStateList[j]="${val}"
break 3
fi
done
- # The value's not valid, unfortunately.
+ # The value is not valid, unfortunately.
Log_Error "Unknown entry '${val}' for option ${opt}"
exit 2
else
+ # Whichever value is valid.
optionsStateList[j]="${val}"
+ # We've correctly recognized the option, so pass to
+ # the next parameter to be parsed.
break 2
fi
;;
esac
fi # valid option
- done # loop through options
-
+ done # loop through available options
+
if $unknownOption
then
Log_Error "Unknown option: -$opt"
@@ -967,13 +919,12 @@
fi
done
export parsedArguments=$[parsedArguments+1]
- fi # dash found
+ fi
else
# The parameter isn't an option.
Add_Argument "$option"
fi
done
-
# These options are common to every script, so check for them directly
# after parsing.
if Boolean "help"
_______________________________________________
gobolinux-devel mailing list
gobolinux-devel@lists.gobolinux.org
http://lists.gobolinux.org/mailman/listinfo/gobolinux-devel