blob: 308414b360a66ddb3171fadbe73c505e97064c91 [file] [log] [blame]
// Copyright 2020 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "tools/symbol-index/command_line_options.h"
#include <lib/cmdline/args_parser.h>
#include "src/lib/fxl/strings/string_printf.h"
namespace symbol_index {
namespace {
const char kHelpIntro[] = R"(symbol-index [ <options> ] <verb> [ <arguments> ... ]
Manipulates a symbol-index file.
Available verbs:
list
Lists all paths in symbol-index.
add <symbol path> [ <build directory> ]
Adds a new symbol path to symbol-index. A symbol path could be either a
a text file in "ids.txt" format, or a directory in ".build-id" structure.
An optional build directory could be supplemented, which is used by zxdb
to locate the source code. If the symbol path is already in symbol-index,
no changes will be made regardless of the optional build directory.
add-all [ <input file> ]
Reads the input and adds all symbol paths with optional build directories.
The input file can contain multiple lines, each describing a symbol path.
An optional build directory could be supplemented and separated from the
symbol path with whitespaces. Relative paths will be resolved based on
the input file. Empty lines and lines starting with "#" will be ignored.
If the input file is not specified, the input will be read from the stdin.
remove <symbol path>
Removes a symbol path from symbol-index.
purge
Removes all non-existent paths from symbol-index.
Options
)";
const char kConfigHelp[] = R"( --config=<path>
-c <path>
Path to the symbol-index config file, default to
~/.fuchsia/debug/symbol-index.)";
const char kHelpHelp[] = R"( --help
-h
Prints this help.)";
const char kVersionHelp[] = R"( --version
-v
Prints the version.)";
using ::analytics::core_dev_tools::kAnalyticsHelp;
using ::analytics::core_dev_tools::kAnalyticsShowHelp;
} // namespace
Error CommandLineOptions::SetVerb(const std::string& str) {
if (str == "list")
verb = Verb::kList;
else if (str == "add")
verb = Verb::kAdd;
else if (str == "add-all")
verb = Verb::kAddAll;
else if (str == "remove")
verb = Verb::kRemove;
else if (str == "purge")
verb = Verb::kPurge;
else
return fxl::StringPrintf("Unsupported verb: %s", str.c_str());
return "";
}
Error CommandLineOptions::Validate() {
size_t params_size = params.size();
switch (verb) {
case Verb::kList:
if (params_size != 0)
return fxl::StringPrintf("Verb list requires 0 arguments, but %lu is given.", params_size);
break;
case Verb::kAdd:
if (params_size < 1 || params_size > 2) {
return fxl::StringPrintf("Verb add requires 1 or 2 arguments, but %lu is given.",
params_size);
}
break;
case Verb::kAddAll:
if (params_size > 1) {
return fxl::StringPrintf("Verb add-all requires 0 or 1 arguments, but %lu is given.",
params_size);
}
break;
case Verb::kRemove:
if (params_size != 1)
return fxl::StringPrintf("Verb remove requires 1 argument, but %lu is given.", params_size);
break;
case Verb::kPurge:
if (params_size != 0)
return fxl::StringPrintf("Verb purge requires 0 arguments, but %lu is given.", params_size);
break;
}
return "";
}
Error ParseCommandLine(int argc, const char* argv[], CommandLineOptions* options) {
using analytics::core_dev_tools::AnalyticsOption;
using analytics::core_dev_tools::ParseAnalyticsOption;
std::vector<std::string> params;
cmdline::ArgsParser<CommandLineOptions> parser;
parser.AddSwitch("config", 'c', kConfigHelp, &CommandLineOptions::symbol_index_file);
parser.AddSwitch("version", 'v', kVersionHelp, &CommandLineOptions::requested_version);
parser.AddSwitch("analytics", 0, kAnalyticsHelp, &CommandLineOptions::analytics);
parser.AddSwitch("analytics-show", 0, kAnalyticsShowHelp, &CommandLineOptions::analytics_show);
// Special --help switch which doesn't exist in the options structure.
bool requested_help = false;
parser.AddGeneralSwitch("help", 'h', kHelpHelp, [&requested_help]() { requested_help = true; });
auto s = parser.Parse(argc, argv, options, &params);
if (s.has_error()) {
return s.error_message();
}
if (options->requested_version) {
return "";
}
if (options->analytics_show || options->analytics == AnalyticsOption::kEnable ||
options->analytics == AnalyticsOption::kDisable) {
return "";
}
if (requested_help || params.empty()) {
return kHelpIntro + parser.GetHelp();
}
if (Error err = options->SetVerb(params[0]); !err.empty()) {
return err;
}
options->params.resize(params.size() - 1);
std::copy(params.begin() + 1, params.end(), options->params.begin());
if (Error err = options->Validate(); !err.empty()) {
return err;
}
return "";
}
} // namespace symbol_index