code / tomo-ini

Lines68 Tomo50 INI10 Markdown8
(63 lines)
2 use patterns
4 _USAGE := "
5 Usage: ini <filename> "[section[/key]]"
6 "
7 _HELP := "
8 ini: A .ini config file reader tool.
9 $_USAGE
12 func parse_ini(path:Path -> {Text:{Text:Text}})
13 text := path.read() or exit("Could not read INI file: \[31;1]$(path)\[]")
14 sections : @{Text:@{Text:Text}}
15 current_section : @{Text:Text}
17 # Line wraps:
18 text = $Pat"\\{1 nl}{0+space}".replace(text, " ")
20 for line in text.lines()
21 line = line.trim()
22 skip if line.starts_with(";") or line.starts_with("#")
23 if m := $Pat"[?]".match(line)
24 section_name := m.captures[1]!.trim().lower()
25 current_section = @{}
26 sections[section_name] = current_section
27 else if m := $Pat"{..}={..}".match(line)
28 key := m.captures[1]!.trim().lower()
29 value := m.captures[2]!.trim()
30 current_section[key] = value
32 return {k:v[] for k,v in sections[]}
34 func main(path:Path, key:Text?)
35 keys := (key or "").split("/")
36 if keys.length > 2
37 exit("
38 Too many arguments!
39 $_USAGE
40 ")
42 data := parse_ini(path)
44 section := (keys[1] or '*').lower()
45 if section == '*'
46 say("$data")
47 return
49 section_data := data[section] or exit("
50 Invalid section name: \[31;1]$section\[]
51 Valid names: \[1]$(", ".join([k.quoted() for k in data.keys]))\[]
52 ")
54 section_key := (keys[2] or '*').lower()
55 if section_key == '*'
56 say("$section_data")
57 return
59 value := section_data[section_key] or exit("
60 Invalid key: \[31;1]$section_key\[]
61 Valid keys: \[1]$(", ".join([s.quoted() for s in section_data.keys]))\[]
62 ")
63 say(value)