Skip to content

Commit 9123d26

Browse files
committed
ENH: Cover all deprecated vnl_math spellings in VNL_ModernizeNaming.py
Handle the namespace-style vnl_math:: spellings (constants, functions, predicates, std re-exports, abs) alongside the legacy vnl_math_* globals, targeting C++17-compatible itk::Math/std equivalents. Report vnl_huge_val occurrences for manual, type-aware migration.
1 parent 7c91dbc commit 9123d26

1 file changed

Lines changed: 70 additions & 89 deletions

File tree

Lines changed: 70 additions & 89 deletions
Original file line numberDiff line numberDiff line change
@@ -1,105 +1,86 @@
1-
#!/bin/env python
1+
#!/usr/bin/env python3
22
# \author Hans J. Johnson
33
#
4-
# Prepare for the future by recommending
5-
# use of itk::Math:: functions over
6-
# vnl_math:: functions.
7-
# Rather than converting vnl_math_ to vnl_math::
8-
# this prefers to convert directly to itk::Math::
9-
# namespace. In cases where vnl_math:: is simply
10-
# an alias to std:: functions, itk::Math directly
11-
# uses the std:: version of the function.
4+
# Migrate a source file away from deprecated vnl_math usage, preferring
5+
# replacements that compile under C++17:
6+
# - vnl_math:: constants, functions, and predicates -> itk::Math:: equivalents
7+
# - vnl_math:: re-exports of std functions (max/min/cbrt/hypot) -> std::
8+
# - vnl_math::abs / vnl_math_abs -> itk::Math::Absolute
9+
# - legacy vnl_math_* global-function spellings -> the same modern targets
10+
# - "vnl/vnl_math.h" include -> "itkMath.h"
11+
# vnl_huge_val cannot be rewritten textually (the replacement type depends on
12+
# context); occurrences are reported for manual migration to
13+
# std::numeric_limits<T>::infinity() or itk::NumericTraits<T>::max().
1214

13-
import os
1415
import sys
1516
from collections import OrderedDict
17+
from pathlib import Path
1618

17-
## slight modification from grep command
18-
info_for_conversion = """
19-
XXXX,vnl_math_isnan,itk::Math::isnan
20-
XXXX,vnl_math_isinf,itk::Math::isinf
21-
XXXX,vnl_math_isfinite,itk::Math::isfinite
22-
XXXX,vnl_math_isnormal,itk::Math::isnormal
23-
XXXX,vnl_math_max,std::max
24-
XXXX,vnl_math_min,std::min
25-
XXXX,vnl_math_cuberoot,itk::Math::cbrt
26-
XXXX,vnl_math_hypot,itk::Math::hypot
27-
XXXX,vnl_math_angle_0_to_2pi,itk::Math::angle_0_to_2pi
28-
XXXX,vnl_math_angle_minuspi_to_pi,itk::Math::angle_minuspi_to_pi
29-
XXXX,vnl_math_rnd_halfinttoeven,itk::Math::halfinttoeven
30-
XXXX,vnl_math_rnd_halfintup,itk::Math::rnd_halfintup
31-
XXXX,vnl_math_rnd,itk::Math::rnd
32-
XXXX,vnl_math_floor,itk::Math::floor
33-
XXXX,vnl_math_ceil,itk::Math::ceil
34-
XXXX,vnl_math_abs,itk::Math::Absolute
35-
XXXX,vnl_math_sqr,itk::Math::sqr
36-
XXXX,vnl_math_cube,itk::Math::cube
37-
XXXX,vnl_math_sgn,itk::Math::sgn
38-
XXXX,vnl_math_sgn0,itk::Math::sgn0
39-
XXXX,vnl_math_squared_magnitude,itk::Math::squared_magnitude
40-
XXXX,vnl_math_remainder_truncated,itk::Math::remainder_truncated
41-
XXXX,vnl_math_remainder_floored,itk::Math::remainder_floored
42-
"""
19+
replacements = OrderedDict()
4320

44-
ITK_replace_head_names = OrderedDict()
45-
ITK_replace_functionnames = OrderedDict()
46-
ITK_replace_manual = OrderedDict()
21+
# Includes.
22+
replacements['"vnl/vnl_math.h"'] = '"itkMath.h"'
23+
replacements["<vnl/vnl_math.h>"] = "<itkMath.h>"
4724

48-
ITK_replace_manual['"vnl/vnl_math.h"'] = '"itkMath.h"'
49-
ITK_replace_manual["<vnl/vnl_math.h>"] = "<itkMath.h>"
25+
# Namespace spellings whose itk::Math name differs (must precede the catch-all).
26+
replacements["vnl_math::max"] = "std::max"
27+
replacements["vnl_math::min"] = "std::min"
28+
replacements["vnl_math::cbrt"] = "std::cbrt"
29+
replacements["vnl_math::hypot"] = "std::hypot"
30+
replacements["vnl_math::abs"] = "itk::Math::Absolute"
5031

