1"""
2Utility script to generate headers for the following macros
3- Z_LISTIFY
4- Z_UTIL_INC
5- Z_UTIL_DEC
6- Z_UTIL_X2
7- Z_IS_EQ
8
9.. note::
10    The script will simply create the header files in the current working directory,
11    they should be copied manually to $ZEPHYR_BASE/include/zephyr/sys/ accordingly.
12
13Usage::
14
15    python $ZEPHYR_BASE/scripts/utils/gen_util_macros.py -l 4095
16
17Copyright (c) 2023, Meta
18SPDX-License-Identifier: Apache-2.0
19"""
20
21import argparse
22
23def write_hidden_start(file):
24    file.write("/**\n")
25    file.write(" * @cond INTERNAL_HIDDEN\n")
26    file.write(" */\n")
27
28
29def write_hidden_stop(file):
30    file.write("/**\n")
31    file.write(" * INTERNAL_HIDDEN @endcond\n")
32    file.write(" */\n")
33
34
35def gen_util_listify(limit:int):
36    with open("util_listify.h", "w") as file:
37        write_hidden_start(file)
38        file.write("\n")
39        file.write("#ifndef ZEPHYR_INCLUDE_SYS_UTIL_LOOPS_H_\n")
40        file.write("#error \"This header should not be used directly, please include util_loops.h instead\"\n")
41        file.write("#endif /* ZEPHYR_INCLUDE_SYS_UTIL_LOOPS_H_ */\n")
42        file.write("\n")
43        file.write("#ifndef ZEPHYR_INCLUDE_SYS_UTIL_LISTIFY_H_\n")
44        file.write("#define ZEPHYR_INCLUDE_SYS_UTIL_LISTIFY_H_\n")
45        file.write("\n")
46
47        file.write("/* Set of UTIL_LISTIFY particles */\n")
48        file.write("#define Z_UTIL_LISTIFY_0(F, sep, ...)\n\n")
49        file.write("#define Z_UTIL_LISTIFY_1(F, sep, ...) \\\n")
50        file.write("	F(0, __VA_ARGS__)\n\n")
51
52        for i in range(2, limit + 3):
53            file.write(f"#define Z_UTIL_LISTIFY_{i}(F, sep, ...) \\\n")
54            file.write(f"	Z_UTIL_LISTIFY_{i - 1}(F, sep, __VA_ARGS__) __DEBRACKET sep \\\n")
55            file.write(f"	F({i - 1}, __VA_ARGS__)\n")
56
57        file.write("\n")
58        file.write("#endif /* ZEPHYR_INCLUDE_SYS_UTIL_LISTIFY_H_ */\n")
59        file.write("\n")
60        write_hidden_stop(file)
61
62
63def gen_util_internal_is_eq(limit):
64    with open("util_internal_is_eq.h", "w") as file:
65        write_hidden_start(file)
66        file.write("\n")
67        file.write("#ifndef ZEPHYR_INCLUDE_SYS_UTIL_INTERNAL_H_\n")
68        file.write("#error \"This header should not be used directly, \
69please include util_internal.h instead\"\n")
70        file.write("#endif /* ZEPHYR_INCLUDE_SYS_UTIL_INTERNAL_H_ */\n")
71        file.write("\n")
72        file.write("#ifndef ZEPHYR_INCLUDE_SYS_UTIL_INTERNAL_IS_EQ_H_\n")
73        file.write("#define ZEPHYR_INCLUDE_SYS_UTIL_INTERNAL_IS_EQ_H_\n")
74        file.write("\n")
75
76        for i in range(0, limit + 1):
77            file.write(f"#define Z_IS_{i}_EQ_{i}(...) \\,\n")
78
79        file.write("\n")
80        file.write("#endif /* ZEPHYR_INCLUDE_SYS_UTIL_INTERNAL_IS_EQ_H_ */\n")
81        file.write("\n")
82        write_hidden_stop(file)
83
84
85def gen_util_internal_util_inc(limit):
86    with open("util_internal_util_inc.h", "w") as file:
87        write_hidden_start(file)
88        file.write("\n")
89        file.write("#ifndef ZEPHYR_INCLUDE_SYS_UTIL_INTERNAL_H_\n")
90        file.write("#error \"This header should not be used directly, \
91please include util_internal.h instead\"\n")
92        file.write("#endif /* ZEPHYR_INCLUDE_SYS_UTIL_INTERNAL_H_ */\n")
93        file.write("\n")
94        file.write("#ifndef ZEPHYR_INCLUDE_SYS_UTIL_INTERNAL_UTIL_INC_H_\n")
95        file.write("#define ZEPHYR_INCLUDE_SYS_UTIL_INTERNAL_UTIL_INC_H_\n")
96        file.write("\n")
97
98        for i in range(0, limit + 2):
99            file.write(f"#define Z_UTIL_INC_{i} {i + 1}\n")
100
101        file.write("\n")
102        file.write("#endif /* ZEPHYR_INCLUDE_SYS_UTIL_INTERNAL_UTIL_INC_H_ */\n")
103        file.write("\n")
104        write_hidden_stop(file)
105
106
107def gen_util_internal_util_dec(limit):
108    with open("util_internal_util_dec.h", "w") as file:
109        write_hidden_start(file)
110        file.write("\n")
111        file.write("#ifndef ZEPHYR_INCLUDE_SYS_UTIL_INTERNAL_H_\n")
112        file.write("#error \"This header should not be used directly, \
113please include util_internal.h instead\"\n")
114        file.write("#endif /* ZEPHYR_INCLUDE_SYS_UTIL_INTERNAL_H_ */\n")
115        file.write("\n")
116        file.write("#ifndef ZEPHYR_INCLUDE_SYS_UTIL_INTERNAL_UTIL_DEC_H_\n")
117        file.write("#define ZEPHYR_INCLUDE_SYS_UTIL_INTERNAL_UTIL_DEC_H_\n")
118        file.write("\n")
119
120        file.write(f"#define Z_UTIL_DEC_0 0\n")
121        for i in range(1, limit + 2):
122            file.write(f"#define Z_UTIL_DEC_{i} {i - 1}\n")
123
124        file.write("\n")
125        file.write("#endif /* ZEPHYR_INCLUDE_SYS_UTIL_INTERNAL_UTIL_DEC_H_ */\n")
126        file.write("\n")
127        write_hidden_stop(file)
128
129
130def gen_util_internal_util_x2(limit):
131    with open("util_internal_util_x2.h", "w") as file:
132        write_hidden_start(file)
133        file.write("\n")
134        file.write("#ifndef ZEPHYR_INCLUDE_SYS_UTIL_INTERNAL_H_\n")
135        file.write("#error \"This header should not be used directly, \
136please include util_internal.h instead\"\n")
137        file.write("#endif /* ZEPHYR_INCLUDE_SYS_UTIL_INTERNAL_H_ */\n")
138        file.write("\n")
139        file.write("#ifndef ZEPHYR_INCLUDE_SYS_UTIL_INTERNAL_UTIL_X2_H_\n")
140        file.write("#define ZEPHYR_INCLUDE_SYS_UTIL_INTERNAL_UTIL_X2_H_\n")
141        file.write("\n")
142
143        for i in range(0, limit + 1):
144            file.write(f"#define Z_UTIL_X2_{i} {i *2}\n")
145
146        file.write("\n")
147        file.write("#endif /* ZEPHYR_INCLUDE_SYS_UTIL_INTERNAL_UTIL_X2_H_ */\n")
148        file.write("\n")
149        write_hidden_stop(file)
150
151
152if __name__ == "__main__":
153    parser = argparse.ArgumentParser(allow_abbrev=False)
154    parser.add_argument(
155        "-l", "--limit", type=int, required=True, help="Limit of macros"
156    )
157    args = parser.parse_args()
158
159    gen_util_listify(args.limit)
160    gen_util_internal_is_eq(args.limit)
161    gen_util_internal_util_inc(args.limit)
162    gen_util_internal_util_dec(args.limit)
163    gen_util_internal_util_x2(args.limit)
164