| 76 | #define MATCH_ENTRY(s, n) (MATCH(section, (s)) && MATCH(name, (n))) |
| 77 | |
| 78 | int Config::ini_handler(void *user, const char *section, const char *name, const char *value) { |
| 79 | Config *config = static_cast<Config *>(user); |
| 80 | std::string_view v = value; |
| 81 | |
| 82 | auto profile_name_to_id = [](const std::string_view &str) -> FizeauProfileId { |
| 83 | return static_cast<FizeauProfileId>(str.back() - '0' - 1); |
| 84 | }; |
| 85 | |
| 86 | auto parse_components = [](const std::string_view &str) -> Component { |
| 87 | if (strcasecmp(str.data(), "none") == 0) { |
| 88 | return Component_None; |
| 89 | } else if (strcasecmp(str.data(), "all") == 0) { |
| 90 | return Component_All; |
| 91 | } else { |
| 92 | std::uint32_t comp = 0; |
| 93 | if ((str.find('r') != std::string_view::npos) || (str.find('R') != std::string_view::npos)) comp |= Component_Red; |
| 94 | if ((str.find('g') != std::string_view::npos) || (str.find('G') != std::string_view::npos)) comp |= Component_Green; |
| 95 | if ((str.find('b') != std::string_view::npos) || (str.find('B') != std::string_view::npos)) comp |= Component_Blue; |
| 96 | return static_cast<Component>(comp); |
| 97 | } |
| 98 | }; |
| 99 | |
| 100 | auto parse_filter = [](const std::string_view &str) -> Component { |
| 101 | if (strcasecmp(str.data(), "red") == 0) |
| 102 | return Component_Red; |
| 103 | else if (strcasecmp(str.data(), "green") == 0) |
| 104 | return Component_Green; |
| 105 | else if (strcasecmp(str.data(), "blue") == 0) |
| 106 | return Component_Blue; |
| 107 | return Component_None; |
| 108 | }; |
| 109 | |
| 110 | auto parse_time = [](const std::string_view &str) -> Time { |
| 111 | Time t = {}; |
| 112 | auto pos = str.find(':'); |
| 113 | t.h = atoi(substr(str, 0, pos)); |
| 114 | t.m = atoi(substr(str, pos + 1)); |
| 115 | return t; |
| 116 | }; |
| 117 | |
| 118 | static_assert(parse_time("09:02") == Time{9, 2}); |
| 119 | |
| 120 | auto parse_range = [](const std::string_view &str) -> ColorRange { |
| 121 | ColorRange r = {}; |
| 122 | auto pos = str.find('-'); |
| 123 | r.lo = atof(substr(str, 0, pos)); |
| 124 | r.hi = atof(substr(str, pos + 1)); |
| 125 | return r; |
| 126 | }; |
| 127 | |
| 128 | static_assert(parse_range("0.18-0.92") == ColorRange{0.18, 0.92}); |
| 129 | |
| 130 | if (MATCH_ENTRY("", "active")) { |
| 131 | if (MATCH(value, "1") || strcasecmp(value, "true") == 0) |
| 132 | config->active = true; |
| 133 | else |
| 134 | config->active = false; |
| 135 | config->has_active_override = true; |