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

Side by Side 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, 7 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 unified diff | Download patch
« no previous file with comments | « courgette/courgette_flow.cc ('k') | courgette/encode_decode_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include <stdarg.h>
5 #include <stddef.h> 6 #include <stddef.h>
6 #include <stdint.h> 7 #include <stdint.h>
7 8
9 #include <initializer_list>
8 #include <memory> 10 #include <memory>
9 #include <string> 11 #include <string>
10 #include <vector> 12 #include <vector>
11 13
12 #include "base/at_exit.h" 14 #include "base/at_exit.h"
13 #include "base/command_line.h" 15 #include "base/command_line.h"
14 #include "base/files/file_path.h" 16 #include "base/files/file_path.h"
15 #include "base/files/file_util.h" 17 #include "base/files/file_util.h"
16 #include "base/files/memory_mapped_file.h" 18 #include "base/files/memory_mapped_file.h"
17 #include "base/logging.h" 19 #include "base/logging.h"
20 #include "base/macros.h"
18 #include "base/strings/string_number_conversions.h" 21 #include "base/strings/string_number_conversions.h"
19 #include "base/strings/string_util.h" 22 #include "base/strings/string_util.h"
20 #include "base/strings/utf_string_conversions.h" 23 #include "base/strings/utf_string_conversions.h"
21 #include "courgette/assembly_program.h" 24 #include "courgette/assembly_program.h"
22 #include "courgette/courgette.h" 25 #include "courgette/courgette.h"
26 #include "courgette/courgette_flow.h"
23 #include "courgette/encoded_program.h" 27 #include "courgette/encoded_program.h"
24 #include "courgette/program_detector.h" 28 #include "courgette/program_detector.h"
25 #include "courgette/streams.h" 29 #include "courgette/streams.h"
26 #include "courgette/third_party/bsdiff/bsdiff.h" 30 #include "courgette/third_party/bsdiff/bsdiff.h"
27 31
32 namespace {
33
34 using courgette::CourgetteFlow;
35
36 const char kUsageGen[] = "-gen <old_in> <new_in> <patch_out>";
37 const char kUsageApply[] = "-apply <old_in> <patch_in> <new_out>";
38 const char kUsageGenbsdiff[] = "-genbsdiff <old_in> <new_in> <patch_out>";
39 const char kUsageApplybsdiff[] = "-applybsdiff <old_in> <patch_in> <new_out>";
40 const char kUsageSupported[] = "-supported <exec_file_in>";
41 const char kUsageDis[] = "-dis <exec_file_in> <assembly_file_out>";
42 const char kUsageAsm[] = "-asm <assembly_file_in> <exec_file_out>";
43 const char kUsageDisadj[] = "-disadj <old_in> <new_in> <new_assembly_file_out>";
44 const char kUsageGen1[] = "-gen1[au] <old_in> <new_in> <patch_base_out>";
45
46 /******** Utilities to print help and exit ********/
47
28 void PrintHelp() { 48 void PrintHelp() {
29 fprintf(stderr, 49 fprintf(stderr, "Main Usage:\n");
30 "Usage:\n" 50 for (auto usage :
31 " courgette -supported <executable_file>\n" 51 {kUsageGen, kUsageApply, kUsageGenbsdiff, kUsageApplybsdiff}) {
32 " courgette -dis <executable_file> <binary_assembly_file>\n" 52 fprintf(stderr, " courgette %s\n", usage);
33 " courgette -asm <binary_assembly_file> <executable_file>\n" 53 }
34 " courgette -disadj <executable_file> <reference> <binary_assembly_file>\n" 54 fprintf(stderr, "Diagnosis Usage:\n");
35 " courgette -gen <v1> <v2> <patch>\n" 55 for (auto usage :
36 " courgette -apply <v1> <patch> <v2>\n" 56 {kUsageSupported, kUsageDis, kUsageAsm, kUsageDisadj, kUsageGen1}) {
37 "\n"); 57 fprintf(stderr, " courgette %s\n", usage);
58 }
38 } 59 }
39 60
40 void UsageProblem(const char* message) { 61 void UsageProblem(const char* message) {
41 fprintf(stderr, "%s", message); 62 fprintf(stderr, "%s", message);
42 fprintf(stderr, "\n"); 63 fprintf(stderr, "\n");
43 PrintHelp(); 64 PrintHelp();
44 exit(1); 65 exit(1);
45 } 66 }
46 67
47 void Problem(const char* format, ...) { 68 void Problem(const char* format, ...) {
48 va_list args; 69 va_list args;
49 va_start(args, format); 70 va_start(args, format);
50 vfprintf(stderr, format, args); 71 vfprintf(stderr, format, args);
51 fprintf(stderr, "\n"); 72 fprintf(stderr, "\n");
52 va_end(args); 73 va_end(args);
53 exit(1); 74 exit(1);
54 } 75 }
55 76
77 /******** BufferedFileReader ********/
78
56 // A file reader that calls Problem() on failure. 79 // A file reader that calls Problem() on failure.
57 class BufferedFileReader { 80 class BufferedFileReader : public courgette::BasicBuffer {
58 public: 81 public:
59 BufferedFileReader(const base::FilePath& file_name, const char* kind) { 82 BufferedFileReader(const base::FilePath& file_name, const char* kind) {
60 if (!buffer_.Initialize(file_name)) 83 if (!buffer_.Initialize(file_name))
61 Problem("Can't read %s file.", kind); 84 Problem("Can't read %s file.", kind);
62 } 85 }
63 const uint8_t* data() const { return buffer_.data(); } 86 ~BufferedFileReader() override {}
64 size_t length() const { return buffer_.length(); } 87
88 // courgette::BasicBuffer:
89 const uint8_t* data() const override { return buffer_.data(); }
90 size_t length() const override { return buffer_.length(); }
65 91
66 private: 92 private:
67 base::MemoryMappedFile buffer_; 93 base::MemoryMappedFile buffer_;
94
95 DISALLOW_COPY_AND_ASSIGN(BufferedFileReader);
68 }; 96 };
69 97
98 /******** Various helpers ********/
99
70 void WriteSinkToFile(const courgette::SinkStream *sink, 100 void WriteSinkToFile(const courgette::SinkStream *sink,
71 const base::FilePath& output_file) { 101 const base::FilePath& output_file) {
72 int count = 102 int count =
73 base::WriteFile(output_file, 103 base::WriteFile(output_file,
74 reinterpret_cast<const char*>(sink->Buffer()), 104 reinterpret_cast<const char*>(sink->Buffer()),
75 static_cast<int>(sink->Length())); 105 static_cast<int>(sink->Length()));
76 if (count == -1) 106 if (count == -1)
77 Problem("Can't write output."); 107 Problem("Can't write output.");
78 if (static_cast<size_t>(count) != sink->Length()) 108 if (static_cast<size_t>(count) != sink->Length())
79 Problem("Incomplete write."); 109 Problem("Incomplete write.");
80 } 110 }
81 111
82 void Disassemble(const base::FilePath& input_file,
83 const base::FilePath& output_file) {
84 BufferedFileReader buffer(input_file, "input");
85
86 std::unique_ptr<courgette::AssemblyProgram> program;
87 const courgette::Status parse_status = courgette::ParseDetectedExecutable(
88 buffer.data(), buffer.length(), &program);
89 if (parse_status != courgette::C_OK)
90 Problem("Can't parse input (code = %d).", parse_status);
91
92 std::unique_ptr<courgette::EncodedProgram> encoded;
93 const courgette::Status encode_status = Encode(*program, &encoded);
94 if (encode_status != courgette::C_OK)
95 Problem("Can't encode program.");
96
97 program.reset();
98
99 courgette::SinkStreamSet sinks;
100 const courgette::Status write_status =
101 courgette::WriteEncodedProgram(encoded.get(), &sinks);
102 if (write_status != courgette::C_OK)
103 Problem("Can't serialize encoded program.");
104
105 encoded.reset();
106
107 courgette::SinkStream sink;
108 if (!sinks.CopyTo(&sink))
109 Problem("Can't combine serialized encoded program streams.");
110
111 WriteSinkToFile(&sink, output_file);
112 }
113
114 bool Supported(const base::FilePath& input_file) { 112 bool Supported(const base::FilePath& input_file) {
115 bool result = false; 113 bool result = false;
116 114
117 BufferedFileReader buffer(input_file, "input"); 115 BufferedFileReader buffer(input_file, "input");
118 116
119 courgette::ExecutableType type; 117 courgette::ExecutableType type;
120 size_t detected_length; 118 size_t detected_length;
121 119
122 DetectExecutableType(buffer.data(), buffer.length(), &type, &detected_length); 120 DetectExecutableType(buffer.data(), buffer.length(), &type, &detected_length);
123 121
(...skipping 22 matching lines...) Expand all
146 case courgette::EXE_WIN_32_X64: 144 case courgette::EXE_WIN_32_X64:
147 format = "Windows 64 PE"; 145 format = "Windows 64 PE";
148 result = true; 146 result = true;
149 break; 147 break;
150 } 148 }
151 149
152 printf("%s Executable\n", format.c_str()); 150 printf("%s Executable\n", format.c_str());
153 return result; 151 return result;
154 } 152 }
155 153
156 void DisassembleAndAdjust(const base::FilePath& program_file, 154 void Disassemble(const base::FilePath& input_file,
157 const base::FilePath& model_file, 155 const base::FilePath& output_file) {
158 const base::FilePath& output_file) { 156 CourgetteFlow flow;
159 BufferedFileReader program_buffer(program_file, "program"); 157 BufferedFileReader input_buffer(input_file, flow.name(flow.ONLY));
160 BufferedFileReader model_buffer(model_file, "model"); 158 flow.ReadAssemblyProgramFromBuffer(flow.ONLY, input_buffer, false);
161 159 flow.CreateEncodedProgramFromAssemblyProgram(flow.ONLY);
162 std::unique_ptr<courgette::AssemblyProgram> program; 160 flow.DestroyAssemblyProgram(flow.ONLY);
163 const courgette::Status parse_program_status = 161 flow.WriteSinkStreamSetFromEncodedProgram(flow.ONLY);
164 courgette::ParseDetectedExecutable(program_buffer.data(), 162 flow.DestroyEncodedProgram(flow.ONLY);
165 program_buffer.length(), &program);
166 if (parse_program_status != courgette::C_OK)
167 Problem("Can't parse program input (code = %d).", parse_program_status);
168
169 std::unique_ptr<courgette::AssemblyProgram> model;
170 const courgette::Status parse_model_status =
171 courgette::ParseDetectedExecutable(model_buffer.data(),
172 model_buffer.length(), &model);
173 if (parse_model_status != courgette::C_OK)
174 Problem("Can't parse model input (code = %d).", parse_model_status);
175
176 const courgette::Status adjust_status = Adjust(*model, program.get());
177 if (adjust_status != courgette::C_OK)
178 Problem("Can't adjust program.");
179
180 model.reset();
181
182 std::unique_ptr<courgette::EncodedProgram> encoded;
183 const courgette::Status encode_status = Encode(*program, &encoded);
184 if (encode_status != courgette::C_OK)
185 Problem("Can't encode program.");
186
187 program.reset();
188
189 courgette::SinkStreamSet sinks;
190 const courgette::Status write_status =
191 courgette::WriteEncodedProgram(encoded.get(), &sinks);
192 if (write_status != courgette::C_OK)
193 Problem("Can't serialize encoded program.");
194
195 encoded.reset();
196
197 courgette::SinkStream sink; 163 courgette::SinkStream sink;
198 if (!sinks.CopyTo(&sink)) 164 flow.WriteSinkStreamFromSinkStreamSet(flow.ONLY, &sink);
199 Problem("Can't combine serialized encoded program streams."); 165 if (flow.failed())
166 Problem(flow.message().c_str());
200 167
201 WriteSinkToFile(&sink, output_file); 168 WriteSinkToFile(&sink, output_file);
202 } 169 }
170
171 void DisassembleAndAdjust(const base::FilePath& old_file,
172 const base::FilePath& new_file,
173 const base::FilePath& output_file) {
174 CourgetteFlow flow;
175 BufferedFileReader old_buffer(old_file, flow.name(flow.OLD));
176 BufferedFileReader new_buffer(new_file, flow.name(flow.NEW));
177 flow.ReadAssemblyProgramFromBuffer(flow.OLD, old_buffer, true);
178 flow.ReadAssemblyProgramFromBuffer(flow.NEW, new_buffer, true);
179 flow.AdjustNewAssemblyProgramToMatchOld();
180 flow.DestroyAssemblyProgram(flow.OLD);
181 flow.CreateEncodedProgramFromAssemblyProgram(flow.NEW);
182 flow.DestroyAssemblyProgram(flow.NEW);
183 flow.WriteSinkStreamSetFromEncodedProgram(flow.NEW);
184 flow.DestroyEncodedProgram(flow.NEW);
185 courgette::SinkStream sink;
186 flow.WriteSinkStreamFromSinkStreamSet(flow.NEW, &sink);
187 if (flow.failed())
188 Problem(flow.message().c_str());
189
190 WriteSinkToFile(&sink, output_file);
191 }
203 192
204 // Diffs two executable files, write a set of files for the diff, one file per 193 // Diffs two executable files, write a set of files for the diff, one file per
205 // stream of the EncodedProgram format. Each file is the bsdiff between the 194 // stream of the EncodedProgram format. Each file is the bsdiff between the
206 // original file's stream and the new file's stream. This is completely 195 // original file's stream and the new file's stream. This is completely
207 // uninteresting to users, but it is handy for seeing how much each which 196 // uninteresting to users, but it is handy for seeing how much each which
208 // streams are contributing to the final file size. Adjustment is optional. 197 // streams are contributing to the final file size. Adjustment is optional.
209 void DisassembleAdjustDiff(const base::FilePath& model_file, 198 void DisassembleAdjustDiff(const base::FilePath& old_file,
210 const base::FilePath& program_file, 199 const base::FilePath& new_file,
211 const base::FilePath& output_file_root, 200 const base::FilePath& output_file_root,
212 bool adjust) { 201 bool adjust) {
213 BufferedFileReader model_buffer(model_file, "old"); 202 CourgetteFlow flow;
214 BufferedFileReader program_buffer(program_file, "new"); 203 BufferedFileReader old_buffer(old_file, flow.name(flow.OLD));
215 204 BufferedFileReader new_buffer(new_file, flow.name(flow.NEW));
216 auto parser = adjust ? courgette::ParseDetectedExecutableWithAnnotation 205 flow.ReadAssemblyProgramFromBuffer(flow.OLD, old_buffer, adjust);
217 : courgette::ParseDetectedExecutable; 206 flow.ReadAssemblyProgramFromBuffer(flow.NEW, new_buffer, adjust);
218 207 if (adjust)
219 std::unique_ptr<courgette::AssemblyProgram> model; 208 flow.AdjustNewAssemblyProgramToMatchOld();
220 const courgette::Status parse_model_status = 209 flow.CreateEncodedProgramFromAssemblyProgram(flow.OLD);
221 parser(model_buffer.data(), model_buffer.length(), &model); 210 flow.DestroyAssemblyProgram(flow.OLD);
222 if (parse_model_status != courgette::C_OK) 211 flow.CreateEncodedProgramFromAssemblyProgram(flow.NEW);
223 Problem("Can't parse model input (code = %d).", parse_model_status); 212 flow.DestroyAssemblyProgram(flow.NEW);
224 213 flow.WriteSinkStreamSetFromEncodedProgram(flow.OLD);
225 std::unique_ptr<courgette::AssemblyProgram> program; 214 flow.DestroyEncodedProgram(flow.OLD);
226 const courgette::Status parse_program_status = 215 flow.WriteSinkStreamSetFromEncodedProgram(flow.NEW);
227 parser(program_buffer.data(), program_buffer.length(), &program); 216 flow.DestroyEncodedProgram(flow.NEW);
228 if (parse_program_status != courgette::C_OK) 217 if (flow.failed())
229 Problem("Can't parse program input (code = %d).", parse_program_status); 218 Problem(flow.message().c_str());
230
231 if (adjust) {
232 const courgette::Status adjust_status = Adjust(*model, program.get());
233 if (adjust_status != courgette::C_OK)
234 Problem("Can't adjust program.");
235 }
236
237 std::unique_ptr<courgette::EncodedProgram> encoded_program;
238 const courgette::Status encode_program_status =
239 Encode(*program, &encoded_program);
240 if (encode_program_status != courgette::C_OK)
241 Problem("Can't encode program.");
242
243 program.reset();
244
245 std::unique_ptr<courgette::EncodedProgram> encoded_model;
246 const courgette::Status encode_model_status = Encode(*model, &encoded_model);
247 if (encode_model_status != courgette::C_OK)
248 Problem("Can't encode model.");
249
250 model.reset();
251
252 courgette::SinkStreamSet program_sinks;
253 const courgette::Status write_program_status =
254 courgette::WriteEncodedProgram(encoded_program.get(), &program_sinks);
255 if (write_program_status != courgette::C_OK)
256 Problem("Can't serialize encoded program.");
257
258 encoded_program.reset();
259
260 courgette::SinkStreamSet model_sinks;
261 const courgette::Status write_model_status =
262 courgette::WriteEncodedProgram(encoded_model.get(), &model_sinks);
263 if (write_model_status != courgette::C_OK)
264 Problem("Can't serialize encoded model.");
265
266 encoded_model.reset();
267 219
268 courgette::SinkStream empty_sink; 220 courgette::SinkStream empty_sink;
269 for (int i = 0; ; ++i) { 221 for (int i = 0; ; ++i) {
270 courgette::SinkStream* old_stream = model_sinks.stream(i); 222 courgette::SinkStream* old_stream = flow.data(flow.OLD)->sinks.stream(i);
271 courgette::SinkStream* new_stream = program_sinks.stream(i); 223 courgette::SinkStream* new_stream = flow.data(flow.NEW)->sinks.stream(i);
272 if (old_stream == NULL && new_stream == NULL) 224 if (old_stream == NULL && new_stream == NULL)
273 break; 225 break;
274 226
275 courgette::SourceStream old_source; 227 courgette::SourceStream old_source;
276 courgette::SourceStream new_source; 228 courgette::SourceStream new_source;
277 old_source.Init(old_stream ? *old_stream : empty_sink); 229 old_source.Init(old_stream ? *old_stream : empty_sink);
278 new_source.Init(new_stream ? *new_stream : empty_sink); 230 new_source.Init(new_stream ? *new_stream : empty_sink);
279 courgette::SinkStream patch_stream; 231 courgette::SinkStream patch_stream;
280 bsdiff::BSDiffStatus status = 232 bsdiff::BSDiffStatus status =
281 bsdiff::CreateBinaryPatch(&old_source, &new_source, &patch_stream); 233 bsdiff::CreateBinaryPatch(&old_source, &new_source, &patch_stream);
282 if (status != bsdiff::OK) 234 if (status != bsdiff::OK)
283 Problem("-xxx failed."); 235 Problem("-xxx failed.");
284 236
285 std::string append = std::string("-") + base::IntToString(i); 237 std::string append = std::string("-") + base::IntToString(i);
286 238
287 WriteSinkToFile(&patch_stream, 239 WriteSinkToFile(&patch_stream,
288 output_file_root.InsertBeforeExtensionASCII(append)); 240 output_file_root.InsertBeforeExtensionASCII(append));
289 } 241 }
290 } 242 }
291 243
292 void Assemble(const base::FilePath& input_file, 244 void Assemble(const base::FilePath& input_file,
293 const base::FilePath& output_file) { 245 const base::FilePath& output_file) {
294 BufferedFileReader buffer(input_file, "input"); 246 CourgetteFlow flow;
295 247 BufferedFileReader input_buffer(input_file, flow.name(flow.ONLY));
296 courgette::SourceStreamSet sources; 248 flow.ReadSourceStreamSetFromBuffer(flow.ONLY, input_buffer);
297 if (!sources.Init(buffer.data(), buffer.length())) 249 flow.ReadEncodedProgramFromSourceStreamSet(flow.ONLY);
298 Problem("Bad input file.");
299
300 std::unique_ptr<courgette::EncodedProgram> encoded;
301 const courgette::Status read_status =
302 courgette::ReadEncodedProgram(&sources, &encoded);
303 if (read_status != courgette::C_OK)
304 Problem("Bad encoded program.");
305
306 courgette::SinkStream sink; 250 courgette::SinkStream sink;
307 251 flow.WriteExecutableFromEncodedProgram(flow.ONLY, &sink);
308 const courgette::Status assemble_status = 252 if (flow.failed())
309 courgette::Assemble(encoded.get(), &sink); 253 Problem(flow.message().c_str());
310 if (assemble_status != courgette::C_OK)
311 Problem("Can't assemble.");
312 254
313 WriteSinkToFile(&sink, output_file); 255 WriteSinkToFile(&sink, output_file);
314 } 256 }
315 257
316 void GenerateEnsemblePatch(const base::FilePath& old_file, 258 void GenerateEnsemblePatch(const base::FilePath& old_file,
317 const base::FilePath& new_file, 259 const base::FilePath& new_file,
318 const base::FilePath& patch_file) { 260 const base::FilePath& patch_file) {
319 BufferedFileReader old_buffer(old_file, "'old' input"); 261 BufferedFileReader old_buffer(old_file, "'old' input");
320 BufferedFileReader new_buffer(new_file, "'new' input"); 262 BufferedFileReader new_buffer(new_file, "'new' input");
321 263
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after
423 courgette::SinkStream new_stream; 365 courgette::SinkStream new_stream;
424 bsdiff::BSDiffStatus status = 366 bsdiff::BSDiffStatus status =
425 bsdiff::ApplyBinaryPatch(&old_stream, &patch_stream, &new_stream); 367 bsdiff::ApplyBinaryPatch(&old_stream, &patch_stream, &new_stream);
426 368
427 if (status != bsdiff::OK) 369 if (status != bsdiff::OK)
428 Problem("-applybsdiff failed."); 370 Problem("-applybsdiff failed.");
429 371
430 WriteSinkToFile(&new_stream, new_file); 372 WriteSinkToFile(&new_stream, new_file);
431 } 373 }
432 374
375 } // namespace
376
433 int main(int argc, const char* argv[]) { 377 int main(int argc, const char* argv[]) {
434 base::AtExitManager at_exit_manager; 378 base::AtExitManager at_exit_manager;
435 base::CommandLine::Init(argc, argv); 379 base::CommandLine::Init(argc, argv);
436 const base::CommandLine& command_line = 380 const base::CommandLine& command_line =
437 *base::CommandLine::ForCurrentProcess(); 381 *base::CommandLine::ForCurrentProcess();
438 382
439 logging::LoggingSettings settings; 383 logging::LoggingSettings settings;
440 settings.logging_dest = logging::LOG_TO_ALL; 384 settings.logging_dest = logging::LOG_TO_ALL;
441 settings.log_file = FILE_PATH_LITERAL("courgette.log"); 385 settings.log_file = FILE_PATH_LITERAL("courgette.log");
442 (void)logging::InitLogging(settings); 386 (void)logging::InitLogging(settings);
(...skipping 18 matching lines...) Expand all
461 405
462 // '-repeat=N' is for debugging. Running many iterations can reveal leaks and 406 // '-repeat=N' is for debugging. Running many iterations can reveal leaks and
463 // bugs in cleanup. 407 // bugs in cleanup.
464 int repeat_count = 1; 408 int repeat_count = 1;
465 std::string repeat_switch = command_line.GetSwitchValueASCII("repeat"); 409 std::string repeat_switch = command_line.GetSwitchValueASCII("repeat");
466 if (!repeat_switch.empty()) 410 if (!repeat_switch.empty())
467 if (!base::StringToInt(repeat_switch, &repeat_count)) 411 if (!base::StringToInt(repeat_switch, &repeat_count))
468 repeat_count = 1; 412 repeat_count = 1;
469 413
470 if (cmd_sup + cmd_dis + cmd_asm + cmd_disadj + cmd_make_patch + 414 if (cmd_sup + cmd_dis + cmd_asm + cmd_disadj + cmd_make_patch +
471 cmd_apply_patch + cmd_make_bsdiff_patch + cmd_apply_bsdiff_patch + 415 cmd_apply_patch + cmd_make_bsdiff_patch + cmd_apply_bsdiff_patch +
472 cmd_spread_1_adjusted + cmd_spread_1_unadjusted 416 cmd_spread_1_adjusted + cmd_spread_1_unadjusted !=
473 != 1) 417 1) {
474 UsageProblem( 418 UsageProblem(
475 "Must have exactly one of:\n" 419 "First argument must be one of:\n"
476 " -supported -asm, -dis, -disadj, -gen or -apply, -genbsdiff" 420 " -supported, -asm, -dis, -disadj, -gen, -apply, -genbsdiff,"
477 " or -applybsdiff."); 421 " -applybsdiff, or -gen1[au].");
422 }
478 423
479 while (repeat_count-- > 0) { 424 while (repeat_count-- > 0) {
480 if (cmd_sup) { 425 if (cmd_sup) {
481 if (values.size() != 1) 426 if (values.size() != 1)
482 UsageProblem("-supported <executable_file>"); 427 UsageProblem(kUsageSupported);
483 return !Supported(values[0]); 428 return !Supported(values[0]);
484 } else if (cmd_dis) { 429 } else if (cmd_dis) {
485 if (values.size() != 2) 430 if (values.size() != 2)
486 UsageProblem("-dis <executable_file> <courgette_file>"); 431 UsageProblem(kUsageDis);
487 Disassemble(values[0], values[1]); 432 Disassemble(values[0], values[1]);
488 } else if (cmd_asm) { 433 } else if (cmd_asm) {
489 if (values.size() != 2) 434 if (values.size() != 2)
490 UsageProblem("-asm <courgette_file_input> <executable_file_output>"); 435 UsageProblem(kUsageAsm);
491 Assemble(values[0], values[1]); 436 Assemble(values[0], values[1]);
492 } else if (cmd_disadj) { 437 } else if (cmd_disadj) {
493 if (values.size() != 3) 438 if (values.size() != 3)
494 UsageProblem("-disadj <executable_file> <model> <courgette_file>"); 439 UsageProblem(kUsageDisadj);
495 DisassembleAndAdjust(values[0], values[1], values[2]); 440 DisassembleAndAdjust(values[0], values[1], values[2]);
496 } else if (cmd_make_patch) { 441 } else if (cmd_make_patch) {
497 if (values.size() != 3) 442 if (values.size() != 3)
498 UsageProblem("-gen <old_file> <new_file> <patch_file>"); 443 UsageProblem(kUsageGen);
499 GenerateEnsemblePatch(values[0], values[1], values[2]); 444 GenerateEnsemblePatch(values[0], values[1], values[2]);
500 } else if (cmd_apply_patch) { 445 } else if (cmd_apply_patch) {
501 if (values.size() != 3) 446 if (values.size() != 3)
502 UsageProblem("-apply <old_file> <patch_file> <new_file>"); 447 UsageProblem(kUsageApply);
503 ApplyEnsemblePatch(values[0], values[1], values[2]); 448 ApplyEnsemblePatch(values[0], values[1], values[2]);
504 } else if (cmd_make_bsdiff_patch) { 449 } else if (cmd_make_bsdiff_patch) {
505 if (values.size() != 3) 450 if (values.size() != 3)
506 UsageProblem("-genbsdiff <old_file> <new_file> <patch_file>"); 451 UsageProblem(kUsageGenbsdiff);
507 GenerateBSDiffPatch(values[0], values[1], values[2]); 452 GenerateBSDiffPatch(values[0], values[1], values[2]);
508 } else if (cmd_apply_bsdiff_patch) { 453 } else if (cmd_apply_bsdiff_patch) {
509 if (values.size() != 3) 454 if (values.size() != 3)
510 UsageProblem("-applybsdiff <old_file> <patch_file> <new_file>"); 455 UsageProblem(kUsageApplybsdiff);
511 ApplyBSDiffPatch(values[0], values[1], values[2]); 456 ApplyBSDiffPatch(values[0], values[1], values[2]);
512 } else if (cmd_spread_1_adjusted || cmd_spread_1_unadjusted) { 457 } else if (cmd_spread_1_adjusted || cmd_spread_1_unadjusted) {
513 if (values.size() != 3) 458 if (values.size() != 3)
514 UsageProblem("-gen1[au] <old_file> <new_file> <patch_files_root>"); 459 UsageProblem(kUsageGen1);
515 DisassembleAdjustDiff(values[0], values[1], values[2], 460 DisassembleAdjustDiff(values[0], values[1], values[2],
516 cmd_spread_1_adjusted); 461 cmd_spread_1_adjusted);
517 } else { 462 } else {
518 UsageProblem("No operation specified"); 463 UsageProblem("No operation specified");
519 } 464 }
520 } 465 }
521 466
522 return 0; 467 return 0;
523 } 468 }
OLDNEW
« 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