Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2016 the V8 project authors. All rights reserved. | 1 // Copyright 2016 the V8 project 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 <cstring> | 5 #include <cstring> |
| 6 #include <fstream> | 6 #include <fstream> |
| 7 | 7 |
| 8 #include "test/cctest/interpreter/bytecode-expectations-printer.h" | 8 #include "test/cctest/interpreter/bytecode-expectations-printer.h" |
| 9 | 9 |
| 10 #include "include/libplatform/libplatform.h" | 10 #include "include/libplatform/libplatform.h" |
| (...skipping 10 matching lines...) Expand all Loading... | |
| 21 | 21 |
| 22 class ProgramOptions { | 22 class ProgramOptions { |
| 23 public: | 23 public: |
| 24 static ProgramOptions FromCommandLine(int argc, char** argv); | 24 static ProgramOptions FromCommandLine(int argc, char** argv); |
| 25 | 25 |
| 26 ProgramOptions() | 26 ProgramOptions() |
| 27 : parsing_failed_(false), | 27 : parsing_failed_(false), |
| 28 print_help_(false), | 28 print_help_(false), |
| 29 read_raw_js_snippet_(false), | 29 read_raw_js_snippet_(false), |
| 30 read_from_stdin_(false), | 30 read_from_stdin_(false), |
| 31 fix_(false), | |
| 32 print_banner_(true), | |
| 33 wrap_(true), | |
| 34 execute_(true), | |
| 31 const_pool_type_( | 35 const_pool_type_( |
| 32 BytecodeExpectationsPrinter::ConstantPoolType::kMixed) {} | 36 BytecodeExpectationsPrinter::ConstantPoolType::kMixed) {} |
| 33 | 37 |
| 34 bool Validate() const; | 38 bool Validate() const; |
| 35 | 39 |
| 36 bool parsing_failed() const { return parsing_failed_; } | 40 bool parsing_failed() const { return parsing_failed_; } |
| 37 bool print_help() const { return print_help_; } | 41 bool print_help() const { return print_help_; } |
| 38 bool read_raw_js_snippet() const { return read_raw_js_snippet_; } | 42 bool read_raw_js_snippet() const { return read_raw_js_snippet_; } |
| 39 bool read_from_stdin() const { return read_from_stdin_; } | 43 bool read_from_stdin() const { return read_from_stdin_; } |
| 40 std::string filename() const { return filename_; } | 44 bool fix() const { return fix_; } |
| 45 bool print_banner() const { return print_banner_; } | |
| 46 bool wrap() const { return wrap_; } | |
| 47 bool execute() const { return execute_; } | |
| 41 BytecodeExpectationsPrinter::ConstantPoolType const_pool_type() const { | 48 BytecodeExpectationsPrinter::ConstantPoolType const_pool_type() const { |
| 42 return const_pool_type_; | 49 return const_pool_type_; |
| 43 } | 50 } |
| 51 std::string input_filename() const { return input_filename_; } | |
| 52 std::string output_filename() const { return output_file_name_; } | |
| 53 std::string top_function_name() const { return top_function_name_; } | |
| 44 | 54 |
| 45 private: | 55 private: |
| 46 bool parsing_failed_; | 56 bool parsing_failed_; |
| 47 bool print_help_; | 57 bool print_help_; |
| 48 bool read_raw_js_snippet_; | 58 bool read_raw_js_snippet_; |
| 49 bool read_from_stdin_; | 59 bool read_from_stdin_; |
| 60 bool fix_; | |
| 61 bool print_banner_; | |
| 62 bool wrap_; | |
| 63 bool execute_; | |
| 50 BytecodeExpectationsPrinter::ConstantPoolType const_pool_type_; | 64 BytecodeExpectationsPrinter::ConstantPoolType const_pool_type_; |
| 51 std::string filename_; | 65 std::string input_filename_; |
| 66 std::string output_file_name_; | |
| 67 std::string top_function_name_; | |
| 68 | |
| 69 friend void ParseOptionsHeader(ProgramOptions*, std::istream&); | |
| 52 }; | 70 }; |
| 53 | 71 |
| 54 class ArrayBufferAllocator final : public v8::ArrayBuffer::Allocator { | 72 class ArrayBufferAllocator final : public v8::ArrayBuffer::Allocator { |
| 55 public: | 73 public: |
| 56 void* Allocate(size_t length) override { | 74 void* Allocate(size_t length) override { |
| 57 void* data = AllocateUninitialized(length); | 75 void* data = AllocateUninitialized(length); |
| 58 if (data != nullptr) memset(data, 0, length); | 76 if (data != nullptr) memset(data, 0, length); |
| 59 return data; | 77 return data; |
| 60 } | 78 } |
| 61 void* AllocateUninitialized(size_t length) override { return malloc(length); } | 79 void* AllocateUninitialized(size_t length) override { return malloc(length); } |
| (...skipping 26 matching lines...) Expand all Loading... | |
| 88 } else if (strcmp(type_string, "mixed") == 0) { | 106 } else if (strcmp(type_string, "mixed") == 0) { |
| 89 return BytecodeExpectationsPrinter::ConstantPoolType::kMixed; | 107 return BytecodeExpectationsPrinter::ConstantPoolType::kMixed; |
| 90 } | 108 } |
| 91 return BytecodeExpectationsPrinter::ConstantPoolType::kUnknown; | 109 return BytecodeExpectationsPrinter::ConstantPoolType::kUnknown; |
| 92 } | 110 } |
| 93 | 111 |
| 94 // static | 112 // static |
| 95 ProgramOptions ProgramOptions::FromCommandLine(int argc, char** argv) { | 113 ProgramOptions ProgramOptions::FromCommandLine(int argc, char** argv) { |
| 96 ProgramOptions options; | 114 ProgramOptions options; |
| 97 | 115 |
| 98 if (argc <= 1) return options; | |
| 99 | |
| 100 for (int i = 1; i < argc; ++i) { | 116 for (int i = 1; i < argc; ++i) { |
| 101 if (strcmp(argv[i], "--help") == 0) { | 117 if (strcmp(argv[i], "--help") == 0) { |
| 102 options.print_help_ = true; | 118 options.print_help_ = true; |
| 103 } else if (strcmp(argv[i], "--raw-js") == 0) { | 119 } else if (strcmp(argv[i], "--raw-js") == 0) { |
| 104 options.read_raw_js_snippet_ = true; | 120 options.read_raw_js_snippet_ = true; |
| 105 } else if (strncmp(argv[i], "--pool-type=", 12) == 0) { | 121 } else if (strncmp(argv[i], "--pool-type=", 12) == 0) { |
| 106 options.const_pool_type_ = ParseConstantPoolType(argv[i] + 12); | 122 options.const_pool_type_ = ParseConstantPoolType(argv[i] + 12); |
| 107 } else if (strcmp(argv[i], "--stdin") == 0) { | 123 } else if (strcmp(argv[i], "--stdin") == 0) { |
| 108 options.read_from_stdin_ = true; | 124 options.read_from_stdin_ = true; |
| 125 } else if (strcmp(argv[i], "--fix") == 0) { | |
| 126 options.fix_ = true; | |
| 127 } else if (strcmp(argv[i], "--no-banner") == 0) { | |
| 128 options.print_banner_ = false; | |
| 129 } else if (strcmp(argv[i], "--no-wrap") == 0) { | |
| 130 options.wrap_ = false; | |
| 131 } else if (strcmp(argv[i], "--no-execute") == 0) { | |
| 132 options.execute_ = false; | |
| 133 } else if (strncmp(argv[i], "--output=", 9) == 0) { | |
| 134 options.output_file_name_ = argv[i] + 9; | |
| 135 } else if (strncmp(argv[i], "--wrapper-name=", 15) == 0) { | |
| 136 options.top_function_name_ = argv[i] + 15; | |
| 109 } else if (strncmp(argv[i], "--", 2) != 0) { // It doesn't start with -- | 137 } else if (strncmp(argv[i], "--", 2) != 0) { // It doesn't start with -- |
| 110 if (!options.filename_.empty()) { | 138 if (!options.input_filename_.empty()) { |
| 111 std::cerr << "ERROR: More than one input file specified\n"; | 139 std::cerr << "ERROR: More than one input file specified\n"; |
| 112 options.parsing_failed_ = true; | 140 options.parsing_failed_ = true; |
| 113 break; | 141 break; |
| 114 } | 142 } |
| 115 options.filename_ = argv[i]; | 143 options.input_filename_ = argv[i]; |
| 116 } else { | 144 } else { |
| 117 std::cerr << "ERROR: Unknonwn option " << argv[i] << "\n"; | 145 std::cerr << "ERROR: Unknonwn option " << argv[i] << "\n"; |
| 118 options.parsing_failed_ = true; | 146 options.parsing_failed_ = true; |
| 119 break; | 147 break; |
| 120 } | 148 } |
| 121 } | 149 } |
| 122 | 150 |
| 123 return options; | 151 return options; |
| 124 } | 152 } |
| 125 | 153 |
| 154 bool ParseBoolean(const char* string) { | |
| 155 if (strcmp(string, "yes") == 0) { | |
| 156 return true; | |
| 157 } else if (strcmp(string, "no") == 0) { | |
| 158 return false; | |
| 159 } else { | |
| 160 UNREACHABLE(); | |
| 161 return false; | |
| 162 } | |
| 163 } | |
| 164 | |
| 165 void ParseOptionsHeader(ProgramOptions* options, | |
| 166 std::istream& stream) { // NOLINT | |
| 167 std::string line; | |
| 168 | |
| 169 // Skip to the beginning of the options header | |
| 170 while (std::getline(stream, line)) { | |
| 171 if (line == "---") break; | |
| 172 } | |
| 173 | |
| 174 while (std::getline(stream, line)) { | |
| 175 if (line.compare(0, 11, "pool type: ") == 0) { | |
| 176 options->const_pool_type_ = ParseConstantPoolType(line.c_str() + 11); | |
| 177 } else if (line.compare(0, 9, "execute: ") == 0) { | |
| 178 options->execute_ = ParseBoolean(line.c_str() + 9); | |
| 179 } else if (line.compare(0, 6, "wrap: ") == 0) { | |
| 180 options->wrap_ = ParseBoolean(line.c_str() + 6); | |
| 181 } else if (line.compare(0, 13, "wrapper name: ") == 0) { | |
| 182 options->top_function_name_ = line.c_str() + 14; | |
| 183 } else { | |
| 184 break; | |
| 185 } | |
| 186 } | |
| 187 } | |
| 188 | |
| 189 const char* BooleanString(bool value) { return value ? "yes" : "no"; } | |
|
rmcilroy
2016/02/16 16:43:48
nit - move up near ParseBoolean
Stefano Sanfilippo
2016/02/16 20:28:26
Done.
| |
| 190 | |
| 191 const char* ConstantPoolTypeString( | |
| 192 BytecodeExpectationsPrinter::ConstantPoolType type) { | |
| 193 switch (type) { | |
| 194 case BytecodeExpectationsPrinter::ConstantPoolType::kDouble: | |
| 195 return "double"; | |
| 196 case BytecodeExpectationsPrinter::ConstantPoolType::kInteger: | |
| 197 return "integer"; | |
| 198 case BytecodeExpectationsPrinter::ConstantPoolType::kMixed: | |
| 199 return "mixed"; | |
| 200 case BytecodeExpectationsPrinter::ConstantPoolType::kString: | |
| 201 return "string"; | |
| 202 default: | |
| 203 UNREACHABLE(); | |
| 204 return nullptr; | |
| 205 } | |
| 206 } | |
| 207 | |
| 208 void EmitOptionsHeader(std::ostream& stream, // NOLINT | |
| 209 const ProgramOptions& options) { | |
| 210 stream << "---" | |
| 211 "\npool type: " | |
| 212 << ConstantPoolTypeString(options.const_pool_type()) | |
| 213 << "\nexecute: " << BooleanString(options.execute()) | |
| 214 << "\nwrap: " << BooleanString(options.wrap()); | |
| 215 | |
| 216 if (!options.top_function_name().empty()) { | |
| 217 stream << "\nwrapper name: " << options.top_function_name(); | |
| 218 } | |
|
rmcilroy
2016/02/16 16:43:48
Could you emit a seperator between the options and
Stefano Sanfilippo
2016/02/16 20:28:26
I have updated the code to use the separator of th
| |
| 219 | |
| 220 stream << "\n\n"; | |
| 221 } | |
| 222 | |
| 126 bool ProgramOptions::Validate() const { | 223 bool ProgramOptions::Validate() const { |
| 127 if (parsing_failed_) return false; | 224 if (parsing_failed_) return false; |
| 128 if (print_help_) return true; | 225 if (print_help_) return true; |
| 129 | 226 |
| 130 if (const_pool_type_ == | 227 if (const_pool_type_ == |
| 131 BytecodeExpectationsPrinter::ConstantPoolType::kUnknown) { | 228 BytecodeExpectationsPrinter::ConstantPoolType::kUnknown) { |
| 132 std::cerr << "ERROR: Unknown constant pool type.\n"; | 229 std::cerr << "ERROR: Unknown constant pool type.\n"; |
| 133 return false; | 230 return false; |
| 134 } | 231 } |
| 135 | 232 |
| 136 if (!read_from_stdin_ && filename_.empty()) { | 233 if (!read_from_stdin_ && input_filename_.empty()) { |
| 137 std::cerr << "ERROR: No input file specified.\n"; | 234 std::cerr << "ERROR: No input file specified.\n"; |
| 138 return false; | 235 return false; |
| 139 } | 236 } |
| 140 | 237 |
| 141 if (read_from_stdin_ && !filename_.empty()) { | 238 if (read_from_stdin_ && !input_filename_.empty()) { |
| 142 std::cerr << "ERROR: Reading from stdin, but input files supplied.\n"; | 239 std::cerr << "ERROR: Reading from stdin, but input files supplied.\n"; |
| 143 return false; | 240 return false; |
| 144 } | 241 } |
| 145 | 242 |
| 243 if (!wrap_ && !top_function_name_.empty()) { | |
| 244 std::cerr << "ERROR: not wrapping, but wrapper name specified.\n"; | |
| 245 return false; | |
| 246 } | |
| 247 | |
|
rmcilroy
2016/02/16 16:43:48
You should also validate that --rebaseline and --r
Stefano Sanfilippo
2016/02/16 20:28:26
Done.
| |
| 146 return true; | 248 return true; |
| 147 } | 249 } |
| 148 | 250 |
| 149 V8InitializationScope::V8InitializationScope(const char* exec_path) | 251 V8InitializationScope::V8InitializationScope(const char* exec_path) |
| 150 : platform_(v8::platform::CreateDefaultPlatform()) { | 252 : platform_(v8::platform::CreateDefaultPlatform()) { |
| 151 i::FLAG_ignition = true; | 253 i::FLAG_ignition = true; |
| 152 i::FLAG_always_opt = false; | 254 i::FLAG_always_opt = false; |
| 153 i::FLAG_allow_natives_syntax = true; | 255 i::FLAG_allow_natives_syntax = true; |
| 154 | 256 |
| 155 v8::V8::InitializeICU(); | 257 v8::V8::InitializeICU(); |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 187 } | 289 } |
| 188 if (!found_begin_snippet) continue; | 290 if (!found_begin_snippet) continue; |
| 189 if (line == "\"") return true; | 291 if (line == "\"") return true; |
| 190 CHECK_GE(line.size(), 2u); // We should have the indent | 292 CHECK_GE(line.size(), 2u); // We should have the indent |
| 191 string_out->append(line.begin() + 2, line.end()); | 293 string_out->append(line.begin() + 2, line.end()); |
| 192 *string_out += '\n'; | 294 *string_out += '\n'; |
| 193 } | 295 } |
| 194 return false; | 296 return false; |
| 195 } | 297 } |
| 196 | 298 |
| 299 std::string UnescapeString(const std::string& escaped_string) { | |
| 300 std::string unescaped_string; | |
| 301 bool previous_was_backslash = false; | |
| 302 for (char c : escaped_string) { | |
| 303 if (previous_was_backslash) { | |
| 304 // If it was not an escape sequence, emit the backslash | |
|
rmcilroy
2016/02/16 16:43:48
/s/the backslash/the previous backslash./
Stefano Sanfilippo
2016/02/16 20:28:26
Done.
| |
| 305 if (c != '\\' && c != '"') unescaped_string += '\\'; | |
| 306 unescaped_string += c; | |
| 307 previous_was_backslash = false; | |
| 308 } else { | |
| 309 if (c == '\\') { | |
| 310 previous_was_backslash = true; | |
| 311 // Defer emission to the point where we can check if it was an escape. | |
| 312 } else { | |
| 313 unescaped_string += c; | |
| 314 } | |
| 315 } | |
| 316 } | |
| 317 return unescaped_string; | |
| 318 } | |
| 319 | |
| 197 void ExtractSnippetsFromStream(std::vector<std::string>* snippet_list, | 320 void ExtractSnippetsFromStream(std::vector<std::string>* snippet_list, |
| 321 ProgramOptions* options, | |
| 198 std::istream& body_stream, // NOLINT | 322 std::istream& body_stream, // NOLINT |
| 199 bool read_raw_js_snippet) { | 323 bool read_raw_js_snippet) { |
| 200 if (read_raw_js_snippet) { | 324 if (read_raw_js_snippet) { |
| 201 snippet_list->push_back(ReadRawJSSnippet(body_stream)); | 325 snippet_list->push_back(ReadRawJSSnippet(body_stream)); |
| 202 } else { | 326 } else { |
| 327 ParseOptionsHeader(options, body_stream); | |
|
rmcilroy
2016/02/16 16:43:48
This should only happen for --rebaseline I think (
Stefano Sanfilippo
2016/02/16 20:28:26
Please see below.
| |
| 203 std::string snippet; | 328 std::string snippet; |
| 204 while (ReadNextSnippet(body_stream, &snippet)) { | 329 while (ReadNextSnippet(body_stream, &snippet)) { |
| 205 snippet_list->push_back(snippet); | 330 snippet_list->push_back(UnescapeString(snippet)); |
| 206 } | 331 } |
| 207 } | 332 } |
| 208 } | 333 } |
| 209 | 334 |
| 210 bool ExtractSnippets(std::vector<std::string>* snippet_list, | 335 bool ExtractSnippets(std::vector<std::string>* snippet_list, |
| 211 const ProgramOptions& options) { | 336 ProgramOptions* options) { |
|
rmcilroy
2016/02/16 16:43:48
This should still be const, right? Any reason to m
Stefano Sanfilippo
2016/02/16 20:28:26
The reason is that ParseOptionsHeader called insid
rmcilroy
2016/02/17 10:16:59
I think the solution is to split out the opening o
rmcilroy
2016/02/17 10:16:59
I think the solution is to split out the opening o
Stefano Sanfilippo
2016/02/17 14:32:29
I've rewritten the piece using a better approach w
| |
| 212 if (options.read_from_stdin()) { | 337 if (options->read_from_stdin()) { |
| 213 ExtractSnippetsFromStream(snippet_list, std::cin, | 338 ExtractSnippetsFromStream(snippet_list, options, std::cin, |
| 214 options.read_raw_js_snippet()); | 339 options->read_raw_js_snippet()); |
| 215 } else { | 340 } else { |
| 216 std::ifstream body_file(options.filename().c_str()); | 341 std::ifstream body_file(options->input_filename().c_str()); |
| 217 if (!body_file.is_open()) { | 342 if (!body_file.is_open()) { |
| 218 std::cerr << "ERROR: Could not open '" << options.filename() << "'.\n"; | 343 std::cerr << "ERROR: Could not open '" << options->input_filename() |
| 344 << "'.\n"; | |
| 219 return false; | 345 return false; |
| 220 } | 346 } |
| 221 ExtractSnippetsFromStream(snippet_list, body_file, | 347 ExtractSnippetsFromStream(snippet_list, options, body_file, |
| 222 options.read_raw_js_snippet()); | 348 options->read_raw_js_snippet()); |
| 223 } | 349 } |
| 224 return true; | 350 return true; |
| 225 } | 351 } |
| 226 | 352 |
| 227 void GenerateExpectationsFile( | 353 void GenerateExpectationsFile(std::ostream& stream, // NOLINT |
| 228 std::ostream& stream, // NOLINT | 354 const std::vector<std::string>& snippet_list, |
| 229 const std::vector<std::string>& snippet_list, | 355 const ProgramOptions& options, |
| 230 BytecodeExpectationsPrinter::ConstantPoolType const_pool_type, | 356 const char* exec_path) { |
| 231 const char* exec_path) { | |
| 232 V8InitializationScope platform(exec_path); | 357 V8InitializationScope platform(exec_path); |
| 233 { | 358 { |
| 234 v8::Isolate::Scope isolate_scope(platform.isolate()); | 359 v8::Isolate::Scope isolate_scope(platform.isolate()); |
| 235 v8::HandleScope handle_scope(platform.isolate()); | 360 v8::HandleScope handle_scope(platform.isolate()); |
| 236 v8::Local<v8::Context> context = v8::Context::New(platform.isolate()); | 361 v8::Local<v8::Context> context = v8::Context::New(platform.isolate()); |
| 237 v8::Context::Scope context_scope(context); | 362 v8::Context::Scope context_scope(context); |
| 238 | 363 |
| 239 stream << "#\n# Autogenerated by generate-bytecode-expectations\n#\n\n"; | 364 if (options.print_banner()) { |
| 365 stream << "#\n# Autogenerated by generate-bytecode-expectations\n#\n\n"; | |
| 366 } | |
| 240 | 367 |
| 241 BytecodeExpectationsPrinter printer(platform.isolate(), const_pool_type); | 368 EmitOptionsHeader(stream, options); |
| 369 | |
| 370 BytecodeExpectationsPrinter printer(platform.isolate(), | |
| 371 options.const_pool_type()); | |
| 372 printer.set_wrap(options.wrap()); | |
| 373 printer.set_execute(options.execute()); | |
| 374 if (!options.top_function_name().empty()) { | |
| 375 printer.set_top_function_name(options.top_function_name()); | |
| 376 } | |
| 377 | |
| 242 for (const std::string& snippet : snippet_list) { | 378 for (const std::string& snippet : snippet_list) { |
| 243 printer.PrintExpectation(stream, snippet); | 379 printer.PrintExpectation(stream, snippet); |
| 244 } | 380 } |
| 245 } | 381 } |
| 246 } | 382 } |
| 247 | 383 |
| 248 void PrintUsage(const char* exec_path) { | 384 void PrintUsage(const char* exec_path) { |
| 249 std::cerr | 385 std::cerr |
| 250 << "\nUsage: " << exec_path | 386 << "\nUsage: " << exec_path |
| 251 << " [OPTIONS]... [INPUT FILE]\n\n" | 387 << " [OPTIONS]... [INPUT FILE]\n\n" |
| 252 "Options:\n" | 388 "Options:\n" |
| 253 " --help Print this help message.\n" | 389 " --help Print this help message.\n" |
| 254 " --raw-js Read raw JavaScript, instead of the output format.\n" | 390 " --raw-js Read raw JavaScript, instead of the output format.\n" |
| 255 " --stdin Read from standard input instead of file.\n" | 391 " --stdin Read from standard input instead of file.\n" |
| 392 " --fix Overwrite input file.\n" | |
|
rmcilroy
2016/02/16 16:43:48
Call this "--rebaseline Rebaseline input snippet
Stefano Sanfilippo
2016/02/16 20:28:26
Done.
| |
| 393 " --no-banner Do not add the \"generated by\" banner.\n" | |
|
rmcilroy
2016/02/16 16:43:48
Why is this one required? All golden files should
Stefano Sanfilippo
2016/02/16 20:28:26
ATM the banner is emitted by the utility before ca
rmcilroy
2016/02/17 10:17:00
I think the banner should be printed by this tool
Stefano Sanfilippo
2016/02/17 14:32:29
Done. I ended up changing the API from accepting a
| |
| 394 " --no-wrap Do not wrap the snippet in a function.\n" | |
| 395 " --no-execute Do not execute after compilation.\n" | |
| 396 " --output=file.name Specify the output file. " | |
| 397 "If not specified, output goes to stdout.\n" | |
| 398 " --wrapper-name=foo Specify the name of the wrapper function.\n" | |
| 256 " --pool-type=(int|double|string|mixed)\n" | 399 " --pool-type=(int|double|string|mixed)\n" |
| 257 " specify the type of the entries in the constant pool " | 400 " Specify the type of the entries in the constant pool " |
| 258 "(default: mixed).\n" | 401 "(default: mixed).\n" |
| 259 "\n" | 402 "\n" |
| 260 "Each raw JavaScript file is interpreted as a single snippet.\n\n" | 403 "Each raw JavaScript file is interpreted as a single snippet.\n\n" |
| 261 "This tool is intended as a help in writing tests.\n" | 404 "This tool is intended as a help in writing tests.\n" |
| 262 "Please, DO NOT blindly copy and paste the output " | 405 "Please, DO NOT blindly copy and paste the output " |
| 263 "into the test suite.\n"; | 406 "into the test suite.\n"; |
| 264 } | 407 } |
| 265 | 408 |
| 266 } // namespace | 409 } // namespace |
| 267 | 410 |
| 268 int main(int argc, char** argv) { | 411 int main(int argc, char** argv) { |
| 269 ProgramOptions options = ProgramOptions::FromCommandLine(argc, argv); | 412 ProgramOptions options = ProgramOptions::FromCommandLine(argc, argv); |
| 270 | 413 |
| 271 if (!options.Validate() || options.print_help()) { | 414 if (!options.Validate() || options.print_help()) { |
| 272 PrintUsage(argv[0]); | 415 PrintUsage(argv[0]); |
| 273 return options.print_help() ? 0 : 1; | 416 return options.print_help() ? 0 : 1; |
| 274 } | 417 } |
| 275 | 418 |
| 276 std::vector<std::string> snippet_list; | 419 std::vector<std::string> snippet_list; |
| 277 if (!ExtractSnippets(&snippet_list, options)) { | 420 if (!ExtractSnippets(&snippet_list, &options)) { |
| 278 return 2; | 421 return 2; |
| 279 } | 422 } |
| 280 | 423 |
| 281 GenerateExpectationsFile(std::cout, snippet_list, options.const_pool_type(), | 424 CHECK(options.Validate()); |
| 282 argv[0]); | 425 |
| 426 if (!options.output_filename().empty() || options.fix()) { | |
| 427 std::ofstream output_file(options.fix() | |
| 428 ? options.input_filename().c_str() | |
| 429 : options.output_filename().c_str()); | |
| 430 if (!output_file.is_open()) { | |
| 431 std::cerr << "ERROR: Could not open '" << options.output_filename() | |
| 432 << "' for writing.\n"; | |
| 433 return 3; | |
| 434 } | |
| 435 GenerateExpectationsFile(output_file, snippet_list, options, argv[0]); | |
| 436 } else { | |
| 437 GenerateExpectationsFile(std::cout, snippet_list, options, argv[0]); | |
| 438 } | |
| 283 } | 439 } |
| OLD | NEW |