4a15e5bef8
I'm not documenting every single change in the codeconverter script because most of that code will be deleted once we finish the QOM code conversion. This patch updates the script to the latest version that was used to perform changes in the QOM code. Signed-off-by: Eduardo Habkost <ehabkost@redhat.com> Message-Id: <20200916182519.415636-2-ehabkost@redhat.com> Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
123 lines
4.3 KiB
Python
Executable File
123 lines
4.3 KiB
Python
Executable File
#!/usr/bin/env python3
|
|
# QEMU library
|
|
#
|
|
# Copyright (C) 2020 Red Hat Inc.
|
|
#
|
|
# Authors:
|
|
# Eduardo Habkost <ehabkost@redhat.com>
|
|
#
|
|
# This work is licensed under the terms of the GNU GPL, version 2. See
|
|
# the COPYING file in the top-level directory.
|
|
#
|
|
import sys
|
|
import argparse
|
|
import os
|
|
import os.path
|
|
import re
|
|
from typing import *
|
|
|
|
from codeconverter.patching import FileInfo, match_class_dict, FileList
|
|
import codeconverter.qom_macros
|
|
from codeconverter.qom_type_info import TI_FIELDS, type_infos, TypeInfoVar
|
|
|
|
import logging
|
|
logger = logging.getLogger(__name__)
|
|
DBG = logger.debug
|
|
INFO = logger.info
|
|
WARN = logger.warning
|
|
|
|
def process_all_files(parser: argparse.ArgumentParser, args: argparse.Namespace) -> None:
|
|
DBG("filenames: %r", args.filenames)
|
|
|
|
files = FileList()
|
|
files.extend(FileInfo(files, fn, args.force) for fn in args.filenames)
|
|
for f in files:
|
|
DBG('opening %s', f.filename)
|
|
f.load()
|
|
|
|
if args.table:
|
|
fields = ['filename', 'variable_name'] + TI_FIELDS
|
|
print('\t'.join(fields))
|
|
for f in files:
|
|
for t in f.matches_of_type(TypeInfoVar):
|
|
assert isinstance(t, TypeInfoVar)
|
|
values = [f.filename, t.name] + \
|
|
[t.get_raw_initializer_value(f)
|
|
for f in TI_FIELDS]
|
|
DBG('values: %r', values)
|
|
assert all('\t' not in v for v in values)
|
|
values = [v.replace('\n', ' ').replace('"', '') for v in values]
|
|
print('\t'.join(values))
|
|
return
|
|
|
|
match_classes = match_class_dict()
|
|
if not args.patterns:
|
|
parser.error("--pattern is required")
|
|
|
|
classes = [p for arg in args.patterns
|
|
for p in re.split(r'[\s,]', arg)
|
|
if p.strip()]
|
|
for c in classes:
|
|
if c not in match_classes \
|
|
or not match_classes[c].regexp:
|
|
print("Invalid pattern name: %s" % (c), file=sys.stderr)
|
|
print("Valid patterns:", file=sys.stderr)
|
|
print(PATTERN_HELP, file=sys.stderr)
|
|
sys.exit(1)
|
|
|
|
DBG("classes: %r", classes)
|
|
files.patch_content(max_passes=args.passes, class_names=classes)
|
|
|
|
for f in files:
|
|
#alltypes.extend(f.type_infos)
|
|
#full_types.extend(f.full_types())
|
|
|
|
if not args.dry_run:
|
|
if args.inplace:
|
|
f.patch_inplace()
|
|
if args.diff:
|
|
f.show_diff()
|
|
if not args.diff and not args.inplace:
|
|
f.write_to_file(sys.stdout)
|
|
sys.stdout.flush()
|
|
|
|
|
|
PATTERN_HELP = ('\n'.join(" %s: %s" % (n, str(c.__doc__).strip())
|
|
for (n,c) in sorted(match_class_dict().items())
|
|
if c.has_replacement_rule()))
|
|
|
|
def main() -> None:
|
|
p = argparse.ArgumentParser(formatter_class=argparse.RawDescriptionHelpFormatter)
|
|
p.add_argument('filenames', nargs='+')
|
|
p.add_argument('--passes', type=int, default=1,
|
|
help="Number of passes (0 means unlimited)")
|
|
p.add_argument('--pattern', required=True, action='append',
|
|
default=[], dest='patterns',
|
|
help="Pattern to scan for")
|
|
p.add_argument('--inplace', '-i', action='store_true',
|
|
help="Patch file in place")
|
|
p.add_argument('--dry-run', action='store_true',
|
|
help="Don't patch files or print patching results")
|
|
p.add_argument('--force', '-f', action='store_true',
|
|
help="Perform changes even if not completely safe")
|
|
p.add_argument('--diff', action='store_true',
|
|
help="Print diff output on stdout")
|
|
p.add_argument('--debug', '-d', action='store_true',
|
|
help="Enable debugging")
|
|
p.add_argument('--verbose', '-v', action='store_true',
|
|
help="Verbose logging on stderr")
|
|
p.add_argument('--table', action='store_true',
|
|
help="Print CSV table of type information")
|
|
p.add_argument_group("Valid pattern names",
|
|
PATTERN_HELP)
|
|
args = p.parse_args()
|
|
|
|
loglevel = (logging.DEBUG if args.debug
|
|
else logging.INFO if args.verbose
|
|
else logging.WARN)
|
|
logging.basicConfig(format='%(levelname)s: %(message)s', level=loglevel)
|
|
DBG("args: %r", args)
|
|
process_all_files(p, args)
|
|
|
|
if __name__ == '__main__':
|
|
main() |