14a4c706fa989e4643cb5b3d675656586b42d895Paul Stewart// Copyright 2014 The Chromium OS Authors. All rights reserved. 24a4c706fa989e4643cb5b3d675656586b42d895Paul Stewart// Use of this source code is governed by a BSD-style license that can be 34a4c706fa989e4643cb5b3d675656586b42d895Paul Stewart// found in the LICENSE file. 44a4c706fa989e4643cb5b3d675656586b42d895Paul Stewart 56ef2d737ce25f4c0debcf87d5f5909289ce15adfAlex Vakulenko#include <memory> 64a4c706fa989e4643cb5b3d675656586b42d895Paul Stewart#include <string> 74a4c706fa989e4643cb5b3d675656586b42d895Paul Stewart 84a4c706fa989e4643cb5b3d675656586b42d895Paul Stewart#include <base/command_line.h> 92b1c6124a7c74225e231132a68e1a92723a26da9Paul Stewart#include <base/files/file_path.h> 106ef2d737ce25f4c0debcf87d5f5909289ce15adfAlex Vakulenko#include <base/files/file_util.h> 116ef2d737ce25f4c0debcf87d5f5909289ce15adfAlex Vakulenko#include <base/json/json_reader.h> 124a4c706fa989e4643cb5b3d675656586b42d895Paul Stewart#include <base/logging.h> 13c95f06bd6f672f408c5f77948781392098f52a86Alex Vakulenko#include <base/strings/string_util.h> 146ef2d737ce25f4c0debcf87d5f5909289ce15adfAlex Vakulenko#include <base/values.h> 15be6240db3b8a0981ce0f800247105154ff8e4960Alex Vakulenko#include <brillo/syslog_logging.h> 164a4c706fa989e4643cb5b3d675656586b42d895Paul Stewart 17b9b3f9d3654f15b221f47f5f24bd874102a27ed2Paul Stewart#include "chromeos-dbus-bindings/adaptor_generator.h" 18154cad5f50f22e473237bb2ead8b5789180cfe2fPaul Stewart#include "chromeos-dbus-bindings/method_name_generator.h" 191dce1ae6ca266668e37d6bc4009692bbc12e2bb6Paul Stewart#include "chromeos-dbus-bindings/proxy_generator.h" 202b1c6124a7c74225e231132a68e1a92723a26da9Paul Stewart#include "chromeos-dbus-bindings/xml_interface_parser.h" 212b1c6124a7c74225e231132a68e1a92723a26da9Paul Stewart 22fafef1300f94cada37c4fac0e0c7ba46aeee5ad1Alex Vakulenkousing chromeos_dbus_bindings::AdaptorGenerator; 23fafef1300f94cada37c4fac0e0c7ba46aeee5ad1Alex Vakulenkousing chromeos_dbus_bindings::MethodNameGenerator; 24fafef1300f94cada37c4fac0e0c7ba46aeee5ad1Alex Vakulenkousing chromeos_dbus_bindings::ProxyGenerator; 256ef2d737ce25f4c0debcf87d5f5909289ce15adfAlex Vakulenkousing chromeos_dbus_bindings::ServiceConfig; 26fafef1300f94cada37c4fac0e0c7ba46aeee5ad1Alex Vakulenko 274a4c706fa989e4643cb5b3d675656586b42d895Paul Stewartnamespace switches { 284a4c706fa989e4643cb5b3d675656586b42d895Paul Stewart 294a4c706fa989e4643cb5b3d675656586b42d895Paul Stewartstatic const char kHelp[] = "help"; 30154cad5f50f22e473237bb2ead8b5789180cfe2fPaul Stewartstatic const char kMethodNames[] = "method-names"; 31b9b3f9d3654f15b221f47f5f24bd874102a27ed2Paul Stewartstatic const char kAdaptor[] = "adaptor"; 321dce1ae6ca266668e37d6bc4009692bbc12e2bb6Paul Stewartstatic const char kProxy[] = "proxy"; 33008e19dd69bfc8439454a14df159b5a829881956Alex Vakulenkostatic const char kMock[] = "mock"; 34a30e09dde8bde67a44a2275b58d3f9d058207e57Christopher Wileystatic const char kProxyPathForMocks[] = "proxy-path-in-mocks"; 356ef2d737ce25f4c0debcf87d5f5909289ce15adfAlex Vakulenkostatic const char kServiceConfig[] = "service-config"; 364a4c706fa989e4643cb5b3d675656586b42d895Paul Stewartstatic const char kHelpMessage[] = "\n" 37c95f06bd6f672f408c5f77948781392098f52a86Alex Vakulenko "generate-chromeos-dbus-bindings itf1.xml [itf2.xml...] [switches]\n" 38c95f06bd6f672f408c5f77948781392098f52a86Alex Vakulenko " itf1.xml, ... = the input interface file(s) [mandatory].\n" 394a4c706fa989e4643cb5b3d675656586b42d895Paul Stewart "Available Switches: \n" 40154cad5f50f22e473237bb2ead8b5789180cfe2fPaul Stewart " --method-names=<method name header filename>\n" 41b9b3f9d3654f15b221f47f5f24bd874102a27ed2Paul Stewart " The output header file with string constants for each method name.\n" 42b9b3f9d3654f15b221f47f5f24bd874102a27ed2Paul Stewart " --adaptor=<adaptor header filename>\n" 431dce1ae6ca266668e37d6bc4009692bbc12e2bb6Paul Stewart " The output header file name containing the DBus adaptor class.\n" 441dce1ae6ca266668e37d6bc4009692bbc12e2bb6Paul Stewart " --proxy=<proxy header filename>\n" 456ef2d737ce25f4c0debcf87d5f5909289ce15adfAlex Vakulenko " The output header file name containing the DBus proxy class.\n" 46008e19dd69bfc8439454a14df159b5a829881956Alex Vakulenko " --mock=<mock header filename>\n" 47008e19dd69bfc8439454a14df159b5a829881956Alex Vakulenko " The output header file name containing the DBus proxy mock class.\n" 486ef2d737ce25f4c0debcf87d5f5909289ce15adfAlex Vakulenko " --service-config=<config.json>\n" 496ef2d737ce25f4c0debcf87d5f5909289ce15adfAlex Vakulenko " The DBus service configuration file for the generator.\n"; 504a4c706fa989e4643cb5b3d675656586b42d895Paul Stewart 514a4c706fa989e4643cb5b3d675656586b42d895Paul Stewart} // namespace switches 524a4c706fa989e4643cb5b3d675656586b42d895Paul Stewart 536ef2d737ce25f4c0debcf87d5f5909289ce15adfAlex Vakulenkonamespace { 546ef2d737ce25f4c0debcf87d5f5909289ce15adfAlex Vakulenko// GYP sometimes enclosed the target file name in extra set of quotes like: 556ef2d737ce25f4c0debcf87d5f5909289ce15adfAlex Vakulenko// generate-chromeos-dbus-bindings in.xml "--adaptor=\"out.h\"" 566ef2d737ce25f4c0debcf87d5f5909289ce15adfAlex Vakulenko// So, this function helps us to remove them. 576ef2d737ce25f4c0debcf87d5f5909289ce15adfAlex Vakulenkobase::FilePath RemoveQuotes(const std::string& path) { 586ef2d737ce25f4c0debcf87d5f5909289ce15adfAlex Vakulenko std::string unquoted; 596ef2d737ce25f4c0debcf87d5f5909289ce15adfAlex Vakulenko base::TrimString(path, "\"'", &unquoted); 606ef2d737ce25f4c0debcf87d5f5909289ce15adfAlex Vakulenko return base::FilePath{unquoted}; 616ef2d737ce25f4c0debcf87d5f5909289ce15adfAlex Vakulenko} 626ef2d737ce25f4c0debcf87d5f5909289ce15adfAlex Vakulenko 636ef2d737ce25f4c0debcf87d5f5909289ce15adfAlex Vakulenko// Makes a canonical path by making the path absolute and by removing any 646ef2d737ce25f4c0debcf87d5f5909289ce15adfAlex Vakulenko// '..' which makes base::ReadFileToString() to fail. 656ef2d737ce25f4c0debcf87d5f5909289ce15adfAlex Vakulenkobase::FilePath SanitizeFilePath(const std::string& path) { 666ef2d737ce25f4c0debcf87d5f5909289ce15adfAlex Vakulenko base::FilePath path_in = RemoveQuotes(path); 676ef2d737ce25f4c0debcf87d5f5909289ce15adfAlex Vakulenko base::FilePath path_out = base::MakeAbsoluteFilePath(path_in); 686ef2d737ce25f4c0debcf87d5f5909289ce15adfAlex Vakulenko if (path_out.value().empty()) { 696ef2d737ce25f4c0debcf87d5f5909289ce15adfAlex Vakulenko LOG(WARNING) << "Failed to canonicalize '" << path << "'"; 706ef2d737ce25f4c0debcf87d5f5909289ce15adfAlex Vakulenko path_out = path_in; 716ef2d737ce25f4c0debcf87d5f5909289ce15adfAlex Vakulenko } 726ef2d737ce25f4c0debcf87d5f5909289ce15adfAlex Vakulenko return path_out; 736ef2d737ce25f4c0debcf87d5f5909289ce15adfAlex Vakulenko} 746ef2d737ce25f4c0debcf87d5f5909289ce15adfAlex Vakulenko 756ef2d737ce25f4c0debcf87d5f5909289ce15adfAlex Vakulenko 766ef2d737ce25f4c0debcf87d5f5909289ce15adfAlex Vakulenko// Load the service configuration from the provided JSON file. 776ef2d737ce25f4c0debcf87d5f5909289ce15adfAlex Vakulenkobool LoadConfig(const base::FilePath& path, ServiceConfig *config) { 786ef2d737ce25f4c0debcf87d5f5909289ce15adfAlex Vakulenko std::string contents; 796ef2d737ce25f4c0debcf87d5f5909289ce15adfAlex Vakulenko if (!base::ReadFileToString(path, &contents)) 806ef2d737ce25f4c0debcf87d5f5909289ce15adfAlex Vakulenko return false; 816ef2d737ce25f4c0debcf87d5f5909289ce15adfAlex Vakulenko 820bd7dd71a61171d9609ecc7722e8fd87e0afdda2Alex Vakulenko std::unique_ptr<base::Value> json{base::JSONReader::Read(contents).release()}; 836ef2d737ce25f4c0debcf87d5f5909289ce15adfAlex Vakulenko if (!json) 846ef2d737ce25f4c0debcf87d5f5909289ce15adfAlex Vakulenko return false; 856ef2d737ce25f4c0debcf87d5f5909289ce15adfAlex Vakulenko 866ef2d737ce25f4c0debcf87d5f5909289ce15adfAlex Vakulenko base::DictionaryValue* dict = nullptr; // Aliased with |json|. 876ef2d737ce25f4c0debcf87d5f5909289ce15adfAlex Vakulenko if (!json->GetAsDictionary(&dict)) 886ef2d737ce25f4c0debcf87d5f5909289ce15adfAlex Vakulenko return false; 896ef2d737ce25f4c0debcf87d5f5909289ce15adfAlex Vakulenko 906ef2d737ce25f4c0debcf87d5f5909289ce15adfAlex Vakulenko dict->GetStringWithoutPathExpansion("service_name", &config->service_name); 9199e8fb04c1176e856026f14fd9ffc04b66115e0cAlex Vakulenko 9299e8fb04c1176e856026f14fd9ffc04b66115e0cAlex Vakulenko base::DictionaryValue* om_dict = nullptr; // Owned by |dict|. 9399e8fb04c1176e856026f14fd9ffc04b66115e0cAlex Vakulenko if (dict->GetDictionaryWithoutPathExpansion("object_manager", &om_dict)) { 9499e8fb04c1176e856026f14fd9ffc04b66115e0cAlex Vakulenko if (!om_dict->GetStringWithoutPathExpansion("name", 9599e8fb04c1176e856026f14fd9ffc04b66115e0cAlex Vakulenko &config->object_manager.name) && 9699e8fb04c1176e856026f14fd9ffc04b66115e0cAlex Vakulenko !config->service_name.empty()) { 9799e8fb04c1176e856026f14fd9ffc04b66115e0cAlex Vakulenko config->object_manager.name = config->service_name + ".ObjectManager"; 9899e8fb04c1176e856026f14fd9ffc04b66115e0cAlex Vakulenko } 9999e8fb04c1176e856026f14fd9ffc04b66115e0cAlex Vakulenko om_dict->GetStringWithoutPathExpansion("object_path", 10099e8fb04c1176e856026f14fd9ffc04b66115e0cAlex Vakulenko &config->object_manager.object_path); 101e2a3338c9b7a772c2e7a2ab7d41551262f00cfebAlex Vakulenko if (config->object_manager.name.empty()) { 102e2a3338c9b7a772c2e7a2ab7d41551262f00cfebAlex Vakulenko LOG(ERROR) << "Object manager name is missing."; 103e2a3338c9b7a772c2e7a2ab7d41551262f00cfebAlex Vakulenko return false; 104e2a3338c9b7a772c2e7a2ab7d41551262f00cfebAlex Vakulenko } 105e2a3338c9b7a772c2e7a2ab7d41551262f00cfebAlex Vakulenko } 106e2a3338c9b7a772c2e7a2ab7d41551262f00cfebAlex Vakulenko 107e2a3338c9b7a772c2e7a2ab7d41551262f00cfebAlex Vakulenko base::ListValue* list = nullptr; // Owned by |dict|. 108e2a3338c9b7a772c2e7a2ab7d41551262f00cfebAlex Vakulenko if (dict->GetListWithoutPathExpansion("ignore_interfaces", &list)) { 109e2a3338c9b7a772c2e7a2ab7d41551262f00cfebAlex Vakulenko config->ignore_interfaces.reserve(list->GetSize()); 110e2a3338c9b7a772c2e7a2ab7d41551262f00cfebAlex Vakulenko for (base::Value* item : *list) { 111e2a3338c9b7a772c2e7a2ab7d41551262f00cfebAlex Vakulenko std::string interface_name; 112e2a3338c9b7a772c2e7a2ab7d41551262f00cfebAlex Vakulenko if (!item->GetAsString(&interface_name)) { 113e2a3338c9b7a772c2e7a2ab7d41551262f00cfebAlex Vakulenko LOG(ERROR) << "Invalid interface name in [ignore_interfaces] section"; 114e2a3338c9b7a772c2e7a2ab7d41551262f00cfebAlex Vakulenko return false; 115e2a3338c9b7a772c2e7a2ab7d41551262f00cfebAlex Vakulenko } 116e2a3338c9b7a772c2e7a2ab7d41551262f00cfebAlex Vakulenko config->ignore_interfaces.push_back(interface_name); 117e2a3338c9b7a772c2e7a2ab7d41551262f00cfebAlex Vakulenko } 11899e8fb04c1176e856026f14fd9ffc04b66115e0cAlex Vakulenko } 11999e8fb04c1176e856026f14fd9ffc04b66115e0cAlex Vakulenko 1206ef2d737ce25f4c0debcf87d5f5909289ce15adfAlex Vakulenko return true; 1216ef2d737ce25f4c0debcf87d5f5909289ce15adfAlex Vakulenko} 1226ef2d737ce25f4c0debcf87d5f5909289ce15adfAlex Vakulenko 1236ef2d737ce25f4c0debcf87d5f5909289ce15adfAlex Vakulenko} // anonymous namespace 1246ef2d737ce25f4c0debcf87d5f5909289ce15adfAlex Vakulenko 1254a4c706fa989e4643cb5b3d675656586b42d895Paul Stewartint main(int argc, char** argv) { 126b000aae2c03cc3fa6980f57993a52a81363b3518Alex Vakulenko base::CommandLine::Init(argc, argv); 127b000aae2c03cc3fa6980f57993a52a81363b3518Alex Vakulenko base::CommandLine* cl = base::CommandLine::ForCurrentProcess(); 1284a4c706fa989e4643cb5b3d675656586b42d895Paul Stewart 129cc0b8b16d1e2b5d286ef2bad41be978fa4a887efAlex Deymo // Setup logging to stderr. This also parses some implicit flags using the 130cc0b8b16d1e2b5d286ef2bad41be978fa4a887efAlex Deymo // CommandLine singleton. 131be6240db3b8a0981ce0f800247105154ff8e4960Alex Vakulenko brillo::InitLog(brillo::kLogToStderr | brillo::kLogHeader); 132cc0b8b16d1e2b5d286ef2bad41be978fa4a887efAlex Deymo 1334a4c706fa989e4643cb5b3d675656586b42d895Paul Stewart if (cl->HasSwitch(switches::kHelp)) { 1344a4c706fa989e4643cb5b3d675656586b42d895Paul Stewart LOG(INFO) << switches::kHelpMessage; 1354a4c706fa989e4643cb5b3d675656586b42d895Paul Stewart return 0; 1364a4c706fa989e4643cb5b3d675656586b42d895Paul Stewart } 1374a4c706fa989e4643cb5b3d675656586b42d895Paul Stewart 138c95f06bd6f672f408c5f77948781392098f52a86Alex Vakulenko auto input_files = cl->GetArgs(); 139c95f06bd6f672f408c5f77948781392098f52a86Alex Vakulenko if (input_files.empty()) { 140c95f06bd6f672f408c5f77948781392098f52a86Alex Vakulenko LOG(ERROR) << "At least one file must be specified."; 1414a4c706fa989e4643cb5b3d675656586b42d895Paul Stewart LOG(ERROR) << switches::kHelpMessage; 1424a4c706fa989e4643cb5b3d675656586b42d895Paul Stewart return 1; 1434a4c706fa989e4643cb5b3d675656586b42d895Paul Stewart } 1444a4c706fa989e4643cb5b3d675656586b42d895Paul Stewart 145e2a3338c9b7a772c2e7a2ab7d41551262f00cfebAlex Vakulenko ServiceConfig config; 146e2a3338c9b7a772c2e7a2ab7d41551262f00cfebAlex Vakulenko if (cl->HasSwitch(switches::kServiceConfig)) { 147e2a3338c9b7a772c2e7a2ab7d41551262f00cfebAlex Vakulenko std::string config_file = cl->GetSwitchValueASCII(switches::kServiceConfig); 148e2a3338c9b7a772c2e7a2ab7d41551262f00cfebAlex Vakulenko if (!config_file.empty() && 149e2a3338c9b7a772c2e7a2ab7d41551262f00cfebAlex Vakulenko !LoadConfig(SanitizeFilePath(config_file), &config)) { 150e2a3338c9b7a772c2e7a2ab7d41551262f00cfebAlex Vakulenko LOG(ERROR) << "Failed to load DBus service config file " << config_file; 151e2a3338c9b7a772c2e7a2ab7d41551262f00cfebAlex Vakulenko return 1; 152e2a3338c9b7a772c2e7a2ab7d41551262f00cfebAlex Vakulenko } 153e2a3338c9b7a772c2e7a2ab7d41551262f00cfebAlex Vakulenko } 154e2a3338c9b7a772c2e7a2ab7d41551262f00cfebAlex Vakulenko 1552b1c6124a7c74225e231132a68e1a92723a26da9Paul Stewart chromeos_dbus_bindings::XmlInterfaceParser parser; 156c95f06bd6f672f408c5f77948781392098f52a86Alex Vakulenko for (const auto& input : input_files) { 1576ef2d737ce25f4c0debcf87d5f5909289ce15adfAlex Vakulenko std::string contents; 1586ef2d737ce25f4c0debcf87d5f5909289ce15adfAlex Vakulenko if (!base::ReadFileToString(SanitizeFilePath(input), &contents)) { 1596ef2d737ce25f4c0debcf87d5f5909289ce15adfAlex Vakulenko LOG(ERROR) << "Failed to read file " << input; 1606ef2d737ce25f4c0debcf87d5f5909289ce15adfAlex Vakulenko return 1; 1616ef2d737ce25f4c0debcf87d5f5909289ce15adfAlex Vakulenko } 162e2a3338c9b7a772c2e7a2ab7d41551262f00cfebAlex Vakulenko if (!parser.ParseXmlInterfaceFile(contents, config.ignore_interfaces)) { 163824b5246a3ab5c70d32938ed9c3b982f5624dfe9Christopher Wiley LOG(ERROR) << "Failed to parse interface file " << input; 164c95f06bd6f672f408c5f77948781392098f52a86Alex Vakulenko return 1; 165c95f06bd6f672f408c5f77948781392098f52a86Alex Vakulenko } 1662b1c6124a7c74225e231132a68e1a92723a26da9Paul Stewart } 1672b1c6124a7c74225e231132a68e1a92723a26da9Paul Stewart 168b9b3f9d3654f15b221f47f5f24bd874102a27ed2Paul Stewart if (cl->HasSwitch(switches::kMethodNames)) { 169154cad5f50f22e473237bb2ead8b5789180cfe2fPaul Stewart std::string method_name_file = 170154cad5f50f22e473237bb2ead8b5789180cfe2fPaul Stewart cl->GetSwitchValueASCII(switches::kMethodNames); 171cc0b8b16d1e2b5d286ef2bad41be978fa4a887efAlex Deymo VLOG(1) << "Outputting method names to " << method_name_file; 172fafef1300f94cada37c4fac0e0c7ba46aeee5ad1Alex Vakulenko if (!MethodNameGenerator::GenerateMethodNames( 173fafef1300f94cada37c4fac0e0c7ba46aeee5ad1Alex Vakulenko parser.interfaces(), 1746ef2d737ce25f4c0debcf87d5f5909289ce15adfAlex Vakulenko RemoveQuotes(method_name_file))) { 175154cad5f50f22e473237bb2ead8b5789180cfe2fPaul Stewart LOG(ERROR) << "Failed to output method names."; 176154cad5f50f22e473237bb2ead8b5789180cfe2fPaul Stewart return 1; 177fafef1300f94cada37c4fac0e0c7ba46aeee5ad1Alex Vakulenko } 178154cad5f50f22e473237bb2ead8b5789180cfe2fPaul Stewart } 179154cad5f50f22e473237bb2ead8b5789180cfe2fPaul Stewart 180b9b3f9d3654f15b221f47f5f24bd874102a27ed2Paul Stewart if (cl->HasSwitch(switches::kAdaptor)) { 181b9b3f9d3654f15b221f47f5f24bd874102a27ed2Paul Stewart std::string adaptor_file = cl->GetSwitchValueASCII(switches::kAdaptor); 182cc0b8b16d1e2b5d286ef2bad41be978fa4a887efAlex Deymo VLOG(1) << "Outputting adaptor to " << adaptor_file; 183fafef1300f94cada37c4fac0e0c7ba46aeee5ad1Alex Vakulenko if (!AdaptorGenerator::GenerateAdaptors(parser.interfaces(), 1846ef2d737ce25f4c0debcf87d5f5909289ce15adfAlex Vakulenko RemoveQuotes(adaptor_file))) { 185b9b3f9d3654f15b221f47f5f24bd874102a27ed2Paul Stewart LOG(ERROR) << "Failed to output adaptor."; 186b9b3f9d3654f15b221f47f5f24bd874102a27ed2Paul Stewart return 1; 187b9b3f9d3654f15b221f47f5f24bd874102a27ed2Paul Stewart } 188b9b3f9d3654f15b221f47f5f24bd874102a27ed2Paul Stewart } 189b9b3f9d3654f15b221f47f5f24bd874102a27ed2Paul Stewart 190008e19dd69bfc8439454a14df159b5a829881956Alex Vakulenko base::FilePath proxy_path; // Used by both Proxy and Mock generation. 1911dce1ae6ca266668e37d6bc4009692bbc12e2bb6Paul Stewart if (cl->HasSwitch(switches::kProxy)) { 1921dce1ae6ca266668e37d6bc4009692bbc12e2bb6Paul Stewart std::string proxy_file = cl->GetSwitchValueASCII(switches::kProxy); 193008e19dd69bfc8439454a14df159b5a829881956Alex Vakulenko proxy_path = RemoveQuotes(proxy_file); 194008e19dd69bfc8439454a14df159b5a829881956Alex Vakulenko base::NormalizeFilePath(proxy_path, &proxy_path); 195008e19dd69bfc8439454a14df159b5a829881956Alex Vakulenko VLOG(1) << "Outputting proxy to " << proxy_path.value(); 1966ef2d737ce25f4c0debcf87d5f5909289ce15adfAlex Vakulenko if (!ProxyGenerator::GenerateProxies(config, parser.interfaces(), 197008e19dd69bfc8439454a14df159b5a829881956Alex Vakulenko proxy_path)) { 1981dce1ae6ca266668e37d6bc4009692bbc12e2bb6Paul Stewart LOG(ERROR) << "Failed to output proxy."; 1991dce1ae6ca266668e37d6bc4009692bbc12e2bb6Paul Stewart return 1; 2001dce1ae6ca266668e37d6bc4009692bbc12e2bb6Paul Stewart } 2011dce1ae6ca266668e37d6bc4009692bbc12e2bb6Paul Stewart } 2021dce1ae6ca266668e37d6bc4009692bbc12e2bb6Paul Stewart 203a30e09dde8bde67a44a2275b58d3f9d058207e57Christopher Wiley base::FilePath proxy_include_path = proxy_path; 204a30e09dde8bde67a44a2275b58d3f9d058207e57Christopher Wiley bool use_literal_include_path = false; 205a30e09dde8bde67a44a2275b58d3f9d058207e57Christopher Wiley if (cl->HasSwitch(switches::kProxyPathForMocks)) { 206a30e09dde8bde67a44a2275b58d3f9d058207e57Christopher Wiley std::string proxy_file_in_mocks = 207a30e09dde8bde67a44a2275b58d3f9d058207e57Christopher Wiley cl->GetSwitchValueASCII(switches::kProxyPathForMocks); 208a30e09dde8bde67a44a2275b58d3f9d058207e57Christopher Wiley proxy_include_path = RemoveQuotes(proxy_file_in_mocks); 209a30e09dde8bde67a44a2275b58d3f9d058207e57Christopher Wiley use_literal_include_path = true; 210a30e09dde8bde67a44a2275b58d3f9d058207e57Christopher Wiley } 211a30e09dde8bde67a44a2275b58d3f9d058207e57Christopher Wiley 212008e19dd69bfc8439454a14df159b5a829881956Alex Vakulenko if (cl->HasSwitch(switches::kMock)) { 213008e19dd69bfc8439454a14df159b5a829881956Alex Vakulenko std::string mock_file = cl->GetSwitchValueASCII(switches::kMock); 214008e19dd69bfc8439454a14df159b5a829881956Alex Vakulenko base::FilePath mock_path = RemoveQuotes(mock_file); 215008e19dd69bfc8439454a14df159b5a829881956Alex Vakulenko base::NormalizeFilePath(mock_path, &mock_path); 216008e19dd69bfc8439454a14df159b5a829881956Alex Vakulenko VLOG(1) << "Outputting mock to " << mock_path.value(); 217008e19dd69bfc8439454a14df159b5a829881956Alex Vakulenko if (!ProxyGenerator::GenerateMocks(config, parser.interfaces(), mock_path, 218a30e09dde8bde67a44a2275b58d3f9d058207e57Christopher Wiley proxy_include_path, 219a30e09dde8bde67a44a2275b58d3f9d058207e57Christopher Wiley use_literal_include_path)) { 220008e19dd69bfc8439454a14df159b5a829881956Alex Vakulenko LOG(ERROR) << "Failed to output mock."; 221008e19dd69bfc8439454a14df159b5a829881956Alex Vakulenko return 1; 222008e19dd69bfc8439454a14df159b5a829881956Alex Vakulenko } 223008e19dd69bfc8439454a14df159b5a829881956Alex Vakulenko } 224008e19dd69bfc8439454a14df159b5a829881956Alex Vakulenko 2254a4c706fa989e4643cb5b3d675656586b42d895Paul Stewart return 0; 2264a4c706fa989e4643cb5b3d675656586b42d895Paul Stewart} 227