-
Notifications
You must be signed in to change notification settings - Fork 182
/
check_syntax
executable file
·152 lines (128 loc) · 4.85 KB
/
check_syntax
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
#!/bin/bash
# Copyright (c) 2008-2024 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