blob: c21c8de2e142c75db07757abd923dfeb7f056aeb [file] [edit]
#!/usr/bin/env python3
# Copyright 2019 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""Main driver program for the Emboss compiler."""
import argparse
import os
import sys
def _parse_args(argv):
parser = argparse.ArgumentParser(description="Emboss compiler")
parser.add_argument(
"--color-output",
default="if_tty",
choices=["always", "never", "if_tty", "auto"],
help="Print error messages using color. 'auto' is a synonym for 'if_tty'.",
)
parser.add_argument(
"--import-dir",
"-I",
dest="import_dirs",
action="append",
default=["."],
help="""A directory to use when searching for imported embs. If no
import-dirs are specified, the current directory will be used.""",
)
parser.add_argument(
"--generate",
nargs=1,
choices=["cc", "lua"],
default=["cc"],
help="Which back end to use: 'cc' (C++) or 'lua' (Wireshark Lua).",
)
parser.add_argument(
"--output-path",
nargs=1,
default=".",
help="Prefix path to use for the generated output file. Defaults to '.'",
)
parser.add_argument(
"--output-file",
nargs=1,
help="""File name to be used for the generated output file. Defaults to
input_file suffixed by '.h' (cc) or '.lua' (lua)""",
)
parser.add_argument(
"--cc-enum-traits",
action=argparse.BooleanOptionalAction,
default=True,
help="Controls generation of EnumTraits by the C++ backend",
)
parser.add_argument("input_file", type=str, nargs=1, help=".emb file to compile.")
return parser.parse_args(argv[1:])
def main(argv):
flags = _parse_args(argv)
base_path = os.path.dirname(__file__) or "."
sys.path.append(base_path)
from compiler.front_end import ( # pylint:disable=import-outside-toplevel
emboss_front_end
)
ir, _, errors = emboss_front_end.parse_and_log_errors(
flags.input_file[0], flags.import_dirs, flags.color_output
)
if errors:
return 1
backend = flags.generate[0] if isinstance(flags.generate, list) else flags.generate
if backend == "cc":
from compiler.back_end.cpp import ( # pylint:disable=import-outside-toplevel
emboss_codegen_cpp, header_generator
)
config = header_generator.Config(include_enum_traits=flags.cc_enum_traits)
output_text, gen_errors = emboss_codegen_cpp.generate_headers_and_log_errors(
ir, flags.color_output, config
)
if not gen_errors:
output_text = emboss_codegen_cpp.format_header(output_text)
default_ext = ".h"
elif backend == "lua":
from compiler.back_end.lua import emboss_codegen_lua # pylint:disable=import-outside-toplevel
output_text, gen_errors = emboss_codegen_lua.generate_dissector_and_log_errors(
ir, flags.color_output
)
default_ext = ".lua"
else:
print("Unknown backend: {}".format(backend), file=sys.stderr)
return 1
if gen_errors:
return 1
if flags.output_file:
output_file = flags.output_file[0]
else:
output_file = flags.input_file[0] + default_ext
output_filepath = os.path.join(flags.output_path[0], output_file)
output_dir = os.path.dirname(output_filepath)
if output_dir:
os.makedirs(output_dir, exist_ok=True)
with open(output_filepath, "w") as output:
output.write(output_text)
return 0
if __name__ == "__main__":
sys.exit(main(sys.argv))