1 // Copyright (C) 2019 The Android Open Source Project
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14
15 #include "utils/config_file.h"
16
17 #include "utils/string_utils.h"
18
19 #include <fstream>
20 #include <map>
21 #include <string>
22
23
24 namespace header_checker {
25 namespace utils {
26
27
ParseFile(std::istream & istream)28 ConfigFile ConfigParser::ParseFile(std::istream &istream) {
29 ConfigParser parser(istream);
30 return parser.ParseFile();
31 }
32
33
ParseFile(const std::string & path)34 ConfigFile ConfigParser::ParseFile(const std::string &path) {
35 std::ifstream stream(path, std::ios_base::in);
36 return ParseFile(stream);
37 }
38
39
ParseFile()40 ConfigFile ConfigParser::ParseFile() {
41 size_t line_no = 0;
42 std::string line;
43 while (std::getline(stream_, line)) {
44 ParseLine(++line_no, line);
45 }
46 return std::move(cfg_);
47 }
48
49
ParseLine(size_t line_no,std::string_view line)50 void ConfigParser::ParseLine(size_t line_no, std::string_view line) {
51 if (line.empty() || line[0] == ';' || line[0] == '#') {
52 // Skip empty or comment line.
53 return;
54 }
55
56 // Parse section name line.
57 if (line[0] == '[') {
58 std::string::size_type pos = line.rfind(']');
59 if (pos == std::string::npos) {
60 ReportError(line_no, "bad section name line");
61 return;
62 }
63 std::string_view section_name = line.substr(1, pos - 1);
64 section_ = &cfg_.map_[std::string(section_name)];
65 return;
66 }
67
68 // Parse key-value line.
69 std::string::size_type pos = line.find('=');
70 if (pos == std::string::npos) {
71 ReportError(line_no, "bad key-value line");
72 return;
73 }
74
75 // Add key-value entry to current section.
76 std::string_view key = Trim(line.substr(0, pos));
77 std::string_view value = Trim(line.substr(pos + 1));
78
79 if (!section_) {
80 section_ = &cfg_.map_[""];
81 }
82 section_->map_[std::string(key)] = std::string(value);
83 }
84
85
86 } // namespace utils
87 } // namespace header_checker
88