summaryrefslogtreecommitdiff
path: root/tools/mpfrlint
blob: b6a6f898b62321dc147aea0a40723fd1b68ecd31 (plain)
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
#!/usr/bin/env bash

# Check possible problems in the MPFR source.

# mpfrlint can be run from the tools directory
dir=`pwd`
[ -d src ] || [ "`basename "$dir"`" != tools ] || cd ..

grep '^# *include *<math\.h>' src/*.c

grep -E 'mpfr_(underflow|overflow|nanflag|inexflag|erangeflag)_p' src/*.{c,h} | \
  grep -v 'mpfr_clear_' | \
  grep -v '^src/exceptions.c:' | \
  grep -v '^src/mpfr-impl.h:#define mpfr_.*_p()' | \
  grep -v '^src/mpfr.h:__MPFR_DECLSPEC '

grep -E 'if +(test|\[).* == ' acinclude.m4 configure.ac
grep -E '="`' acinclude.m4 configure.ac

srctests=`find src tests -name '*.[ch]'`

grep GMP_LIMB_BITS $srctests

grep GMP_RND $srctests | grep -v '#define GMP_RND'

grep -E 'mp_(src)?ptr' $srctests

# Do not use __mpfr_struct structure members in .c files.
grep -E '[^0-9a-z_]_mpfr_(prec|sign|exp|d)' {src,tests}/*.c

for i in exp prec rnd
do
  grep mp_${i}_t {src,tests}/*.{c,h} | \
    grep -v "\(# *define\|# *ifndef\|typedef\) *mp_${i}_t" | \
    grep -v "\[mp_${i}_t\]"
done

sp="[[:space:]]*"
grep "MPFR_LOG_MSG$sp($sp($sp\".*\"$sp)$sp)$sp;" $srctests

# Do not use snprintf as it is not available in ISO C90.
# Even on platforms where it is available, the prototype
# may not be included (e.g. with gcc -ansi), so that the
# code may be compiled incorrectly.
grep '[^a-z_]snprintf *([^)]' $srctests

# Constant checking should use MPFR_ASSERTN, not MPFR_ASSERTD.
# This test is a heuristic.
grep 'MPFR_ASSERTD[^a-z]*;' src/*.c

# ASSERT and ASSERT_ALWAYS must not be used for assertion checking.
# Use MPFR_STAT_STATIC_ASSERT for static assertions, otherwise either
# MPFR_ASSERTD (debug mode / hint for the compiler) or MPFR_ASSERTN.
grep -E '[^_]ASSERT(_ALWAYS)? *(\(|$)' {src,tests}/*.c

# Use MPFR_TMP_LIMBS_ALLOC.
grep 'MPFR_TMP_ALLOC.*\(BYTES_PER_MP_LIMB\|sizeof.*mp_limb_t\)' src/*.c

for file in $srctests */Makefile.am acinclude.m4 configure.ac
do
  # Note: this is one less that the POSIX minimum limit in case
  # implementations are buggy like POSIX examples. :)
  perl -ne "/.{2047,}/ and print \
    \"Line \$. of file '$file' has more than 2046 bytes.\n\"" "$file"
done

# In general, one needs to include mpfr-impl.h (note that some platforms
# such as MS Windows use a config.h, which is included by mpfr-impl.h).
for file in src/*.c
do
  [ "$file" = src/jyn_asympt.c ] || \
    [ "$file" = src/round_raw_generic.c ] || \
    grep -q '^# *include *"\(mpfr-impl\|fits.*\|gen_inverse\)\.h"' $file || \
    echo "Missing '#include \"mpfr-impl.h\"' in $file?"
done

# "mpfr-impl.h" must not be included directly by the test programs.
# Otherwise __MPFR_WITHIN_MPFR will be defined, yielding failures
# under MS Windows with DLL.
grep --exclude=mpfr-test.h '^ *# *include *"mpfr-impl.h"' tests/*.{c,h}

# mpfr_printf-like functions shouldn't be used in the tests,
# as they need <stdarg.h> (HAVE_STDARG defined).
for file in tests/*.c
do
  sed '/#if\(def\)\? *HAVE_STDARG/,/#\(endif\|else\) .*HAVE_STDARG/d
       /\/\*.*\*\//d
       /\/\*/,/\*\//d' $file | grep -q "mpfr_[a-z]*printf" && \
    echo "$file contains unprotected mpfr_printf-like function calls"
done

grep -E '[^a-z_](m|re)alloc *\(' tests/*.c | grep -v '^tests/memory.c:'

# Check a Texinfo rule (Section "Ending a Sentence") with common words
# that end with a capital letter:
#   Use '@.' instead of a period, '@!' instead of an exclamation point,
#   and '@?' instead of a question mark at the end of a sentence that
#   does end with a capital letter.
grep -E '(LIP|MPFR?|NaN)\)?[.!?]' doc/mpfr.texi | grep -v '^\* .*::'

fdlv1="`sed -n '/Version / {
  s/.*Version //
  s/,.*//
  p
  q
  }' doc/fdl.texi`"
fdlv2="`sed -n '/GNU Free Documentation License/ {
  s/.*Version //
  s/ or.*//
  p
  q
  }' doc/mpfr.texi`"
[ "x$fdlv1" = "x$fdlv2" ] || cat <<EOF
GFDL versions differ:
   fdl.texi: $fdlv1
  mpfr.texi: $fdlv2
EOF

tools/ck-copyright-notice
which gcc > /dev/null 2> /dev/null && tools/ck-mparam

texisvnd=`LC_ALL=C TZ=UTC svn info doc/mpfr.texi 2> /dev/null | sed -n 's/Last Changed Date:.*, [0-9]* \([A-Z][a-z][a-z] [0-9][0-9][0-9][0-9]\)).*/\1/p'`
if [ $? -eq 0 ] && [ -n "$texisvnd" ]; then
  texidate=`sed -n 's/@set UPDATED-MONTH \([A-Z][a-z][a-z]\).*\( [0-9][0-9][0-9][0-9]\)/\1\2/p' doc/mpfr.texi`
  [ "$texidate" = "$texisvnd" ] || cat <<EOF
mpfr.texi's UPDATED-MONTH seems to be incorrect:
  mpfr.texi's UPDATED-MONTH: $texidate
  Last Changed Date in WC:   $texisvnd
EOF
fi

acv1="`sed -n 's/.*autoconf \([0-9.]\+\) (at least).*/\1/p' doc/README.dev`"
acv2="`sed -n 's/AC_PREREQ(\([0-9.]\+\).*/\1/p' acinclude.m4`"
[ "x$acv1" = "x$acv2" ] || cat <<EOF
autoconf minimal versions differ:
  README.dev:   $acv1
  acinclude.m4: $acv2
EOF

cd "$dir"
"`dirname -- "$0"`"/check_inits_clears

true