Chromium Code Reviews| Index: test/cctest/interpreter/generate-bytecode-expectations.cc | 
| diff --git a/test/cctest/interpreter/generate-bytecode-expectations.cc b/test/cctest/interpreter/generate-bytecode-expectations.cc | 
| index db55a6cbabfe7e7cf7f2c6412fb1aa9a2d46d3a3..c634c8ed042abd3e7c20ec1181b9453162bd4817 100644 | 
| --- a/test/cctest/interpreter/generate-bytecode-expectations.cc | 
| +++ b/test/cctest/interpreter/generate-bytecode-expectations.cc | 
| @@ -4,6 +4,7 @@ | 
| #include <cstring> | 
| #include <fstream> | 
| +#include <vector> | 
| #include "test/cctest/interpreter/bytecode-expectations-printer.h" | 
| @@ -17,6 +18,8 @@ | 
| using v8::internal::interpreter::BytecodeExpectationsPrinter; | 
| +#define ERROR(MESSAGE) (((std::cerr << "ERROR: ") << MESSAGE) << '\n') | 
| 
 
Stefano Sanfilippo
2016/02/25 13:25:33
Using a macro instead of a function allows the fol
 
 | 
| + | 
| namespace { | 
| class ProgramOptions final { | 
| @@ -57,7 +60,7 @@ class ProgramOptions final { | 
| BytecodeExpectationsPrinter::ConstantPoolType const_pool_type() const { | 
| return const_pool_type_; | 
| } | 
| - std::string input_filename() const { return input_filename_; } | 
| + std::vector<std::string> input_filenames() const { return input_filenames_; } | 
| std::string output_filename() const { return output_filename_; } | 
| std::string test_function_name() const { return test_function_name_; } | 
| @@ -73,7 +76,7 @@ class ProgramOptions final { | 
| bool legacy_const_; | 
| bool do_expressions_; | 
| BytecodeExpectationsPrinter::ConstantPoolType const_pool_type_; | 
| - std::string input_filename_; | 
| + std::vector<std::string> input_filenames_; | 
| std::string output_filename_; | 
| std::string test_function_name_; | 
| }; | 
| @@ -174,14 +177,9 @@ ProgramOptions ProgramOptions::FromCommandLine(int argc, char** argv) { | 
| } else if (strncmp(argv[i], "--test-function-name=", 21) == 0) { | 
| options.test_function_name_ = argv[i] + 21; | 
| } else if (strncmp(argv[i], "--", 2) != 0) { // It doesn't start with -- | 
| - if (!options.input_filename_.empty()) { | 
| - std::cerr << "ERROR: More than one input file specified\n"; | 
| - options.parsing_failed_ = true; | 
| - break; | 
| - } | 
| - options.input_filename_ = argv[i]; | 
| + options.input_filenames_.push_back(argv[i]); | 
| } else { | 
| - std::cerr << "ERROR: Unknonwn option " << argv[i] << "\n"; | 
| + ERROR("Unknonwn option " << argv[i]); | 
| options.parsing_failed_ = true; | 
| break; | 
| } | 
| @@ -196,28 +194,42 @@ bool ProgramOptions::Validate() const { | 
| if (const_pool_type_ == | 
| BytecodeExpectationsPrinter::ConstantPoolType::kUnknown) { | 
| - std::cerr << "ERROR: Unknown constant pool type.\n"; | 
| + ERROR("Unknown constant pool type."); | 
| return false; | 
| } | 
| - if (!read_from_stdin_ && input_filename_.empty()) { | 
| - std::cerr << "ERROR: No input file specified.\n"; | 
| + if (!read_from_stdin_ && input_filenames_.empty()) { | 
| + ERROR("No input file specified."); | 
| return false; | 
| } | 
| - if (read_from_stdin_ && !input_filename_.empty()) { | 
| - std::cerr << "ERROR: Reading from stdin, but input files supplied.\n"; | 
| + if (read_from_stdin_ && !input_filenames_.empty()) { | 
| + ERROR("Reading from stdin, but input files supplied."); | 
| return false; | 
| } | 
| if (rebaseline_ && read_raw_js_snippet_) { | 
| - std::cerr << "ERROR: Cannot use --rebaseline on a raw JS snippet.\n"; | 
| + ERROR("Cannot use --rebaseline on a raw JS snippet."); | 
| + return false; | 
| + } | 
| + | 
| + if (rebaseline_ && !output_filename_.empty()) { | 
| + ERROR("Output file cannot be specified together with --rebaseline."); | 
| + return false; | 
| + } | 
| + | 
| + if (rebaseline_ && read_from_stdin_) { | 
| + ERROR("Cannot --rebaseline when input is --stdin."); | 
| + return false; | 
| + } | 
| + | 
| + if (input_filenames_.size() > 1 && !rebaseline_ && !read_raw_js_snippet()) { | 
| + ERROR("Multiple input files, but no --rebaseline or --raw-js specified."); | 
| return false; | 
| } | 
| if (top_level_ && !test_function_name_.empty()) { | 
| - std::cerr << "ERROR: test function name specified while processing " | 
| - "top level code.\n"; | 
| + ERROR("Test function name specified while processing top level code."); | 
| return false; | 
| } | 
| @@ -360,39 +372,36 @@ void ExtractSnippets(std::vector<std::string>* snippet_list, | 
| void GenerateExpectationsFile(std::ostream& stream, // NOLINT | 
| const std::vector<std::string>& snippet_list, | 
| - const ProgramOptions& options, | 
| - const char* exec_path) { | 
| - V8InitializationScope platform(exec_path); | 
| - { | 
| - v8::Isolate::Scope isolate_scope(platform.isolate()); | 
| - v8::HandleScope handle_scope(platform.isolate()); | 
| - v8::Local<v8::Context> context = v8::Context::New(platform.isolate()); | 
| - v8::Context::Scope context_scope(context); | 
| - | 
| - BytecodeExpectationsPrinter printer(platform.isolate(), | 
| - options.const_pool_type()); | 
| - printer.set_wrap(options.wrap()); | 
| - printer.set_execute(options.execute()); | 
| - printer.set_top_level(options.top_level()); | 
| - if (!options.test_function_name().empty()) { | 
| - printer.set_test_function_name(options.test_function_name()); | 
| - } | 
| + const V8InitializationScope& platform, | 
| + const ProgramOptions& options) { | 
| + v8::Isolate::Scope isolate_scope(platform.isolate()); | 
| + v8::HandleScope handle_scope(platform.isolate()); | 
| + v8::Local<v8::Context> context = v8::Context::New(platform.isolate()); | 
| + v8::Context::Scope context_scope(context); | 
| + | 
| + BytecodeExpectationsPrinter printer(platform.isolate(), | 
| + options.const_pool_type()); | 
| + printer.set_wrap(options.wrap()); | 
| + printer.set_execute(options.execute()); | 
| + printer.set_top_level(options.top_level()); | 
| + if (!options.test_function_name().empty()) { | 
| + printer.set_test_function_name(options.test_function_name()); | 
| + } | 
| - if (options.legacy_const()) i::FLAG_legacy_const = true; | 
| - if (options.do_expressions()) i::FLAG_harmony_do_expressions = true; | 
| + if (options.legacy_const()) i::FLAG_legacy_const = true; | 
| + if (options.do_expressions()) i::FLAG_harmony_do_expressions = true; | 
| - stream << "#\n# Autogenerated by generate-bytecode-expectations.\n#\n\n"; | 
| - options.PrintHeader(stream); | 
| - for (const std::string& snippet : snippet_list) { | 
| - printer.PrintExpectation(stream, snippet); | 
| - } | 
| + stream << "#\n# Autogenerated by generate-bytecode-expectations.\n#\n\n"; | 
| + options.PrintHeader(stream); | 
| + for (const std::string& snippet : snippet_list) { | 
| + printer.PrintExpectation(stream, snippet); | 
| } | 
| } | 
| void PrintUsage(const char* exec_path) { | 
| std::cerr | 
| << "\nUsage: " << exec_path | 
| - << " [OPTIONS]... [INPUT FILE]\n\n" | 
| + << " [OPTIONS]... [INPUT FILES]...\n\n" | 
| "Options:\n" | 
| " --help Print this help message.\n" | 
| " --raw-js Read raw JavaScript, instead of the output format.\n" | 
| @@ -402,7 +411,7 @@ void PrintUsage(const char* exec_path) { | 
| " --no-execute Do not execute after compilation.\n" | 
| " --test-function-name=foo " | 
| "Specify the name of the test function.\n" | 
| - " --top-level Process top level code, not the top-level function." | 
| + " --top-level Process top level code, not the top-level function.\n" | 
| " --legacy-const Enable legacy_const flag.\n" | 
| " --do-expressions Enable harmony_do_expressions flag.\n" | 
| " --output=file.name\n" | 
| @@ -421,49 +430,124 @@ void PrintUsage(const char* exec_path) { | 
| "into the test suite.\n"; | 
| } | 
| -} // namespace | 
| +int DoRebaseline(const V8InitializationScope& platform, | 
| + const ProgramOptions& base_options) { | 
| + DCHECK(base_options.rebaseline()); | 
| + for (const std::string& input_filename : base_options.input_filenames()) { | 
| + std::cerr << "Updating " << input_filename << '\n'; | 
| -int main(int argc, char** argv) { | 
| - ProgramOptions options = ProgramOptions::FromCommandLine(argc, argv); | 
| + std::ifstream input_stream(input_filename); | 
| + if (!input_stream.is_open()) { | 
| + ERROR("Could not open " << input_filename << " for reading."); | 
| + return 2; | 
| + } | 
| - if (!options.Validate() || options.print_help()) { | 
| - PrintUsage(argv[0]); | 
| - return options.print_help() ? 0 : 1; | 
| + ProgramOptions options = base_options; | 
| + options.UpdateFromHeader(input_stream); | 
| + CHECK(options.Validate()); | 
| + | 
| + std::vector<std::string> snippet_list; | 
| + ExtractSnippets(&snippet_list, input_stream, false); | 
| + | 
| + std::ofstream output_stream(input_filename); | 
| + if (!output_stream.is_open()) { | 
| + ERROR("Could not open " << input_filename << " for writing."); | 
| + return 3; | 
| + } | 
| + | 
| + GenerateExpectationsFile(output_stream, snippet_list, platform, options); | 
| + } | 
| + return 0; | 
| +} | 
| + | 
| +int DoRawJS(const V8InitializationScope& platform, | 
| + const ProgramOptions& options) { | 
| + DCHECK(options.read_raw_js_snippet()); | 
| + | 
| + std::vector<std::string> snippet_list; | 
| + | 
| + if (options.read_from_stdin()) { | 
| + snippet_list.push_back(ReadRawJSSnippet(std::cin)); | 
| + } else { | 
| + for (const std::string& input_filename : options.input_filenames()) { | 
| + std::cerr << "Reading " << input_filename << '\n'; | 
| + | 
| + std::ifstream input_stream(input_filename.c_str()); | 
| + if (!input_stream.is_open()) { | 
| + ERROR("Could not open " << input_filename << " for reading."); | 
| + return 2; | 
| + } | 
| + | 
| + snippet_list.push_back(ReadRawJSSnippet(input_stream)); | 
| + } | 
| + } | 
| + | 
| + std::ofstream output_file_handle; | 
| + if (!options.write_to_stdout()) { | 
| + output_file_handle.open(options.output_filename().c_str()); | 
| + if (!output_file_handle.is_open()) { | 
| + ERROR("Could not open " << options.output_filename() << " for writing."); | 
| + return 3; | 
| + } | 
| } | 
| + std::ostream& output_stream = | 
| + options.write_to_stdout() ? std::cout : output_file_handle; | 
| + | 
| + GenerateExpectationsFile(output_stream, snippet_list, platform, options); | 
| + return 0; | 
| +} | 
| + | 
| +int DoDefault(const V8InitializationScope& platform, | 
| + const ProgramOptions& options) { | 
| std::ifstream input_file_handle; | 
| if (!options.read_from_stdin()) { | 
| - input_file_handle.open(options.input_filename().c_str()); | 
| + const char* input_filename = options.input_filenames().front().c_str(); | 
| + input_file_handle.open(input_filename); | 
| if (!input_file_handle.is_open()) { | 
| - std::cerr << "ERROR: Could not open '" << options.input_filename() | 
| - << "' for reading.\n"; | 
| + ERROR("Could not open " << input_filename << " for reading."); | 
| return 2; | 
| } | 
| } | 
| std::istream& input_stream = | 
| options.read_from_stdin() ? std::cin : input_file_handle; | 
| - if (options.rebaseline()) { | 
| - options.UpdateFromHeader(input_stream); | 
| - CHECK(options.Validate()); | 
| - } | 
| - | 
| std::vector<std::string> snippet_list; | 
| - ExtractSnippets(&snippet_list, input_stream, options.read_raw_js_snippet()); | 
| + ExtractSnippets(&snippet_list, input_stream, false); | 
| std::ofstream output_file_handle; | 
| if (!options.write_to_stdout()) { | 
| - output_file_handle.open(options.rebaseline() | 
| - ? options.input_filename().c_str() | 
| - : options.output_filename().c_str()); | 
| + output_file_handle.open(options.output_filename().c_str()); | 
| if (!output_file_handle.is_open()) { | 
| - std::cerr << "ERROR: Could not open '" << options.output_filename() | 
| - << "' for writing.\n"; | 
| + ERROR("Could not open " << options.output_filename() << " for writing."); | 
| return 3; | 
| } | 
| } | 
| std::ostream& output_stream = | 
| options.write_to_stdout() ? std::cout : output_file_handle; | 
| - GenerateExpectationsFile(output_stream, snippet_list, options, argv[0]); | 
| + GenerateExpectationsFile(output_stream, snippet_list, platform, options); | 
| + | 
| + return 0; | 
| +} | 
| + | 
| +} // namespace | 
| + | 
| +int main(int argc, char** argv) { | 
| + ProgramOptions options = ProgramOptions::FromCommandLine(argc, argv); | 
| + | 
| + if (!options.Validate() || options.print_help()) { | 
| + PrintUsage(argv[0]); | 
| + return options.print_help() ? 0 : 1; | 
| + } | 
| + | 
| + V8InitializationScope platform(argv[0]); | 
| + | 
| + if (options.read_raw_js_snippet()) { | 
| + return DoRawJS(platform, options); | 
| + } else if (options.rebaseline()) { | 
| + return DoRebaseline(platform, options); | 
| + } else { | 
| + return DoDefault(platform, options); | 
| + } | 
| } |