-
Notifications
You must be signed in to change notification settings - Fork 77
/
Copy pathincremental_avg.sh
executable file
·139 lines (125 loc) · 4.7 KB
/
incremental_avg.sh
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
#! /bin/bash
set -e # exit immediately if a command fails
set -o pipefail # or all $? in pipe instead of returning exit code of the last command only
if [ $# -lt 2 ]; then
echo "Usage: $0 <repo_path> <start_commit> [<limit of commits>]"
exit 1
fi
repo_path=${1}
repetitions=${2}
start_commit=${3}
limit=${4-"999"}
out="out"
diff_exclude=":^fonts :^tests :^chkfont.c :^getopt.c :^figfont.txt :^showfigfonts :^figmagic :^figlist :^figlet.6 :^chkfont.6 :^figlist.6
:^showfigfonts.6 :^Makefile :^Makefile.tc :^README :^CHANGES :^FAQ :^LICENSE :^run-tests.sh :^tests.sh :^.gitignore"
function git_bwd() { # checkout previous commit
git -C $repo_path checkout HEAD^
}
function git_fwd() { # checkout next commit
git -C $repo_path log --reverse --pretty=%H master | grep -A 1 $(git -C $repo_path rev-parse HEAD) | tail -n1 | xargs git -C $repo_path checkout
}
# function git_dirty {
# dir=${1-"`pwd`"};
# test -n "$(git -C $repo_path status --porcelain)"
# }
# if git_dirty "$repo_path"; then
# echo "The repository is not in a clean state. Abort!"
# exit 1
# fi
if [ ! -f scripts/incremental.sh ]; then
echo "Please run from root of analyzer repo."
exit 1
fi
if [ ! -f goblint ]; then
echo "Binary goblint is missing!"
exit 1
fi
function finish {
rm -rf goblint_temp_*
}
trap finish EXIT
outp=$out/$(basename $repo_path)
rm -rf "$outp"
function log {
echo "$*" | tee -a $outp/incremental.log
}
mkdir -p "$outp"
log $(date)
j=0
while
loc=$(git -C $repo_path diff --shortstat 4b825dc642cb6eb9a060e54bf8d69288fbee4904 $start_commit -- . $diff_exclude)
git checkout master
git -C $repo_path checkout $start_commit
rm -r $repo_path/.gob
i=1
prev_commit=''
echo -e "index\tcommit\tl_ins\tl_del\tl_max\ttime\tvars\tevals\tchanged\tadded\tremoved\tchanged_start\tnew_start" >> $outp/incremental_runtime_$j.log
while
commit=$(git -C $repo_path rev-parse HEAD)
if [ "$commit" = "$prev_commit" ]; then
log "Reached last commit $commit"
break
fi
if [ "$prev_commit" != '' ]; then
loc=$(git -C $repo_path diff --shortstat $prev_commit $commit -- . $diff_exclude)
echo $loc
fi
prev_commit=$commit
outc=$outp/$commit_$j
mkdir -p $outc
git -C $repo_path show > $outc/commit.patch
log "Analyze $i. commit $commit"
if [ -e "$repo_path/.gob/$commit" ]; then
log " Incremental results for this commit already exists!"
fi
files=$(git -C $repo_path diff-tree --no-commit-id --name-only --root -r $commit)
# if [ ! $(echo "$files" | grep ".*\.c$") ]; then
if ! grep ".*\.[ch]$" > /dev/null <<< "$files"; then
log " No *.c or *.h files are included in this commit!"
fi
log " All files: $(git -C $repo_path show --pretty=format:"" --shortstat $commit)"
log " *.c and *.h: $(git -C $repo_path show --pretty=format:"" --shortstat $commit -- *.c *.h)"
start=$(echo "scale=3; $(date +%s%3N) /1000" | bc)
# running it with (gtime -v ./goblint ...) doesn't react to ^C
(date && ./goblint -v --conf conf/incremental.json $repo_path/Makefile 2>&1) | tee $outc/analyzer.log
end=$(echo "scale=3; $(date +%s%3N) /1000" | bc)
runtime=$(echo "$end-$start" | bc)
log " Goblint ran $runtime seconds"
vars=$(grep 'vars = ' $outc/analyzer.log | cut -d" " -f3)
evals=$(grep 'evals = ' $outc/analyzer.log | cut -d" " -f9)
changed=$(grep 'change_info = { ' $outc/analyzer.log | cut -d" " -f9 | cut -d";" -f1)
added=$(grep 'change_info = { ' $outc/analyzer.log | cut -d" " -f12 | cut -d";" -f1)
removed=$(grep 'change_info = { ' $outc/analyzer.log | cut -d" " -f15 | cut -d";" -f1)
changed_start=$(grep 'has changed start state' $outc/analyzer.log | wc -l)
new_start=$(grep 'New start function' $outc/analyzer.log | wc -l)
l_ins=0
l_del=0
if [[ $loc == *"insertion"* ]]; then
l_ins=$(echo $loc | cut -d" " -f4)
if [[ $loc == *"deletion"* ]]; then
l_del=$(echo $loc | cut -d" " -f6)
fi
else
if [[ $loc == *"deletion"* ]]; then
l_del=$(echo $loc | cut -d" " -f4)
fi
fi
if [[ $l_ins < $l_del ]]; then
l_max=$l_del
else
l_max=$l_ins
fi
echo -e "$i\t$commit\t$l_ins\t$l_del\t$l_max\t$runtime\t$vars\t$evals\t$changed\t$added\t$removed\t$changed_start\t$new_start" >> $outp/incremental_runtime_$j.log
log " $(grep 'evals = ' $outc/analyzer.log)"
log " $(grep 'change_info = ' $outc/analyzer.log)"
log " Obsolete functions: $(grep 'Obsolete function' $outc/analyzer.log | wc -l)"
log " Changed start state: $changed_start"
log " New start functions: $new_start"
i="$((i+1))"
git_fwd # TODO use this as exit condition
[ "$i" -lt "$limit" ]
do :; done
j=$((j+1))
[ $j -lt $repetitions ]
do :; done
log $(date)