use re use str use ./list fn is-moptions {|o| re:match '^\-\w{2,}$' $o } fn is-soption {|o| re:match '^\-\w$' $o } fn is-loption {|o| re:match '^\-\-\w+(=.*)?$' $o } fn is-option {|o| or (is-soption $o) (is-loption $o) (is-moptions $o) } fn -splitm {|o| each {|e| put -$e } $o[1:] } fn -splitl {|o| if (str:contains $o '=') { var opt @value = (str:split '=' $o) put $opt str:join '=' $value } else { put $o } } fn split {|o| if (is-moptions $o) { -splitm $o } elif (is-loption $o) { -splitl $o } else { put $o } } fn -joins {|opt| var o = (each {|o| put $o[1:] } $opt | str:join '') if (not-eq $o '') { put -$o } } fn join {|@opt| var opt = (list:-p $@opt) var cb = {|o| or (is-soption $o) (is-moptions $o) } var idx = [(list:filter-index-not $cb $opt)] var i0 = 0 each {|i| -joins $opt[{$i0}:$i] put $opt[$i] set i0 = (+ $i 1) } $idx -joins $opt[{$i0}:] } fn expand {|@argv| each $split~ (list:-p $@argv) } fn map {|@argv| use ./map set argv = [(expand $@argv)] var result i c = [&] 0 (count $argv) while (< $i $c) { var o = $argv[$i] if (is-option $o) { var k v = $o [] if (< $i (- $c 1)) { var e = $argv[(+ $i 1)] if (not (is-option $e)) { set v = [$@v $e] set i = (+ $i 1) } } set result = (map:add $result $k $@v) } else { set result = (map:add $result '' [$o]) } set i = (+ $i 1) } put $result }