4 # Copyright (C) 2020 Red Hat Inc.
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__':