1 // Copyright 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 // A simple command-line compiler for JTL (JSON Traversal Language).
7 // Translates rules from a text-based, human-readable format to an easy-to-parse
8 // byte-code format, which then can be interpreted by JtlInterpreter.
11 // jtl_compiler --input=blah.txt --hash-seed="foobar" --output=blah.dat
16 #include "base/command_line.h"
17 #include "base/file_util.h"
18 #include "base/files/file_path.h"
19 #include "chrome/tools/profile_reset/jtl_compiler.h"
23 // Command-line argument name: path to the input text-based JTL source code.
24 const char kInputPath
[] = "input";
26 // Command-line argument name: path to the output byte-code.
27 const char kOutputPath
[] = "output";
29 // Command-line argument name: the hash seed to use.
30 const char kHashSeed
[] = "hash-seed";
33 const char kMismatchedDoubleQuotes
[] = "Mismatched double-quotes before EOL.";
34 const char kParsingError
[] = "Parsing error. Input is ill-formed.";
35 const char kArgumentCountError
[] = "Wrong number of arguments for operation.";
36 const char kArgumentTypeError
[] = "Wrong argument type(s) for operation.";
37 const char kArgumentValueError
[] = "Wrong argument value(s) for operation.";
38 const char kUnknownOperationError
[] = "No operation by this name.";
39 const char kUnknownError
[] = "Unknown error.";
41 const char* ResolveErrorCode(JtlCompiler::CompileError::ErrorCode code
) {
43 case JtlCompiler::CompileError::MISMATCHED_DOUBLE_QUOTES
:
44 return kMismatchedDoubleQuotes
;
45 case JtlCompiler::CompileError::PARSING_ERROR
:
47 case JtlCompiler::CompileError::INVALID_ARGUMENT_COUNT
:
48 return kArgumentCountError
;
49 case JtlCompiler::CompileError::INVALID_ARGUMENT_TYPE
:
50 return kArgumentTypeError
;
51 case JtlCompiler::CompileError::INVALID_ARGUMENT_VALUE
:
52 return kArgumentValueError
;
53 case JtlCompiler::CompileError::INVALID_OPERATION_NAME
:
54 return kUnknownOperationError
;
62 int main(int argc
, char* argv
[]) {
63 CommandLine::Init(argc
, argv
);
64 CommandLine
* cmd_line
= CommandLine::ForCurrentProcess();
65 if (!cmd_line
->HasSwitch(kInputPath
) || !cmd_line
->HasSwitch(kHashSeed
) ||
66 !cmd_line
->HasSwitch(kOutputPath
)) {
67 std::cerr
<< "Usage: " << argv
[0] << " <required switches>" << std::endl
;
68 std::cerr
<< "\nRequired switches are:" << std::endl
;
69 std::cerr
<< " --" << kInputPath
<< "=<file>"
70 << "\t\tPath to the input text-based JTL source code."
72 std::cerr
<< " --" << kOutputPath
<< "=<file>"
73 << "\t\tPath to the output byte-code." << std::endl
;
74 std::cerr
<< " --" << kHashSeed
<< "=<value>"
75 << "\t\tThe hash seed to use." << std::endl
;
79 base::FilePath source_code_path
=
80 MakeAbsoluteFilePath(cmd_line
->GetSwitchValuePath(kInputPath
));
81 std::string source_code
;
82 if (!base::ReadFileToString(source_code_path
, &source_code
)) {
83 std::cerr
<< "ERROR: Cannot read input file." << std::endl
;
88 JtlCompiler::CompileError error
;
89 std::string hash_seed
= cmd_line
->GetSwitchValueASCII(kHashSeed
);
90 if (!JtlCompiler::Compile(source_code
, hash_seed
, &bytecode
, &error
)) {
91 std::cerr
<< "COMPILE ERROR: " << ResolveErrorCode(error
.error_code
)
93 std::cerr
<< " Line number: " << (error
.line_number
+ 1) << std::endl
;
94 std::cerr
<< " Context: " << (error
.context
.size() > 63
95 ? error
.context
.substr(0, 60) + "..."
96 : error
.context
) << std::endl
;
100 base::FilePath bytecode_path
=
101 MakeAbsoluteFilePath(cmd_line
->GetSwitchValuePath(kOutputPath
));
103 file_util::WriteFile(cmd_line
->GetSwitchValuePath(kOutputPath
),
105 static_cast<int>(bytecode
.size()));
106 if (bytes_written
!= static_cast<int>(bytecode
.size())) {
107 std::cerr
<< "ERROR: Cannot write output file." << std::endl
;