cpp-common/bt2c/fmt.hpp: use `wise_enum::string_type` in `EnableIfIsWiseEnum` definition
[babeltrace.git] / tests / utils / python / mctf.py
1 # SPDX-License-Identifier: GPL-2.0-only
2 #
3 # Copyright (C) 2023 EfficiOS Inc.
4 #
5 # pyright: strict, reportTypeCommentUsage=false
6
7 import os
8 import sys
9 import typing
10 import argparse
11 from typing import Any, List, Union
12
13 import normand
14 import moultipart
15
16
17 class ErrorCause:
18 def __init__(self, what: str, line_no: int, col_no: int):
19 self._what = what
20 self._line_no = line_no
21 self._col_no = col_no
22
23 @property
24 def what(self):
25 return self._what
26
27 @property
28 def line_no(self):
29 return self._line_no
30
31 @property
32 def col_no(self):
33 return self._col_no
34
35
36 class Error(RuntimeError):
37 def __init__(self, causes: List[ErrorCause]):
38 self._causes = causes
39
40 @property
41 def causes(self):
42 return self._causes
43
44
45 def _write_file(
46 name: str, base_dir: str, content: Union[str, bytearray], verbose: bool
47 ):
48 path = os.path.join(base_dir, name)
49
50 if verbose:
51 print("Writing `{}`.".format(os.path.normpath(path)))
52
53 os.makedirs(os.path.normpath(os.path.dirname(path)), exist_ok=True)
54
55 with open(path, "w" if isinstance(content, str) else "wb") as f:
56 f.write(content)
57
58
59 def _normand_parse(
60 part: moultipart.Part, init_vars: normand.VariablesT, init_labels: normand.LabelsT
61 ):
62 try:
63 return normand.parse(
64 part.content, init_variables=init_vars, init_labels=init_labels
65 )
66 except normand.ParseError as e:
67 raise Error(
68 [
69 ErrorCause(
70 msg.text,
71 msg.text_location.line_no + part.first_content_line_no - 1,
72 msg.text_location.col_no,
73 )
74 for msg in e.messages
75 ]
76 ) from e
77
78
79 def _generate_from_part(
80 part: moultipart.Part,
81 base_dir: str,
82 verbose: bool,
83 normand_vars: normand.VariablesT,
84 normand_labels: normand.LabelsT,
85 ):
86 content = part.content
87
88 if part.header_info != "metadata":
89 res = _normand_parse(part, normand_vars, normand_labels)
90 content = res.data
91 normand_vars = res.variables
92 normand_labels = res.labels
93
94 _write_file(part.header_info, base_dir, content, verbose)
95 return normand_vars, normand_labels
96
97
98 def generate(input_path: str, base_dir: str, verbose: bool):
99 with open(input_path) as input_file:
100 variables = {} # type: normand.VariablesT
101 labels = {} # type: normand.LabelsT
102
103 for part in moultipart.parse(input_file):
104 variables, labels = _generate_from_part(
105 part, base_dir, verbose, variables, labels
106 )
107
108
109 def _parse_cli_args():
110 argparser = argparse.ArgumentParser()
111 argparser.add_argument(
112 "input_path", metavar="PATH", type=str, help="moultipart input file name"
113 )
114 argparser.add_argument(
115 "--base-dir", type=str, help="base directory of generated files", default=""
116 )
117 argparser.add_argument(
118 "--verbose", "-v", action="store_true", help="increase verbosity"
119 )
120 return argparser.parse_args()
121
122
123 def _run_cli(args: Any):
124 generate(
125 typing.cast(str, args.input_path),
126 typing.cast(str, args.base_dir),
127 typing.cast(bool, args.verbose),
128 )
129
130
131 def _try_run_cli():
132 args = _parse_cli_args()
133
134 try:
135 _run_cli(args)
136 except Error as exc:
137 print("Failed to process Normand part:", file=sys.stderr)
138
139 for cause in reversed(exc.causes):
140 print(
141 " {}:{}:{} - {}{}".format(
142 os.path.abspath(args.input_path),
143 cause.line_no,
144 cause.col_no,
145 cause.what,
146 "." if cause.what[-1] not in ".:;" else "",
147 ),
148 file=sys.stderr,
149 )
150
151
152 if __name__ == "__main__":
153 _try_run_cli()
This page took 0.033624 seconds and 4 git commands to generate.