1#!/usr/bin/python 2"""Toggle settings in `ftoption.h` file based on command-line arguments. 3 4This script takes an `ftoption.h` file as input and rewrites 5`#define`/`#undef` lines in it based on `--enable=CONFIG_VARNAME` or 6`--disable=CONFIG_VARNAME` arguments passed to it, where `CONFIG_VARNAME` is 7configuration variable name, such as `FT_CONFIG_OPTION_USE_LZW`, that may 8appear in the file. 9 10Note that if one of `CONFIG_VARNAME` is not found in the input file, this 11script exits with an error message listing the missing variable names. 12""" 13 14import argparse 15import os 16import re 17import sys 18 19 20def main(): 21 parser = argparse.ArgumentParser(description=__doc__) 22 23 parser.add_argument( 24 "input", metavar="FTOPTION_H", help="Path to input ftoption.h file." 25 ) 26 27 parser.add_argument("--output", help="Output to file instead of stdout.") 28 29 parser.add_argument( 30 "--enable", 31 action="append", 32 default=[], 33 help="Enable a given build option (e.g. FT_CONFIG_OPTION_USE_LZW).", 34 ) 35 36 parser.add_argument( 37 "--disable", 38 action="append", 39 default=[], 40 help="Disable a given build option.", 41 ) 42 43 args = parser.parse_args() 44 45 common_options = set(args.enable) & set(args.disable) 46 if common_options: 47 parser.error( 48 "Options cannot be both enabled and disabled: %s" 49 % sorted(common_options) 50 ) 51 return 1 52 53 with open(args.input) as f: 54 input_file = f.read() 55 56 options_seen = set() 57 58 new_lines = [] 59 for line in input_file.splitlines(): 60 # Expected formats: 61 # #define <CONFIG_VAR> 62 # /* #define <CONFIG_VAR> */ 63 # #undef <CONFIG_VAR> 64 line = line.rstrip() 65 if line.startswith("/* #define ") and line.endswith(" */"): 66 option_name = line[11:-3].strip() 67 option_enabled = False 68 elif line.startswith("#define "): 69 option_name = line[8:].strip() 70 option_enabled = True 71 elif line.startswith("#undef "): 72 option_name = line[7:].strip() 73 option_enabled = False 74 else: 75 new_lines.append(line) 76 continue 77 78 options_seen.add(option_name) 79 if option_enabled and option_name in args.disable: 80 line = "#undef " + option_name 81 elif not option_enabled and option_name in args.enable: 82 line = "#define " + option_name 83 new_lines.append(line) 84 85 result = "\n".join(new_lines) 86 87 # Sanity check that all command-line options were actually processed. 88 cmdline_options = set(args.enable) | set(args.disable) 89 assert cmdline_options.issubset( 90 options_seen 91 ), "Could not find options in input file: " + ", ".join( 92 sorted(cmdline_options - options_seen) 93 ) 94 95 if args.output: 96 with open(args.output, "w") as f: 97 f.write(result) 98 else: 99 print(result) 100 101 return 0 102 103 104if __name__ == "__main__": 105 sys.exit(main()) 106