Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(125)

Unified Diff: courgette/courgette_tool.cc

Issue 2827103002: [Courgette] Refactor: Add CourgetteFlow; improve courgette_tool.cc help text. (Closed)
Patch Set: Add virtual destructor to BasicBuffer and its implementations. Created 3 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « courgette/courgette_flow.cc ('k') | courgette/encode_decode_unittest.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: courgette/courgette_tool.cc
diff --git a/courgette/courgette_tool.cc b/courgette/courgette_tool.cc
index 5ca91d1aa96d165c518f0a45e6128e9ab93a2ad7..46bd578e1d38b4db610295686a3d97dcb870ef40 100644
--- a/courgette/courgette_tool.cc
+++ b/courgette/courgette_tool.cc
@@ -2,9 +2,11 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+#include <stdarg.h>
#include <stddef.h>
#include <stdint.h>
+#include <initializer_list>
#include <memory>
#include <string>
#include <vector>
@@ -15,26 +17,45 @@
#include "base/files/file_util.h"
#include "base/files/memory_mapped_file.h"
#include "base/logging.h"
+#include "base/macros.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/string_util.h"
#include "base/strings/utf_string_conversions.h"
#include "courgette/assembly_program.h"
#include "courgette/courgette.h"
+#include "courgette/courgette_flow.h"
#include "courgette/encoded_program.h"
#include "courgette/program_detector.h"
#include "courgette/streams.h"
#include "courgette/third_party/bsdiff/bsdiff.h"
+namespace {
+
+using courgette::CourgetteFlow;
+
+const char kUsageGen[] = "-gen <old_in> <new_in> <patch_out>";
+const char kUsageApply[] = "-apply <old_in> <patch_in> <new_out>";
+const char kUsageGenbsdiff[] = "-genbsdiff <old_in> <new_in> <patch_out>";
+const char kUsageApplybsdiff[] = "-applybsdiff <old_in> <patch_in> <new_out>";
+const char kUsageSupported[] = "-supported <exec_file_in>";
+const char kUsageDis[] = "-dis <exec_file_in> <assembly_file_out>";
+const char kUsageAsm[] = "-asm <assembly_file_in> <exec_file_out>";
+const char kUsageDisadj[] = "-disadj <old_in> <new_in> <new_assembly_file_out>";
+const char kUsageGen1[] = "-gen1[au] <old_in> <new_in> <patch_base_out>";
+
+/******** Utilities to print help and exit ********/
+
void PrintHelp() {
- fprintf(stderr,
- "Usage:\n"
- " courgette -supported <executable_file>\n"
- " courgette -dis <executable_file> <binary_assembly_file>\n"
- " courgette -asm <binary_assembly_file> <executable_file>\n"
- " courgette -disadj <executable_file> <reference> <binary_assembly_file>\n"
- " courgette -gen <v1> <v2> <patch>\n"
- " courgette -apply <v1> <patch> <v2>\n"
- "\n");
+ fprintf(stderr, "Main Usage:\n");
+ for (auto usage :
+ {kUsageGen, kUsageApply, kUsageGenbsdiff, kUsageApplybsdiff}) {
+ fprintf(stderr, " courgette %s\n", usage);
+ }
+ fprintf(stderr, "Diagnosis Usage:\n");
+ for (auto usage :
+ {kUsageSupported, kUsageDis, kUsageAsm, kUsageDisadj, kUsageGen1}) {
+ fprintf(stderr, " courgette %s\n", usage);
+ }
}
void UsageProblem(const char* message) {
@@ -53,20 +74,29 @@ void Problem(const char* format, ...) {
exit(1);
}
+/******** BufferedFileReader ********/
+
// A file reader that calls Problem() on failure.
-class BufferedFileReader {
+class BufferedFileReader : public courgette::BasicBuffer {
public:
BufferedFileReader(const base::FilePath& file_name, const char* kind) {
if (!buffer_.Initialize(file_name))
Problem("Can't read %s file.", kind);
}
- const uint8_t* data() const { return buffer_.data(); }
- size_t length() const { return buffer_.length(); }
+ ~BufferedFileReader() override {}
+
+ // courgette::BasicBuffer:
+ const uint8_t* data() const override { return buffer_.data(); }
+ size_t length() const override { return buffer_.length(); }
private:
base::MemoryMappedFile buffer_;
+
+ DISALLOW_COPY_AND_ASSIGN(BufferedFileReader);
};
+/******** Various helpers ********/
+
void WriteSinkToFile(const courgette::SinkStream *sink,
const base::FilePath& output_file) {
int count =
@@ -79,38 +109,6 @@ void WriteSinkToFile(const courgette::SinkStream *sink,
Problem("Incomplete write.");
}
-void Disassemble(const base::FilePath& input_file,
- const base::FilePath& output_file) {
- BufferedFileReader buffer(input_file, "input");
-
- std::unique_ptr<courgette::AssemblyProgram> program;
- const courgette::Status parse_status = courgette::ParseDetectedExecutable(
- buffer.data(), buffer.length(), &program);
- if (parse_status != courgette::C_OK)
- Problem("Can't parse input (code = %d).", parse_status);
-
- std::unique_ptr<courgette::EncodedProgram> encoded;
- const courgette::Status encode_status = Encode(*program, &encoded);
- if (encode_status != courgette::C_OK)
- Problem("Can't encode program.");
-
- program.reset();
-
- courgette::SinkStreamSet sinks;
- const courgette::Status write_status =
- courgette::WriteEncodedProgram(encoded.get(), &sinks);
- if (write_status != courgette::C_OK)
- Problem("Can't serialize encoded program.");
-
- encoded.reset();
-
- courgette::SinkStream sink;
- if (!sinks.CopyTo(&sink))
- Problem("Can't combine serialized encoded program streams.");
-
- WriteSinkToFile(&sink, output_file);
-}
-
bool Supported(const base::FilePath& input_file) {
bool result = false;
@@ -153,50 +151,41 @@ bool Supported(const base::FilePath& input_file) {
return result;
}
-void DisassembleAndAdjust(const base::FilePath& program_file,
- const base::FilePath& model_file,
- const base::FilePath& output_file) {
- BufferedFileReader program_buffer(program_file, "program");
- BufferedFileReader model_buffer(model_file, "model");
-
- std::unique_ptr<courgette::AssemblyProgram> program;
- const courgette::Status parse_program_status =
- courgette::ParseDetectedExecutable(program_buffer.data(),
- program_buffer.length(), &program);
- if (parse_program_status != courgette::C_OK)
- Problem("Can't parse program input (code = %d).", parse_program_status);
-
- std::unique_ptr<courgette::AssemblyProgram> model;
- const courgette::Status parse_model_status =
- courgette::ParseDetectedExecutable(model_buffer.data(),
- model_buffer.length(), &model);
- if (parse_model_status != courgette::C_OK)
- Problem("Can't parse model input (code = %d).", parse_model_status);
-
- const courgette::Status adjust_status = Adjust(*model, program.get());
- if (adjust_status != courgette::C_OK)
- Problem("Can't adjust program.");
-
- model.reset();
-
- std::unique_ptr<courgette::EncodedProgram> encoded;
- const courgette::Status encode_status = Encode(*program, &encoded);
- if (encode_status != courgette::C_OK)
- Problem("Can't encode program.");
-
- program.reset();
-
- courgette::SinkStreamSet sinks;
- const courgette::Status write_status =
- courgette::WriteEncodedProgram(encoded.get(), &sinks);
- if (write_status != courgette::C_OK)
- Problem("Can't serialize encoded program.");
+void Disassemble(const base::FilePath& input_file,
+ const base::FilePath& output_file) {
+ CourgetteFlow flow;
+ BufferedFileReader input_buffer(input_file, flow.name(flow.ONLY));
+ flow.ReadAssemblyProgramFromBuffer(flow.ONLY, input_buffer, false);
+ flow.CreateEncodedProgramFromAssemblyProgram(flow.ONLY);
+ flow.DestroyAssemblyProgram(flow.ONLY);
+ flow.WriteSinkStreamSetFromEncodedProgram(flow.ONLY);
+ flow.DestroyEncodedProgram(flow.ONLY);
+ courgette::SinkStream sink;
+ flow.WriteSinkStreamFromSinkStreamSet(flow.ONLY, &sink);
+ if (flow.failed())
+ Problem(flow.message().c_str());
- encoded.reset();
+ WriteSinkToFile(&sink, output_file);
+}
+void DisassembleAndAdjust(const base::FilePath& old_file,
+ const base::FilePath& new_file,
+ const base::FilePath& output_file) {
+ CourgetteFlow flow;
+ BufferedFileReader old_buffer(old_file, flow.name(flow.OLD));
+ BufferedFileReader new_buffer(new_file, flow.name(flow.NEW));
+ flow.ReadAssemblyProgramFromBuffer(flow.OLD, old_buffer, true);
+ flow.ReadAssemblyProgramFromBuffer(flow.NEW, new_buffer, true);
+ flow.AdjustNewAssemblyProgramToMatchOld();
+ flow.DestroyAssemblyProgram(flow.OLD);
+ flow.CreateEncodedProgramFromAssemblyProgram(flow.NEW);
+ flow.DestroyAssemblyProgram(flow.NEW);
+ flow.WriteSinkStreamSetFromEncodedProgram(flow.NEW);
+ flow.DestroyEncodedProgram(flow.NEW);
courgette::SinkStream sink;
- if (!sinks.CopyTo(&sink))
- Problem("Can't combine serialized encoded program streams.");
+ flow.WriteSinkStreamFromSinkStreamSet(flow.NEW, &sink);
+ if (flow.failed())
+ Problem(flow.message().c_str());
WriteSinkToFile(&sink, output_file);
}
@@ -206,69 +195,32 @@ void DisassembleAndAdjust(const base::FilePath& program_file,
// original file's stream and the new file's stream. This is completely
// uninteresting to users, but it is handy for seeing how much each which
// streams are contributing to the final file size. Adjustment is optional.
-void DisassembleAdjustDiff(const base::FilePath& model_file,
- const base::FilePath& program_file,
+void DisassembleAdjustDiff(const base::FilePath& old_file,
+ const base::FilePath& new_file,
const base::FilePath& output_file_root,
bool adjust) {
- BufferedFileReader model_buffer(model_file, "old");
- BufferedFileReader program_buffer(program_file, "new");
-
- auto parser = adjust ? courgette::ParseDetectedExecutableWithAnnotation
- : courgette::ParseDetectedExecutable;
-
- std::unique_ptr<courgette::AssemblyProgram> model;
- const courgette::Status parse_model_status =
- parser(model_buffer.data(), model_buffer.length(), &model);
- if (parse_model_status != courgette::C_OK)
- Problem("Can't parse model input (code = %d).", parse_model_status);
-
- std::unique_ptr<courgette::AssemblyProgram> program;
- const courgette::Status parse_program_status =
- parser(program_buffer.data(), program_buffer.length(), &program);
- if (parse_program_status != courgette::C_OK)
- Problem("Can't parse program input (code = %d).", parse_program_status);
-
- if (adjust) {
- const courgette::Status adjust_status = Adjust(*model, program.get());
- if (adjust_status != courgette::C_OK)
- Problem("Can't adjust program.");
- }
-
- std::unique_ptr<courgette::EncodedProgram> encoded_program;
- const courgette::Status encode_program_status =
- Encode(*program, &encoded_program);
- if (encode_program_status != courgette::C_OK)
- Problem("Can't encode program.");
-
- program.reset();
-
- std::unique_ptr<courgette::EncodedProgram> encoded_model;
- const courgette::Status encode_model_status = Encode(*model, &encoded_model);
- if (encode_model_status != courgette::C_OK)
- Problem("Can't encode model.");
-
- model.reset();
-
- courgette::SinkStreamSet program_sinks;
- const courgette::Status write_program_status =
- courgette::WriteEncodedProgram(encoded_program.get(), &program_sinks);
- if (write_program_status != courgette::C_OK)
- Problem("Can't serialize encoded program.");
-
- encoded_program.reset();
-
- courgette::SinkStreamSet model_sinks;
- const courgette::Status write_model_status =
- courgette::WriteEncodedProgram(encoded_model.get(), &model_sinks);
- if (write_model_status != courgette::C_OK)
- Problem("Can't serialize encoded model.");
-
- encoded_model.reset();
+ CourgetteFlow flow;
+ BufferedFileReader old_buffer(old_file, flow.name(flow.OLD));
+ BufferedFileReader new_buffer(new_file, flow.name(flow.NEW));
+ flow.ReadAssemblyProgramFromBuffer(flow.OLD, old_buffer, adjust);
+ flow.ReadAssemblyProgramFromBuffer(flow.NEW, new_buffer, adjust);
+ if (adjust)
+ flow.AdjustNewAssemblyProgramToMatchOld();
+ flow.CreateEncodedProgramFromAssemblyProgram(flow.OLD);
+ flow.DestroyAssemblyProgram(flow.OLD);
+ flow.CreateEncodedProgramFromAssemblyProgram(flow.NEW);
+ flow.DestroyAssemblyProgram(flow.NEW);
+ flow.WriteSinkStreamSetFromEncodedProgram(flow.OLD);
+ flow.DestroyEncodedProgram(flow.OLD);
+ flow.WriteSinkStreamSetFromEncodedProgram(flow.NEW);
+ flow.DestroyEncodedProgram(flow.NEW);
+ if (flow.failed())
+ Problem(flow.message().c_str());
courgette::SinkStream empty_sink;
for (int i = 0; ; ++i) {
- courgette::SinkStream* old_stream = model_sinks.stream(i);
- courgette::SinkStream* new_stream = program_sinks.stream(i);
+ courgette::SinkStream* old_stream = flow.data(flow.OLD)->sinks.stream(i);
+ courgette::SinkStream* new_stream = flow.data(flow.NEW)->sinks.stream(i);
if (old_stream == NULL && new_stream == NULL)
break;
@@ -291,24 +243,14 @@ void DisassembleAdjustDiff(const base::FilePath& model_file,
void Assemble(const base::FilePath& input_file,
const base::FilePath& output_file) {
- BufferedFileReader buffer(input_file, "input");
-
- courgette::SourceStreamSet sources;
- if (!sources.Init(buffer.data(), buffer.length()))
- Problem("Bad input file.");
-
- std::unique_ptr<courgette::EncodedProgram> encoded;
- const courgette::Status read_status =
- courgette::ReadEncodedProgram(&sources, &encoded);
- if (read_status != courgette::C_OK)
- Problem("Bad encoded program.");
-
+ CourgetteFlow flow;
+ BufferedFileReader input_buffer(input_file, flow.name(flow.ONLY));
+ flow.ReadSourceStreamSetFromBuffer(flow.ONLY, input_buffer);
+ flow.ReadEncodedProgramFromSourceStreamSet(flow.ONLY);
courgette::SinkStream sink;
-
- const courgette::Status assemble_status =
- courgette::Assemble(encoded.get(), &sink);
- if (assemble_status != courgette::C_OK)
- Problem("Can't assemble.");
+ flow.WriteExecutableFromEncodedProgram(flow.ONLY, &sink);
+ if (flow.failed())
+ Problem(flow.message().c_str());
WriteSinkToFile(&sink, output_file);
}
@@ -430,6 +372,8 @@ void ApplyBSDiffPatch(const base::FilePath& old_file,
WriteSinkToFile(&new_stream, new_file);
}
+} // namespace
+
int main(int argc, const char* argv[]) {
base::AtExitManager at_exit_manager;
base::CommandLine::Init(argc, argv);
@@ -468,50 +412,51 @@ int main(int argc, const char* argv[]) {
repeat_count = 1;
if (cmd_sup + cmd_dis + cmd_asm + cmd_disadj + cmd_make_patch +
- cmd_apply_patch + cmd_make_bsdiff_patch + cmd_apply_bsdiff_patch +
- cmd_spread_1_adjusted + cmd_spread_1_unadjusted
- != 1)
+ cmd_apply_patch + cmd_make_bsdiff_patch + cmd_apply_bsdiff_patch +
+ cmd_spread_1_adjusted + cmd_spread_1_unadjusted !=
+ 1) {
UsageProblem(
- "Must have exactly one of:\n"
- " -supported -asm, -dis, -disadj, -gen or -apply, -genbsdiff"
- " or -applybsdiff.");
+ "First argument must be one of:\n"
+ " -supported, -asm, -dis, -disadj, -gen, -apply, -genbsdiff,"
+ " -applybsdiff, or -gen1[au].");
+ }
while (repeat_count-- > 0) {
if (cmd_sup) {
if (values.size() != 1)
- UsageProblem("-supported <executable_file>");
+ UsageProblem(kUsageSupported);
return !Supported(values[0]);
} else if (cmd_dis) {
- if (values.size() != 2)
- UsageProblem("-dis <executable_file> <courgette_file>");
- Disassemble(values[0], values[1]);
+ if (values.size() != 2)
+ UsageProblem(kUsageDis);
+ Disassemble(values[0], values[1]);
} else if (cmd_asm) {
if (values.size() != 2)
- UsageProblem("-asm <courgette_file_input> <executable_file_output>");
+ UsageProblem(kUsageAsm);
Assemble(values[0], values[1]);
} else if (cmd_disadj) {
if (values.size() != 3)
- UsageProblem("-disadj <executable_file> <model> <courgette_file>");
+ UsageProblem(kUsageDisadj);
DisassembleAndAdjust(values[0], values[1], values[2]);
} else if (cmd_make_patch) {
if (values.size() != 3)
- UsageProblem("-gen <old_file> <new_file> <patch_file>");
+ UsageProblem(kUsageGen);
GenerateEnsemblePatch(values[0], values[1], values[2]);
} else if (cmd_apply_patch) {
if (values.size() != 3)
- UsageProblem("-apply <old_file> <patch_file> <new_file>");
+ UsageProblem(kUsageApply);
ApplyEnsemblePatch(values[0], values[1], values[2]);
} else if (cmd_make_bsdiff_patch) {
if (values.size() != 3)
- UsageProblem("-genbsdiff <old_file> <new_file> <patch_file>");
+ UsageProblem(kUsageGenbsdiff);
GenerateBSDiffPatch(values[0], values[1], values[2]);
} else if (cmd_apply_bsdiff_patch) {
if (values.size() != 3)
- UsageProblem("-applybsdiff <old_file> <patch_file> <new_file>");
+ UsageProblem(kUsageApplybsdiff);
ApplyBSDiffPatch(values[0], values[1], values[2]);
} else if (cmd_spread_1_adjusted || cmd_spread_1_unadjusted) {
if (values.size() != 3)
- UsageProblem("-gen1[au] <old_file> <new_file> <patch_files_root>");
+ UsageProblem(kUsageGen1);
DisassembleAdjustDiff(values[0], values[1], values[2],
cmd_spread_1_adjusted);
} else {
« no previous file with comments | « courgette/courgette_flow.cc ('k') | courgette/encode_decode_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698