2 # Rust is fairly relaxed in checking the validity of arguments passed to #[cfg].
3 # While it should probably be more strict when checking features, it cannot be
4 # strict when checking loose cfg tags, because those can be anything and are
5 # simply passed to rustc via unconstrained arguments.
7 # Thus, we do it for rustc manually, but scanning all our source and checking
8 # that all our cfg tags match a known cfg tag.
11 def check_feature(feature):
14 elif feature == "no-std":
16 elif feature == "possiblyrandom":
18 elif feature == "getrandom":
20 elif feature == "hashbrown":
22 elif feature == "backtrace":
24 elif feature == "grind_signatures":
26 elif feature == "unsafe_revoked_tx_signing":
28 elif feature == "futures":
30 elif feature == "tokio":
32 elif feature == "rest-client":
34 elif feature == "rpc-client":
36 elif feature == "serde":
38 elif feature == "esplora-blocking":
40 elif feature == "esplora-async":
42 elif feature == "async-interface":
44 elif feature == "electrum":
46 elif feature == "time":
48 elif feature == "_test_utils":
50 elif feature == "_test_vectors":
52 elif feature == "afl":
54 elif feature == "honggfuzz":
56 elif feature == "libfuzzer_fuzz":
58 elif feature == "stdin_fuzz":
60 elif feature == "max_level_off":
62 elif feature == "max_level_error":
64 elif feature == "max_level_warn":
66 elif feature == "max_level_info":
68 elif feature == "max_level_debug":
70 elif feature == "max_level_trace":
73 print("Bad feature: " + feature)
76 def check_target_os(os):
82 def check_cfg_tag(cfg):
85 elif cfg == "secp256k1_fuzz":
87 elif cfg == "hashes_fuzz":
91 elif cfg == "debug_assertions":
93 elif cfg == "c_bindings":
95 elif cfg == "ldk_bench":
97 elif cfg == "taproot":
99 elif cfg == "async_signing":
101 elif cfg == "require_route_graph_test":
103 elif cfg == "dual_funding":
105 elif cfg == "splicing":
107 elif cfg == "async_payments":
110 print("Bad cfg tag: " + cfg)
113 def check_cfg_args(cfg):
114 if cfg.startswith("all(") or cfg.startswith("any(") or cfg.startswith("not("):
117 while pos < len(cfg):
120 elif cfg[pos] == ")":
123 check_cfg_args(cfg[4:pos])
124 if pos + 1 != len(cfg):
125 assert cfg[pos + 1] == ","
126 check_cfg_args(cfg[pos + 2:].strip())
130 assert(cfg.endswith(")"))
131 check_cfg_args(cfg[4:len(cfg)-1])
133 parts = [part.strip() for part in cfg.split(",", 1)]
137 elif cfg.startswith("feature") or cfg.startswith("target_os") or cfg.startswith("target_pointer_width"):
139 if cfg.startswith("feature"):
140 arg = arg[7:].strip()
141 elif cfg.startswith("target_os"):
142 arg = arg[9:].strip()
144 arg = arg[20:].strip()
145 assert arg.startswith("=")
146 arg = arg[1:].strip()
147 assert arg.startswith("\"")
148 assert arg.endswith("\"")
149 arg = arg[1:len(arg)-1]
150 assert not "\"" in arg
151 if cfg.startswith("feature"):
153 elif cfg.startswith("target_os"):
156 assert arg == "32" or arg == "64"
158 check_cfg_tag(cfg.strip())
160 cfg_regex = re.compile("#\[cfg\((.*)\)\]")
161 for path in glob.glob(sys.path[0] + "/../**/*.rs", recursive = True):
162 with open(path, "r") as file:
164 line = file.readline()
168 if not line.strip().startswith("//"):
169 cfg_part = cfg_regex.match(line.strip()).group(1)
170 check_cfg_args(cfg_part)