blob: dde600f5ef56c25f92da6ad39d6f3aaa15781f98 [file] [log] [blame]
// Copyright 2018 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 "src/developer/debug/zxdb/console/format_settings.h"
#include "src/developer/debug/zxdb/client/session.h"
#include "src/developer/debug/zxdb/client/setting_schema.h"
#include "src/developer/debug/zxdb/client/setting_store.h"
#include "src/developer/debug/zxdb/client/system.h"
#include "src/developer/debug/zxdb/client/target.h"
#include "src/developer/debug/zxdb/client/thread.h"
#include "src/developer/debug/zxdb/common/err.h"
#include "src/developer/debug/zxdb/console/command.h"
#include "src/developer/debug/zxdb/console/format_table.h"
#include "src/developer/debug/zxdb/console/output_buffer.h"
#include "src/developer/debug/zxdb/console/string_util.h"
#include "src/lib/fxl/strings/join_strings.h"
#include "src/lib/fxl/strings/string_printf.h"
namespace zxdb {
namespace {
std::string SettingValueToString(const SettingValue& value) {
switch (value.type) {
case SettingType::kBoolean:
return value.get_bool() ? "true" : "false";
case SettingType::kInteger:
return fxl::StringPrintf("%d", value.get_int());
case SettingType::kString: {
auto string = value.get_string();
return string.empty() ? "<empty>" : string;
}
case SettingType::kList:
// Lists are formatted as a colon separated string.
// Example
// list = {"first", "second", "third"} -> "first:second:third"
return fxl::JoinStrings(value.get_list(), ":");
case SettingType::kNull:
return "<null>";
}
}
std::vector<std::string> ListToBullet(const std::vector<std::string>& list) {
std::vector<std::string> output;
output.reserve(list.size());
auto bullet = GetBullet();
for (const std::string& item : list)
output.emplace_back(
fxl::StringPrintf("%s %s", bullet.c_str(), item.c_str()));
return output;
}
// |add_heading| refers whether it should show the setting name or just list the
// values.
void AddSettingToTable(const Setting& setting,
std::vector<std::vector<OutputBuffer>>* rows,
bool add_heading = true) {
// TODO(donosoc): We need to check what level the setting comes from so we can
// highlight it in the listing.
if (!setting.value.is_list()) {
// Normal values as just entered as key-value pairs.
auto& row = rows->emplace_back();
if (add_heading)
row.emplace_back(setting.info.name);
row.emplace_back(SettingValueToString(setting.value));
} else {
// List get special treatment so that we can show them as bullet lists.
// This make reading them much easier when the elements of the lists
// are long (eg. paths).
auto bullet_list = ListToBullet(setting.value.get_list());
// Special case for empty list.
if (bullet_list.empty()) {
auto& row = rows->emplace_back();
if (add_heading)
row.emplace_back(setting.info.name);
row.emplace_back("<empty>");
} else {
for (size_t i = 0; i < bullet_list.size(); i++) {
auto& row = rows->emplace_back();
if (add_heading) {
// The first entry has the setting name.
auto title = i == 0 ? OutputBuffer(setting.info.name)
: OutputBuffer();
auto it = row.emplace_back(std::move(title));
}
row.emplace_back(std::move(bullet_list[i]));
}
}
}
}
} // namespace
OutputBuffer FormatSettingStore(const SettingStore& store) {
std::vector<std::vector<OutputBuffer>> rows;
for (auto [key, _] : store.schema()->settings()) {
auto setting = store.GetSetting(key);
FXL_DCHECK(!setting.value.is_null());
AddSettingToTable(setting, &rows);
}
OutputBuffer table;
FormatTable(std::vector<ColSpec>(3), rows, &table);
return table;
}
OutputBuffer FormatSetting(const Setting& setting) {
OutputBuffer out;
out.Append({Syntax::kHeading, setting.info.name});
out.Append(OutputBuffer("\n"));
out.Append(setting.info.description);
out.Append(OutputBuffer("\n\n"));
out.Append({Syntax::kHeading, "Type: "});
out.Append(SettingTypeToString(setting.value.type));
out.Append("\n\n");
out.Append({Syntax::kHeading, "Value(s):\n"});
out.Append(FormatSettingShort(setting));
// List have a copy-paste value for setting the value.
if (setting.value.is_list()) {
out.Append("\n");
out.Append({Syntax::kComment,
"See \"help set\" about using the set value for lists.\n"});
out.Append(fxl::StringPrintf("Set value: %s",
SettingValueToString(setting.value).c_str()));
out.Append("\n");
}
return out;
}
OutputBuffer FormatSettingShort(const Setting& setting) {
FXL_DCHECK(!setting.value.is_null());
OutputBuffer out;
std::vector<std::vector<OutputBuffer>> rows;
AddSettingToTable(setting, &rows, false);
FormatTable(std::vector<ColSpec>{1}, std::move(rows), &out);
return out;
}
} // namespace zxdb