#! /bin/bash # # Copyright (C) KL4YFD 2013-2021 # Released under GNU GPL # # This script generates interactive HTML DOXYGEN documentation from the fldigi source tree # Checks are done to ensure needed binaries and files exist # before calling Doxygen/GitStats/CppCheck # List of all needed binaries / packages binaries=("cppcheck" "dot" "doxygen" "mscgen") packages=("cppcheck graphviz doxygen mscgen") # Change to the directory this script is in, # so all later directories can be by reference cd $( dirname ${BASH_SOURCE[0]} ) # CppCheck variables INCLUDEDIR="../../src/include" SRCDIR="../../src" CPPRESULTSDIR="HTML/results" THREADS=8 function usage { printf "\n\nThis script generates Doxygen sourcecode documentation for the Fldigi suite programs." printf "\nUnless disabled, the tool \"cppcheck\" is also called." printf "\n\nUsage:" printf "\n Generate documentation:\t ./gen_doxygen_srcdoc.sh run" printf "\n Delete all documentation:\t ./gen_doxygen_srcdoc.sh clean" printf "\n Install needed binaries:\t ./gen_doxygen_srcdoc.sh install" printf "\n Print this usage summary:\t ./gen_doxygen_srcdoc.sh help" printf "\n\n Generate documentation without CppCheck:\t ./gen_doxygen_srcdoc.sh run nocppcheck" printf "\n\n" } # Ensure that all needed binaries are present # Give a useful error, then exit if something is missing. function bincheck { missingcount=0 printf "\nChecking for needed binaries:" for i in "${binaries[@]}" do printf "\n\t$i :" if ! which $i > /dev/null ; then printf " MISSING " let missingcount++ else printf " FOUND " fi done if [ $missingcount != 0 ]; then printf "\n\nERROR: Please install the missing binaries\n" exit fi printf "\n" } # Install the required packages for Debian based systems (Ubuntu, Mint, etc) function do_install { printf "\n\nEnter the root password to auto-install the needed binaries" printf "\n NOTE: This currently only works on Debian / Ubuntu\n\n" sudo apt-get -y install $packages exit } # Cleanup all files generated by this script function do_clean { rm -Rf HTML printf "\n\nDoxygen sourcecode documentation deleted!\n\n" } # Run CppCheck, and parse the results into separate files. function do_cppcheck { mkdir $CPPRESULTSDIR cppcheck --template=cppcheck1 --inline-suppr --inconclusive --enable=all -I $INCLUDEDIR -j $THREADS --force --verbose $SRCDIR 2> $CPPRESULTSDIR/ALL.txt cd $CPPRESULTSDIR touch error.txt warning.txt style.txt performance.txt portability.txt information.txt debug.txt touch error_inconclusive.txt warning_inconclusive.txt style_inconclusive.txt performance_inconclusive.txt portability_inconclusive.txt information_inconclusive.txt touch leftover.txt # Separate out the results into files based on their "cppcheck types" cat ALL.txt | grep "(error)" > error.txt cat ALL.txt | grep "(warning)" > warning.txt cat ALL.txt | grep "(style)" > style.txt cat ALL.txt | grep "(performance)" > performance.txt cat ALL.txt | grep "(portability)" > portability.txt cat ALL.txt | grep "(information)" > information.txt cat ALL.txt | grep "(debug)" > debug.txt # Separate out the tests with inconclusive results cat ALL.txt | grep "(error, inconclusive)" > error_inconclusive.txt cat ALL.txt | grep "(warning, inconclusive)" > warning_inconclusive.txt cat ALL.txt | grep "(style, inconclusive)" > style_inconclusive.txt cat ALL.txt | grep "(performance, inconclusive)" > performance_inconclusive.txt cat ALL.txt | grep "(portability, inconclusive)" > portability_inconclusive.txt cat ALL.txt | grep "(information, inconclusive)" > information_inconclusive.txt #cat ALL.txt | grep "(debug, inconclusive)" > debug.txt # debug is for Messages from cppcheck itself, not a test-result. Therefore no such combination. # Just in case... Catch everything _not_ in the above blocks. cat ALL.txt | grep --invert-match "(error)" \ | grep --invert-match "(warning)" \ | grep --invert-match "(style)" \ | grep --invert-match "(performance)" \ | grep --invert-match "(portability)" \ | grep --invert-match "(information)" \ | grep --invert-match "(debug)" \ | grep --invert-match "(error, inconclusive)" \ | grep --invert-match "(warning, inconclusive)" \ | grep --invert-match "(style, inconclusive)" \ | grep --invert-match "(performance, inconclusive)" \ | grep --invert-match "(portability, inconclusive)" \ | grep --invert-match "(information, inconclusive)" > leftover.txt cd - > /dev/null printf "\n === CppCheck static source-code analysis complete. ===" } # Count the number of errors in each category of CppCheck results. function do_cppcheckTOTALS { RFILE="TOTALS.txt" cd $CPPRESULTSDIR # enter working subdirectory touch $RFILE # Append the counts of each error-type to this txt file echo -n "ERRORS: " >> $RFILE cat error.txt | wc -l >> $RFILE echo -n "WARNINGS: " >> $RFILE cat warning.txt | wc -l >> $RFILE echo -n "STYLE: " >> $RFILE cat style.txt | wc -l >> $RFILE echo -n "PERFORMANCE: " >> $RFILE cat performance.txt | wc -l >> $RFILE echo -n "PORTABILITY: " >> $RFILE cat portability.txt | wc -l >> $RFILE echo -n "INFORMATION " >> $RFILE cat information.txt | wc -l >> $RFILE echo -n "DEBUG: " >> $RFILE cat debug.txt | wc -l >> $RFILE ############# echo -n "INCONCLUSIVE ERRORS: " >> $RFILE cat error_inconclusive.txt | wc -l >> $RFILE echo -n "INCONCLUSIVE WARNINGS " >> $RFILE cat warning_inconclusive.txt | wc -l >> $RFILE echo -n "INCONCLUSIVE STYLE " >> $RFILE cat style_inconclusive.txt | wc -l >> $RFILE echo -n "INCONCLUSIVE PERFORMANCE " >> $RFILE cat performance_inconclusive.txt | wc -l >> $RFILE echo -n "INCONCLUSIVE PORTABILITY: " >> $RFILE cat portability_inconclusive.txt | wc -l >> $RFILE echo -n "INCONCLUSIVE INFORMATION: " >> $RFILE cat information_inconclusive.txt | wc -l >> $RFILE echo -n "LEFTOVER (UNCATEGORIZED): " >> $RFILE cat leftover.txt | wc -l >> $RFILE cd - > /dev/null # go back up one ditectory printf "\n === CppCheck TOTALS complete. ===" } # Extract ALL the patches from the branch, and save to a subdirectory function do_patches { cd HTML mkdir __git; cd __git DEPTH=$(git rev-list HEAD --count) let DEPTH-- git format-patch --summary -n HEAD~"$DEPTH" # Create patches for ALL commits git log --stat -n $DEPTH > gitlog.txt # Dump the history of ALL commits cd .. cd .. } # Get the Git commit-tags, branch-info, and commit-hash # and add this info to both: /HTML/index.html, and VERSION.TXT function do_versioninfo { TOREPLACE="000GIT_REVISION000" # search for this string in index.html and replace with git info-string VERSIONINFO=$(git log --decorate=full | head -1) # Get the full version info for current branch #sed -i "s|$TOREPLACE|
$VERSIONINFO|g" HTML/index.html # Replace placeholder string in main HTML file. sed -i "s|$TOREPLACE|
$VERSIONINFO|g" HTML/*.html # Replace placeholder string in main HTML file. echo $VERSIONINFO > HTML/VERSION.TXT # Write the Git version to a text file } ###################### # set defaults nocppcheck_flag=false # Ensure either 1 or 2 variables was passed, else give usage & exit if [[ $# -ne 2 && $# -ne 1 ]]; then usage exit fi # Parse the commandline options passed # If no options, or invalid passed, display Usage and exit case "$1" in "run") bincheck # Check that all the needed binaries are actually installed, will exit if missing ;; "clean") do_clean exit ;; "install") do_install exit ;; *) usage exit ;; esac if [[ $# -eq 2 ]]; then # Set a global variable if commandline requests a run without CppCheck case "$2" in "nocppcheck") nocppcheck_flag=true ;; *) usage exit ;; esac fi # Ensure the Doxygen config file exists, abort if missing if [ ! -e ./doxyfile.txt ]; then printf "\n\nERROR: Doxygen configuration file: \"doxyfile.txt\" not found." printf "\n\n === ABORTING === \n\n" exit 1 fi ######## # All Prep Finished: RUN ######## do_clean # delete data from previous run mkdir HTML # all files generated will be placed in this Subdirectory doxygen doxyfile.txt # Run Doxygen (also calls dot & mscgen) do_patches # Generate the last 100 patches from Git if [ "$nocppcheck_flag" != true ]; then do_cppcheck do_cppcheckTOTALS fi do_versioninfo # Write the version info to a file AND add it to Doxygen's finished index.html ######## printf "\n\n === DOXYGEN documentation generation complete. ===" printf "\n\nDocumentation Directory: $(pwd)/HTML" printf "\nMain file: $(pwd)/HTML/index.html\n\n"