1 # The MIT License (MIT)
3 # Copyright (c) 2014-2020 Philippe Proulx <pproulx@efficios.com>
5 # Permission is hereby granted, free of charge, to any person obtaining
6 # a copy of this software and associated documentation files (the
7 # "Software"), to deal in the Software without restriction, including
8 # without limitation the rights to use, copy, modify, merge, publish,
9 # distribute, sublicense, and/or sell copies of the Software, and to
10 # permit persons to whom the Software is furnished to do so, subject to
11 # the following conditions:
13 # The above copyright notice and this permission notice shall be
14 # included in all copies or substantial portions of the Software.
16 # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17 # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18 # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
19 # IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
20 # CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
21 # TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
22 # SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
29 import barectf
.config_parse_common
as barectf_config_parse_common
34 # Colors and prints the error message `msg` and exits with status code
36 def _print_error(msg
):
37 termcolor
.cprint('Error: ', 'red', end
='', file=sys
.stderr
)
38 termcolor
.cprint(msg
, 'red', attrs
=['bold'], file=sys
.stderr
)
42 # Pretty-prints the barectf configuration error `exc` and exits with
44 def _print_config_error(exc
):
45 # reverse: most precise message comes last
46 for ctx
in reversed(exc
.context
):
49 if ctx
.message
is not None:
50 msg
= f
' {ctx.message}'
53 termcolor
.cprint(f
'{ctx.name}', color
, attrs
=['bold'], file=sys
.stderr
, end
='')
54 termcolor
.cprint(':', color
, file=sys
.stderr
, end
='')
55 termcolor
.cprint(msg
, color
, file=sys
.stderr
)
60 # Pretty-prints the unknown exception `exc`.
61 def _print_unknown_exc(exc
):
65 _print_error(f
'Unknown exception: {exc}')
69 ap
= argparse
.ArgumentParser()
71 ap
.add_argument('-c', '--code-dir', metavar
='DIR', action
='store', default
=os
.getcwd(),
72 help='output directory of C source file')
73 ap
.add_argument('--dump-config', action
='store_true',
74 help='also dump the effective YAML configuration file used for generation')
75 ap
.add_argument('-H', '--headers-dir', metavar
='DIR', action
='store', default
=os
.getcwd(),
76 help='output directory of C header files')
77 ap
.add_argument('-I', '--include-dir', metavar
='DIR', action
='append', default
=[],
78 help='add directory DIR to the list of directories to be searched for include files')
79 ap
.add_argument('--ignore-include-not-found', action
='store_true',
80 help='continue to process the configuration file when included files are not found')
81 ap
.add_argument('-m', '--metadata-dir', metavar
='DIR', action
='store', default
=os
.getcwd(),
82 help='output directory of CTF metadata')
83 ap
.add_argument('-p', '--prefix', metavar
='PREFIX', action
='store',
84 help='override configuration\'s prefixes')
85 ap
.add_argument('-V', '--version', action
='version',
86 version
='%(prog)s {}'.format(barectf
.__version
__))
87 ap
.add_argument('config', metavar
='CONFIG', action
='store',
88 help='barectf YAML configuration file')
91 args
= ap
.parse_args()
93 # validate output directories
94 for dir in [args
.code_dir
, args
.headers_dir
, args
.metadata_dir
] + args
.include_dir
:
95 if not os
.path
.isdir(dir):
96 _print_error(f
'`{dir}` is not an existing directory')
98 # validate that configuration file exists
99 if not os
.path
.isfile(args
.config
):
100 _print_error(f
'`{args.config}` is not an existing, regular file')
102 # Load configuration file to get its major version in order to
103 # append the correct implicit inclusion directory.
105 with
open(args
.config
) as f
:
106 config_major_version
= barectf
.configuration_file_major_version(f
)
107 except barectf
._ConfigurationParseError
as exc
:
108 _print_config_error(exc
)
109 except Exception as exc
:
110 _print_unknown_exc(exc
)
112 # append current working directory and implicit inclusion directory
113 args
.include_dir
+= [
115 pkg_resources
.resource_filename(__name__
, f
'include/{config_major_version}')
125 # create configuration
127 with
open(args
.config
) as f
:
129 # print effective configuration file
130 print(barectf
.effective_configuration_file(f
, args
.include_dir
,
131 args
.ignore_include_not_found
))
133 # barectf.configuration_from_file() reads the file again
137 config
= barectf
.configuration_from_file(f
, args
.include_dir
,
138 args
.ignore_include_not_found
)
139 except barectf
._ConfigurationParseError
as exc
:
140 _print_config_error(exc
)
141 except Exception as exc
:
142 _print_unknown_exc(exc
)
147 # For historical reasons, the `--prefix` option applies the
148 # barectf 2 configuration prefix rules. Therefore, get the
149 # equivalent barectf 3 prefixes first.
150 v3_prefixes
= barectf_config_parse_common
._v
3_prefixes
_from
_v
2_prefix
(args
.prefix
)
151 cg_opts
= config
.options
.code_generation_options
152 cg_opts
= barectf
.ConfigurationCodeGenerationOptions(v3_prefixes
.identifier
,
153 v3_prefixes
.file_name
,
154 cg_opts
.default_stream_type
,
155 cg_opts
.header_options
,
156 cg_opts
.clock_type_c_types
)
157 config
= barectf
.Configuration(config
.trace
, barectf
.ConfigurationOptions(cg_opts
))
159 # create a barectf code generator
160 code_gen
= barectf
.CodeGenerator(config
)
162 def write_file(dir, file):
163 with
open(os
.path
.join(dir, file.name
), 'w') as f
:
164 f
.write(file.contents
)
166 def write_files(dir, files
):
168 write_file(dir, file)
171 # generate and write metadata stream file
172 write_file(args
.metadata_dir
, code_gen
.generate_metadata_stream())
174 # generate and write C header files
175 write_files(args
.headers_dir
, code_gen
.generate_c_headers())
177 # generate and write C source files
178 write_files(args
.code_dir
, code_gen
.generate_c_sources())
179 except Exception as exc
:
180 # We know `config` is valid, therefore the code generator cannot
181 # fail for a reason known to barectf.
182 _print_unknown_exc(exc
)