libshell-0.0.6/000075500000000000000000000000001107536225200133145ustar00rootroot00000000000000libshell-0.0.6/COPYING000064400000000000000000000013631107536225200143520ustar00rootroot00000000000000The file shell-getopt Version 1.2 2008 by Alexey Gladkov , 2008 by Dmitry V. Levin Version 1.1 2004 by Raphael Version 1.0 1997 by Grigoriy Strokin (grg@philol.msu.ru), Public Domain The files shell-quote, shell-args are Copyright (C) 2007 Dmitry V. Levin , 2008 Alexey Gladkov The file shell-ini-config are Copyright (C) 2008 Stanislav Ievlev , 2008 Alexey Gladkov The files shell-version, shell-config, shell-error, shell-ip-address, shell-mail-address, shell-unittest, shell-signal are Copyright (C) 2008 Alexey Gladkov libshell-0.0.6/SYMS000064400000000000000000000024301107536225200140310ustar00rootroot00000000000000shell-args opt_check_dir shell-args opt_check_number shell-args opt_check_read shell-args parse_common_option shell-args print_version shell-args show_help shell-args show_usage shell-config shell_config_comment shell-config shell_config_del shell-config shell_config_get shell-config shell_config_set shell-error fatal shell-error message shell-error verbose shell-getopt getopt shell-getopt getoptex shell-getopt getopts shell-getopt getsubopt shell-ini-config ini_config_comment shell-ini-config ini_config_del shell-ini-config ini_config_get shell-ini-config ini_config_set shell-ip-address valid_ipv4 shell-mail-address valid_email shell-quote quote_sed_regexp shell-quote quote_shell shell-quote string_quote_remove shell-signal set_cleanup_handler shell-signal signal_handler shell-signal unset_cleanup_handler shell-unittest appendTests shell-unittest assertEquals shell-unittest assertFalse shell-unittest assertNotEquals shell-unittest assertNotNull shell-unittest assertNotSame shell-unittest assertNull shell-unittest assertSame shell-unittest assertTrue shell-unittest messageTest shell-unittest registerTests shell-unittest runUnitTests shell-unittest setUp shell-unittest setUpTests shell-unittest shouldSkip shell-unittest showSummary shell-unittest tearDown shell-unittest tearDownTests libshell-0.0.6/contrib/000075500000000000000000000000001107536225200147545ustar00rootroot00000000000000libshell-0.0.6/contrib/getoptx_1.0.bash000064400000000000000000000215741107536225200176740ustar00rootroot00000000000000#From: "Grigoriy Strokin" #Newsgroups: comp.unix.shell #Subject: BASH: getopt function that parses long-named options #Date: Mon, 22 Dec 1997 20:35:18 +0300 #Hi, I have written a BASH function named getoptex, that is like bash builtin #"getopts", but does parse long-named options and optional arguments. It only #uses builtin bash commands, so it is very fast. In order to use it in your #bash scripts, include a command ". getopt.sh" ( getopt.sh) to the file #containing your script, and that will define functions getopt, getoptex, and #optlistex (the file getopt.sh with its detailed description is listed #below). #*** file getopt.sh *** #! /bin/bash # # getopt.sh: # functions like getopts but do long-named options parsing # and support optional arguments # # Version 1.0 1997 by Grigoriy Strokin (grg@philol.msu.ru), Public Domain # Date created: December 21, 1997 # Date modified: December 21, 1997 # # IMPORTANT FEATURES # # 1) Parses both short and long-named options # 2) Supports optional arguments # 3) Only uses bash builtins, thus no calls to external # utilities such as expr or sed is done. Therefore, # parsing speed is high enough # # # DESCRIPTION # # FUNCTION getopt # Usage: getopt OPTLIST {"$@"|ALTERNATIVE_PARAMETERS} # # like getopts, but parse options with both required and optional arguments, # Options with optional arguments must have "." instead of ":" after them. # Furthemore, a variable name to place option name cannot be specified # and is always placed in OPTOPT variable # # This function is provided for compatibility with getopts() # OPTLIST style, and it actually calls getoptex (see bellow) # # NOTE that a list of parameters is required and must be either "$@", # if processing command line arguments, or some alternative parameters. # # FUNCTION getoptex # Usage: getoptex OPTION_LIST {"$@"|ALTERNATIVE_PARAMETERS} # # like getopts, but parse long-named options. # # Both getopt and getoptex return 0 if an option has been parsed, # and 1 if all options are already parsed or an error occured # # Both getopt and getoptex set or test the following variables: # # OPTERR -- tested for whether error messages must be given for invalid options # # OPTOPT -- set to the name of an option parsed, # or to "?" if no more options or error # OPTARG -- set to the option argument, if any; # unset if ther is no argument; # on error, set to the erroneous option name # # OPTIND -- Initialized to 1. # Then set to the number of the next parameter to be parsed # when getopt or getoptex will be called next time. # When all options are parsed, contains a number of # the first non-option argument. # # # OPTOFS -- If a parameter number $OPTIND containg an option parsed # does not contain any more options, OPTOFS is unset; # otherwise, OPTOFS is set to such a number of "?" signs # which is equal to the number of options parsed # # You might not set variables OPTIND and OPTOFS yourself # unless you want to parse a list of parameters more than once. # Otherwise, you whould unset OPTIND (or set it to 1) # and unset OPTOFS each time you want to parse a new parameters list # # Option list format is DIFFERENT from one for getopts or getopt. getopts-style # option list can be converted to getoptex-style using a function optlistex # (see bellow) # # DESCRIPTION of option list used with getoptex: # Option names are separated by whitespace. Options consiting of # more than one character are treated as long-named (--option) # # Special characters can appear at the and of option names specifying # whether an argument is required (default is ";"): # ";" (default) -- no argument # ":" -- required argument # "," -- optional argument # # For example, an option list "a b c help version f: file: separator." # defines the following options: # -a, -b, -c, --help, --version -- no argument # -f, --file -- argument required # --separator -- optional argument # # FUNCTION optlistex # Usage new_style_optlist=`optlistex OLD_STYLE_OPTLIST` # # Converts getopts-style option list in a format suitable for use with getoptex # Namely, it inserts spaces after each option name. # # # HOW TO USE # # In order o use in your bash scripts the functions described, # include a command ". getopt.sh" to the file containing the script, # which will define functions getopt, getoptex, and optlistex # # EXAMPLES # # See files 'getopt1' and 'getopt2' that contain sample scripts that use # getopt and getoptex functions respectively # # # Please send your comments to grg@philol.msu.ru function getoptex() { let $# || return 1 local optlist="${1#;}" let OPTIND || OPTIND=1 [ $OPTIND -lt $# ] || return 1 shift $OPTIND if [ "$1" != "-" ] && [ "$1" != "${1#-}" ] then OPTIND=$[OPTIND+1]; if [ "$1" != "--" ] then local o o="-${1#-$OPTOFS}" for opt in ${optlist#;} do OPTOPT="${opt%[;.:]}" unset OPTARG local opttype="${opt##*[^;:.]}" [ -z "$opttype" ] && opttype=";" if [ ${#OPTOPT} -gt 1 ] then # long-named option case $o in "--$OPTOPT") if [ "$opttype" != ":" ]; then return 0; fi OPTARG="$2" if [ -z "$OPTARG" ]; then # error: must have an agrument let OPTERR && echo "$0: error: $OPTOPT must have an argument" >&2 OPTARG="$OPTOPT"; OPTOPT="?" return 1; fi OPTIND=$[OPTIND+1] # skip option's argument return 0 ;; "--$OPTOPT="*) if [ "$opttype" = ";" ]; then # error: must not have arguments let OPTERR && echo "$0: error: $OPTOPT must not have arguments" >&2 OPTARG="$OPTOPT" OPTOPT="?" return 1 fi OPTARG=${o#"--$OPTOPT="} return 0 ;; esac else # short-named option case "$o" in "-$OPTOPT") unset OPTOFS [ "$opttype" != ":" ] && return 0 OPTARG="$2" if [ -z "$OPTARG" ] then echo "$0: error: -$OPTOPT must have an argument" >&2 OPTARG="$OPTOPT" OPTOPT="?" return 1 fi OPTIND=$[OPTIND+1] # skip option's argument return 0 ;; "-$OPTOPT"*) if [ $opttype = ";" ] then # an option with no argument is in a chain of options OPTOFS="$OPTOFS?" # move to the next option in the chain OPTIND=$[OPTIND-1] # the chain still has other options return 0 else unset OPTOFS OPTARG="${o#-$OPTOPT}" return 0 fi ;; esac fi done echo "$0: error: invalid option: $o" fi; fi OPTOPT="?" unset OPTARG return 1 } function optlistex { local l="$1" local m # mask local r # to store result while [ ${#m} -lt $[${#l}-1] ]; do m="$m?"; done # create a "???..." mask while [ -n "$l" ] do r="${r:+"$r "}${l%$m}" # append the first character of $l to $r l="${l#?}" # cut the first charecter from $l m="${m#?}" # cut one "?" sign from m if [ -n "${l%%[^:.;]*}" ] then # a special character (";", ".", or ":") was found r="$r${l%$m}" # append it to $r l="${l#?}" # cut the special character from l m="${m#?}" # cut one more "?" sign fi done echo $r } function getopt() { local optlist=`optlistex "$1"` shift getoptex "$optlist" "$@" return $? } #************************************** # cut here #************************************** #*** (end of getopt.sh) *** #*** file getopt1 *** #! /bin/bash # getopt1: # Sample script using the function getopt # # Type something like "getopt1 -ab -d 10 -e20 text1 text2" # on the command line to see how it works # # See getopt.sh for more information #. getopt.sh #echo Using getopt to parse arguments: #while getopt "abcd:e." "$@" #do # echo "Option <$OPTOPT> ${OPTARG:+has an arg <$OPTARG>}" #done #shift $[OPTIND-1] #for arg in "$@" #do # echo "Non option argument <$arg>" #done # #************************************** # cut here #************************************** #*** (end of getopt1) *** # # #*** file getopt2 *** # #! /bin/bash # getopt2: # Sample script using the function getoptex # # Type something like "getopt2 -ab -d 10 -e20 --opt1 --opt4=100 text1 text2" # to see how it works # # See getopt.sh for more information . getopt.sh #echo Using getoptex to parse arguments: #while getoptex "a; b; c; d: e. opt1 opt2 opt3 opt4: opt5." "$@" #do # echo "Option <$OPTOPT> ${OPTARG:+has an arg <$OPTARG>}" #done #shift $[OPTIND-1] #for arg in "$@" #do # echo "Non option argument <$arg>" #done # #************************************** # cut here #************************************** #*** (end of getopt2) *** libshell-0.0.6/contrib/getoptx_1.1.bash000064400000000000000000000171641107536225200176750ustar00rootroot00000000000000#! /bin/bash # # getopt.sh: # functions like getopts but do long-named options parsing # and support optional arguments # # Version 1.1 2004 by Raphael # Date modified: April 6, 2004 # Version 1.0 1997 by Grigoriy Strokin (grg@philol.msu.ru), Public Domain # Date created: December 21, 1997 # Date modified: December 21, 1997 # # UPDATE (by raphael) # # I found the routine wouldn't report option that need arguments right # if they where between or before other options. Rather it would take # the following option as the argument. The routine now checks if # the required argument starts with a dash '-' indicating that it is an # option. See source below. # # IMPORTANT FEATURES # # 1) Parses both short and long-named options # 2) Supports optional arguments # 3) Only uses bash builtins, thus no calls to external # utilities such as expr or sed is done. Therefore, # parsing speed is high enough # # # DESCRIPTION # # FUNCTION getopt # Usage: getopt OPTLIST {"$@"|ALTERNATIVE_PARAMETERS} # # like getopts, but parse options with both required and optional arguments, # Options with optional arguments must have "." instead of ":" after them. # Furthemore, a variable name to place option name cannot be specified # and is always placed in OPTOPT variable # # This function is provided for compatibility with getopts() # OPTLIST style, and it actually calls getoptex (see bellow) # # NOTE that a list of parameters is required and must be either "$@", # if processing command line arguments, or some alternative parameters. # # FUNCTION getoptex # Usage: getoptex OPTION_LIST {"$@"|ALTERNATIVE_PARAMETERS} # # like getopts, but parse long-named options. # # Both getopt and getoptex return 0 if an option has been parsed, # and 1 if all options are already parsed or an error occured # # Both getopt and getoptex set or test the following variables: # # OPTERR -- tested for whether error messages must be given for invalid options # # OPTOPT -- set to the name of an option parsed, # or to "?" if no more options or error # OPTARG -- set to the option argument, if any; # unset if ther is no argument; # on error, set to the erroneous option name # # OPTIND -- Initialized to 1. # Then set to the number of the next parameter to be parsed # when getopt or getoptex will be called next time. # When all options are parsed, contains a number of # the first non-option argument. # # # OPTOFS -- If a parameter number $OPTIND containg an option parsed # does not contain any more options, OPTOFS is unset; # otherwise, OPTOFS is set to such a number of "?" signs # which is equal to the number of options parsed # # You might not set variables OPTIND and OPTOFS yourself # unless you want to parse a list of parameters more than once. # Otherwise, you whould unset OPTIND (or set it to 1) # and unset OPTOFS each time you want to parse a new parameters list # # Option list format is DIFFERENT from one for getopts or getopt. getopts-style # option list can be converted to getoptex-style using a function optlistex # (see bellow) # # DESCRIPTION of option list used with getoptex: # Option names are separated by whitespace. Options consiting of # more than one character are treated as long-named (--option) # # Special characters can appear at the and of option names specifying # whether an argument is required (default is ";"): # ";" (default) -- no argument # ":" -- required argument # "," -- optional argument # # For example, an option list "a b c help version f: file: separator." # defines the following options: # -a, -b, -c, --help, --version -- no argument # -f, --file -- argument required # --separator -- optional argument # # FUNCTION optlistex # Usage new_style_optlist=`optlistex OLD_STYLE_OPTLIST` # # Converts getopts-style option list in a format suitable for use with getoptex # Namely, it inserts spaces after each option name. # # # HOW TO USE # # In order o use in your bash scripts the functions described, # include a command ". getopt.sh" to the file containing the script, # which will define functions getopt, getoptex, and optlistex # # EXAMPLES # # See files 'getopt1' and 'getopt2' that contain sample scripts that use # getopt and getoptex functions respectively # # # Please send your comments to grg@philol.msu.ru function getoptex() { let $# || return 1 local optlist="${1#;}" let OPTIND || OPTIND=1 [ $OPTIND -lt $# ] || return 1 shift $OPTIND if [ "$1" != "-" -a "$1" != "${1#-}" ] then OPTIND=$[OPTIND+1]; if [ "$1" != "--" ] then local o o="-${1#-$OPTOFS}" for opt in ${optlist#;} do OPTOPT="${opt%[;.:]}" unset OPTARG local opttype="${opt##*[^;:.]}" [ -z "$opttype" ] && opttype=";" if [ ${#OPTOPT} -gt 1 ] then # long-named option case $o in "--$OPTOPT") if [ "$opttype" != ":" ]; then return 0; fi OPTARG="$2" # Added test on following argument being an option identified by '-' this way # # the routine no longer takes options as an argument thus breaking error # # detection. 2004-04-04 by raphael at oninet dot pt # if [ -z "$OPTARG" -o "${OPTARG:0:1}" = "-" ] ; then # error: must have an agrument let OPTERR && echo "$0: error: $OPTOPT must have an argument" >&2 OPTARG="$OPTOPT"; OPTOPT="?" return 1; fi OPTIND=$[OPTIND+1] # skip option's argument return 0 ;; "--$OPTOPT="*) if [ "$opttype" = ";" ]; then # error: must not have arguments let OPTERR && echo "$0: error: $OPTOPT must not have arguments" >&2 OPTARG="$OPTOPT" OPTOPT="?" return 1 fi OPTARG=${o#"--$OPTOPT="} return 0 ;; esac else # short-named option case "$o" in "-$OPTOPT") unset OPTOFS [ "$opttype" != ":" ] && return 0 OPTARG="$2" # Added test on following argument being an option identified by '-' this way # # the routine no longer takes options as an argument thus breaking error # # detection. 2004-04-04 by raphael at oninet dot pt # if [ -z "$OPTARG" -o "${OPTARG:0:1}" = "-" ] ; then echo "$0: error: -$OPTOPT must have an argument" >&2 OPTARG="$OPTOPT" OPTOPT="?" return 1 fi OPTIND=$[OPTIND+1] # skip option's argument return 0 ;; "-$OPTOPT"*) if [ $opttype = ";" ] then # an option with no argument is in a chain of options OPTOFS="$OPTOFS?" # move to the next option in the chain OPTIND=$[OPTIND-1] # the chain still has other options return 0 else unset OPTOFS OPTARG="${o#-$OPTOPT}" return 0 fi ;; esac fi done echo "$0: error: invalid option: $o" fi; fi OPTOPT="?" unset OPTARG return 1 } function optlistex { local l="$1" local m # mask local r # to store result while [ ${#m} -lt $[${#l}-1] ]; do m="$m?"; done # create a "???..." mask while [ -n "$l" ] do r="${r:+"$r "}${l%$m}" # append the first character of $l to $r l="${l#?}" # cut the first charecter from $l m="${m#?}" # cut one "?" sign from m if [ -n "${l%%[^:.;]*}" ] then # a special character (";", ".", or ":") was found r="$r${l%$m}" # append it to $r l="${l#?}" # cut the special character from l m="${m#?}" # cut one more "?" sign fi done echo $r } function getopt() { local optlist=`optlistex "$1"` shift getoptex "$optlist" "$@" return $? } libshell-0.0.6/shell-args000064400000000000000000000032501107536225200153000ustar00rootroot00000000000000#!/bin/sh -efu if [ -z "${__included_shell_args-}" ]; then __included_shell_args=1 . shell-error # Checks that given option value is a readable file. # Arguments: $1 is option name, $2 is option value. # If $2 is a readable file, outputs canonicalized file name, # otherwise fails. opt_check_read() { local value [ -r "$2" ] && value="$(readlink -ev "$2")" || fatal "$1: $2: file not available." printf %s "$value" } # Checks that given option value is a traversable directory. # Arguments: $1 is option name, $2 is option value. # If $2 is a readable file, outputs canonicalized directory name, # otherwise fails. opt_check_dir() { local value [ -d "$2" -a -x "$2" ] && value="$(readlink -ev "$2")" || fatal "$1: $2: directory not available." printf %s "$value" } # Checks that given option value is a positive decimal number. # Arguments: $1 is option name, $2 is option value. # If $2 is a positive decimal number, outputs it, otherwise fails. opt_check_number() { [ -n "${2##0*}" -a -n "${2##*[!0-9]*}" ] && [ "$2" -gt 0 ] 2>/dev/null || fatal "$1: $2: invalid number." printf %s "$2" } show_usage() { [ -z "$*" ] || message "$*" echo "Try \`$PROG --help' for more information." >&2 exit 1 } show_help() { fatal "show_help(): Undefined function" } print_version() { fatal "print_version() Undefined function" } readonly getopt_common_opts="q,v,V,h" readonly getopt_common_longopts="quiet,verbose,version,help" parse_common_option() { case "$1" in -h|--help) show_help ;; -q|--quiet) quiet=-q ;; -v|--verbose) verbose=-v; quiet= ;; -V|--version) print_version "$PROG" ;; *) fatal "Unrecognized option: $1" ;; esac } fi #__included_shell_args libshell-0.0.6/shell-config000064400000000000000000000040521107536225200156120ustar00rootroot00000000000000#!/bin/sh -efu if [ -z "${__included_shell_config-}" ]; then __included_shell_config=1 . shell-error . shell-quote __shell_config_comment='#' shell_config_get() { [ "$#" -ge 2 -a "$#" -le 3 ] || fatal "Usage: shell_config_get file name [delim]" local file="$1" name="$2" delim="${3-=}" [ -s "$file" ] || return 0 name="$(quote_sed_regexp "$name")" sed -n -e "s/^[[:space:]]*$name$delim//p" -- "$file" } shell_config_set() { [ "$#" -ge 3 -a "$#" -le 5 ] || fatal "Usage: shell_config_set file name value [read-delim [write-delim]]" local file="$1" name="$2" value="$3" r_delim="${4-=}" w_delim="${5-=}" local n v nv= created= if [ ! -f "$file" ]; then if [ ! -w "${file%/*}" ]; then message "${file%/*}: not writable." return 1 fi touch -- "$file" || return 1 created=1 fi if [ -z "$created" ]; then n="$(quote_sed_regexp "$name")" if v="$(grep -m1 "^[[:space:]]*$n$r_delim" -- "$file" 2>/dev/null)"; then if [ "${v#*$name$r_delim}" != "$value" ]; then nv="$(quote_sed_regexp "$w_delim$value")" sed -i -e "s/^[[:space:]]*$n$r_delim.*/$n$nv/" -- "$file" fi return fi if [ -n "${__shell_config_comment-}" ] && v="$(grep -m1 "^[[:space:]]*${__shell_config_comment:-#}[[:space:]]*$n$r_delim" -- "$file" 2>/dev/null)"; then v="$(quote_sed_regexp "$v")" nv="$(quote_sed_regexp "$w_delim$value")" sed -i -e "s/^$v\$/$n$nv/" -- "$file" return fi fi printf '%s\n' "$name$w_delim$value" >> "$file" } shell_config_del() { [ "$#" -ge 2 -a "$#" -le 3 ] || fatal "Usage: shell_config_del file name [delim]" local file="$1" name="$2" delim="${3-=}" [ -s "$file" ] || return 0 name="$(quote_sed_regexp "$name")" sed -i -e "/^[[:space:]]*$name$delim/d" -- "$file" } shell_config_comment() { [ "$#" -ge 2 -a "$#" -le 3 ] || fatal "Usage: shell_config_comment file name [delim]" local file="$1" name="$2" delim="${3-=}" [ -s "$file" ] || return 0 name="$(quote_sed_regexp "$name")" sed -i -e "s/^[[:space:]]*$name$delim.*/${__shell_config_comment:-#}&/" -- "$file" } fi #__included_shell_config libshell-0.0.6/shell-error000064400000000000000000000005001107536225200154700ustar00rootroot00000000000000#!/bin/sh -efu if [ -z "${__included_shell_error-}" ]; then __included_shell_error=1 PROG="${PROG:-${0##*/}}" message() { printf %s\\n "$PROG: $*" >&2 } fatal() { message "$@" exit 1 } quiet="${quiet-}" verbose="${verbose-}" verbose() { [ -n "$verbose" ] || return 0 message "$@" } fi #__included_shell_error libshell-0.0.6/shell-getopt000064400000000000000000000210331107536225200156450ustar00rootroot00000000000000#! /bin/sh -efu if [ -z "${__included_shell_getopt-}" ]; then __included_shell_getopt=1 . shell-error . shell-quote # Ignore unknown options. GETOPT_ALLOW_UNKNOWN= # Long options may be abbreviated, as long as the abbreviation is not ambiguous. GETOPT_ALLOW_ABBREV=1 # Allow long options to start with a single ‘-’. See (getopt -a). GETOPT_ALLOW_ALTERNATIVE= OPTERR=1 OPTTYP= OPTUKN= OPTOPT= OPTARG= OPTIND=1 OPTOFS= #*** Example *** ### Usage: getopt2 -ab -d 10 -e20 --opt1 --opt4=100 text1 text2 ### # . shell-getopt # echo Using getoptex to parse arguments: # while getoptex "a; b; c; d: e. opt1 opt2 opt3 opt4: opt5." "$@"; do # echo "Option <$OPTOPT> ${OPTARG:+has an arg <$OPTARG>}" # done # shift $(($OPTIND-1)) # set -- $@ ${OPTUKN-} # for arg in "$@"; do # echo "Non option argument <$arg>" # done getoptex() { [ "$#" -gt 0 ] || return 1 [ "${OPTIND-}" -gt 0 ] 2>/dev/null || OPTIND=1 [ "$OPTIND" -lt "$#" ] || return 1 getoptex_badarg() { [ -z "${OPTERR-}" ] || message "option requires an argument -- $OPTOPT" OPTARG="$OPTOPT" OPTOPT='?' } getoptex_argument() { [ "$OPTTYP" = ':' ] || return 0 OPTARG="$1" # Added test on following argument being an option identified by '-' this way # # the routine no longer takes options as an argument thus breaking error # # detection. 2004-04-04 by raphael at oninet dot pt # [ -n "$OPTARG" -a -n "${OPTARG%%-*}" ] || { getoptex_badarg; return 1; } OPTARG="${1#\#}" OPTIND=$(($OPTIND+1)) # skip option's argument } getoptex_option_long() { local arg="$1" v p for p in '--' ${GETOPT_ALLOW_ALTERNATIVE:+'-'}; do if [ -n "${GETOPT_ALLOW_ABBREV-}" ]; then arg="${1%%=*}" v="${1#*=}" o="$p$OPTOPT" if [ -z "${o##$arg*}" ]; then [ "$arg" != "$v" ] && arg="$o=$v" || arg="$o" unset o v fi fi case "$arg" in $p$OPTOPT=*) [ -n "$OPTTYP" ] || { getoptex_badarg; return 3; } OPTARG="${arg#$p$OPTOPT=}" return 1 ;; $p$OPTOPT) getoptex_argument "$2" || return 3 return 1 ;; esac done } getoptex_option_short() { local o="-${1#-${OPTOFS-}}" case "$o" in -$OPTOPT) OPTOFS= getoptex_argument "$2" || return 3 return 1 ;; -$OPTOPT*) if [ -z "$OPTTYP" ]; then # an option with no argument is in a chain of options OPTOFS="${OPTOFS-}?" # move to the next option in the chain OPTIND=$(($OPTIND-1)) # the chain still has other options else OPTOFS= OPTARG="${o#-$OPTOPT}" fi return 1 ;; esac } local optlist="${1#;}" value= shift $OPTIND [ "$#" -lt 2 ] || value="#$2" OPTTYP= # test whether $1 is an option. if [ "$1" = '--' ]; then OPTTYP='--' OPTIND=$(($OPTIND+1)) elif [ "$1" != '-' -a "$1" != "${1#-}" ]; then OPTIND=$(($OPTIND+1)) local cmd argtype for opt in $optlist; do OPTOPT="${opt%[;.:]}" OPTARG= OPTTYP= [ "$OPTTYP" = ';' ] || OPTTYP="${opt#$OPTOPT}" cmd=long [ "${#OPTOPT}" -gt 1 ] || cmd=short getoptex_option_$cmd "$1" "$value" || return $(($?-1)) done OPTOPT='?' OPTARG= if [ -n "${GETOPT_ALLOW_UNKNOWN-}" ]; then OPTUKN="${OPTUKN:+$OPTUKN } \"$(quote_shell "$1")\"" return 0 fi message "unrecognized option \`$1'" return 2 fi OPTOPT='?' OPTARG= return 1 } #*** Example *** ### Usage: getopt1 -ab -d 10 -e20 text1 text2 ### # . shell-getopt # echo "Using getopt to parse arguments:" # while getopts "abcd:e." "$@"; do # echo "Option <$OPTOPT> ${OPTARG:+has an arg <$OPTARG>}" # done # shift $(($OPTIND-1)) # set -- $@ ${OPTUKN-} # for arg in "$@"; do # echo "Non option argument <$arg>" # done getopts() { local l="$1" local m= # mask local r= # to store result while [ ${#m} -lt $((${#l}-1)) ]; do m="$m?" done # create a "???..." mask while [ -n "$l" ]; do r="${r:+"$r "}${l%$m}" # append the first character of $l to $r l="${l#?}" # cut the first charecter from $l m="${m#?}" # cut one "?" sign from m if [ "${l#[:.;]}" != "$l" ]; then # a special character (";", ".", or ":") was found r="$r${l%$m}" # append it to $r l="${l#?}" # cut the special character from l m="${m#?}" # cut one more "?" sign fi done shift getoptex "$r" "$@" || return $? } #*** Example *** # . shell-getopt # while getsubopt 'rw mode: path: dev:' 'rw,mode=755,path="/zzz xxx",dev=/dev/zzz'; do # echo "Option <$OPTOPT> ${OPTARG:+has an arg <$OPTARG>}" # done __getsubopt_arguments= getsubopt() { local l="$2" if [ -z "$__getsubopt_arguments" ]; then local ch m= while [ ${#m} -lt $((${#l}-1)) ]; do m="$m?" done __getsubopt_arguments='--' while [ -n "$l" ]; do ch="${l%$m}" l="${l#?}" m="${m#?}" case "$ch" in ,) ch=' --' ;; [\\\\\`\$\"\ ]) ch="\\$ch" ;; esac __getsubopt_arguments="$__getsubopt_arguments$ch" done fi local GETOPT_ALLOW_ABBREV= eval getoptex "\"$1\"" "$__getsubopt_arguments" || return $? } . shell-version GETOPT_POSIXLY_CORRECT= getopt() { __getopt_version() { cat <<-EOF $PROG version $libshell_version Written by Alexey Gladkov Copyright (C) 2008 Alexey Gladkov This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. EOF } __getopt_usage() { cat <<-EOF Try \`$PROG --help' for more information. EOF } __getopt_help() { cat <<-EOF Usage: $PROG optstring parameters or: $PROG [options] [--] optstring parameters or: $PROG [options] -o|--options optstring [options] [--] parameters Options ignored: -s, --shell=shell Set shell quoting conventions; -u, --unqote Do not quote the output; Options: -a, --alternative Allow long options starting with single -; -l, --longoptions=longopts Long options to be recognized; -n, --name=progname The name under which errors are reported; -o, --options=optstring Short options to be recognized; -q, --quiet Disable error reporting; -Q, --quiet-output No normal output; -T, --test Test for getopt version; -V, --version Output version information; -h, --help This small usage guide. Report bugs to http://bugzilla.altlinux.org/ EOF } local PROG='getopt' OPTERR=1 prg= opts= lopts= quiet_output= alt= order= rc local GETOPT_POSIXLY_CORRECT while getoptex 'a alternative h help l: longoptions: n: name: o: options: q quiet Q quiet-output s shell T test u unquoted V version' "$@" && rc=0 || rc=$?; do case "$rc" in 2) __getopt_usage; return 2 ;; 1) break ;; esac case "$OPTOPT" in a|alternative) alt=1 ;; n|name) prg="$OPTARG" ;; o|options) opts="$OPTARG " ;; l|longoptions) lopts="$OPTARG" ;; q|quiet) OPTERR= ;; Q|quiet-output) quiet_output=1 ;; T|test) return 4 ;; V|version) __getopt_version return 0 ;; h|help) __getopt_help return 2 ;; esac done shift $(($OPTIND-1)) set -- "$@" if [ -z "${opts##+*}" ]; then opts="${opts#+}" GETOPT_POSIXLY_CORRECT=1 elif [ -z "${opts##-*}" ]; then opts="${opts#-}" order=1 fi if [ -z "$opts" ]; then if [ "$#" -gt 1 -a "${1#-}" = "$1" -a "$1" != '--' ]; then opts="$1" shift else message "$PROG: missing optstring argument" __getopt_usage return 2 fi fi opts="${lopts:+$lopts,}$opts" while :; do case "$opts" in *,*) opts="${opts%%,*} ${opts#*,}" ;; *::*) opts="${opts%%::*}.${opts#*::}" ;; *) break ;; esac done local OPTIND=1 OPTOFS= GETOPT_ALLOW_ALTERNATIVE="${alt:+1}" local ret=0 out=' -- ' ! printenv POSIXLY_CORRECT >/dev/null 2>&1 || GETOPT_POSIXLY_CORRECT=1 __getopt_out_arg() { shift $(($OPTIND-1)) [ -z "$order" ] && out="${out%% -- *} -- ${out#* -- } \"$(quote_shell "$1")\"" || out="${out%% -- *} \"$(quote_shell "$1")\" -- ${out#* -- }" } PROG="$prg" while getoptex "$opts" "$@" && rc=0 || rc=$?; do case "$rc" in 1) [ $# -ge $OPTIND -a -z "${GETOPT_POSIXLY_CORRECT-}" ] || break __getopt_out_arg "$@" OPTIND=$(($OPTIND+1)) [ "$OPTTYP" != '--' ] || break continue ;; 2) ret=1 ;; esac [ "$OPTOPT" != '?' ] || continue pfx='-' [ "${#OPTOPT}" -eq 1 ] || pfx='--' out="${out%% -- *} $pfx$OPTOPT ${OPTTYP:+'$OPTARG'} -- ${out#* -- }" done shift $(($OPTIND-1)) set -- "$@" while [ "$#" -gt 0 ]; do out="${out%% -- *} -- ${out#* -- } \"$(quote_shell "$1")\"" shift done [ -n "$quiet_output" ] || printf '%s\n' "$out${OPTUKN:+$OPTUKN}" return $ret } fi #__included_shell_getopt libshell-0.0.6/shell-ini-config000064400000000000000000000053741107536225200163770ustar00rootroot00000000000000#!/bin/sh -efu if [ -z "${__included_shell_ini_config-}" ]; then __included_shell_ini_config=1 shell_ini_config_rdelim='[[:space:]]*=[[:space:]]*' shell_ini_config_wdelim=' = ' shell_ini_config_comment='# ' shell_ini_config_lbegin='^[[:space:]]*' shell_ini_config_sbegin="$shell_ini_config_lbegin\[" shell_ini_config_send='\]' . shell-quote ini_config_get() { [ "$#" -eq 3 ] || fatal 'Usage: ini_config_get file section name' local fn section name fn="$1" section="$(quote_sed_regexp "$2")" name="$(quote_sed_regexp "$3")" sed -n -e "/$shell_ini_config_sbegin$section$shell_ini_config_send/,/$shell_ini_config_sbegin/ s/$shell_ini_config_lbegin$name$shell_ini_config_rdelim\(.*\)/\1/p" \ "$fn" } ini_config_set() { [ "$#" -eq 4 ] || fatal 'Usage: ini_config_set file section name value' local fn section name value fn="$1" section="$(quote_sed_regexp "$2")" name="$(quote_sed_regexp "$3")" value="$(quote_sed_regexp "$4")" sed -i -e \ "/$shell_ini_config_sbegin$section$shell_ini_config_send/ { :loop n /$shell_ini_config_lbegin$name$shell_ini_config_rdelim/ { s/\($shell_ini_config_lbegin$name\)$shell_ini_config_rdelim.*/\1$shell_ini_config_wdelim$value/ b end } /$shell_ini_config_sbegin/ { i \ $name$shell_ini_config_wdelim$value b end } \$! b loop \$ a \ $name$shell_ini_config_wdelim$value :end }" \ "$fn" } ini_config_del() { [ "$#" -ge 2 -a "$#" -le 3 ] || fatal 'Usage: ini_config_del file section [name]' local fn section name= fn="$1" section="$(quote_sed_regexp "$2")" [ -z "${3-}" ] || name="$(quote_sed_regexp "$3")" if [ -n "$name" ];then sed -i -e "/$shell_ini_config_sbegin$section$shell_ini_config_send/,/$shell_ini_config_sbegin/ {/$shell_ini_config_lbegin$name$shell_ini_config_rdelim/ d}" \ "$fn" else sed -i -e "/$shell_ini_config_sbegin$section$shell_ini_config_send/,/$shell_ini_config_sbegin/ {/$shell_ini_config_sbegin$section$shell_ini_config_send/ d;/$shell_ini_config_sbegin/! d}" \ "$fn" fi } ini_config_comment() { [ "$#" -ge 2 -a "$#" -le 3 ] || fatal 'Usage: ini_config_comment file section [name]' local fn section name= fn="$1" section="$(quote_sed_regexp "$2")" [ -z "${3-}" ] || name="$(quote_sed_regexp "$3")" if [ -n "$name" ];then sed -i -e "/$shell_ini_config_sbegin$section$shell_ini_config_send/,/$shell_ini_config_sbegin/ { s/$shell_ini_config_lbegin$name$shell_ini_config_rdelim/$shell_ini_config_comment&/ }" \ "$fn" else sed -i -e "/$shell_ini_config_sbegin$section$shell_ini_config_send/,/$shell_ini_config_sbegin/ { /$shell_ini_config_sbegin/! s/^.*/$shell_ini_config_comment&/; s/$shell_ini_config_sbegin$section$shell_ini_config_send/$shell_ini_config_comment&/}" \ "$fn" fi } fi #__included_shell_ini_config libshell-0.0.6/shell-ip-address000064400000000000000000000031221107536225200163750ustar00rootroot00000000000000#!/bin/sh -efu if [ -z "${__included_shell_ip_address-}" ]; then __included_shell_ip_address=1 # Regexp for single byte readonly regex_byte='([01]?[0-9][0-9]?|2[0-4][0-9]|25[0-5])' # Regexp for 4-byte address readonly regex_ipaddr="$regexp_byte(\.$regexp_byte){3}" # Regexp for IPv4 address # # (http://en.wikipedia.org/wiki/IP_address) # # Some first-octet values have special meanings: # # * First octet 127 represents the local computer, regardless of what network # it is really in. This is useful when testing internal operations. # # * First octet 224 and above are reserved for special purposes such as # multicasting. # # Octets 0 and 255 are not acceptable values in some situations, but 0 can be used # as the second and/or third octet (e.g. 10.2.0.100). # readonly __regex_fbyte='([1-9][0-9]?|1[0-9][0-9]|2[01][0-9]|22[0-3])' readonly __regex_sbyte='([1]?[0-9][0-9]?|2[0-4][0-9]|25[0-4])' readonly __regex_lbyte='([1]?[0-9][0-9]?|2[0-4][0-9]|25[0-4])' readonly regex_ipv4="${__regex_fbyte}(\.${__regex_sbyte}){2}\.${__regex_lbyte}" # Checks that given option value is a valid IPv4 address. valid_ipv4() { local ipaddr="$1" local i=0 byte byte="${ipaddr##*.}" ipaddr="${ipaddr%.$byte}" [ "$byte" -gt 0 -a "$byte" -lt 255 ] 2>/dev/null || return 1 while [ $i -lt 3 ]; do byte="${ipaddr##*.}" [ "$byte" != "$ipaddr" ] || break ipaddr="${ipaddr%.$byte}" [ "$byte" -ge 0 -a "$byte" -lt 255 ] 2>/dev/null || return 1 i=$(($i+1)) done [ $i -eq 2 -a \ "$byte" -ne 127 -a "$byte" -gt 0 -a "$byte" -lt 224 ] 2>/dev/null || return 1 } fi #__included_shell_ip_address libshell-0.0.6/shell-mail-address000064400000000000000000000047201107536225200167140ustar00rootroot00000000000000#!/bin/sh -efu if [ -z "${__included_shell_mail_address-}" ]; then __included_shell_mail_address=1 if [ -n "${shell_mail_address_strict-}" ]; then # # (http://en.wikipedia.org/wiki/Country_code_top-level_domain) # # A country code top-level domain (ccTLD) is an Internet top-level domain # generally used or reserved for a country or a dependent territory. # readonly regex_cctld_active='(a[cdefgilmnoqrstuwxz]|b[abdefghijmnorstwyz]|c[acdfghiklmnoruvxyz]|d[ejkmoz]|e[cegrstu]|f[ijkmor]|g[adefghilmnpqrstuwy]|h[kmnrtu]|i[delmnoqrst]|j[emop]|k[eghimnprwyz]|l[abcikrstuvy]|m[acdeghklmnopqrstuvwxyz]|n[acefgilopruz]|om|p[aefghklnrstwy]|qa|r[eosuw]|s[abcdeghiklmnrtuvyz]|t[cdfghjklmnortvwz]|u[agksyz]|v[aceginu]|w[fs]|ye|z[amw])' readonly regex_cctld_reserved='(um|bl|eh|mf)' readonly regex_cctld_allocated='(bv|gb|pm|sj|so|yt)' readonly regex_cctld_phaseout='(tp|yu)' readonly regex_cctld_deleted='(cs|dd|zr)' # (http://en.wikipedia.org/wiki/GTLD) # # A generic top-level domain (gTLD) is a top-level domain used by a # particular class of organization. # readonly regex_gtld='(aero|arpa|asia|biz|cat|com|coop|edu|gov|info|int|jobs|mil|mobi|museum|name|net|org|pro|tel|travel)' regex_tld="($regex_gtld|$regex_cctld_active|$regex_cctld_reserved|$regex_cctld_allocated|$regex_cctld_phaseout)" else regex_tld='([a-zA-Z]{2,4}|museum)' fi # 6. ADDRESS SPECIFICATION (http://tools.ietf.org/html/rfc822) # # addr-spec = local-part "@" domain ; global address # local-part = word *("." word) ; uninterpreted # ; case-preserved # domain = sub-domain *("." sub-domain) # sub-domain = domain-ref / domain-literal # domain-ref = atom ; symbolic reference # # 6.2.3. DOMAIN TERMS # A domain-ref must be THE official name of a registry, network, # or host. # This regexp should be used ignoring case. readonly regex_domain="([a-zA-Z0-9-]+(\.[a-zA-Z0-9-]+)*)\.$regex_tld" # Regexp can be used to check and parse email address. This regexp # should be used ignoring case. # Usage example: # username="$(printf '%s' "$email" |sed -e "s/^$regex_email\$/\1/i") # domain="$(printf '%s' "$email" |sed -e "s/^$regex_email\$/\2/i") # readonly regex_email="([_a-zA-Z0-9-]+(\.[_a-zA-Z0-9-]+)*)@($regex_domain)" # Checks that given option value is a valid email address. valid_email() { local email="$1" printf '%s' "$email" | egrep -iqs "^$regex_email\$" || return 1 } fi #__included_shell_mail_address libshell-0.0.6/shell-quote000064400000000000000000000020711107536225200155010ustar00rootroot00000000000000#!/bin/sh -efu if [ -z "${__included_shell_quote-}" ]; then __included_shell_quote=1 # Quote given arguments for sed basic regular expression. # Usage example: sed "s/$(quote_sed_regexp "$var_pattern")/$(quote_sed_regexp "$var_replacement")/" quote_sed_regexp() { local out="$*" if [ -z "${out##*[\[\].*&^\$\\\\/]*}" ]; then out="$(printf %s "$out" |sed -e 's/[].*&^$[\/]/\\&/g')" || return 1 fi printf %s "$out" } # Quote argument for shell. # Usage example: eval "$var_name=\"$(quote_shell "$var_value")\"" quote_shell() { local out="$*" if [ -z "${out##*[\"\$\`\\\\]*}" ]; then out="$(printf %s "$out" |sed -e 's/["$`\\]/\\&/g')" || return 1 fi printf %s "$out" } # Remove quote symbol from string # Usage example: for i in "\"str1\"" "'str2'" "\"str3'"; do echo "$(string_quote_remove "$i")"; done # str1 # str2 # "str3' string_quote_remove() { local out="$1" if [ -z "${1##*'}${1%%'*}" ]; then out="${1#'}" out="${out%'}" elif [ -z "${1##*\"}${1%%\"*}" ]; then out="${1#\"}" out="${out%\"}" fi printf %s "$out" } fi #__included_shell_quote libshell-0.0.6/shell-regexp000077700000000000000000000000001107536225200200202shell-quoteustar00rootroot00000000000000libshell-0.0.6/shell-signal000064400000000000000000000035241107536225200156250ustar00rootroot00000000000000#!/bin/sh -efu if [ -z "${__included_shell_signal-}" ]; then __included_shell_signal=1 if [ -n "${__libshell_experimental-}" ]; then . shell-error . shell-quote __shell_signal_handlers= # Set handler code whan any of the specified signals are received. # Special handlers is SIG_IGN and SIG_DFL (See signal(2)). # Usage example: # signal_handler 'echo $rc' TERM EXIT HUP # signal_handler SIG_IGN TERM EXIT HUP # signal_handler SIG_DFL TERM EXIT HUP signal_handler() { act="$1" shift __shell_signal_handler() { local s rc=$? sign="$1" eval set -- ${__shell_signal_handlers-} for s; do [ -n "${s##$sign:*}" ] || eval ${s#$sign:} $rc ||: done } __shell_signal_append() { local s arg="$1" eval set -- ${__shell_signal_handlers-} for s; do [ "$s" != "$arg" ] || return 0 done __shell_signal_handlers="$__shell_signal_handlers $arg" } __shell_signal_remove() { local s nlist= sign="$1" eval set -- ${__shell_signal_handlers-} for s; do [ -z "${s##$sign:*}" ] || nlist="$nlist $s" done __shell_signal_handlers="$nlist" } for sign; do case "$act" in SIG_IGN) __shell_signal_remove "$sign" act=: ;; SIG_DFL) __shell_signal_remove "$sign" act=- ;; *) act="$(quote_shell "$act")" __shell_signal_append "\"$sign:$act\"" act="__shell_signal_handler $sign" ;; esac trap "$act" $sign done } __cleanup_handler_name= set_cleanup_handler() { __cleanup_handler_name="${1-}" __cleanup_handler() { trap - EXIT [ -z "${__cleanup_handler_name-}" ] || "$__cleanup_handler_name" "$1" ||: exit "$1" } signal_handler '__cleanup_handler $rc' EXIT signal_handler '__cleanup_handler 1' HUP PIPE INT QUIT TERM } unset_cleanup_handler() { signal_handler SIG_DFL EXIT HUP PIPE INT QUIT TERM __cleanup_handler_name= } fi #__libshell_experimental fi #__included_shell_signal libshell-0.0.6/shell-unittest000064400000000000000000000124161107536225200162270ustar00rootroot00000000000000#!/bin/sh -efu if [ -z "${__included_shell_unittest-}" ]; then __included_shell_unittest=1 . shell-error # Append tests condition to comment message if test failed. unittest_show_condition= # Called before each test is run. setUp() { :; } # Called after each test is run. tearDown() { :; } # Called before any test is run. setUpTests() { :; } # Called after any test is run. tearDownTests() { :; } # Register new testing function. # appendTests (TestFunc) __shell_unit_tests= appendTests() { local n while [ "$#" -gt 0 ]; do n="$1" if [ -z "${__shell_unit_tests}" -o -n "${__shell_unit_tests##* $n *}" ]; then __shell_unit_tests="$__shell_unit_tests $n " fi shift done } # Automatically register test functions with 'UnitTest' comment. # Name of current shell script will be used if argument is not present. # registerTests([/tmp/Tests-File]) # Example: # my_testcase_function() { # UnitTest # blah blah blah ... # } registerTests() { local l="$(sed -ne 's/^\([[:alnum:]_]\+\)().*[[:space:]]*#[[:space:]]*UnitTest/\1/p' "${1:-$0}")" [ -z "$l" ] || appendTests $l } # Skip test (called in testing function) shouldSkip() { exit 2 } # Asserts that a given shell test condition (or integer) is true. # assertTrue([comment], condition) # assertTrue([comment], integer) assertTrue() { local comment condition [ "$#" -lt 2 ] || { comment="$1"; shift; } condition="$1"; shift [ -z "$unittest_show_condition" ] || comment="${comment:+$comment }($condition) == false" if [ -n "${condition##*[!0-9\-]*}" ]; then [ $condition -ne 0 ] || return 0 [ -z "$comment" ] || printf '%s' "$comment" exit 1 fi if ! ( eval "$condition" ) >/dev/null; then [ -z "$comment" ] || printf '%s' "$comment" exit 1 fi } # Asserts that a given shell test condition (or integer) is false. # assertFalse([comment], condition) # assertFalse([comment], integer) assertFalse() { local comment condition [ "$#" -lt 2 ] || { comment="$1"; shift; } condition="$1"; shift [ -z "$unittest_show_condition" ] || comment="${comment:+$comment }($condition) == true" if [ -n "${condition##*[!0-9\-]*}" ]; then [ $condition -eq 0 ] || return 0 [ -z "$comment" ] || printf '%s' "$comment" exit 1 fi if ( eval "$condition" ) >/dev/null; then [ -z "$comment" ] || printf '%s' "$comment" exit 1 fi } # Asserts that two arguments are equal to one another. # assertEquals([comment], expected, actual) assertEquals() { local comment expected actual [ "$#" -lt 3 ] || { comment="$1"; shift; } expected="$1"; shift actual="$1"; shift if [ "$expected" != "$actual" ]; then [ -z "$unittest_show_condition" ] || comment="${comment:+$comment }($expected) != ($actual)" [ -z "$comment" ] || printf '%s' "$comment" exit 1 fi } # Asserts that two arguments are same. # assertSame([comment], expected, actual) assertSame() { assertEquals "${@-}" } # Asserts that two arguments are not equal to one another. # assertNotEquals([comment], expected, actual) assertNotEquals() { local comment expected actual [ "$#" -lt 3 ] || { comment="$1"; shift; } expected="$1"; shift actual="$1"; shift if [ "$expected" = "$actual" ]; then [ -z "$unittest_show_condition" ] || comment="${comment:+$comment }($expected) == ($actual)" [ -z "$comment" ] || printf '%s' "$comment" exit 1 fi } # Asserts that two arguments are not same. # assertNotSame([comment], expected, actual) assertNotSame() { assertNotEquals "${@-}" } # Asserts that argument is a zero-length string. # assertNull([comment], value) assertNull() { local comment value [ "$#" -lt 2 ] || { comment="$1"; shift; } value="$1"; shift if [ -n "$value" ]; then [ -z "$unittest_show_condition" ] || comment="${comment:+$comment }($value) == ''" [ -z "$comment" ] || printf '%s' "$comment" exit 1 fi } # Asserts that argument is not empty string. # assertNotNull([comment], value) assertNotNull() { local comment value [ "$#" -lt 2 ] || { comment="$1"; shift; } value="$1"; shift if [ -z "$value" ]; then [ -z "$unittest_show_condition" ] || comment="${comment:+$comment }($value) != ''" [ -z "$comment" ] || printf '%s' "$comment" exit 1 fi } # Display status message after each test. messageTest() { case "$3" in 0) printf '[done]' ;; 1) printf '[FAIL]' ;; 2) printf '[skip]' ;; esac printf ' (%s) %s\n' "$1" "$2" } # Display summary statistic. showSummary() { if [ "$total" -eq 0 ]; then message "Nothing to do" return fi printf '\n' printf 'tests passed: %6d %3d%%\n' "$passed" "$((($passed*100)/$total))" printf 'tests failed: %6d %3d%%\n' "$failed" "$((($failed*100)/$total))" printf 'tests skipped: %6d %3d%%\n' "$skipped" "$((($skipped*100)/$total))" printf 'tests total: %6d\n\n' "$total" } # Run tests. runUnitTests() { run_or_exit() { "$@" || fatal "$1() fail rc=$?" } run_or_exit setUpTests set -- ${__shell_unit_tests-} local retval=0 rc passed=0 failed=0 skipped=0 total="$#" while [ "$#" -gt 0 ]; do run_or_exit setUp rc=0 msg="$("$1")" || rc=$? case "$rc" in 0) passed=$(($passed+1)) ;; 1) failed=$(($failed+1)); retval=1; ;; 2) skipped=$(($skipped+1)) ;; esac run_or_exit messageTest "$1" "$msg" "$rc" run_or_exit tearDown shift done run_or_exit showSummary run_or_exit tearDownTests return $retval } fi #__included_shell_unittest libshell-0.0.6/shell-version000064400000000000000000000002141107536225200160260ustar00rootroot00000000000000#!/bin/sh -efu if [ -z "${__included_shell_version-}" ]; then __included_shell_version=1 libshell_version=2 fi #__included_shell_version libshell-0.0.6/tests/000075500000000000000000000000001107536225200144565ustar00rootroot00000000000000libshell-0.0.6/tests/fatal000064400000000000000000000014241107536225200154710ustar00rootroot00000000000000#!/bin/ash -efu PROG='TEST' fatal_test1() { # UnitTest . ../shell-error expect="$PROG: message message;" result=`fatal "message message" 2>&1 |tr '\n' ';'` assertEquals "$result" "$result" "$expect" } fatal_test2() { # UnitTest . ../shell-error expect="$PROG: message;message;" result=`fatal "message message" 2>&1 |tr '\n' ';'` assertEquals "$result" "$result" "$expect" } fatal_test3() { # UnitTest . ../shell-error zzz=ZZZ expect="$PROG: message ZZZ message;" result=`fatal "message $zzz message" 2>&1 |tr '\n' ';'` assertEquals "$result" "$result" "$expect" } fatal_test4() { # UnitTest . ../shell-error expect="$PROG: message message;" result=`{ fatal "message message" 2>&1; echo "another message"; } |tr '\n' ';'` assertEquals "$result" "$result" "$expect" } libshell-0.0.6/tests/getopt000064400000000000000000000122101107536225200156770ustar00rootroot00000000000000#!/bin/ash -efu normalize() { sed \ -e "s/\"/'/g" \ -e 's/[[:space:]]\+/ /g' \ -e 's/^[[:space:]]\+//' \ -e 's/[[:space:]]\+$//' } getopt_test1() { # UnitTest LANG=C expect=`{ getopt -n TEST -o ; echo rc=$?; } 2>&1 |normalize |tr '\n' ';'` . ../shell-getopt result=`{ getopt -n TEST -o ; echo rc=$?; } 2>&1 |normalize |tr '\n' ';'` assertEquals "$result" "$result" "$expect" } getopt_test2() { # UnitTest LANG=C expect=`{ getopt -n TEST -o ' ' ; echo rc=$?; } 2>&1 |normalize |tr '\n' ';'` . ../shell-getopt result=`{ getopt -n TEST -o ' ' ; echo rc=$?; } 2>&1 |normalize |tr '\n' ';'` assertEquals "$result" "$result" "$expect" } getopt_test3() { # UnitTest LANG=C expect=`{ getopt -n TEST -o '' -l ' ' -- ZZZ; echo rc=$?; } 2>&1 |normalize |tr '\n' ';'` . ../shell-getopt result=`{ getopt -n TEST -o '' -l ' ' -- ZZZ; echo rc=$?; } 2>&1 |normalize |tr '\n' ';'` assertEquals "$result" "$result" "$expect" } getopt_test4() { # UnitTest LANG=C expect=`{ getopt -n TEST -o 'a,b,c' -- -abc -a -b -c ; echo rc=$?; } 2>&1 |normalize |tr '\n' ';'` . ../shell-getopt result=`{ getopt -n TEST -o 'a,b,c' -- -abc -a -b -c ; echo rc=$?; } 2>&1 |normalize |tr '\n' ';'` assertEquals "$result" "$result" "$expect" } getopt_test5() { # UnitTest LANG=C expect=`{ getopt -n TEST -o 'a,b,c' -l 'caa:,cba:' -- -abc --caa 'AAA' --cba='BBB' ; echo rc=$?; } 2>&1 |normalize |tr '\n' ';'` . ../shell-getopt result=`{ getopt -n TEST -o 'a,b,c' -l 'caa:,cba:' -- -abc --caa 'AAA' --cba='BBB' ; echo rc=$?; } 2>&1 |normalize |tr '\n' ';'` assertEquals "$result" "$result" "$expect" } getopt_test6() { # UnitTest LANG=C expect=`{ getopt -n TEST -o 'a,b,c' -l 'caa:,cba:' -- --cb 'AAA' --c='BBB' ; echo rc=$?; } 2>&1 |normalize |tr '\n' ';'` . ../shell-getopt result=`{ getopt -n TEST -o 'a,b,c' -l 'caa:,cba:' -- --cb 'AAA' --c='BBB' ; echo rc=$?; } 2>&1 |normalize |tr '\n' ';'` assertEquals "$result" "$result" "$expect" } getopt_test7() { # UnitTest LANG=C expect=`{ getopt -n TEST -o 'a,b,c' -l 'caa:,cba:' -- --cbz 'AAA' --c='BBB' ; echo rc=$?; } 2>&1 |normalize |tr '\n' ';'` . ../shell-getopt result=`{ getopt -n TEST -o 'a,b,c' -l 'caa:,cba:' -- --cbz 'AAA' --c='BBB' ; echo rc=$?; } 2>&1 |normalize |tr '\n' ';'` assertEquals "$result" "$result" "$expect" } getopt_test8() { # UnitTest LANG=C expect=`{ getopt -a -n TEST -o 'a,b,c' -l 'caa:,cba:' -- -cb 'AAA' ; echo rc=$?; } 2>&1 |normalize |tr '\n' ';'` . ../shell-getopt result=`{ getopt -a -n TEST -o 'a,b,c' -l 'caa:,cba:' -- -cb 'AAA' ; echo rc=$?; } 2>&1 |normalize |tr '\n' ';'` assertEquals "$result" "$result" "$expect" } getopt_test9() { # UnitTest LANG=C expect=`{ getopt -a -n TEST -o 'a,b,c' -l 'caa:,cba:' -- -c='AAA' ; echo rc=$?; } 2>&1 |normalize |tr '\n' ';'` . ../shell-getopt result=`{ getopt -a -n TEST -o 'a,b,c' -l 'caa:,cba:' -- -c='AAA' ; echo rc=$?; } 2>&1 |normalize |tr '\n' ';'` assertEquals "$result" "$result" "$expect" } getopt_test10() { # UnitTest LANG=C expect=`{ getopt -n TEST -o 'a,b,c' -l 'caa:,cba:' -- -c='AAA'; echo rc=$?; } 2>&1 |normalize |tr '\n' ';'` . ../shell-getopt result=`{ getopt -n TEST -o 'a,b,c' -l 'caa:,cba:' -- -c='AAA'; echo rc=$?; } 2>&1 |normalize |tr '\n' ';'` assertEquals "$result" "$result" "$expect" } getopt_test11() { # UnitTest LANG=C expect=`{ getopt -n TEST -o 'a,b,c' -l 'abcd:,cbce:' -- --abcx 'AAA'; echo rc=$?; } 2>&1 |normalize |tr '\n' ';'` . ../shell-getopt result=`{ getopt -n TEST -o 'a,b,c' -l 'abcd:,cbce:' -- --abcx 'AAA'; echo rc=$?; } 2>&1 |normalize |tr '\n' ';'` assertEquals "$result" "$result" "$expect" } getopt_test12() { # UnitTest LANG=C expect=`{ getopt -n TEST -o 'a:,b,c' -- -abc 'AAA'; echo rc=$?; } 2>&1 |normalize |tr '\n' ';'` . ../shell-getopt result=`{ getopt -n TEST -o 'a:,b,c' -- -abc 'AAA'; echo rc=$?; } 2>&1 |normalize |tr '\n' ';'` assertEquals "$result" "$result" "$expect" } getopt_test13() { # UnitTest LANG=C expect=`{ getopt -n TEST -o 'a::,b,c' -- -a -bc 'AAA'; echo rc=$?; } 2>&1 |normalize |tr '\n' ';'` . ../shell-getopt result=`{ getopt -n TEST -o 'a::,b,c' -- -a -bc 'AAA'; echo rc=$?; } 2>&1 |normalize |tr '\n' ';'` assertEquals "$result" "$result" "$expect" } getopt_test14() { # UnitTest LANG=C expect=`{ getopt -n TEST -o 'a,b,c' -l 'caa:,cba:' -- 'BBB' 'XXX ZZZ'; echo rc=$?; } 2>&1 |normalize |tr '\n' ';'` . ../shell-getopt result=`{ getopt -n TEST -o 'a,b,c' -l 'caa:,cba:' -- 'BBB' 'XXX ZZZ'; echo rc=$?; } 2>&1 |normalize |tr '\n' ';'` assertEquals "$result" "$result" "$expect" } getopt_test15() { # UnitTest LANG=C expect=`{ getopt -n TEST -o '+a,b,c' -l 'caa:,cba:' -- --caa='AAA' 'BBB' --zzz -x; echo rc=$?; } 2>&1 |normalize |tr '\n' ';'` . ../shell-getopt result=`{ getopt -n TEST -o '+a,b,c' -l 'caa:,cba:' -- --caa='AAA' 'BBB' --zzz -x; echo rc=$?; } 2>&1 |normalize |tr '\n' ';'` assertEquals "$result" "$result" "$expect" } getopt_test16() { # UnitTest LANG=C expect=`{ getopt -n TEST -o '-a,b,c' -l 'caa:,cba:' -- 'AAA' --caa='BBB' 'CCC'; echo rc=$?; } 2>&1 |normalize |tr '\n' ';'` . ../shell-getopt result=`{ getopt -n TEST -o '-a,b,c' -l 'caa:,cba:' -- 'AAA' --caa='BBB' 'CCC'; echo rc=$?; } 2>&1 |normalize |tr '\n' ';'` assertEquals "$result" "$result" "$expect" } libshell-0.0.6/tests/message000064400000000000000000000014641107536225200160320ustar00rootroot00000000000000#!/bin/ash -efu PROG='TEST' message_test1() { # UnitTest . ../shell-error expect="$PROG: message message;" result=`message "message message" 2>&1 |tr '\n' ';'` assertEquals "$result" "$result" "$expect" } message_test2() { # UnitTest . ../shell-error expect="$PROG: message;message;" result=`message "message message" 2>&1 |tr '\n' ';'` assertEquals "$result" "$result" "$expect" } message_test3() { # UnitTest . ../shell-error zzz=ZZZ expect="$PROG: message ZZZ message;" result=`message "message $zzz message" 2>&1 |tr '\n' ';'` assertEquals "$result" "$result" "$expect" } message_test4() { # UnitTest . ../shell-error expect="$PROG: message message;another message;" result=`{ message "message message" 2>&1; echo "another message"; } |tr '\n' ';'` assertEquals "$result" "$result" "$expect" } libshell-0.0.6/tests/opt_check_dir000064400000000000000000000011701107536225200171750ustar00rootroot00000000000000#!/bin/ash -efu opt_check_dir_test1() { # UnitTest . ../shell-args [ -d "$WORKDIR/dir-644" ] || mkdir -m644 "$WORKDIR/dir-644" cd "$WORKDIR" expect="$(message "DIR: ./dir-644: directory not available." 2>&1)" result="$(opt_check_dir "DIR" "./dir-644" 2>&1)" ||: rmdir "dir-644" assertEquals "$result" "$result" "$expect" } opt_check_dir_test2() { # UnitTest . ../shell-args [ -d "$WORKDIR/dir-755" ] || mkdir -m755 "$WORKDIR/dir-755" cd "$WORKDIR" expect="$(readlink -ev ./dir-755 2>&1)" ||: result="$(opt_check_dir "DIR" "./dir-755" 2>&1)" ||: rmdir "dir-755" assertEquals "$result" "$result" "$expect" } libshell-0.0.6/tests/opt_check_number000064400000000000000000000012341107536225200177100ustar00rootroot00000000000000#!/bin/ash -efu opt_check_number_test1() { # UnitTest . ../shell-args string="1234" expect="1234" result="$(opt_check_number "NUM" "$string" 2>&1)" ||: assertEquals "$result" "$result" "$expect" } opt_check_number_test2() { # UnitTest . ../shell-args string="0001" expect="$(message "NUM: $string: invalid number." 2>&1)" result="$(opt_check_number "NUM" "$string" 2>&1)" ||: assertEquals "$result" "$result" "$expect" } opt_check_number_test3() { # UnitTest . ../shell-args string="1 2" expect="$(message "NUM: $string: invalid number." 2>&1)" result="$(opt_check_number "NUM" "$string" 2>&1)" ||: assertEquals "$result" "$result" "$expect" } libshell-0.0.6/tests/opt_check_read000064400000000000000000000025301107536225200173330ustar00rootroot00000000000000#!/bin/ash -efu opt_check_read_test1() { # UnitTest . ../shell-args if [ ! -f "$WORKDIR/file-000" ]; then > "$WORKDIR/file-000" chmod 000 "$WORKDIR/file-000" fi cd "$WORKDIR" expect="$(message "FILE: ./file-000: file not available." 2>&1)" result="$(opt_check_read "FILE" "./file-000" 2>&1)" ||: assertEquals "$result" "$result" "$expect" } opt_check_read_test2() { # UnitTest . ../shell-args if [ ! -f "$WORKDIR/file-200" ]; then > "$WORKDIR/file-200" chmod 200 "$WORKDIR/file-200" fi cd "$WORKDIR" expect="$(message "FILE: ./file-200: file not available." 2>&1)" result="$(opt_check_read "FILE" "./file-200" 2>&1)" ||: assertEquals "$result" "$result" "$expect" } opt_check_read_test3() { # UnitTest . ../shell-args if [ ! -f "$WORKDIR/file-644" ]; then > "$WORKDIR/file-644" chmod 644 "$WORKDIR/file-644" fi cd "$WORKDIR" expect="$(readlink -ev ./file-644)" result="$(opt_check_read "FILE" "./file-644" 2>&1)" ||: assertEquals "$result" "$result" "$expect" } opt_check_read_test4() { # UnitTest . ../shell-args if [ ! -e "$WORKDIR/broken-symlink" ]; then ln -s "$WORKDIR/broken-symlink" "$WORKDIR/broken-symlink" fi cd "$WORKDIR" expect="$(message "FILE: ./broken-symlink: file not available." 2>&1)" result="$(opt_check_read "FILE" "./broken-symlink" 2>&1)" ||: assertEquals "$result" "$result" "$expect" } libshell-0.0.6/tests/quote_sed_regexp000064400000000000000000000020121107536225200177360ustar00rootroot00000000000000#!/bin/ash -efu quote_sed_regexp_test1() { # UnitTest . ../shell-quote local string='.*' local regexp="$(quote_sed_regexp "$string")" local result="$(printf '%s\n' "$string passed" |sed -e "s/^$regexp/test/")" assertEquals "$string" "$result" 'test passed' } quote_sed_regexp_test2() { # UnitTest . ../shell-quote local string='[[:space:]]' local regexp="$(quote_sed_regexp "$string")" local result="$(printf '%s\n' "test $string" |sed -e "s/$regexp/passed/")" assertEquals "$string" "$result" 'test passed' } quote_sed_regexp_test3() { # UnitTest . ../shell-quote local string='t{1,3}' local regexp="$(quote_sed_regexp "$string")" local result="$(printf '%s\n' "test$string passed" |sed -e "s/$regexp//")" assertEquals "$string" "$result" 'test passed' } quote_sed_regexp_test4() { # UnitTest . ../shell-quote local string='&\1' local regexp="$(quote_sed_regexp "$string")" local result="$(printf '%s\n' "test not passed" |sed -e "s/\(not\)/$regexp/")" #" assertEquals "$string" "$result" 'test &\1 passed' } libshell-0.0.6/tests/quote_shell000064400000000000000000000010661107536225200167300ustar00rootroot00000000000000#!/bin/ash -efu quote_shell_test1() { # UnitTest . ../shell-quote local string='`true`' local result eval "result=\"$(quote_shell "$string")\"" assertEquals "$string" "$result" "$string" } quote_shell_test2() { # UnitTest . ../shell-quote local string='$(true)' local result eval "result=\"$(quote_shell "$string")\"" assertEquals "$string" "$result" "$string" } quote_shell_test3() { # UnitTest . ../shell-quote local string='\`true\`; echo zzz' local result eval "result=\"$(quote_shell "$string")\"" assertEquals "$string" "$result" "$string" } libshell-0.0.6/tests/runtests000075500000000000000000000005421107536225200162740ustar00rootroot00000000000000#!/bin/ash -efu . ../shell-unittest WORKDIR= setUpTests() { WORKDIR="$(mktemp -d "$PROG.XXXXXXXXX")" } tearDownTests() { rm -rf -- "$WORKDIR" } for s in \ quote_sed_regexp quote_shell string_quote_remove \ opt_check_dir opt_check_number opt_check_read \ getopt \ fatal message verbose \ ; do . "./$s" registerTests "./$s" done runUnitTests libshell-0.0.6/tests/string_quote_remove000064400000000000000000000014101107536225200204750ustar00rootroot00000000000000#!/bin/sh string_quote_remove_test1() { # UnitTest . ../shell-quote local string='"test passed"' local result="$(string_quote_remove "$string")" assertEquals "$string" "$result" 'test passed' } string_quote_remove_test2() { # UnitTest . ../shell-quote local string="'test passed'" local result="$(string_quote_remove "$string")" assertEquals "$string" "$result" 'test passed' } string_quote_remove_test3() { # UnitTest . ../shell-quote local string="'test passed\"" local result="$(string_quote_remove "$string")" assertEquals "$string" "$result" "'test passed\"" } string_quote_remove_test4() { # UnitTest . ../shell-quote local string="test ' passed" local result="$(string_quote_remove "$string")" assertEquals "$string" "$result" "test ' passed" } libshell-0.0.6/tests/verbose000064400000000000000000000006051107536225200160470ustar00rootroot00000000000000#!/bin/ash -efu PROG='TEST' verbose_test1() { # UnitTest . ../shell-error verbose=1 expect="$PROG: message message;" result=`verbose "message message" 2>&1 |tr '\n' ';'` assertEquals "$result" "$result" "$expect" } verbose_test2() { # UnitTest . ../shell-error verbose= expect= result=`verbose "message message" 2>&1 |tr '\n' ';'` assertEquals "$result" "$result" "$expect" }