| 64 | |
| 65 | |
| 66 | Kernel::ParseStageResult |
| 67 | Kernel::parseStageOption(std::string o, std::string& stage, std::string& option, |
| 68 | std::string& value) |
| 69 | { |
| 70 | value.clear(); |
| 71 | if ((o.size() < 2) || (o[0] != '-') || (o[1] != '-')) |
| 72 | return ParseStageResult::Unknown; |
| 73 | |
| 74 | o = o.substr(2); |
| 75 | |
| 76 | // Options are stage_type.stage_name.option_name |
| 77 | // stage_type is always lowercase stage_names start with lowercase and |
| 78 | // then are lowercase or digits. Option names start with lowercase and |
| 79 | // then contain lowercase, digits or underscore. |
| 80 | |
| 81 | // This awfulness is to work around the multiply-defined islower. Seems |
| 82 | // a bit better than the cast solution. |
| 83 | auto islc = [](char c) |
| 84 | { return std::islower(c); }; |
| 85 | |
| 86 | std::string::size_type pos = 0; |
| 87 | std::string::size_type count = 0; |
| 88 | |
| 89 | // Get stage_type. |
| 90 | count = Utils::extract(o, pos, islc); |
| 91 | pos += count; |
| 92 | std::string stageType = o.substr(0, pos); |
| 93 | if (!isStagePrefix(stageType) || pos >= o.length() || o[pos++] != '.') |
| 94 | return ParseStageResult::Unknown; |
| 95 | |
| 96 | // Get stage_name. |
| 97 | bool ok; |
| 98 | if (stageType == "stage") |
| 99 | ok = Stage::parseTagName(o, pos); |
| 100 | else |
| 101 | ok = Stage::parseName(o, pos); |
| 102 | if (!ok) |
| 103 | return ParseStageResult::Unknown; |
| 104 | |
| 105 | stage = o.substr(0, pos); |
| 106 | if (pos >= o.length() || o[pos++] != '.') |
| 107 | return ParseStageResult::Unknown; |
| 108 | |
| 109 | // Get option name. |
| 110 | std::string::size_type optionStart = pos; |
| 111 | count = Option::parse(o, pos); |
| 112 | pos += count; |
| 113 | option = o.substr(optionStart, count); |
| 114 | |
| 115 | // We've gotten a good option name, so return true, even if the value |
| 116 | // is missing. The caller can handle the missing value if desired. |
| 117 | if (pos >= o.length()) |
| 118 | return ParseStageResult::Ok; |
| 119 | |
| 120 | if (o[pos++] == '=') |
| 121 | { |
| 122 | value = o.substr(pos); |
| 123 | if (value.size()) |