51-
for line in info_for_conversion.splitlines():
52-
linevalues = line.split(",")
53-
if len(linevalues) != 3:
54-
# print("SKIPPING: " + str(linevalues))
55-
continue
56-
fname = linevalues[0]
57-
new_name = fname.replace("ITK_", "").replace(".h", "")
58-
ITK_replace_head_names[
59-
f'#include "{fname}"'
60-
] = f"""#if !defined( ITK_LEGACY_FUTURE_REMOVE )
61-
# include "{fname}"
62-
#endif
63-
#include <{new_name}>"""
64-
ITK_replace_head_names[
65-
f"#include <{fname}>"
66-
] = f"""#if !defined( ITK_LEGACY_FUTURE_REMOVE )
67-
# include <{fname}>
68-
#endif
69-
#include <{new_name}>"""
70-
ITK_pat = linevalues[1]
71-
new_pat = linevalues[2]
72-
ITK_replace_functionnames[ITK_pat] = new_pat
73-
# Need to fix the fact that both std::ios is a base and a prefix
74-
if "std::ios::" in new_pat:
75-
ITK_replace_manual[new_pat.replace("std::ios::", "std::ios_")] = new_pat
32+
# Catch-all: every other deprecated vnl_math:: member (constants, the 14
33+
# functions, isnan/isinf/isfinite/isnormal) maps name-identically.
34+
replacements["vnl_math::"] = "itk::Math::"
7635

77-
# print(ITK_replace_head_names)
78-
# print(ITK_replace_functionnames)
36+
# Legacy global-function spellings. Longer names precede their prefixes so
37+
# sequential str.replace cannot corrupt them.
38+
replacements["vnl_math_isnan"] = "itk::Math::isnan"
39+
replacements["vnl_math_isinf"] = "itk::Math::isinf"
40+
replacements["vnl_math_isfinite"] = "itk::Math::isfinite"
41+
replacements["vnl_math_isnormal"] = "itk::Math::isnormal"
42+
replacements["vnl_math_max"] = "std::max"
43+
replacements["vnl_math_min"] = "std::min"
44+
replacements["vnl_math_cuberoot"] = "std::cbrt"
45+
replacements["vnl_math_hypot"] = "std::hypot"
46+
replacements["vnl_math_abs"] = "itk::Math::Absolute"
47+
replacements["vnl_math_angle_0_to_2pi"] = "itk::Math::angle_0_to_2pi"
48+
replacements["vnl_math_angle_minuspi_to_pi"] = "itk::Math::angle_minuspi_to_pi"
49+
replacements["vnl_math_rnd_halfinttoeven"] = "itk::Math::rnd_halfinttoeven"
50+
replacements["vnl_math_rnd_halfintup"] = "itk::Math::rnd_halfintup"
51+
replacements["vnl_math_rnd"] = "itk::Math::rnd"
52+
replacements["vnl_math_floor"] = "itk::Math::floor"
53+
replacements["vnl_math_ceil"] = "itk::Math::ceil"
54+
replacements["vnl_math_sqr"] = "itk::Math::sqr"
55+
replacements["vnl_math_cube"] = "itk::Math::cube"
56+
replacements["vnl_math_sgn0"] = "itk::Math::sgn0"
57+
replacements["vnl_math_sgn"] = "itk::Math::sgn"
58+
replacements["vnl_math_squared_magnitude"] = "itk::Math::squared_magnitude"
59+
replacements["vnl_math_remainder_truncated"] = "itk::Math::remainder_truncated"
60+
replacements["vnl_math_remainder_floored"] = "itk::Math::remainder_floored"
7961

80-
cfile = sys.argv[1]
8162

82-
file_as_string = ""
83-
with open(cfile) as rfp:
84-
original_string = rfp.read()
85-
file_as_string = original_string
63+
def main() -> int:
64+
cfile = Path(sys.argv[1])
65+
original_string = cfile.read_text()
66+
file_as_string = original_string
8667

87-
required_header = "" ## For ITK, this is always empty
68+
for searchval, replaceval in replacements.items():
69+
file_as_string = file_as_string.replace(searchval, replaceval)
8870

89-
for searchval, replaceval in ITK_replace_head_names.items():
90-
file_as_string_new = file_as_string.replace(searchval, required_header + replaceval)
91-
if file_as_string_new != file_as_string:
92-
required_header = ""
93-
file_as_string = file_as_string_new
71+
if "vnl_huge_val" in file_as_string:
72+
print(
73+
f"MANUAL FIX NEEDED: {cfile}: vnl_huge_val -> "
74+
"std::numeric_limits<T>::infinity() or itk::NumericTraits<T>::max()"
75+
)
9476

77+
if file_as_string != original_string:
78+
print(f"Processing: {cfile}")
79+
cfile.write_text(file_as_string)
80+
else:
81+
print(f"SKIPPING: {cfile}")
82+
return 0
9583

96-
for searchval, replaceval in ITK_replace_functionnames.items():
97-
file_as_string = file_as_string.replace(searchval, replaceval)
98-
for searchval, replaceval in ITK_replace_manual.items():
99-
file_as_string = file_as_string.replace(searchval, replaceval)
100-
if file_as_string != original_string:
101-
print(f"Processing: {cfile}")
102-
with open(cfile, "w") as wfp:
103-
wfp.write(file_as_string)
104-
else:
105-
print(f"SKIPPING: {cfile}")
84+
85+
if __name__ == "__main__":
86+
sys.exit(main())

0 commit comments

Comments
 (0)