cli: error msg: specify "regular file"
[deliverable/barectf.git] / barectf / cli.py
1 # The MIT License (MIT)
2 #
3 # Copyright (c) 2014-2016 Philippe Proulx <pproulx@efficios.com>
4 #
5 # Permission is hereby granted, free of charge, to any person obtaining a copy
6 # of this software and associated documentation files (the "Software"), to deal
7 # in the Software without restriction, including without limitation the rights
8 # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 # copies of the Software, and to permit persons to whom the Software is
10 # furnished to do so, subject to the following conditions:
11 #
12 # The above copyright notice and this permission notice shall be included in
13 # all copies or substantial portions of the Software.
14 #
15 # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21 # THE SOFTWARE.
22
23 from pkg_resources import resource_filename
24 from termcolor import cprint, colored
25 import barectf.tsdl182gen
26 import barectf.config
27 import barectf.gen
28 import argparse
29 import os.path
30 import barectf
31 import sys
32 import os
33 import re
34
35
36 def _perror(msg):
37 cprint('Error: ', 'red', end='', file=sys.stderr)
38 cprint(msg, 'red', attrs=['bold'], file=sys.stderr)
39 sys.exit(1)
40
41
42 def _pconfig_error(e):
43 lines = []
44
45 while True:
46 if e is None:
47 break
48
49 lines.append(str(e))
50
51 if not hasattr(e, 'prev'):
52 break
53
54 e = e.prev
55
56 if len(lines) == 1:
57 _perror(lines[0])
58
59 cprint('Error:', 'red', file=sys.stderr)
60
61 for i, line in enumerate(lines):
62 suf = ':' if i < len(lines) - 1 else ''
63 cprint(' ' + line + suf, 'red', attrs=['bold'], file=sys.stderr)
64
65 sys.exit(1)
66
67
68 def _psuccess(msg):
69 cprint('{}'.format(msg), 'green', attrs=['bold'])
70
71
72 def _parse_args():
73 ap = argparse.ArgumentParser()
74
75 ap.add_argument('-c', '--code-dir', metavar='DIR', action='store',
76 default=os.getcwd(),
77 help='output directory of C source file')
78 ap.add_argument('--dump-config', action='store_true',
79 help='also dump the effective YAML configuration file used for generation')
80 ap.add_argument('-H', '--headers-dir', metavar='DIR', action='store',
81 default=os.getcwd(),
82 help='output directory of C header files')
83 ap.add_argument('-I', '--include-dir', metavar='DIR', action='append',
84 default=[],
85 help='add directory DIR to the list of directories to be searched for include files')
86 ap.add_argument('--ignore-include-not-found', action='store_true',
87 help='continue to process the configuration file when included files are not found')
88 ap.add_argument('-m', '--metadata-dir', metavar='DIR', action='store',
89 default=os.getcwd(),
90 help='output directory of CTF metadata')
91 ap.add_argument('-p', '--prefix', metavar='PREFIX', action='store',
92 help='override configuration\'s prefix')
93 ap.add_argument('-V', '--version', action='version',
94 version='%(prog)s {}'.format(barectf.__version__))
95 ap.add_argument('config', metavar='CONFIG', action='store',
96 help='barectf YAML configuration file')
97
98 # parse args
99 args = ap.parse_args()
100
101 # validate output directories
102 for d in [args.code_dir, args.headers_dir, args.metadata_dir] + args.include_dir:
103 if not os.path.isdir(d):
104 _perror('"{}" is not an existing directory'.format(d))
105
106 # validate that configuration file exists
107 if not os.path.isfile(args.config):
108 _perror('"{}" is not an existing, regular file'.format(args.config))
109
110 # append current working directory and provided include directory
111 args.include_dir += [os.getcwd(), resource_filename(__name__, 'include')]
112
113 return args
114
115
116 def _write_file(d, name, content):
117 with open(os.path.join(d, name), 'w') as f:
118 f.write(content)
119
120
121 def run():
122 # parse arguments
123 args = _parse_args()
124
125 # create configuration
126 try:
127 config = barectf.config.from_yaml_file(args.config, args.include_dir,
128 args.ignore_include_not_found,
129 args.dump_config)
130 except barectf.config.ConfigError as e:
131 _pconfig_error(e)
132 except Exception as e:
133 _perror('unknown exception: {}'.format(e))
134
135 # replace prefix if needed
136 if args.prefix:
137 try:
138 config.prefix = args.prefix
139 except barectf.config.ConfigError as e:
140 _pconfig_error(e)
141
142 # generate metadata
143 metadata = barectf.tsdl182gen.from_metadata(config.metadata)
144
145 try:
146 _write_file(args.metadata_dir, 'metadata', metadata)
147 except Exception as e:
148 _perror('cannot write metadata file: {}'.format(e))
149
150 # create generator
151 generator = barectf.gen.CCodeGenerator(config)
152
153 # generate C headers
154 header = generator.generate_header()
155 bitfield_header = generator.generate_bitfield_header()
156
157 try:
158 _write_file(args.headers_dir, generator.get_header_filename(), header)
159 _write_file(args.headers_dir, generator.get_bitfield_header_filename(),
160 bitfield_header)
161 except Exception as e:
162 _perror('cannot write header files: {}'.format(e))
163
164 # generate C source
165 c_src = generator.generate_c_src()
166
167 try:
168 _write_file(args.code_dir, '{}.c'.format(config.prefix.rstrip('_')),
169 c_src)
170 except Exception as e:
171 _perror('cannot write C source file: {}'.format(e))
This page took 0.03342 seconds and 5 git commands to generate.