4 # Copyright (C) 2020 Red Hat Inc.
7 # Eduardo Habkost <ehabkost@redhat.com>
9 # This work is licensed under the terms of the GNU GPL, version 2. See
10 # the COPYING file in the top-level directory.
19 from codeconverter
.patching
import FileInfo
, match_class_dict
, FileList
20 import codeconverter
.qom_macros
21 from codeconverter
.qom_type_info
import TI_FIELDS
, type_infos
, TypeInfoVar
24 logger
= logging
.getLogger(__name__
)
29 def process_all_files(parser
: argparse
.ArgumentParser
, args
: argparse
.Namespace
) -> None:
30 DBG("filenames: %r", args
.filenames
)
33 files
.extend(FileInfo(files
, fn
, args
.force
) for fn
in args
.filenames
)
35 DBG('opening %s', f
.filename
)
39 fields
= ['filename', 'variable_name'] + TI_FIELDS
40 print('\t'.join(fields
))
42 for t
in f
.matches_of_type(TypeInfoVar
):
43 assert isinstance(t
, TypeInfoVar
)
44 values
= [f
.filename
, t
.name
] + \
45 [t
.get_raw_initializer_value(f
)
47 DBG('values: %r', values
)
48 assert all('\t' not in v
for v
in values
)
49 values
= [v
.replace('\n', ' ').replace('"', '') for v
in values
]
50 print('\t'.join(values
))
53 match_classes
= match_class_dict()
55 parser
.error("--pattern is required")
57 classes
= [p
for arg
in args
.patterns
58 for p
in re
.split(r
'[\s,]', arg
)
61 if c
not in match_classes \
62 or not match_classes
[c
].regexp
:
63 print("Invalid pattern name: %s" % (c
), file=sys
.stderr
)
64 print("Valid patterns:", file=sys
.stderr
)
65 print(PATTERN_HELP
, file=sys
.stderr
)
68 DBG("classes: %r", classes
)
69 files
.patch_content(max_passes
=args
.passes
, class_names
=classes
)
72 #alltypes.extend(f.type_infos)
73 #full_types.extend(f.full_types())
80 if not args
.diff
and not args
.inplace
:
81 f
.write_to_file(sys
.stdout
)
85 PATTERN_HELP
= ('\n'.join(" %s: %s" % (n
, str(c
.__doc
__).strip())
86 for (n
,c
) in sorted(match_class_dict().items())
87 if c
.has_replacement_rule()))
90 p
= argparse
.ArgumentParser(formatter_class
=argparse
.RawDescriptionHelpFormatter
)
91 p
.add_argument('filenames', nargs
='+')
92 p
.add_argument('--passes', type=int, default
=1,
93 help="Number of passes (0 means unlimited)")
94 p
.add_argument('--pattern', required
=True, action
='append',
95 default
=[], dest
='patterns',
96 help="Pattern to scan for")
97 p
.add_argument('--inplace', '-i', action
='store_true',
98 help="Patch file in place")
99 p
.add_argument('--dry-run', action
='store_true',
100 help="Don't patch files or print patching results")
101 p
.add_argument('--force', '-f', action
='store_true',
102 help="Perform changes even if not completely safe")
103 p
.add_argument('--diff', action
='store_true',
104 help="Print diff output on stdout")
105 p
.add_argument('--debug', '-d', action
='store_true',
106 help="Enable debugging")
107 p
.add_argument('--verbose', '-v', action
='store_true',
108 help="Verbose logging on stderr")
109 p
.add_argument('--table', action
='store_true',
110 help="Print CSV table of type information")
111 p
.add_argument_group("Valid pattern names",
113 args
= p
.parse_args()
115 loglevel
= (logging
.DEBUG
if args
.debug
116 else logging
.INFO
if args
.verbose
118 logging
.basicConfig(format
='%(levelname)s: %(message)s', level
=loglevel
)
119 DBG("args: %r", args
)
120 process_all_files(p
, args
)
122 if __name__
== '__main__':