xref: /aosp_15_r20/external/emboss/compiler/back_end/cpp/emboss_codegen_cpp.py (revision 99e0aae7469b87d12f0ad23e61142c2d74c1ef70)
1# Copyright 2019 Google LLC
2#
3# Licensed under the Apache License, Version 2.0 (the "License");
4# you may not use this file except in compliance with the License.
5# You may obtain a copy of the License at
6#
7#     https://www.apache.org/licenses/LICENSE-2.0
8#
9# Unless required by applicable law or agreed to in writing, software
10# distributed under the License is distributed on an "AS IS" BASIS,
11# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12# See the License for the specific language governing permissions and
13# limitations under the License.
14
15"""Emboss C++ code generator.
16
17This is a driver program that reads IR, feeds it to header_generator, and prints
18the result.
19"""
20
21from __future__ import print_function
22
23import argparse
24import os
25import sys
26
27from compiler.back_end.cpp import header_generator
28from compiler.util import error
29from compiler.util import ir_data
30from compiler.util import ir_data_utils
31
32
33def _parse_command_line(argv):
34  """Parses the given command-line arguments."""
35  parser = argparse.ArgumentParser(description="Emboss compiler C++ back end.",
36                                   prog=argv[0])
37  parser.add_argument("--input-file",
38                      type=str,
39                      help=".emb.ir file to compile.")
40  parser.add_argument("--output-file",
41                      type=str,
42                      help="Write header to file.  If not specified, write " +
43                           "header to stdout.")
44  parser.add_argument("--color-output",
45                      default="if_tty",
46                      choices=["always", "never", "if_tty", "auto"],
47                      help="Print error messages using color.  'auto' is a "
48                           "synonym for 'if_tty'.")
49  parser.add_argument("--cc-enum-traits",
50                      action=argparse.BooleanOptionalAction,
51                      default=True,
52                      help="""Controls generation of EnumTraits by the C++
53                              backend""")
54  return parser.parse_args(argv[1:])
55
56
57def _show_errors(errors, ir, color_output):
58  """Prints errors with source code snippets."""
59  source_codes = {}
60  for module in ir.module:
61    source_codes[module.source_file_name] = module.source_text
62  use_color = (color_output == "always" or
63               (color_output in ("auto", "if_tty") and
64                os.isatty(sys.stderr.fileno())))
65  print(error.format_errors(errors, source_codes, use_color), file=sys.stderr)
66
67def generate_headers_and_log_errors(ir, color_output, config: header_generator.Config):
68  """Generates a C++ header and logs any errors.
69
70  Arguments:
71    ir: EmbossIr of the module.
72    color_output: "always", "never", "if_tty", "auto"
73    config: Header generation configuration.
74
75  Returns:
76    A tuple of (header, errors)
77  """
78  header, errors = header_generator.generate_header(ir, config)
79  if errors:
80    _show_errors(errors, ir, color_output)
81  return (header, errors)
82
83def main(flags):
84  if flags.input_file:
85    with open(flags.input_file) as f:
86      ir = ir_data_utils.IrDataSerializer.from_json(ir_data.EmbossIr, f.read())
87  else:
88    ir = ir_data_utils.IrDataSerializer.from_json(ir_data.EmbossIr, sys.stdin.read())
89  config = header_generator.Config(include_enum_traits=flags.cc_enum_traits)
90  header, errors = generate_headers_and_log_errors(ir, flags.color_output, config)
91  if errors:
92    return 1
93  if flags.output_file:
94    with open(flags.output_file, "w") as f:
95      f.write(header)
96  else:
97    print(header)
98  return 0
99
100
101if __name__ == '__main__':
102  sys.exit(main(_parse_command_line(sys.argv)))
103