1*99e0aae7SDavid Rees#!/usr/bin/env python3 2*99e0aae7SDavid Rees 3*99e0aae7SDavid Rees# Copyright 2019 Google LLC 4*99e0aae7SDavid Rees# 5*99e0aae7SDavid Rees# Licensed under the Apache License, Version 2.0 (the "License"); 6*99e0aae7SDavid Rees# you may not use this file except in compliance with the License. 7*99e0aae7SDavid Rees# You may obtain a copy of the License at 8*99e0aae7SDavid Rees# 9*99e0aae7SDavid Rees# https://www.apache.org/licenses/LICENSE-2.0 10*99e0aae7SDavid Rees# 11*99e0aae7SDavid Rees# Unless required by applicable law or agreed to in writing, software 12*99e0aae7SDavid Rees# distributed under the License is distributed on an "AS IS" BASIS, 13*99e0aae7SDavid Rees# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14*99e0aae7SDavid Rees# See the License for the specific language governing permissions and 15*99e0aae7SDavid Rees# limitations under the License. 16*99e0aae7SDavid Rees 17*99e0aae7SDavid Rees"""Main driver program for the Emboss compiler.""" 18*99e0aae7SDavid Rees 19*99e0aae7SDavid Reesimport argparse 20*99e0aae7SDavid Reesimport os 21*99e0aae7SDavid Reesimport sys 22*99e0aae7SDavid Rees 23*99e0aae7SDavid Rees 24*99e0aae7SDavid Reesdef _parse_args(argv): 25*99e0aae7SDavid Rees parser = argparse.ArgumentParser(description="Emboss compiler") 26*99e0aae7SDavid Rees parser.add_argument("--color-output", 27*99e0aae7SDavid Rees default="if_tty", 28*99e0aae7SDavid Rees choices=["always", "never", "if_tty", "auto"], 29*99e0aae7SDavid Rees help="Print error messages using color. 'auto' is a " 30*99e0aae7SDavid Rees "synonym for 'if_tty'.") 31*99e0aae7SDavid Rees parser.add_argument("--import-dir", "-I", 32*99e0aae7SDavid Rees dest="import_dirs", 33*99e0aae7SDavid Rees action="append", 34*99e0aae7SDavid Rees default=["."], 35*99e0aae7SDavid Rees help="A directory to use when searching for imported " 36*99e0aae7SDavid Rees "embs. If no import-dirs are specified, the " 37*99e0aae7SDavid Rees "current directory will be used.") 38*99e0aae7SDavid Rees parser.add_argument("--generate", 39*99e0aae7SDavid Rees nargs=1, 40*99e0aae7SDavid Rees choices=["cc"], 41*99e0aae7SDavid Rees default="cc", 42*99e0aae7SDavid Rees help="Which back end to use. Currently only C++ is " 43*99e0aae7SDavid Rees "supported.") 44*99e0aae7SDavid Rees parser.add_argument("--output-path", 45*99e0aae7SDavid Rees nargs=1, 46*99e0aae7SDavid Rees default=".", 47*99e0aae7SDavid Rees help="""Prefix path to use for the generated output file. 48*99e0aae7SDavid Rees Defaults to '.'""") 49*99e0aae7SDavid Rees parser.add_argument("--output-file", 50*99e0aae7SDavid Rees nargs=1, 51*99e0aae7SDavid Rees help="""File name to be used for the generated output 52*99e0aae7SDavid Rees file. Defaults to input_file suffixed by '.h'""") 53*99e0aae7SDavid Rees parser.add_argument("--cc-enum-traits", 54*99e0aae7SDavid Rees action=argparse.BooleanOptionalAction, 55*99e0aae7SDavid Rees default=True, 56*99e0aae7SDavid Rees help="""Controls generation of EnumTraits by the C++ 57*99e0aae7SDavid Rees backend""") 58*99e0aae7SDavid Rees parser.add_argument("input_file", 59*99e0aae7SDavid Rees type=str, 60*99e0aae7SDavid Rees nargs=1, 61*99e0aae7SDavid Rees help=".emb file to compile.") 62*99e0aae7SDavid Rees return parser.parse_args(argv[1:]) 63*99e0aae7SDavid Rees 64*99e0aae7SDavid Rees 65*99e0aae7SDavid Reesdef main(argv): 66*99e0aae7SDavid Rees flags = _parse_args(argv) 67*99e0aae7SDavid Rees base_path = os.path.dirname(__file__) or "." 68*99e0aae7SDavid Rees sys.path.append(base_path) 69*99e0aae7SDavid Rees 70*99e0aae7SDavid Rees from compiler.back_end.cpp import ( # pylint:disable=import-outside-toplevel 71*99e0aae7SDavid Rees emboss_codegen_cpp, header_generator 72*99e0aae7SDavid Rees ) 73*99e0aae7SDavid Rees from compiler.front_end import ( # pylint:disable=import-outside-toplevel 74*99e0aae7SDavid Rees emboss_front_end 75*99e0aae7SDavid Rees ) 76*99e0aae7SDavid Rees 77*99e0aae7SDavid Rees ir, _, errors = emboss_front_end.parse_and_log_errors( 78*99e0aae7SDavid Rees flags.input_file[0], flags.import_dirs, flags.color_output) 79*99e0aae7SDavid Rees 80*99e0aae7SDavid Rees if errors: 81*99e0aae7SDavid Rees return 1 82*99e0aae7SDavid Rees 83*99e0aae7SDavid Rees config = header_generator.Config(include_enum_traits=flags.cc_enum_traits) 84*99e0aae7SDavid Rees header, errors = emboss_codegen_cpp.generate_headers_and_log_errors( 85*99e0aae7SDavid Rees ir, flags.color_output, config) 86*99e0aae7SDavid Rees 87*99e0aae7SDavid Rees if errors: 88*99e0aae7SDavid Rees return 1 89*99e0aae7SDavid Rees 90*99e0aae7SDavid Rees if flags.output_file: 91*99e0aae7SDavid Rees output_file = flags.output_file[0] 92*99e0aae7SDavid Rees else: 93*99e0aae7SDavid Rees output_file = flags.input_file[0] + ".h" 94*99e0aae7SDavid Rees 95*99e0aae7SDavid Rees output_filepath = os.path.join(flags.output_path[0], output_file) 96*99e0aae7SDavid Rees os.makedirs(os.path.dirname(output_filepath), exist_ok=True) 97*99e0aae7SDavid Rees 98*99e0aae7SDavid Rees with open(output_filepath, "w") as output: 99*99e0aae7SDavid Rees output.write(header) 100*99e0aae7SDavid Rees return 0 101*99e0aae7SDavid Rees 102*99e0aae7SDavid Rees 103*99e0aae7SDavid Reesif __name__ == "__main__": 104*99e0aae7SDavid Rees sys.exit(main(sys.argv)) 105