| 66 | } |
| 67 | |
| 68 | std::vector<STPhraseValue> LoadSTPhraseValues(const std::string& path, |
| 69 | const std::string& source) { |
| 70 | std::ifstream stream(path); |
| 71 | if (!stream.is_open()) { |
| 72 | ADD_FAILURE() << path; |
| 73 | return std::vector<STPhraseValue>(); |
| 74 | } |
| 75 | |
| 76 | std::vector<STPhraseValue> values; |
| 77 | std::unordered_set<std::string> seenValues; |
| 78 | std::string line; |
| 79 | size_t lineNumber = 0; |
| 80 | while (std::getline(stream, line)) { |
| 81 | ++lineNumber; |
| 82 | if (line.empty() || line[0] == '#') { |
| 83 | continue; |
| 84 | } |
| 85 | |
| 86 | const size_t tab = line.find('\t'); |
| 87 | if (tab == std::string::npos) { |
| 88 | continue; |
| 89 | } |
| 90 | |
| 91 | const std::string key = line.substr(0, tab); |
| 92 | const std::string valueText = line.substr(tab + 1); |
| 93 | for (const std::string& value : SplitValues(valueText)) { |
| 94 | if (seenValues.insert(value).second) { |
| 95 | values.push_back(STPhraseValue{source, lineNumber, key, value}); |
| 96 | } |
| 97 | } |
| 98 | } |
| 99 | return values; |
| 100 | } |
| 101 | |
| 102 | bool IsCoveredBySTPhraseValue(const std::string& key, |
| 103 | const std::vector<STPhraseValue>& stValues) { |
no test coverage detected