diff options
author | Samuel Huang <huangs@chromium.org> | 2018-03-13 18:19:34 +0000 |
---|---|---|
committer | Edward Lesmes <ehmaldonado@google.com> | 2021-07-23 21:50:59 +0000 |
commit | 06f1ae9aaca969ee95ef840f22b6b461c304542d (patch) | |
tree | f1e5c6624e70628e81fbf38d6cd14b974abe5d93 /main_utils.cc | |
download | zucchini-06f1ae9aaca969ee95ef840f22b6b461c304542d.tar.gz |
[Zucchini] Move Zucchini from /chrome/installer/ to /components/.
(Use "git log --follow" to see older revisions of files).
/components/ is the most logical place to put Zucchini, which only
depends on /base and /testing/gtest. This move also enables Zucchini to
be used by the Component Updater. Details:
- Move all files; run the following to change deps and guards:
sed 's/chrome\/installer/components/' *.cc *.h -i
sed 's/CHROME_INSTALLER/COMPONENTS/' *.cc *.h -i
- Sorting works out pretty well!
- Change all 'chrome/installer/zucchini' to 'components/zucchini'
throughout other parts of the repo; sort if necessary.
- Fix 6 'git cl lint' errors.
- Change 1 Bind() usage to BindRepeated().
- Update OWNER.
Bug: 729154
Change-Id: I50c5a7d411ea85f707b5994ab319dfb2a1acccf7
Reviewed-on: https://chromium-review.googlesource.com/954923
Reviewed-by: Greg Thompson <grt@chromium.org>
Reviewed-by: Jochen Eisinger <jochen@chromium.org>
Reviewed-by: Samuel Huang <huangs@chromium.org>
Commit-Queue: Samuel Huang <huangs@chromium.org>
Cr-Commit-Position: refs/heads/master@{#542857}
NOKEYCHECK=True
GitOrigin-RevId: 577ef6c435e8d43be6e3e60ccbcbd1881780f4ec
Diffstat (limited to 'main_utils.cc')
-rw-r--r-- | main_utils.cc | 193 |
1 files changed, 193 insertions, 0 deletions
diff --git a/main_utils.cc b/main_utils.cc new file mode 100644 index 0000000..b874dd0 --- /dev/null +++ b/main_utils.cc @@ -0,0 +1,193 @@ +// Copyright 2017 The Chromium 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 "components/zucchini/main_utils.h" + +#include <stddef.h> + +#include <memory> +#include <ostream> +#include <vector> + +#include "base/command_line.h" +#include "base/logging.h" +#include "base/time/time.h" +#include "build/build_config.h" +#include "components/zucchini/io_utils.h" +#include "components/zucchini/zucchini_commands.h" + +#if defined(OS_WIN) +#include <windows.h> // This include must come first. + +#include <psapi.h> +#endif + +namespace { + +#if defined(OS_WIN) +#endif + +/******** Command ********/ + +// Specifications for a Zucchini command. +struct Command { + constexpr Command(const char* name_in, + const char* usage_in, + int num_args_in, + CommandFunction command_function_in) + : name(name_in), + usage(usage_in), + num_args(num_args_in), + command_function(command_function_in) {} + Command(const Command&) = default; + ~Command() = default; + + // Unique name of command. |-name| is used to select from command-line. + const char* const name; + + // Usage help text of command. + const char* const usage; + + // Number of arguments (assumed to be filenames) used by the command. + const int num_args; + + // Main function to run for the command. + const CommandFunction command_function; +}; + +/******** List of Zucchini commands ********/ + +constexpr Command kCommands[] = { + {"gen", "-gen <old_file> <new_file> <patch_file> [-raw]", 3, &MainGen}, + {"apply", "-apply <old_file> <patch_file> <new_file>", 3, &MainApply}, + {"read", "-read <exe> [-dump]", 1, &MainRead}, + {"detect", "-detect <archive_file> [-dd=format#]", 1, &MainDetect}, + {"match", "-match <old_file> <new_file>", 2, &MainMatch}, + {"crc32", "-crc32 <file>", 1, &MainCrc32}, +}; + +/******** ScopedResourceUsageTracker ********/ + +// A class to track and log system resource usage. +class ScopedResourceUsageTracker { + public: + // Initializes states for tracking. + ScopedResourceUsageTracker() { + start_time_ = base::TimeTicks::Now(); + +#if defined(OS_WIN) + PROCESS_MEMORY_COUNTERS pmc; + if (::GetProcessMemoryInfo(::GetCurrentProcess(), &pmc, sizeof(pmc))) { + start_peak_page_file_usage_ = pmc.PeakPagefileUsage; + start_peak_working_set_size_ = pmc.PeakWorkingSetSize; + } +#endif + } + + // Computes and prints usage. + ~ScopedResourceUsageTracker() { + base::TimeTicks end_time = base::TimeTicks::Now(); + +#if defined(OS_WIN) + size_t cur_peak_page_file_usage = 0; + size_t cur_peak_working_set_size = 0; + PROCESS_MEMORY_COUNTERS pmc; + if (::GetProcessMemoryInfo(::GetCurrentProcess(), &pmc, sizeof(pmc))) { + cur_peak_page_file_usage = pmc.PeakPagefileUsage; + cur_peak_working_set_size = pmc.PeakWorkingSetSize; + } + + LOG(INFO) << "Zucchini.PeakPagefileUsage " + << cur_peak_page_file_usage / 1024 << " KiB"; + LOG(INFO) << "Zucchini.PeakPagefileUsageChange " + << (cur_peak_page_file_usage - start_peak_page_file_usage_) / 1024 + << " KiB"; + LOG(INFO) << "Zucchini.PeakWorkingSetSize " + << cur_peak_working_set_size / 1024 << " KiB"; + LOG(INFO) << "Zucchini.PeakWorkingSetSizeChange " + << (cur_peak_working_set_size - start_peak_working_set_size_) / + 1024 + << " KiB"; +#endif // !defined(OS_MACOSX) + + LOG(INFO) << "Zucchini.TotalTime " << (end_time - start_time_).InSecondsF() + << " s"; + } + + private: + base::TimeTicks start_time_; +#if defined(OS_WIN) + size_t start_peak_page_file_usage_ = 0; + size_t start_peak_working_set_size_ = 0; +#endif // !defined(OS_MACOSX) +}; + +/******** Helper functions ********/ + +// Translates |command_line| arguments to a vector of base::FilePath (expecting +// exactly |expected_count|). On success, writes the results to |paths| and +// returns true. Otherwise returns false. +bool CheckAndGetFilePathParams(const base::CommandLine& command_line, + size_t expected_count, + std::vector<base::FilePath>* paths) { + const base::CommandLine::StringVector& args = command_line.GetArgs(); + if (args.size() != expected_count) + return false; + + paths->clear(); + paths->reserve(args.size()); + for (const auto& arg : args) + paths->emplace_back(arg); + return true; +} + +// Prints main Zucchini usage text. +void PrintUsage(std::ostream& err) { + err << "Usage:" << std::endl; + for (const Command& command : kCommands) + err << " zucchini " << command.usage << std::endl; +} + +} // namespace + +/******** Exported Functions ********/ + +zucchini::status::Code RunZucchiniCommand(const base::CommandLine& command_line, + std::ostream& out, + std::ostream& err) { + // Look for a command with name that matches input. + const Command* command_use = nullptr; + for (const Command& command : kCommands) { + if (command_line.HasSwitch(command.name)) { + if (command_use) { // Too many commands found. + command_use = nullptr; // Set to null to flag error. + break; + } + command_use = &command; + } + } + + // Expect exactly 1 matching command. If 0 or >= 2, print usage and quit. + if (!command_use) { + err << "Must have exactly one of:" << std::endl; + err << " ["; + zucchini::PrefixSep sep(", "); + for (const Command& command : kCommands) + err << sep << "-" << command.name; + err << "]" << std::endl; + PrintUsage(err); + return zucchini::status::kStatusInvalidParam; + } + + // Try to parse filename arguments. On failure, print usage and quit. + std::vector<base::FilePath> paths; + if (!CheckAndGetFilePathParams(command_line, command_use->num_args, &paths)) { + err << command_use->usage << std::endl; + PrintUsage(err); + return zucchini::status::kStatusInvalidParam; + } + + ScopedResourceUsageTracker resource_usage_tracker; + return command_use->command_function({command_line, paths, out, err}); +} |