sistema_progs

Programas para customizar o meu entorno de traballo nos meus equipos persoais
Log | Files | Refs

getopt1.sh (3910B)


      1 #!/bin/bash
      2 # -*- coding:utf-8 -*-
      3 
      4 # Usage
      5 #
      6 #   local "${_ble_getopt_vars[@]/%/=}" # WA #D1570 checked
      7 #   ble-getopt-begin "progname" "m:n c:n,n k:n,n" "$@"
      8 #   ble-getopt
      9 #
     10 # ToDo
     11 #
     12 #   * next-argument: appropriate error message
     13 #   * next-argument: negative tests
     14 #   * next-argument: function calls
     15 #   * getopt_index を OPTIND に名前を変える?
     16 
     17 _ble_getopt_vars=(
     18   optargs      # 読み取られたオプション
     19 
     20   getopt_cmd   # 呼出元コマンド名
     21   getopt_odefs # オプション定義
     22   getopt_args  # コマンド引数
     23   getopt_len   # コマンド引数の数
     24   getopt_index # 現在のコマンド引数の位置 OPTIND
     25 
     26   getopt_opt   # 解析中オプション
     27   getopt_oarg  # オプション引数
     28   getopt_olen  # オプション引数の数
     29   getopt_oind  # オプション引数の現在位置
     30 )
     31 
     32 function .ble-getopt.next-argument {
     33   local type=$1 oarg
     34   if ((getopt_oind<getopt_olen)); then
     35     oarg=${getopt_oarg[getopt_oind++]}
     36   elif ((getopt_index<getopt_len)); then
     37     oarg=${getopt_args[getopt_index++]}
     38   else
     39     if [[ $type == '?'* ]]; then
     40       oarg=${type:1}
     41       [[ ! $oarg ]] && return 0
     42     else
     43       ble/util/print "$getopt_cmd: missing an argument of the option \`${optargs[0]}'." 1>&2
     44       return 1
     45     fi
     46   fi
     47 
     48   # check
     49   case $type in
     50   [nefdhcbpugkrwxsv])
     51     if [ ! -$type "$oarg" ]; then
     52       ble/util/print "$getopt_cmd: the argument of the option \`${optargs[0]}' is empty string (oarg=$oarg)." 1>&2
     53       return 1
     54     fi ;;
     55   esac
     56 
     57   optargs[${#optargs[@]}]=$oarg
     58 }
     59 
     60 function .ble-getopt.process-option {
     61   local name=$1
     62   optargs=("$name")
     63 
     64   # search the option definition
     65   local i f_found adef
     66   for ((i=0;i<${#getopt_odefs[@]};i++)); do
     67     if [[ $name == "${getopt_odefs[$i]%%:*}" ]]; then
     68       f_found=1
     69       ble/string#split adef : "${getopt_odefs[i]}"
     70       break
     71     fi
     72   done
     73 
     74   # unknown option
     75   if [[ ! $f_found ]]; then
     76     if [[ $f_longname ]]; then
     77       ble/util/print "an unknown long-name option \`--$name'" 1>&2
     78     else
     79       ble/util/print "an unknown option \`-$name'" 1>&2
     80     fi
     81     return 1
     82   fi
     83 
     84   for ((i=1;i<${#adef[@]};i++)); do
     85     .ble-getopt.next-argument "${adef[$i]}" || return 1
     86   done
     87 }
     88 
     89 function ble-getopt-begin {
     90   ble/string#split-words getopt_cmd "$1"
     91   ble/string#split-words getopt_odefs "$2"
     92   shift 2
     93   getopt_args=("$@")
     94   getopt_len=${#getopt_args[@]}
     95   getopt_index=0
     96 
     97   getopt_opt=
     98   getopt_olen=0
     99   getopt_oind=0
    100 
    101   optargs=()
    102 }
    103 
    104 function .ble-getopt.check-oarg-processed {
    105   if ((getopt_oind<getopt_olen)); then
    106     ble/util/print "$getopt_cmd: an option argument not processed (oarg=${getopt_oarg[$getopt_oind]})." 1>&2
    107     getopt_oind=0
    108     getopt_olen=0
    109     builtin unset -v 'getopt_oarg[@]'
    110     return 1
    111   fi
    112 }
    113 
    114 function ble-getopt {
    115   # 読み掛けのオプション列
    116   if [[ $getopt_opt ]]; then
    117     local o=${getopt_opt::1}
    118     getopt_opt=${getopt_opt:1}
    119     .ble-getopt.process-option "$o"
    120     return "$?"
    121   fi
    122 
    123   # oarg が残っていたらエラー
    124   .ble-getopt.check-oarg-processed || return 1
    125 
    126   # 完了
    127   if ((getopt_index>=getopt_len)); then
    128     builtin unset -v 'optargs[@]'
    129     return 2
    130   fi
    131 
    132   local arg=${getopt_args[getopt_index++]}
    133   if [[ $arg == -?* ]]; then
    134     
    135     if [[ $arg == --?* ]]; then
    136       # longname option
    137       local f_longname=1
    138       getopt_opt=${arg:2}
    139 
    140       local o=${getopt_opt%%=*}
    141       if [[ $o != "$getopt_opt" ]]; then
    142         getopt_oarg=("${getopt_opt#*=}")
    143         getopt_oind=0
    144         getopt_olen=1
    145       fi
    146       getopt_opt=
    147 
    148       .ble-getopt.process-option "$o"
    149       .ble-getopt.check-oarg-processed || return 1
    150       return 0
    151     else
    152       # short options
    153       local f_longname=
    154       getopt_opt=${arg:1}
    155 
    156       ble/string#split getopt_oarg : "$getopt_opt"
    157       getopt_olen=${#getopt_oarg[@]}
    158       getopt_oind=1
    159       ble-getopt
    160       return "$?"
    161     fi
    162   else
    163     # 通常の引数
    164     optargs=('' "$arg")
    165   fi
    166 
    167 }