File: detect

package info (click to toggle)
widelands 1%3A12-3
  • links: PTS, VCS
  • area: main
  • in suites: lenny
  • size: 118,052 kB
  • ctags: 9,799
  • sloc: cpp: 71,051; python: 1,368; ada: 444; sh: 292; makefile: 282; objc: 274
file content (126 lines) | stat: -rwxr-xr-x 4,425 bytes parent folder | download
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
#!/bin/bash
#
#  Detects style errors in the C++ source code. Run this from the top directory
#  (which has the subdirectories build, src and utils).
#
#  The output may include colour codes if and only if standard output is a
#  terminal.
#
#  Several check commands are used:
#  * grep with a set of regular expressions
#  * whitespace_checker (with detect_spurious_indentation.py as an inferior
#    fallback)
#
#  Results are cached (there are separate caches for colour/nocolour). The
#  check commands do not write directly to a file at the cahce file location
#  because that could leave behind an incomplete cache file that is newer than
#  the source file in case that the check commands are interrupted. Instead
#  write the output from the check commands to a temporary file and when that
#  file is complete, move it to the cache file location.
#
#  Instead of storing empty cache files for source files that do not give any
#  errors, a per-directory timestamp file is stored. This drastically reduces
#  the number of cache files. The drawback is that if the script is interrupted
#  whilst checking a sequence of files with equal mtime, it will have to start
#  over with that sequence the next time it is executed. But reducing the
#  number of cache files is worth that minor inconvenience.

CHECKER=utils/spurious_source_code/whitespace_checker
if [ ! -f $CHECKER ]; then
	echo "WARNING: $CHECKER does not exist!"
	echo "WARNING:    Go to utils/spurious_source_code and build it with make!"
	echo "WARNING:    Else many checks will be done much slower or not at all!"
	unset CHECKER
fi

#  Make sure that several instances of this script running concurrently each
#  have a separate temporary directory.
TMP_DIR=/tmp/spurious_source_code_detect.$PPID
rm -fr $TMP_DIR
mkdir $TMP_DIR || { echo "ERROR: could not create $TMP_DIR"; exit; }


REGEXPS_FILE=$TMP_DIR/regexps
for r in utils/spurious_source_code/regexps/*; do
	[[ -d $r && ! -f $r/disabled && ( ! $CHECKER || ! -f $r/redundant_with_whitespace_checker ) ]] &&
		cat $r/regexps >> $REGEXPS_FILE
done


[[ -t 1 ]] && COLOUR=.colourized || unset COLOUR


RESULT_FILE=$TMP_DIR/result

#  Runs all checks on single source file. The result is written to
#  $RESULT_FILE.
#
#  Requirements on the result:
#  * Error message lines must begin with <filename>:<linenumber> so that they
#    can be parsed by tools like KDevelop.
#  * Any colour codes produced by commands like "grep --colour" must be
#    included if and only if $COLOUR is set.
#
#  Parameters:
#    $1
#      The name of the source file to be checked.
function check {
	egrep --with-filename --line-number $([ $COLOUR ] && echo --colour=always) -f $REGEXPS_FILE $1 >  $RESULT_FILE
	([[ $CHECKER ]] && $CHECKER $1 || utils/detect_spurious_indentation.py $1)                     >> $RESULT_FILE
}


CACHE_DIR="build/stylecheck"

#  Detects errors recursively and stores the result in a cache. The cache
#  content (if any) is echoed to standard output.
#
#  If a cached entry exists and is not older than the source file, no checks
#  are done on that source file.
#
#  Calls itself recursively for each subdirectory. Then checks all the source
#  files in the current directory that are newer than the timestamp file there.
#  Files are checked in mtime order, oldest first. After checking group of
#  files that have the same mtime, the timestamp is is set to that mtime.
#
#  Parameters:
#    $1
#      The name of the directory to start the search and check in.
function detect {
	mkdir -p $CACHE_DIR/$1
	for d in $1/*; do
		[[ -d $d ]] && detect $d
	done
	TIMESTAMP=$CACHE_DIR/$1/timestamp
	PREVIOUS_FILE=$1
	for f in $(ls -tr $1/*.h $1/*.cc 2>/dev/null); do
		CACHE_BASE=$CACHE_DIR/$f.stylecheck
		CACHE_COLOUR=$CACHE_BASE.colourized
		CACHE=$CACHE_BASE$COLOUR
		if [[ $f -nt $TIMESTAMP || -s $CACHE_BASE || -s $CACHE_COLOUR ]]; then
			if [ $f -nt $CACHE ]; then
				echo "Checking for errors in $f ..."
				check $f
				if [ -s $RESULT_FILE ]; then
					mv $RESULT_FILE $CACHE
					[[ $f -nt $PREVIOUS_FILE && $PREVIOUS_FILE -nt $TIMESTAMP ]] &&
						touch --reference=$PREVIOUS_FILE $TIMESTAMP
					cat $CACHE
				else
					rm -f $CACHE_BASE $CACHE_COLOUR
				fi
			else
				echo "Showing cached errors in $f ..."
				cat $CACHE
			fi
		fi
		PREVIOUS_FILE=$f
	done
	[[ $PREVIOUS_FILE -nt $TIMESTAMP ]] &&
		touch --reference=$PREVIOUS_FILE $TIMESTAMP
}


detect src

rm -fr $TMP_DIR