• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 <json/json.h>
18 #include <llvm/Support/raw_ostream.h>
19 
20 #include <fstream>
21 #include <map>
22 #include <string>
23 
24 
25 static const std::string GLOBAL_SECTION_NAME = "global";
26 
27 
28 namespace header_checker {
29 namespace utils {
30 
31 
LoadFlags(const Json::Value & section)32 static std::map<std::string, bool> LoadFlags(const Json::Value &section) {
33   std::map<std::string, bool> map;
34   if (section.isMember("flags")) {
35     for (auto &flag_keys : section["flags"].getMemberNames()) {
36       map[flag_keys] = section["flags"][flag_keys].asBool();
37     }
38   }
39   return map;
40 }
41 
42 static std::vector<std::string>
LoadIgnoreLinkerSetKeys(const Json::Value & section)43 LoadIgnoreLinkerSetKeys(const Json::Value &section) {
44   std::vector<std::string> vec;
45   for (auto &key : section.get("ignore_linker_set_keys", {})) {
46     vec.emplace_back(key.asString());
47   }
48   return vec;
49 }
50 
HasGlobalSection()51 bool ConfigFile::HasGlobalSection() {
52   return HasSection(GLOBAL_SECTION_NAME, "");
53 }
54 
GetGlobalSection()55 const ConfigSection &ConfigFile::GetGlobalSection() {
56   return GetSection(GLOBAL_SECTION_NAME, "");
57 }
58 
Load(std::istream & istream)59 bool ConfigFile::Load(std::istream &istream) {
60   Json::Value root;
61   Json::CharReaderBuilder builder;
62   std::string errorMessage;
63   if (!Json::parseFromStream(builder, istream, &root, &errorMessage)) {
64     llvm::errs() << "Failed to parse JSON: " << errorMessage << "\n";
65     return false;
66   }
67   for (auto &key : root.getMemberNames()) {
68     if (key == GLOBAL_SECTION_NAME) {
69       ConfigSection &config_section = map_[{GLOBAL_SECTION_NAME, ""}];
70       config_section.map_ = LoadFlags(root[GLOBAL_SECTION_NAME]);
71       config_section.ignored_linker_set_keys_ =
72           LoadIgnoreLinkerSetKeys(root[GLOBAL_SECTION_NAME]);
73       continue;
74     }
75     for (auto &section : root[key]) {
76       ConfigSection &config_section =
77           map_[{key, section["target_version"].asString()}];
78       config_section.map_ = LoadFlags(section);
79       config_section.ignored_linker_set_keys_ = LoadIgnoreLinkerSetKeys(section);
80     }
81   }
82   return true;
83 }
84 
Load(const std::string & path)85 bool ConfigFile::Load(const std::string &path) {
86   std::ifstream stream(path);
87   return stream && Load(stream);
88 }
89 
90 }  // namespace utils
91 }  // namespace header_checker
92