As part of my programming training, I was told to research metrics for programming. I went ahead and turned the metrics into code starting with the cyclomatic complexity by McCabe. It works for bash sourcecode which I was targeting in this example.
My approach relies heavily on the while read line to read the Code line by line.
I tried to use more Regex at first but I soon hit a wall and decided to do it this way. Im familiar with Regex but inexperienced in combining them with sed or awk. So I'd like to ditch the while read line if that is possible for this kind of problem, and general readability tips for bash scripting would also be nice (im using vim to write the code).
if [ "$1" == "" ]
then
echo "Type in file name: "
read filename
else
# $1 is the first input parameter
filename=$1
fi
counter=1
caseflag=0
casecounter=0
while read line
do
if [ "$caseflag" == "1" ]
then
if [[ $line == *"#"* ]]
then
#takes care of the comments in the SC
temp=${line%%#*}
tempcounter=$(echo $temp|awk '/;;$/{counter++}END{print counter}')
let counter=$counter+$tempcounter > /dev/null 2>&1
else
tempcounter=$(echo $line|awk '/;;$/{counter++}END{print counter}')
let counter=$counter+$tempcounter > /dev/null 2>&1
fi
fi
#loop detection
temp=`echo $line | cut -d ' ' -f1`
if [ "$temp" == "until" ] || [ "$temp" == "if" ] || [ "$temp" == "else" ] || [ "$temp" == "elif" ] || [ "$temp" == "while" ] || [ "$temp" == "for" ]
then
let counter=$counter+1
fi
#case detection
if [ "$temp" == "case" ]
then
caseflag=1
let casecounter=$casecounter+1
elif [ "$temp" == "esac" ]
then
caseflag=0
fi
done < $filename
let counter=$counter-$casecounter > /dev/null 2>&1
echo "Cyclomatic complexity score: $counter"