| 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.data; | |
| 20 |
2/2✓ Branch 0 (25→3) taken 85 times.
✓ Branch 1 (25→26) taken 5 times.
|
90 | for (size_t pos = ctx->pos, len = ctx->input.length; pos < len; ) { |
| 21 | 85 | StringView line = buf_slice_next_line(input, &pos, len); | |
| 22 | 85 | strview_trim_left(&line); | |
| 23 |
6/6✓ Branch 0 (5→6) taken 64 times.
✓ Branch 1 (5→8) taken 21 times.
✓ Branch 2 (6→7) taken 57 times.
✓ Branch 3 (6→8) taken 7 times.
✓ Branch 4 (7→8) taken 1 times.
✓ Branch 5 (7→9) taken 56 times.
|
85 | if (line.length < 2 || line.data[0] == '#' || line.data[0] == ';') { |
| 24 | // Skip past comment/blank lines and lines that are too short | ||
| 25 | // to be valid (shorter than "k=") | ||
| 26 | 50 | continue; | |
| 27 | } | ||
| 28 | |||
| 29 | 56 | strview_trim_right(&line); | |
| 30 | 56 | BUG_ON(line.length == 0); | |
| 31 | |||
| 32 |
2/2✓ Branch 0 (13→14) taken 15 times.
✓ Branch 1 (13→15) taken 41 times.
|
56 | if (strview_remove_matching_affixes(&line, strview("["), strview("]"))) { |
| 33 | // Keep track of (and skip past) section headings | ||
| 34 | 15 | ctx->section = line; | |
| 35 | 15 | ctx->name_count = 0; | |
| 36 | 15 | continue; | |
| 37 | } | ||
| 38 | |||
| 39 | 41 | size_t val_offset = 0; | |
| 40 | 41 | StringView name = get_delim(line.data, &val_offset, line.length, '='); | |
| 41 |
2/2✓ Branch 0 (16→17) taken 4 times.
✓ Branch 1 (16→18) taken 37 times.
|
41 | if (val_offset >= line.length) { |
| 42 | 4 | continue; // Invalid line (no delimiter) | |
| 43 | } | ||
| 44 | |||
| 45 | 37 | strview_trim_right(&name); | |
| 46 |
2/2✓ Branch 0 (19→20) taken 2 times.
✓ Branch 1 (19→21) taken 35 times.
|
37 | if (name.length == 0) { |
| 47 | 2 | continue; // Invalid line (empty name) | |
| 48 | } | ||
| 49 | |||
| 50 | 35 | StringView value = line; | |
| 51 | 35 | strview_remove_prefix(&value, val_offset); | |
| 52 | 35 | strview_trim_left(&value); | |
| 53 | |||
| 54 | 35 | ctx->name = name; | |
| 55 | 35 | ctx->value = value; | |
| 56 | 35 | ctx->name_count++; | |
| 57 | 35 | ctx->pos = pos; | |
| 58 | 35 | return true; | |
| 59 | } | ||
| 60 | |||
| 61 | 5 | return false; | |
| 62 | } | ||
| 63 |