forked from bsletten/rootbeer1
-
Notifications
You must be signed in to change notification settings - Fork 4
/
Copy pathfindCommitFromTrace
152 lines (135 loc) · 5.77 KB
/
findCommitFromTrace
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
# File Name: findCommitFromTrace
#
# findCommitFromTrace --short develop \
# src/soot/SootMethod.java getBodyFromMethodSource 324 \
# src/soot/SootMethod.java getBody 91 \
# src/soot/coffi/CoffiMethodSource.java getPhaseOptions 49 \
# src/soot/PhaseOptions.java getPM 49 \
# src/soot/PhaseOptions.java v 39 \
# src/soot/PackManager.java soot_PackManager 344 \
# src/soot/Singletons.java PackManager 472 \
# src/soot/PackManager.java DexPrinter 529
#
# findCommitFromTrace --short pfuscherei \
# src/org/trifort/rootbeer/runtime/Serializer.java doReadFromHeap 155 \
# src/org/trifort/rootbeer/runtime/CUDAContext.java readFromHeap 452 \
# src/org/trifort/rootbeer/runtime/CUDAContext.java readBlocksList 332 \
# src/org/trifort/rootbeer/runtime/CUDAContext.java onEvent 308
# soot/rbclassload/RootbeerClassLoader/loadScene (RootbeerClassLoader.java:857)
# soot/rbclassload/RootbeerClassLoader/loadNecessaryClasses (RootbeerClassLoader.java:320)
verbose=1
goUp='\n'
if [ "$1" == '--short' ]; then
verbose=0
goUp='\r'
shift
fi
branch=$1 # Note: you can use --all
shift
echo "Searching on branch: $branch"
function assert() { if [ ! $? -eq 0 ];then echo "Assert failed at line $1!"; fi }
if [ ! $(( $# % 3 )) -eq 0 ]; then
echo -e "\e[31mNumber of arguments must be a multiple of 3: findCommitFromTrace (<file> <match> <line>)*\e[0m"
exit
fi
args=( "$@" )
if [ ! $# -eq ${#args[@]} ]; then
echo -e "\e[31mSomething went wrong when copying arguments to array\e[0m"
exit
fi
stringContains() {
#echo " String to test: $1"
#echo " Substring to test for: $2"
[ -z "${1##*$2*}" ] && [ ! -z "$1" ]
}
lastMatchedCommits=()
newMatchedCommits=()
# Try to match a method call at the given line in a given file, collect all
# matchong commits.
# For the next rule, collect all commits which where matched last and also
# matches now
# As we only test commits which actually changed the file, we also need to
# testadd all inbetween
initialCommit=$(git rev-parse HEAD)
for (( iArg=0; 3*iArg<${#args[@]}; ++iArg )); do
{
file=${args[ 3*iArg + 0 ]}
keyword=${args[ 3*iArg + 1 ]}
lineNumber=${args[ 3*iArg + 2 ]}
if [[ ! "$line" =~ [0-9]* ]]; then
echo -e "\e[31mThe specified line number ($lineNumber) contains some non-digits.\e[0m"
exit
fi
git checkout -f "$initialCommit" -- "$file"
commits=( $(git log --oneline $branch -- "$file" | sed 's| .*||' ) )
echo -e "\e[35mTrying to find matches for $file:$lineNumber with '$keyword'\e[0m"
lastWasMatched=""
for (( i=0; i<${#commits[@]}; ++i )); do
{
git checkout -f "${commits[i]}" -- "$file" 2>/dev/null
# if match found
if sed -n "${lineNumber}p" "$file" | grep -q "$keyword"; then
{
matchString=$(sed -n "${lineNumber}{ s|^[ \t]*||; p; }" "$file")
echo -ne "\e[32m ${commits[i]}"
printf "%$((70-${#matchString}))s\n" ' '
echo -ne "\e[0m"
# the first matches are always added
if [ $iArg -eq 0 ]; then
{
# add all commits between last positive and this positive
# (note that we only tested commits which actually changed
# the currently specified file)
if [ -n "$lastWasMatched" ]; then
newMatchedCommits+=( $(git log --oneline $branch | sed -n "/${commits[i-1]}/,/${commits[i]}/"'{ s| .*||p; }') )
else
newMatchedCommits+=( ${commits[i]} )
fi
}
else
{
newCommitCandidates=()
if [ -n "$lastWasMatched" ]; then
newCommitCandidates+=( $(git log --oneline $branch | sed -n "/${commits[i-1]}/,/${commits[i]}/"'{ s| .*||p; }') )
if [ $verbose -eq 1 ]; then
echo " newCommitCandidates = ${newCommitCandidates[@]}"
fi
else
newCommitCandidates+=( ${commits[i]} )
fi
# check if matching commits were already found, if so add them
for (( iCommitCandidate=0; iCommitCandidate<${#newCommitCandidates[@]}; ++iCommitCandidate )); do
{
commit=${newCommitCandidates[iCommitCandidate]}
if stringContains "${lastMatchedCommits[*]}" "$commit"; then
newMatchedCommits+=( ${newCommitCandidates[iCommitCandidate]} )
else
echo -ne "\e[33m Testing match $commit [$((iCommitCandidate+1))/${#newCommitCandidates[@]}]: commit not found before -> skipping\e[0m$goUp"
fi
}
done
echo '' # line break to see last Testing message
}
fi
lastWasMatched=${commits[i]}
}
else
# No match found
echo -ne " \e[37m${commits[i]}\e[0m"; printf "%60s$goUp" ' '
lastWasMatched=''
fi
shift
}
done
echo -e "The commits matching all specified criteria are up till now ($((iArg+1))) are:\n \e[32m${newMatchedCommits[@]}\e[0m"
[ ${#lastMatchedCommits[@]} -ge ${#newMatchedCommits[@]} ]
echo "last matches: ${#lastMatchedCommits[@]} <-> new matches: ${#newMatchedCommits[@]}"
assert $LINENO
# swap arrays lastMatchedCommits with newMatchedCommits
[ ${#lastMatchedCommits[@]} -eq ${#lastMatchedCommits[@]} ]
assert $LINENO
lastMatchedCommits=( "${newMatchedCommits[@]}" )
newMatchedCommits=()
}
done