1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152
|
#!/bin/bash
# Copyright (c) 2008-2025 the MRtrix3 contributors.
#
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
#
# Covered Software is provided under this License on an "as is"
# basis, without warranty of any kind, either expressed, implied, or
# statutory, including, without limitation, warranties that the
# Covered Software is free of defects, merchantable, fit for a
# particular purpose or non-infringing.
# See the Mozilla Public License v. 2.0 for more details.
#
# For more details, see http://www.mrtrix.org/.
LOG=syntax.log
echo -n "Checking syntax and memory alignment for Eigen 3.3 compatibility... "
echo "Checking syntax and memory alignment for Eigen 3.3 compatibility..." > $LOG
echo "" >> $LOG
grep=grep
v=`grep --version`
if [[ "$OSTYPE" == darwin* ]] && [[ $v == *"BSD"* ]]; then
if ! hash ggrep 2>/dev/null; then
echo 'Aborting, this script requires gnu-grep which you can install for instance via "brew install grep"'
exit 1
else
grep=ggrep
fi
fi
retval=0
for f in $(find cmd core src -type f -name '*.h' -o -name '*.cpp' | $grep -v '_moc.cpp'); do
# files to ignore:
[[ "$f" -ef "src/gui/shview/icons.h" ||
"$f" -ef "src/gui/shview/icons.cpp" ||
"$f" -ef "src/gui/mrview/icons.h" ||
"$f" -ef "src/gui/mrview/icons.cpp" ||
"$f" -ef "core/file/mgh.h" ||
"$f" -ef "core/file/json.h" ||
"$f" -ef "core/file/nifti2.h" ||
"$f" -ef "core/signal_handler.h" ||
"$f" -ef "core/signal_handler.cpp" ]] && continue
# process the file to strip comments, macros, etc:
cat $f | \
# remove C preprocessor macros:
$grep -v '^#' | \
# remove C++ single-line comments:
perl -pe 's|//.*$||' | \
# remove all newlines to make file one long line:
tr '\n' ' ' | \
# remove any duplicate spaces:
perl -pe 's|\s+| |g' | \
# remove C-style comments:
perl -pe 's|/\*.*?\*/||g' > .check_syntax2.tmp
# remove quoted strings:
cat .check_syntax2.tmp | perl -pe 's/(")(\\"|.)*?"//g' > .check_syntax.tmp
# detect classes not declared MEMALIGN or NOMEMALIGN:
res=$(
cat .check_syntax.tmp | \
# remove any text within a template declaration (i.e. within <>):
perl -pe 's|<[^{};<]*?>||g' | \
# and do it multiple times to handle nested declarations:
perl -pe 's|<[^{};<]*?>||g' | \
perl -pe 's|<[^{};<]*?>||g' | \
perl -pe 's|<[^{};<]*?>||g' | \
# match for the parts we're interested in and output just the bits that match:
$grep -Eo '(enum\s*)?\b(class|struct)\b[^;{]*?{(\s*(MEMALIGN\s*\([^\)]*\)|NOMEMALIGN))?' | \
# remove matches that correspond to an enum class declaration:
$grep -Ev '\benum\s*class\b' | \
# remove matches that are properly specified:
$grep -Ev '\b(class|struct)\b[^;{]*?{(\s*(MEMALIGN\s*\([^\)]*\)|NOMEMALIGN))'
)
# detect any instances of std::vector:
res="$res"$(
cat .check_syntax.tmp | \
# match for the parts we're interested in and output just the bits that match:
$grep -Po '(?<!::)std::vector\b'
)
# detect any instances of std::make_shared:
res="$res"$(
cat .check_syntax.tmp | \
# match for the parts we're interested in and output just the bits that match:
$grep -Po '(?<!::)std::make_shared\b'
)
# detect any instances of "using namespace std;":
res="$res"$(
cat .check_syntax.tmp | \
# match for the parts we're interested in and output just the bits that match:
$grep -Po '\busing\s+namespace\s+std\s*;'
)
# detect any instances of std::abs (outside of the SFINAE call in core/types.h):
if [[ ! "$f" -ef "core/types.h" ]]; then
res="$res"$(
cat .check_syntax.tmp | \
# match for the parts we're interested in and output just the bits that match:
$grep -Po '(?<!::)std::abs\b'
)
fi
# detect any instances of %zu in a print() call (not supported on MSYS2):
res="$res"$(
cat .check_syntax2.tmp | \
# match for the parts we're interested in and output just the bits that match:
$grep -Po '\w*print\w*.*?%\d?zu\b' |
$grep -Po '\w*print(?!.*?print).*?$'
)
# delete intermediate files
rm -f .check_syntax.tmp .check_syntax2.tmp
# if anything is left after that, show it:
if [[ ! -z $res ]]; then
echo "################################### $f" >> $LOG
echo "$res" >> $LOG
retval=1
fi
done
# set exit code:
if [[ $retval == 0 ]]; then
echo "OK"
echo "no issues detected" >> $LOG
else
echo "FAIL (see syntax.log for details)"
echo "" >> $LOG
echo "Please check the following syntax requirements:
- Add MEMALIGN() or NOMEMALIGN macro to any class declarations identified above;
- Replace all occurrences of std::vector<> with MR::vector<> (or just vector<>);
- Avoid use of std::make_shared();
- Replace all instances of std::abs() with MR::abs() (or just abs());
- Replace all instances of %zu in print() calls with PRI_SIZET." >> $LOG
exit 1
fi
|