elv-lib/mods/option.elv

86 lines
1.6 KiB
Plaintext
Raw Normal View History

2021-12-26 15:40:57 +00:00
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
}