aboutsummaryrefslogtreecommitdiff
path: root/examples/ini.tm
blob: 1f818a2ec025ff1ea31fcd6e1d24aef4b04b0472 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
_USAGE := "
    Usage: ini <filename> "[section[/key]]"
"
_HELP := "
    ini: A .ini config file reader tool.
    $_USAGE
"

file := use ./file.tm

func parse_ini(filename:Text)->{Text:{Text:Text}}:
    text := when file.read(filename) is Failure(err): fail(err)
    is Success(text): text

    sections := {:Text:@{Text:Text}}
    current_section := @{:Text:Text}
    sections:set("", current_section)

    # Line wraps:
    text = text:replace($/\{1 nl}{0+space}/, " ")

    for line in text:lines():
        line = line:trim()
        if line:matches($/{0+space}[{..}]/):
            section_name := line:replace($/{0+space}[{..}]{..}/, "\2"):trim():lower()
            current_section = @{:Text:Text}
            sections:set(section_name, current_section)
        else if line:matches($/{..}={..}/):
            key := line:replace($/{..}={..}/, "\1"):trim():lower()
            value := line:replace($/{..}={..}/, "\2"):trim()
            current_section:set(key, value)

    return {k:v[] for k,v in sections}

func main(filename:Text, key:Text):
    keys := key:split($Pattern"/")
    if keys.length > 2:
        fail("
            Too many arguments! 
            $_USAGE
        ")

    data := parse_ini(filename)
    if keys.length < 1 or keys[1] == '*':
        !! $data
        return

    section := keys[1]:lower()
    if not data:has(section):
        fail("Invalid section name: $section; valid names: $(", ":join([k:quoted() for k in data.keys]))")

    section_data := data:get(section)
    if keys.length < 2 or keys[2] == '*':
        !! $section_data
        return

    section_key := keys[2]:lower()
    if not section_data:has(section_key):
        fail("Invalid key: $section_key; valid keys: $(", ":join(section_data.keys))")

    say(section_data:get(section_key))