Line | Branch | Exec | Source |
---|---|---|---|
1 | #include "ini.h" | ||
2 | #include "util/debug.h" | ||
3 | #include "util/str-util.h" | ||
4 | |||
5 | /* | ||
6 | * This is a "pull" style INI parser that returns true (and fills | ||
7 | * ctx->name and ctx->value) for each name=value pair encountered, | ||
8 | * or false when there's nothing further to parse. The current | ||
9 | * section name is tracked as ctx->section and lines that aren't | ||
10 | * actionable by the caller (i.e. section/comment/blank/invalid | ||
11 | * lines) are skipped over without returning anything. | ||
12 | * | ||
13 | * Note that "inline" comments are not supported, since the | ||
14 | * EditorConfig specification forbids them and that's the only | ||
15 | * use case in this codebase (see commit a61b90f630cd6a32). | ||
16 | */ | ||
17 | 40 | bool ini_parse(IniParser *ctx) | |
18 | { | ||
19 | 40 | const char *input = ctx->input; | |
20 | 40 | const size_t len = ctx->input_len; | |
21 | 40 | size_t pos = ctx->pos; | |
22 | |||
23 |
2/2✓ Branch 0 (25→3) taken 83 times.
✓ Branch 1 (25→26) taken 5 times.
|
88 | while (pos < len) { |
24 | 83 | StringView line = buf_slice_next_line(input, &pos, len); | |
25 | 83 | strview_trim_left(&line); | |
26 |
5/6✓ Branch 0 (5→6) taken 62 times.
✓ Branch 1 (5→8) taken 21 times.
✓ Branch 2 (6→7) taken 56 times.
✓ Branch 3 (6→8) taken 6 times.
✗ Branch 4 (7→8) not taken.
✓ Branch 5 (7→9) taken 56 times.
|
83 | if (line.length < 2 || line.data[0] == '#' || line.data[0] == ';') { |
27 | // Skip past comment/blank lines and lines that are too short | ||
28 | // to be valid (shorter than "k=") | ||
29 | 48 | continue; | |
30 | } | ||
31 | |||
32 | 56 | strview_trim_right(&line); | |
33 | 56 | BUG_ON(line.length == 0); | |
34 | |||
35 |
2/2✓ Branch 0 (13→14) taken 15 times.
✓ Branch 1 (13→15) taken 41 times.
|
56 | if (strview_remove_matching_prefix_and_suffix(&line, "[", "]")) { |
36 | // Keep track of (and skip past) section headings | ||
37 | 15 | ctx->section = line; | |
38 | 15 | ctx->name_count = 0; | |
39 | 15 | continue; | |
40 | } | ||
41 | |||
42 | 41 | size_t val_offset = 0; | |
43 | 41 | StringView name = get_delim(line.data, &val_offset, line.length, '='); | |
44 |
2/2✓ Branch 0 (16→17) taken 4 times.
✓ Branch 1 (16→18) taken 37 times.
|
41 | if (val_offset >= line.length) { |
45 | 4 | continue; // Invalid line (no delimiter) | |
46 | } | ||
47 | |||
48 | 37 | strview_trim_right(&name); | |
49 |
2/2✓ Branch 0 (19→20) taken 2 times.
✓ Branch 1 (19→21) taken 35 times.
|
37 | if (name.length == 0) { |
50 | 2 | continue; // Invalid line (empty name) | |
51 | } | ||
52 | |||
53 | 35 | StringView value = line; | |
54 | 35 | strview_remove_prefix(&value, val_offset); | |
55 | 35 | strview_trim_left(&value); | |
56 | |||
57 | 35 | ctx->name = name; | |
58 | 35 | ctx->value = value; | |
59 | 35 | ctx->name_count++; | |
60 | 35 | ctx->pos = pos; | |
61 | 35 | return true; | |
62 | } | ||
63 | |||
64 | return false; | ||
65 | } | ||
66 |