| 218 | } |
| 219 | |
| 220 | cm::optional<std::pair<std::string, std::string>> ParseOSReleaseLine( |
| 221 | std::string const& line) |
| 222 | { |
| 223 | std::string key; |
| 224 | std::string value; |
| 225 | |
| 226 | char prev = 0; |
| 227 | enum ParserState |
| 228 | { |
| 229 | PARSE_KEY_1ST, |
| 230 | PARSE_KEY, |
| 231 | FOUND_EQ, |
| 232 | PARSE_SINGLE_QUOTE_VALUE, |
| 233 | PARSE_DBL_QUOTE_VALUE, |
| 234 | PARSE_VALUE, |
| 235 | IGNORE_REST |
| 236 | } state = PARSE_KEY_1ST; |
| 237 | |
| 238 | for (auto ch : line) { |
| 239 | switch (state) { |
| 240 | case PARSE_KEY_1ST: |
| 241 | if (cmsysString_isalpha(ch) || ch == '_') { |
| 242 | key += ch; |
| 243 | state = PARSE_KEY; |
| 244 | } else if (!cmsysString_isspace(ch)) { |
| 245 | state = IGNORE_REST; |
| 246 | } |
| 247 | break; |
| 248 | |
| 249 | case PARSE_KEY: |
| 250 | if (ch == '=') { |
| 251 | state = FOUND_EQ; |
| 252 | } else if (cmsysString_isalnum(ch) || ch == '_') { |
| 253 | key += ch; |
| 254 | } else { |
| 255 | state = IGNORE_REST; |
| 256 | } |
| 257 | break; |
| 258 | |
| 259 | case FOUND_EQ: |
| 260 | switch (ch) { |
| 261 | case '\'': |
| 262 | state = PARSE_SINGLE_QUOTE_VALUE; |
| 263 | break; |
| 264 | case '"': |
| 265 | state = PARSE_DBL_QUOTE_VALUE; |
| 266 | break; |
| 267 | case '#': |
| 268 | case '\\': |
| 269 | state = IGNORE_REST; |
| 270 | break; |
| 271 | default: |
| 272 | value += ch; |
| 273 | state = PARSE_VALUE; |
| 274 | } |
| 275 | break; |
| 276 | |
| 277 | case PARSE_SINGLE_QUOTE_VALUE: |
no test coverage detected
searching dependent graphs…