idmap2: move commands to Result<Unit>
Change the signature of the idmap2 commands (Create, Dump, ...) to
return Result<Unit> instead of bool. This removes the need to pass in an
ostream for error messages: instead, those messages are part of the
returned Result.
Consolidate error messages: texts in Error objects should not be
prefixed with "error:", that is the responsibility of the outer-most
caller (i.e. main()).
Test: make idmap2_tests
Change-Id: I074881b3d1982ea8f4be5752161ac74b14fcba95
diff --git a/cmds/idmap2/idmap2/Commands.h b/cmds/idmap2/idmap2/Commands.h
index dcc69b3..718e361 100644
--- a/cmds/idmap2/idmap2/Commands.h
+++ b/cmds/idmap2/idmap2/Commands.h
@@ -20,10 +20,12 @@
#include <string>
#include <vector>
-bool Create(const std::vector<std::string>& args, std::ostream& out_error);
-bool Dump(const std::vector<std::string>& args, std::ostream& out_error);
-bool Lookup(const std::vector<std::string>& args, std::ostream& out_error);
-bool Scan(const std::vector<std::string>& args, std::ostream& out_error);
-bool Verify(const std::vector<std::string>& args, std::ostream& out_error);
+#include "idmap2/Result.h"
+
+android::idmap2::Result<android::idmap2::Unit> Create(const std::vector<std::string>& args);
+android::idmap2::Result<android::idmap2::Unit> Dump(const std::vector<std::string>& args);
+android::idmap2::Result<android::idmap2::Unit> Lookup(const std::vector<std::string>& args);
+android::idmap2::Result<android::idmap2::Unit> Scan(const std::vector<std::string>& args);
+android::idmap2::Result<android::idmap2::Unit> Verify(const std::vector<std::string>& args);
#endif // IDMAP2_IDMAP2_COMMANDS_H_
diff --git a/cmds/idmap2/idmap2/Create.cpp b/cmds/idmap2/idmap2/Create.cpp
index c416fa1..fdbb210 100644
--- a/cmds/idmap2/idmap2/Create.cpp
+++ b/cmds/idmap2/idmap2/Create.cpp
@@ -33,14 +33,17 @@
using android::ApkAssets;
using android::idmap2::BinaryStreamVisitor;
using android::idmap2::CommandLineOptions;
+using android::idmap2::Error;
using android::idmap2::Idmap;
using android::idmap2::PoliciesToBitmask;
using android::idmap2::PolicyBitmask;
using android::idmap2::PolicyFlags;
+using android::idmap2::Result;
+using android::idmap2::Unit;
using android::idmap2::utils::kIdmapFilePermissionMask;
using android::idmap2::utils::UidHasWriteAccessToPath;
-bool Create(const std::vector<std::string>& args, std::ostream& out_error) {
+Result<Unit> Create(const std::vector<std::string>& args) {
SYSTRACE << "Create " << args;
std::string target_apk_path;
std::string overlay_apk_path;
@@ -63,15 +66,14 @@
&policies)
.OptionalFlag("--ignore-overlayable", "disables overlayable and policy checks",
&ignore_overlayable);
- if (!opts.Parse(args, out_error)) {
- return false;
+ const auto opts_ok = opts.Parse(args);
+ if (!opts_ok) {
+ return opts_ok.GetError();
}
const uid_t uid = getuid();
if (!UidHasWriteAccessToPath(uid, idmap_path)) {
- out_error << "error: uid " << uid << " does not have write access to " << idmap_path
- << std::endl;
- return false;
+ return Error("uid %d does not have write access to %s", uid, idmap_path.c_str());
}
PolicyBitmask fulfilled_policies = 0;
@@ -79,8 +81,7 @@
if (conv_result) {
fulfilled_policies |= *conv_result;
} else {
- out_error << "error: " << conv_result.GetErrorMessage() << std::endl;
- return false;
+ return conv_result.GetError();
}
if (fulfilled_policies == 0) {
@@ -89,36 +90,33 @@
const std::unique_ptr<const ApkAssets> target_apk = ApkAssets::Load(target_apk_path);
if (!target_apk) {
- out_error << "error: failed to load apk " << target_apk_path << std::endl;
- return false;
+ return Error("failed to load apk %s", target_apk_path.c_str());
}
const std::unique_ptr<const ApkAssets> overlay_apk = ApkAssets::Load(overlay_apk_path);
if (!overlay_apk) {
- out_error << "error: failed to load apk " << overlay_apk_path << std::endl;
- return false;
+ return Error("failed to load apk %s", overlay_apk_path.c_str());
}
+ std::stringstream stream;
const std::unique_ptr<const Idmap> idmap =
Idmap::FromApkAssets(target_apk_path, *target_apk, overlay_apk_path, *overlay_apk,
- fulfilled_policies, !ignore_overlayable, out_error);
+ fulfilled_policies, !ignore_overlayable, stream);
if (!idmap) {
- return false;
+ return Error("failed to create idmap: %s", stream.str().c_str());
}
umask(kIdmapFilePermissionMask);
std::ofstream fout(idmap_path);
if (fout.fail()) {
- out_error << "failed to open idmap path " << idmap_path << std::endl;
- return false;
+ return Error("failed to open idmap path %s", idmap_path.c_str());
}
BinaryStreamVisitor visitor(fout);
idmap->accept(&visitor);
fout.close();
if (fout.fail()) {
- out_error << "failed to write to idmap path " << idmap_path << std::endl;
- return false;
+ return Error("failed to write to idmap path %s", idmap_path.c_str());
}
- return true;
+ return Unit{};
}
diff --git a/cmds/idmap2/idmap2/Dump.cpp b/cmds/idmap2/idmap2/Dump.cpp
index 3947703..fd58222 100644
--- a/cmds/idmap2/idmap2/Dump.cpp
+++ b/cmds/idmap2/idmap2/Dump.cpp
@@ -17,6 +17,7 @@
#include <fstream>
#include <iostream>
#include <memory>
+#include <sstream>
#include <string>
#include <vector>
@@ -24,14 +25,18 @@
#include "idmap2/Idmap.h"
#include "idmap2/PrettyPrintVisitor.h"
#include "idmap2/RawPrintVisitor.h"
+#include "idmap2/Result.h"
#include "idmap2/SysTrace.h"
using android::idmap2::CommandLineOptions;
+using android::idmap2::Error;
using android::idmap2::Idmap;
using android::idmap2::PrettyPrintVisitor;
using android::idmap2::RawPrintVisitor;
+using android::idmap2::Result;
+using android::idmap2::Unit;
-bool Dump(const std::vector<std::string>& args, std::ostream& out_error) {
+Result<Unit> Dump(const std::vector<std::string>& args) {
SYSTRACE << "Dump " << args;
std::string idmap_path;
bool verbose;
@@ -40,14 +45,16 @@
CommandLineOptions("idmap2 dump")
.MandatoryOption("--idmap-path", "input: path to idmap file to pretty-print", &idmap_path)
.OptionalFlag("--verbose", "annotate every byte of the idmap", &verbose);
- if (!opts.Parse(args, out_error)) {
- return false;
+ const auto opts_ok = opts.Parse(args);
+ if (!opts_ok) {
+ return opts_ok.GetError();
}
+ std::stringstream stream;
std::ifstream fin(idmap_path);
- const std::unique_ptr<const Idmap> idmap = Idmap::FromBinaryStream(fin, out_error);
+ const std::unique_ptr<const Idmap> idmap = Idmap::FromBinaryStream(fin, stream);
fin.close();
if (!idmap) {
- return false;
+ return Error("failed to load idmap: %s", stream.str().c_str());
}
if (verbose) {
@@ -58,5 +65,5 @@
idmap->accept(&visitor);
}
- return true;
+ return Unit{};
}
diff --git a/cmds/idmap2/idmap2/Lookup.cpp b/cmds/idmap2/idmap2/Lookup.cpp
index 83a40ef..677c6fa 100644
--- a/cmds/idmap2/idmap2/Lookup.cpp
+++ b/cmds/idmap2/idmap2/Lookup.cpp
@@ -57,6 +57,7 @@
using android::idmap2::IdmapHeader;
using android::idmap2::ResourceId;
using android::idmap2::Result;
+using android::idmap2::Unit;
using android::idmap2::Xml;
using android::idmap2::ZipFile;
using android::util::Utf16ToUtf8;
@@ -157,7 +158,7 @@
}
} // namespace
-bool Lookup(const std::vector<std::string>& args, std::ostream& out_error) {
+Result<Unit> Lookup(const std::vector<std::string>& args) {
SYSTRACE << "Lookup " << args;
std::vector<std::string> idmap_paths;
std::string config_str;
@@ -172,14 +173,14 @@
"'[package:]type/name') to look up",
&resid_str);
- if (!opts.Parse(args, out_error)) {
- return false;
+ const auto opts_ok = opts.Parse(args);
+ if (!opts_ok) {
+ return opts_ok.GetError();
}
ConfigDescription config;
if (!ConfigDescription::Parse(config_str, &config)) {
- out_error << "error: failed to parse config" << std::endl;
- return false;
+ return Error("failed to parse config");
}
std::vector<std::unique_ptr<const ApkAssets>> apk_assets;
@@ -191,39 +192,33 @@
auto idmap_header = IdmapHeader::FromBinaryStream(fin);
fin.close();
if (!idmap_header) {
- out_error << "error: failed to read idmap from " << idmap_path << std::endl;
- return false;
+ return Error("failed to read idmap from %s", idmap_path.c_str());
}
if (i == 0) {
target_path = idmap_header->GetTargetPath().to_string();
auto target_apk = ApkAssets::Load(target_path);
if (!target_apk) {
- out_error << "error: failed to read target apk from " << target_path << std::endl;
- return false;
+ return Error("failed to read target apk from %s", target_path.c_str());
}
apk_assets.push_back(std::move(target_apk));
const Result<std::string> package_name =
GetTargetPackageNameFromManifest(idmap_header->GetOverlayPath().to_string());
if (!package_name) {
- out_error << "error: failed to parse android:targetPackage from overlay manifest"
- << std::endl;
- return false;
+ return Error("failed to parse android:targetPackage from overlay manifest");
}
target_package_name = *package_name;
} else if (target_path != idmap_header->GetTargetPath()) {
- out_error << "error: different target APKs (expected target APK " << target_path << " but "
- << idmap_path << " has target APK " << idmap_header->GetTargetPath() << ")"
- << std::endl;
- return false;
+ return Error("different target APKs (expected target APK %s but %s has target APK %s)",
+ target_path.c_str(), idmap_path.c_str(),
+ idmap_header->GetTargetPath().to_string().c_str());
}
auto overlay_apk = ApkAssets::LoadOverlay(idmap_path);
if (!overlay_apk) {
- out_error << "error: failed to read overlay apk from " << idmap_header->GetOverlayPath()
- << std::endl;
- return false;
+ return Error("failed to read overlay apk from %s",
+ idmap_header->GetOverlayPath().to_string().c_str());
}
apk_assets.push_back(std::move(overlay_apk));
}
@@ -238,16 +233,14 @@
const Result<ResourceId> resid = ParseResReference(am, resid_str, target_package_name);
if (!resid) {
- out_error << "error: failed to parse resource ID" << std::endl;
- return false;
+ return Error(resid.GetError(), "failed to parse resource ID");
}
const Result<std::string> value = GetValue(am, *resid);
if (!value) {
- out_error << StringPrintf("error: resource 0x%08x not found", *resid) << std::endl;
- return false;
+ return Error(value.GetError(), "resource 0x%08x not found", *resid);
}
std::cout << *value << std::endl;
- return true;
+ return Unit{};
}
diff --git a/cmds/idmap2/idmap2/Main.cpp b/cmds/idmap2/idmap2/Main.cpp
index a0ffccb..d8867fe 100644
--- a/cmds/idmap2/idmap2/Main.cpp
+++ b/cmds/idmap2/idmap2/Main.cpp
@@ -24,14 +24,17 @@
#include <vector>
#include "idmap2/CommandLineOptions.h"
+#include "idmap2/Result.h"
#include "idmap2/SysTrace.h"
#include "Commands.h"
using android::idmap2::CommandLineOptions;
+using android::idmap2::Result;
+using android::idmap2::Unit;
using NameToFunctionMap =
- std::map<std::string, std::function<bool(const std::vector<std::string>&, std::ostream&)>>;
+ std::map<std::string, std::function<Result<Unit>(const std::vector<std::string>&)>>;
namespace {
@@ -69,5 +72,10 @@
PrintUsage(commands, std::cerr);
return EXIT_FAILURE;
}
- return iter->second(*args, std::cerr) ? EXIT_SUCCESS : EXIT_FAILURE;
+ const auto result = iter->second(*args);
+ if (!result) {
+ std::cerr << "error: " << result.GetErrorMessage() << std::endl;
+ return EXIT_FAILURE;
+ }
+ return EXIT_SUCCESS;
}
diff --git a/cmds/idmap2/idmap2/Scan.cpp b/cmds/idmap2/idmap2/Scan.cpp
index e85f132..24331af 100644
--- a/cmds/idmap2/idmap2/Scan.cpp
+++ b/cmds/idmap2/idmap2/Scan.cpp
@@ -30,6 +30,7 @@
#include "idmap2/FileUtils.h"
#include "idmap2/Idmap.h"
#include "idmap2/ResourceUtils.h"
+#include "idmap2/Result.h"
#include "idmap2/SysTrace.h"
#include "idmap2/Xml.h"
#include "idmap2/ZipFile.h"
@@ -37,6 +38,7 @@
#include "Commands.h"
using android::idmap2::CommandLineOptions;
+using android::idmap2::Error;
using android::idmap2::Idmap;
using android::idmap2::kPolicyProduct;
using android::idmap2::kPolicyPublic;
@@ -45,6 +47,7 @@
using android::idmap2::PolicyBitmask;
using android::idmap2::PolicyFlags;
using android::idmap2::Result;
+using android::idmap2::Unit;
using android::idmap2::utils::ExtractOverlayManifestInfo;
using android::idmap2::utils::FindFiles;
using android::idmap2::utils::OverlayManifestInfo;
@@ -69,8 +72,8 @@
return version == "Q" || version == "q";
}
-std::unique_ptr<std::vector<std::string>> FindApkFiles(const std::vector<std::string>& dirs,
- bool recursive, std::ostream& out_error) {
+Result<std::unique_ptr<std::vector<std::string>>> FindApkFiles(const std::vector<std::string>& dirs,
+ bool recursive) {
SYSTRACE << "FindApkFiles " << dirs << " " << recursive;
const auto predicate = [](unsigned char type, const std::string& path) -> bool {
static constexpr size_t kExtLen = 4; // strlen(".apk")
@@ -82,8 +85,7 @@
for (const auto& dir : dirs) {
const auto apk_paths = FindFiles(dir, recursive, predicate);
if (!apk_paths) {
- out_error << "error: failed to open directory " << dir << std::endl;
- return nullptr;
+ return Error("failed to open directory %s", dir.c_str());
}
paths.insert(apk_paths->cbegin(), apk_paths->cend());
}
@@ -110,7 +112,7 @@
} // namespace
-bool Scan(const std::vector<std::string>& args, std::ostream& out_error) {
+Result<Unit> Scan(const std::vector<std::string>& args) {
SYSTRACE << "Scan " << args;
std::vector<std::string> input_directories;
std::string target_package_name;
@@ -135,22 +137,22 @@
"input: an overlayable policy this overlay fulfills "
"(if none or supplied, the overlays will not have their policies overriden",
&override_policies);
- if (!opts.Parse(args, out_error)) {
- return false;
+ const auto opts_ok = opts.Parse(args);
+ if (!opts_ok) {
+ return opts_ok.GetError();
}
- const auto apk_paths = FindApkFiles(input_directories, recursive, out_error);
+ const auto apk_paths = FindApkFiles(input_directories, recursive);
if (!apk_paths) {
- return false;
+ return Error(apk_paths.GetError(), "failed to find apk files");
}
std::vector<InputOverlay> interesting_apks;
- for (const std::string& path : *apk_paths) {
+ for (const std::string& path : **apk_paths) {
Result<OverlayManifestInfo> overlay_info =
ExtractOverlayManifestInfo(path, /* assert_overlay */ false);
if (!overlay_info) {
- out_error << "error: " << overlay_info.GetErrorMessage() << std::endl;
- return false;
+ return overlay_info.GetError();
}
if (!overlay_info->is_static) {
@@ -194,16 +196,13 @@
std::stringstream stream;
for (const auto& overlay : interesting_apks) {
- // Create the idmap for the overlay if it currently does not exist or if it is not up to date.
- std::stringstream dev_null;
-
std::vector<std::string> verify_args = {"--idmap-path", overlay.idmap_path};
for (const std::string& policy : overlay.policies) {
verify_args.emplace_back("--policy");
verify_args.emplace_back(policy);
}
- if (!Verify(std::vector<std::string>(verify_args), dev_null)) {
+ if (!Verify(std::vector<std::string>(verify_args))) {
std::vector<std::string> create_args = {"--target-apk-path", target_apk_path,
"--overlay-apk-path", overlay.apk_path,
"--idmap-path", overlay.idmap_path};
@@ -216,8 +215,9 @@
create_args.emplace_back(policy);
}
- if (!Create(create_args, out_error)) {
- return false;
+ const auto create_ok = Create(create_args);
+ if (!create_ok) {
+ return Error(create_ok.GetError(), "failed to create idmap");
}
}
@@ -226,5 +226,5 @@
std::cout << stream.str();
- return true;
+ return Unit{};
}
diff --git a/cmds/idmap2/idmap2/Verify.cpp b/cmds/idmap2/idmap2/Verify.cpp
index d8fe7aa..9cb67b3 100644
--- a/cmds/idmap2/idmap2/Verify.cpp
+++ b/cmds/idmap2/idmap2/Verify.cpp
@@ -21,29 +21,39 @@
#include "idmap2/CommandLineOptions.h"
#include "idmap2/Idmap.h"
+#include "idmap2/Result.h"
#include "idmap2/SysTrace.h"
using android::idmap2::CommandLineOptions;
+using android::idmap2::Error;
using android::idmap2::IdmapHeader;
+using android::idmap2::Result;
+using android::idmap2::Unit;
-bool Verify(const std::vector<std::string>& args, std::ostream& out_error) {
+Result<Unit> Verify(const std::vector<std::string>& args) {
SYSTRACE << "Verify " << args;
std::string idmap_path;
const CommandLineOptions opts =
CommandLineOptions("idmap2 verify")
.MandatoryOption("--idmap-path", "input: path to idmap file to verify", &idmap_path);
- if (!opts.Parse(args, out_error)) {
- return false;
+
+ const auto opts_ok = opts.Parse(args);
+ if (!opts_ok) {
+ return opts_ok.GetError();
}
std::ifstream fin(idmap_path);
const std::unique_ptr<const IdmapHeader> header = IdmapHeader::FromBinaryStream(fin);
fin.close();
if (!header) {
- out_error << "error: failed to parse idmap header" << std::endl;
- return false;
+ return Error("failed to parse idmap header");
}
- return header->IsUpToDate(out_error);
+ const auto header_ok = header->IsUpToDate();
+ if (!header_ok) {
+ return Error(header_ok.GetError(), "idmap not up to date");
+ }
+
+ return Unit{};
}
diff --git a/cmds/idmap2/idmap2d/Idmap2Service.cpp b/cmds/idmap2/idmap2d/Idmap2Service.cpp
index fa94414..e03a9cc 100644
--- a/cmds/idmap2/idmap2d/Idmap2Service.cpp
+++ b/cmds/idmap2/idmap2d/Idmap2Service.cpp
@@ -104,8 +104,7 @@
std::ifstream fin(idmap_path);
const std::unique_ptr<const IdmapHeader> header = IdmapHeader::FromBinaryStream(fin);
fin.close();
- std::stringstream dev_null;
- *_aidl_return = header && header->IsUpToDate(dev_null);
+ *_aidl_return = header && header->IsUpToDate();
// TODO(b/119328308): Check that the set of fulfilled policies of the overlay has not changed
diff --git a/cmds/idmap2/include/idmap2/CommandLineOptions.h b/cmds/idmap2/include/idmap2/CommandLineOptions.h
index 6db6bf9..52ac818 100644
--- a/cmds/idmap2/include/idmap2/CommandLineOptions.h
+++ b/cmds/idmap2/include/idmap2/CommandLineOptions.h
@@ -23,6 +23,8 @@
#include <string>
#include <vector>
+#include "idmap2/Result.h"
+
namespace android::idmap2 {
/*
@@ -46,7 +48,7 @@
std::string* value);
CommandLineOptions& OptionalOption(const std::string& name, const std::string& description,
std::vector<std::string>* value);
- bool Parse(const std::vector<std::string>& argv, std::ostream& outError) const;
+ Result<Unit> Parse(const std::vector<std::string>& argv) const;
void Usage(std::ostream& out) const;
private:
diff --git a/cmds/idmap2/include/idmap2/Idmap.h b/cmds/idmap2/include/idmap2/Idmap.h
index 1666dc8..673d18d 100644
--- a/cmds/idmap2/include/idmap2/Idmap.h
+++ b/cmds/idmap2/include/idmap2/Idmap.h
@@ -115,7 +115,7 @@
// Invariant: anytime the idmap data encoding is changed, the idmap version
// field *must* be incremented. Because of this, we know that if the idmap
// header is up-to-date the entire file is up-to-date.
- bool IsUpToDate(std::ostream& out_error) const;
+ Result<Unit> IsUpToDate() const;
void accept(Visitor* v) const;
diff --git a/cmds/idmap2/libidmap2/CommandLineOptions.cpp b/cmds/idmap2/libidmap2/CommandLineOptions.cpp
index a49a607..d5fd2ce 100644
--- a/cmds/idmap2/libidmap2/CommandLineOptions.cpp
+++ b/cmds/idmap2/libidmap2/CommandLineOptions.cpp
@@ -19,12 +19,14 @@
#include <iostream>
#include <memory>
#include <set>
+#include <sstream>
#include <string>
#include <vector>
#include "android-base/macros.h"
#include "idmap2/CommandLineOptions.h"
+#include "idmap2/Result.h"
namespace android::idmap2 {
@@ -77,7 +79,7 @@
return *this;
}
-bool CommandLineOptions::Parse(const std::vector<std::string>& argv, std::ostream& outError) const {
+Result<Unit> CommandLineOptions::Parse(const std::vector<std::string>& argv) const {
const auto pivot = std::partition(options_.begin(), options_.end(), [](const Option& opt) {
return opt.count != Option::COUNT_OPTIONAL && opt.count != Option::COUNT_OPTIONAL_ONCE_OR_MORE;
});
@@ -89,8 +91,9 @@
for (size_t i = 0; i < argv_size; i++) {
const std::string arg = argv[i];
if ("--help" == arg || "-h" == arg) {
- Usage(outError);
- return false;
+ std::stringstream stream;
+ Usage(stream);
+ return Error("%s", stream.str().c_str());
}
bool match = false;
for (const Option& opt : options_) {
@@ -100,9 +103,9 @@
if (opt.argument) {
i++;
if (i >= argv_size) {
- outError << "error: " << opt.name << ": missing argument" << std::endl;
- Usage(outError);
- return false;
+ std::stringstream stream;
+ Usage(stream);
+ return Error("%s: missing argument\n%s", opt.name.c_str(), stream.str().c_str());
}
}
opt.action(argv[i]);
@@ -111,20 +114,27 @@
}
}
if (!match) {
- outError << "error: " << arg << ": unknown option" << std::endl;
- Usage(outError);
- return false;
+ std::stringstream stream;
+ Usage(stream);
+ return Error("%s: unknown option\n%s", arg.c_str(), stream.str().c_str());
}
}
if (!mandatory_opts.empty()) {
+ std::stringstream stream;
+ bool separator = false;
for (const auto& opt : mandatory_opts) {
- outError << "error: " << opt << ": missing mandatory option" << std::endl;
+ if (separator) {
+ stream << ", ";
+ }
+ separator = true;
+ stream << opt << ": missing mandatory option";
}
- Usage(outError);
- return false;
+ stream << std::endl;
+ Usage(stream);
+ return Error("%s", stream.str().c_str());
}
- return true;
+ return Unit{};
}
void CommandLineOptions::Usage(std::ostream& out) const {
diff --git a/cmds/idmap2/libidmap2/Idmap.cpp b/cmds/idmap2/libidmap2/Idmap.cpp
index a7d180c..2a39c2f 100644
--- a/cmds/idmap2/libidmap2/Idmap.cpp
+++ b/cmds/idmap2/libidmap2/Idmap.cpp
@@ -142,62 +142,46 @@
return std::move(idmap_header);
}
-bool IdmapHeader::IsUpToDate(std::ostream& out_error) const {
+Result<Unit> IdmapHeader::IsUpToDate() const {
if (magic_ != kIdmapMagic) {
- out_error << base::StringPrintf("error: bad magic: actual 0x%08x, expected 0x%08x", magic_,
- kIdmapMagic)
- << std::endl;
- return false;
+ return Error("bad magic: actual 0x%08x, expected 0x%08x", magic_, kIdmapMagic);
}
if (version_ != kIdmapCurrentVersion) {
- out_error << base::StringPrintf("error: bad version: actual 0x%08x, expected 0x%08x", version_,
- kIdmapCurrentVersion)
- << std::endl;
- return false;
+ return Error("bad version: actual 0x%08x, expected 0x%08x", version_, kIdmapCurrentVersion);
}
const std::unique_ptr<const ZipFile> target_zip = ZipFile::Open(target_path_);
if (!target_zip) {
- out_error << "error: failed to open target " << target_path_ << std::endl;
- return false;
+ return Error("failed to open target %s", GetTargetPath().to_string().c_str());
}
Result<uint32_t> target_crc = GetCrc(*target_zip);
if (!target_crc) {
- out_error << "error: failed to get target crc" << std::endl;
- return false;
+ return Error("failed to get target crc");
}
if (target_crc_ != *target_crc) {
- out_error << base::StringPrintf(
- "error: bad target crc: idmap version 0x%08x, file system version 0x%08x",
- target_crc_, *target_crc)
- << std::endl;
- return false;
+ return Error("bad target crc: idmap version 0x%08x, file system version 0x%08x", target_crc_,
+ *target_crc);
}
const std::unique_ptr<const ZipFile> overlay_zip = ZipFile::Open(overlay_path_);
if (!overlay_zip) {
- out_error << "error: failed to open overlay " << overlay_path_ << std::endl;
- return false;
+ return Error("failed to open overlay %s", GetOverlayPath().to_string().c_str());
}
Result<uint32_t> overlay_crc = GetCrc(*overlay_zip);
if (!overlay_crc) {
- out_error << "error: failed to get overlay crc" << std::endl;
- return false;
+ return Error("failed to get overlay crc");
}
if (overlay_crc_ != *overlay_crc) {
- out_error << base::StringPrintf(
- "error: bad overlay crc: idmap version 0x%08x, file system version 0x%08x",
- overlay_crc_, *overlay_crc)
- << std::endl;
- return false;
+ return Error("bad overlay crc: idmap version 0x%08x, file system version 0x%08x", overlay_crc_,
+ *overlay_crc);
}
- return true;
+ return Unit{};
}
std::unique_ptr<const IdmapData::Header> IdmapData::Header::FromBinaryStream(std::istream& stream) {
diff --git a/cmds/idmap2/tests/CommandLineOptionsTests.cpp b/cmds/idmap2/tests/CommandLineOptionsTests.cpp
index 39f18d3..d567af6 100644
--- a/cmds/idmap2/tests/CommandLineOptionsTests.cpp
+++ b/cmds/idmap2/tests/CommandLineOptionsTests.cpp
@@ -46,14 +46,13 @@
CommandLineOptions opts =
CommandLineOptions("test").OptionalFlag("--foo", "", &foo).OptionalFlag("--bar", "", &bar);
- std::ostream fakeStdErr(nullptr);
- bool success = opts.Parse({"--foo", "--bar"}, fakeStdErr);
+ auto success = opts.Parse({"--foo", "--bar"});
ASSERT_TRUE(success);
ASSERT_TRUE(foo);
ASSERT_TRUE(bar);
foo = bar = false;
- success = opts.Parse({"--foo"}, fakeStdErr);
+ success = opts.Parse({"--foo"});
ASSERT_TRUE(success);
ASSERT_TRUE(foo);
ASSERT_FALSE(bar);
@@ -65,21 +64,19 @@
CommandLineOptions opts = CommandLineOptions("test")
.MandatoryOption("--foo", "", &foo)
.MandatoryOption("--bar", "", &bar);
- std::ostream fakeStdErr(nullptr);
- bool success = opts.Parse({"--foo", "FOO", "--bar", "BAR"}, fakeStdErr);
+ auto success = opts.Parse({"--foo", "FOO", "--bar", "BAR"});
ASSERT_TRUE(success);
ASSERT_EQ(foo, "FOO");
ASSERT_EQ(bar, "BAR");
- success = opts.Parse({"--foo"}, fakeStdErr);
+ success = opts.Parse({"--foo"});
ASSERT_FALSE(success);
}
TEST(CommandLineOptionsTests, MandatoryOptionMultipleArgsButExpectedOnce) {
std::string foo;
CommandLineOptions opts = CommandLineOptions("test").MandatoryOption("--foo", "", &foo);
- std::ostream fakeStdErr(nullptr);
- bool success = opts.Parse({"--foo", "FIRST", "--foo", "SECOND"}, fakeStdErr);
+ auto success = opts.Parse({"--foo", "FIRST", "--foo", "SECOND"});
ASSERT_TRUE(success);
ASSERT_EQ(foo, "SECOND");
}
@@ -87,8 +84,7 @@
TEST(CommandLineOptionsTests, MandatoryOptionMultipleArgsAndExpectedOnceOrMore) {
std::vector<std::string> args;
CommandLineOptions opts = CommandLineOptions("test").MandatoryOption("--foo", "", &args);
- std::ostream fakeStdErr(nullptr);
- bool success = opts.Parse({"--foo", "FOO", "--foo", "BAR"}, fakeStdErr);
+ auto success = opts.Parse({"--foo", "FOO", "--foo", "BAR"});
ASSERT_TRUE(success);
ASSERT_EQ(args.size(), 2U);
ASSERT_EQ(args[0], "FOO");
@@ -101,23 +97,22 @@
CommandLineOptions opts = CommandLineOptions("test")
.OptionalOption("--foo", "", &foo)
.OptionalOption("--bar", "", &bar);
- std::ostream fakeStdErr(nullptr);
- bool success = opts.Parse({"--foo", "FOO", "--bar", "BAR"}, fakeStdErr);
+ auto success = opts.Parse({"--foo", "FOO", "--bar", "BAR"});
ASSERT_TRUE(success);
ASSERT_EQ(foo, "FOO");
ASSERT_EQ(bar, "BAR");
- success = opts.Parse({"--foo", "BAZ"}, fakeStdErr);
+ success = opts.Parse({"--foo", "BAZ"});
ASSERT_TRUE(success);
ASSERT_EQ(foo, "BAZ");
- success = opts.Parse({"--foo"}, fakeStdErr);
+ success = opts.Parse({"--foo"});
ASSERT_FALSE(success);
- success = opts.Parse({"--foo", "--bar", "BAR"}, fakeStdErr);
+ success = opts.Parse({"--foo", "--bar", "BAR"});
ASSERT_FALSE(success);
- success = opts.Parse({"--foo", "FOO", "--bar"}, fakeStdErr);
+ success = opts.Parse({"--foo", "FOO", "--bar"});
ASSERT_FALSE(success);
}
@@ -127,8 +122,7 @@
CommandLineOptions opts = CommandLineOptions("test")
.OptionalOption("--foo", "", &foo)
.OptionalOption("--bar", "", &bar);
- std::ostream fakeStdErr(nullptr);
- bool success = opts.Parse({"--foo", "FOO", "--bar", "BAR"}, fakeStdErr);
+ auto success = opts.Parse({"--foo", "FOO", "--bar", "BAR"});
ASSERT_TRUE(success);
ASSERT_EQ(foo.size(), 1U);
ASSERT_EQ(foo[0], "FOO");
@@ -137,7 +131,7 @@
foo.clear();
bar.clear();
- success = opts.Parse({"--foo", "BAZ"}, fakeStdErr);
+ success = opts.Parse({"--foo", "BAZ"});
ASSERT_TRUE(success);
ASSERT_EQ(foo.size(), 1U);
ASSERT_EQ(foo[0], "BAZ");
@@ -145,8 +139,7 @@
foo.clear();
bar.clear();
- success =
- opts.Parse({"--foo", "BAZ", "--foo", "BIZ", "--bar", "FIZ", "--bar", "FUZZ"}, fakeStdErr);
+ success = opts.Parse({"--foo", "BAZ", "--foo", "BIZ", "--bar", "FIZ", "--bar", "FUZZ"});
ASSERT_TRUE(success);
ASSERT_EQ(foo.size(), 2U);
ASSERT_EQ(foo[0], "BAZ");
@@ -157,17 +150,17 @@
foo.clear();
bar.clear();
- success = opts.Parse({"--foo"}, fakeStdErr);
+ success = opts.Parse({"--foo"});
ASSERT_FALSE(success);
foo.clear();
bar.clear();
- success = opts.Parse({"--foo", "--bar", "BAR"}, fakeStdErr);
+ success = opts.Parse({"--foo", "--bar", "BAR"});
ASSERT_FALSE(success);
foo.clear();
bar.clear();
- success = opts.Parse({"--foo", "FOO", "--bar"}, fakeStdErr);
+ success = opts.Parse({"--foo", "FOO", "--bar"});
ASSERT_FALSE(success);
}
@@ -179,14 +172,13 @@
.MandatoryOption("--foo", "", &foo)
.OptionalFlag("--baz", "", &baz)
.OptionalOption("--bar", "", &bar);
- std::ostream fakeStdErr(nullptr);
- bool success = opts.Parse({"--unexpected"}, fakeStdErr);
+ auto success = opts.Parse({"--unexpected"});
ASSERT_FALSE(success);
- success = opts.Parse({"--bar", "BAR"}, fakeStdErr);
+ success = opts.Parse({"--bar", "BAR"});
ASSERT_FALSE(success);
- success = opts.Parse({"--baz", "--foo", "FOO"}, fakeStdErr);
+ success = opts.Parse({"--baz", "--foo", "FOO"});
ASSERT_TRUE(success);
ASSERT_TRUE(baz);
ASSERT_EQ(foo, "FOO");
diff --git a/cmds/idmap2/tests/IdmapTests.cpp b/cmds/idmap2/tests/IdmapTests.cpp
index 8d65428..c20ae7b 100644
--- a/cmds/idmap2/tests/IdmapTests.cpp
+++ b/cmds/idmap2/tests/IdmapTests.cpp
@@ -501,7 +501,7 @@
std::unique_ptr<const IdmapHeader> header = IdmapHeader::FromBinaryStream(stream);
ASSERT_THAT(header, NotNull());
- ASSERT_TRUE(header->IsUpToDate(error)) << error.str();
+ ASSERT_TRUE(header->IsUpToDate());
// magic: bytes (0x0, 0x03)
std::string bad_magic_string(stream.str());
@@ -514,7 +514,7 @@
IdmapHeader::FromBinaryStream(bad_magic_stream);
ASSERT_THAT(bad_magic_header, NotNull());
ASSERT_NE(header->GetMagic(), bad_magic_header->GetMagic());
- ASSERT_FALSE(bad_magic_header->IsUpToDate(error));
+ ASSERT_FALSE(bad_magic_header->IsUpToDate());
// version: bytes (0x4, 0x07)
std::string bad_version_string(stream.str());
@@ -527,7 +527,7 @@
IdmapHeader::FromBinaryStream(bad_version_stream);
ASSERT_THAT(bad_version_header, NotNull());
ASSERT_NE(header->GetVersion(), bad_version_header->GetVersion());
- ASSERT_FALSE(bad_version_header->IsUpToDate(error));
+ ASSERT_FALSE(bad_version_header->IsUpToDate());
// target crc: bytes (0x8, 0xb)
std::string bad_target_crc_string(stream.str());
@@ -540,7 +540,7 @@
IdmapHeader::FromBinaryStream(bad_target_crc_stream);
ASSERT_THAT(bad_target_crc_header, NotNull());
ASSERT_NE(header->GetTargetCrc(), bad_target_crc_header->GetTargetCrc());
- ASSERT_FALSE(bad_target_crc_header->IsUpToDate(error));
+ ASSERT_FALSE(bad_target_crc_header->IsUpToDate());
// overlay crc: bytes (0xc, 0xf)
std::string bad_overlay_crc_string(stream.str());
@@ -553,7 +553,7 @@
IdmapHeader::FromBinaryStream(bad_overlay_crc_stream);
ASSERT_THAT(bad_overlay_crc_header, NotNull());
ASSERT_NE(header->GetOverlayCrc(), bad_overlay_crc_header->GetOverlayCrc());
- ASSERT_FALSE(bad_overlay_crc_header->IsUpToDate(error));
+ ASSERT_FALSE(bad_overlay_crc_header->IsUpToDate());
// target path: bytes (0x10, 0x10f)
std::string bad_target_path_string(stream.str());
@@ -563,7 +563,7 @@
IdmapHeader::FromBinaryStream(bad_target_path_stream);
ASSERT_THAT(bad_target_path_header, NotNull());
ASSERT_NE(header->GetTargetPath(), bad_target_path_header->GetTargetPath());
- ASSERT_FALSE(bad_target_path_header->IsUpToDate(error));
+ ASSERT_FALSE(bad_target_path_header->IsUpToDate());
// overlay path: bytes (0x110, 0x20f)
std::string bad_overlay_path_string(stream.str());
@@ -573,7 +573,7 @@
IdmapHeader::FromBinaryStream(bad_overlay_path_stream);
ASSERT_THAT(bad_overlay_path_header, NotNull());
ASSERT_NE(header->GetOverlayPath(), bad_overlay_path_header->GetOverlayPath());
- ASSERT_FALSE(bad_overlay_path_header->IsUpToDate(error));
+ ASSERT_FALSE(bad_overlay_path_header->IsUpToDate());
}
class TestVisitor : public Visitor {