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