86 lines
1.6 KiB
Plaintext
86 lines
1.6 KiB
Plaintext
use re
|
|
use str
|
|
use ./common
|
|
use ./list
|
|
use ./map
|
|
use ./num
|
|
|
|
fn is-aggregate {|option|
|
|
re:match '^\-\w{2,}$' $option
|
|
}
|
|
|
|
fn is-short {|option|
|
|
re:match '^\-\w$' $option
|
|
}
|
|
|
|
fn is-long {|option|
|
|
re:match '^\-\-\w+(=.*)?$' $option
|
|
}
|
|
|
|
fn is-option {|option|
|
|
or (is-short $option) (is-long $option) (is-aggregate $option)
|
|
}
|
|
|
|
fn split {|option|
|
|
if (is-aggregate $option) {
|
|
each {|e| put -$e} $option[1..]
|
|
} elif (is-long $option) {
|
|
var i = (str:index $option '=')
|
|
if (num:is-neg $i) {
|
|
put $option
|
|
} else {
|
|
put $option[..$i] $option[(num:++ $i)..]
|
|
}
|
|
} else {
|
|
put $option
|
|
}
|
|
}
|
|
|
|
fn -j {|options|
|
|
var o = (each {|o| put $o[1..] } $options | str:join '')
|
|
if (not-eq $o '') {
|
|
put -$o
|
|
}
|
|
}
|
|
|
|
fn join {|@options|
|
|
set options = (common:to-list $@options)
|
|
var cb = {|_ o| or (is-short $o) (is-aggregate $o) }
|
|
var i0 = 0
|
|
list:search-not $cb $options | each {|e|
|
|
var i1 v = $@e
|
|
-j $options[$i0..$i1]
|
|
put $v
|
|
set i0 = (num:++ $i1)
|
|
}
|
|
-j $options[$i0..]
|
|
}
|
|
|
|
fn expand {|@argv|
|
|
each $split~ (common:to-list $@argv)
|
|
}
|
|
|
|
fn map {|@argv|
|
|
set @argv = (expand $@argv)
|
|
var result i c = [&] 0 (count $argv)
|
|
var last = (num:-- $c)
|
|
while (< $i $c) {
|
|
var e = $argv[$i]
|
|
if (is-option $e) {
|
|
var k v = $e []
|
|
if (< $i $last) {
|
|
var j = (num:++ $i)
|
|
set e = $argv[$j]
|
|
if (not (is-option $e)) {
|
|
set i @v = $j $@v $e
|
|
}
|
|
}
|
|
set result = (map:add $result $k $v)
|
|
} else {
|
|
set result = (map:add $result '' [$e])
|
|
}
|
|
set i = (num:++ $i)
|
|
}
|
|
put $result
|
|
}
|