1#!/usr/bin/env python3 2# pylint: disable=R0903 3# Copyright(c) 2025: Mauro Carvalho Chehab <[email protected]>. 4# SPDX-License-Identifier: GPL-2.0 5 6""" 7Parse ABI documentation and produce results from it. 8""" 9 10import argparse 11import logging 12import os 13import sys 14 15# Import Python modules 16 17LIB_DIR = "lib/abi" 18SRC_DIR = os.path.dirname(os.path.realpath(__file__)) 19 20sys.path.insert(0, os.path.join(SRC_DIR, LIB_DIR)) 21 22from abi_parser import AbiParser # pylint: disable=C0413 23from helpers import ABI_DIR, DEBUG_HELP # pylint: disable=C0413 24 25# Command line classes 26 27 28REST_DESC = """ 29Produce output in ReST format. 30 31The output is done on two sections: 32 33- Symbols: show all parsed symbols in alphabetic order; 34- Files: cross reference the content of each file with the symbols on it. 35""" 36 37class AbiRest: 38 """Initialize an argparse subparser for rest output""" 39 40 def __init__(self, subparsers): 41 """Initialize argparse subparsers""" 42 43 parser = subparsers.add_parser("rest", 44 formatter_class=argparse.RawTextHelpFormatter, 45 description=REST_DESC) 46 47 parser.add_argument("--enable-lineno", action="store_true", 48 help="enable lineno") 49 parser.add_argument("--raw", action="store_true", 50 help="output text as contained in the ABI files. " 51 "It not used, output will contain dynamically" 52 " generated cross references when possible.") 53 parser.add_argument("--no-file", action="store_true", 54 help="Don't the files section") 55 parser.add_argument("--show-hints", help="Show-hints") 56 57 parser.set_defaults(func=self.run) 58 59 def run(self, args): 60 """Run subparser""" 61 62 parser = AbiParser(args.dir, debug=args.debug) 63 parser.parse_abi() 64 parser.check_issues() 65 66 for t in parser.doc(args.raw, not args.no_file): 67 if args.enable_lineno: 68 print (f".. LINENO {t[1]}#{t[2]}\n\n") 69 70 print(t[0]) 71 72class AbiValidate: 73 """Initialize an argparse subparser for ABI validation""" 74 75 def __init__(self, subparsers): 76 """Initialize argparse subparsers""" 77 78 parser = subparsers.add_parser("validate", 79 formatter_class=argparse.ArgumentDefaultsHelpFormatter, 80 description="list events") 81 82 parser.set_defaults(func=self.run) 83 84 def run(self, args): 85 """Run subparser""" 86 87 parser = AbiParser(args.dir, debug=args.debug) 88 parser.parse_abi() 89 parser.check_issues() 90 91 92class AbiSearch: 93 """Initialize an argparse subparser for ABI search""" 94 95 def __init__(self, subparsers): 96 """Initialize argparse subparsers""" 97 98 parser = subparsers.add_parser("search", 99 formatter_class=argparse.ArgumentDefaultsHelpFormatter, 100 description="Search ABI using a regular expression") 101 102 parser.add_argument("expression", 103 help="Case-insensitive search pattern for the ABI symbol") 104 105 parser.set_defaults(func=self.run) 106 107 def run(self, args): 108 """Run subparser""" 109 110 parser = AbiParser(args.dir, debug=args.debug) 111 parser.parse_abi() 112 parser.search_symbols(args.expression) 113 114 115def main(): 116 """Main program""" 117 118 parser = argparse.ArgumentParser(formatter_class=argparse.RawTextHelpFormatter) 119 120 parser.add_argument("-d", "--debug", type=int, default=0, help="debug level") 121 parser.add_argument("-D", "--dir", default=ABI_DIR, help=DEBUG_HELP) 122 123 subparsers = parser.add_subparsers() 124 125 AbiRest(subparsers) 126 AbiValidate(subparsers) 127 AbiSearch(subparsers) 128 129 args = parser.parse_args() 130 131 if args.debug: 132 level = logging.DEBUG 133 else: 134 level = logging.INFO 135 136 logging.basicConfig(level=level, format="[%(levelname)s] %(message)s") 137 138 if "func" in args: 139 args.func(args) 140 else: 141 sys.exit(f"Please specify a valid command for {sys.argv[0]}") 142 143 144# Call main method 145if __name__ == "__main__": 146 main() 147