#!/bin/bash ScriptFile=$(readlink -f "${BASH_SOURCE[0]}") ScriptDir=$(dirname "${ScriptFile}") SearchDir="${ScriptDir}" FileExts="h;in;hpp;inl;c;cpp;make;cmake;txt;json;js;jsx;ts;tsx;html;tpl;css" Verbose=0 function Log() { printf "$@\n" } function Error() { >&2 printf "$@\n" } function Panic() { Error "$@" exit 1 } function PrintHelp() { printf " This is a tool to calculate the number of code lines within a certain folder. The tool looks for a 'CMakeLists.txt' or a 'Makefile' in the subfolders. If such a file exists, the folder is treated as subproject. Subprojects have their own counters. Parameters: -d|--dir Directory to search in (default ${SearchDir}). -e|--ext File extension to look for (default: ${FileExts}) -v|--verbose Verbose output (Print lines of code for each file extension) (default: false) -?|-h|--help Print this help. " } # Parse arguments while [ $# -gt 0 ]; do case $1 in "-d" | "--dir" ) if [ $# -lt 2 ]; then Panic "Parameter $1 expects exactly one parameter!" fi SearchDir=$(readlink -m "$2") shift ;; "-e" | "--ext" ) if [ $# -lt 2 ]; then Panic "Parameter $1 expects exactly one parameter!" fi FileExts="$2" shift ;; "-v" | "--verbose" ) Verbose=1 ;; "-h" | "-?" | "--help" ) PrintHelp exit 0 ;; * ) Panic "Invalid or unknown parameter: $1" ;; esac shift done OLD_IFS=${IFS} IFS=';' read -ra Exts <<< "${FileExts}" IFS=${OLD_IFS} Projects="$(find ${SearchDir} -type d -exec sh -c 'test -f "$1/CMakeLists.txt" || test -f "$1/Makefile"' -- {} \; -print -prune)" First=1 declare -A ExtLines TotalLines=0 echo "=======================================" echo "= Lines of Code =" echo "=======================================" for Project in ${Projects[@]}; do Name=${Project#"$SearchDir"} if [ "$Verbose" -eq 1 ]; then if [ "$First" -eq 1 ]; then echo "_______________________________________" fi printf "%-30s\n" "${Name:-root}:" echo " \`+-----------------------------------" fi ProjectLines=0 for ext in "${Exts[@]}"; do Lines=$(find ${Project} \ -type f \ -iname *.${ext} \ 2>/dev/null \ | xargs cat 2>/dev/null \ | wc -l) if [ "$Verbose" -eq 1 ] && [ "$Lines" -gt 0 ]; then printf " |%-26s %8d\n" "${ext}" ${Lines} fi if [ "$First" -eq 1 ]; then ExtLines[$ext]=$Lines else let ExtLines[$ext]=${ExtLines[$ext]}+${Lines} fi let ProjectLines=${ProjectLines}+${Lines} done if [ "$Verbose" -eq 1 ]; then echo " +-----------------------------------" printf " |%-26s %8d\n" "total:" ${ProjectLines} else printf "%-30s %8d\n" "${Name:-root}:" ${ProjectLines} fi First=0 let TotalLines=${TotalLines}+${ProjectLines} done echo "=======================================" if [ "$Verbose" -eq 1 ]; then printf "%-30s\n" "total:" echo " \`+-----------------------------------" for ext in "${Exts[@]}"; do if [ "${ExtLines[$ext]}" -gt 0 ]; then printf " |%-26s %8d\n" "${ext}" ${ExtLines[$ext]} fi done echo " +-----------------------------------" printf " |%-26s %8d\n" "total:" ${TotalLines} else printf "%-30s %8d\n" "total:" ${TotalLines} fi echo "======================================="