File indexing completed on 2025-01-18 09:10:44
0001
0002
0003 from pathlib import Path
0004 import os
0005 import argparse
0006 from fnmatch import fnmatch
0007 import re
0008 import sys
0009
0010
0011 math_constants = [
0012 ("M_PI", "std::numbers::pi"),
0013 ("M_PI_2", "std::numbers::pi / 2."),
0014 ("M_PI_4", "std::numbers::pi / 4."),
0015 ("M_1_PI", "std::numbers::inv_pi"),
0016 ("M_2_PI", "2. * std::numbers::inv_pi"),
0017 ("M_2_SQRTPI", "2. * std::numbers::inv_sqrtpi"),
0018 ("M_E", "std::numbers::e"),
0019 ("M_LOG2E", "std::numbers::log2e"),
0020 ("M_LOG10E", "std::numbers::log10e"),
0021 ("M_LN2", "std::numbers::ln2"),
0022 ("M_LN10", "std::numbers::ln10"),
0023 ("M_SQRT2", "std::numbers::sqrt2"),
0024 ("M_SQRT1_2", "1. / std::numbers::sqrt2"),
0025 ("M_SQRT3", "std::numbers::sqrt3"),
0026 ("M_INV_SQRT3", "std::numbers::inv_sqrt3"),
0027 ("M_EGAMMA", "std::numbers::egamma"),
0028 ("M_PHI", "std::numbers::phi"),
0029 ]
0030
0031
0032 github = "GITHUB_ACTIONS" in os.environ
0033
0034
0035 def handle_file(
0036 file: Path, fix: bool, math_const: tuple[str, str]
0037 ) -> list[tuple[int, str]]:
0038 ex = re.compile(rf"(?<!\w){math_const[0]}(?!\w)")
0039
0040 content = file.read_text()
0041 lines = content.splitlines()
0042
0043 changed_lines = []
0044
0045 for i, oline in enumerate(lines):
0046 line, n_subs = ex.subn(rf"{math_const[1]}", oline)
0047 lines[i] = line
0048 if n_subs > 0:
0049 changed_lines.append((i, oline))
0050
0051 if fix and len(changed_lines) > 0:
0052 file.write_text("\n".join(lines) + "\n")
0053
0054 return changed_lines
0055
0056
0057 def main():
0058 p = argparse.ArgumentParser()
0059 p.add_argument("input", nargs="+")
0060 p.add_argument("--fix", action="store_true", help="Attempt to fix M_* macros.")
0061 p.add_argument("--exclude", "-e", action="append", default=[])
0062
0063 args = p.parse_args()
0064
0065 exit_code = 0
0066
0067 inputs = []
0068
0069 if len(args.input) == 1 and os.path.isdir(args.input[0]):
0070
0071 for root, _, files in os.walk(args.input[0]):
0072 root = Path(root)
0073 for filename in files:
0074
0075 filepath = root / filename
0076 if filepath.suffix not in (
0077 ".hpp",
0078 ".cpp",
0079 ".ipp",
0080 ".h",
0081 ".C",
0082 ".c",
0083 ".cu",
0084 ".cuh",
0085 ):
0086 continue
0087
0088 if any([fnmatch(str(filepath), e) for e in args.exclude]):
0089 continue
0090
0091 inputs.append(filepath)
0092 else:
0093 for file in args.input:
0094 inputs.append(Path(file))
0095
0096 for filepath in inputs:
0097 for math_const in math_constants:
0098 changed_lines = handle_file(
0099 file=filepath, fix=args.fix, math_const=math_const
0100 )
0101 if len(changed_lines) > 0:
0102 exit_code = 1
0103 print()
0104 print(filepath)
0105 for i, oline in changed_lines:
0106 print(f"{i}: {oline}")
0107
0108 if github:
0109 print(
0110 f"::error file={filepath},line={i+1},title=Do not use macro {math_const[0]}::Replace {math_const[0]} with std::{math_const[1]}"
0111 )
0112
0113 if exit_code == 1 and github:
0114 print(f"::info You will need in each flagged file #include <numbers>")
0115
0116 return exit_code
0117
0118
0119 if "__main__" == __name__:
0120 sys.exit(main())