# to be sourced by bash

### firmware

function list_fw_official_calls_with_disc_dup()
{
    cut -f 2 -d "," <all_fw_calls_official_list.csv
}

function list_fw_official_calls_dedup()
{
    list_fw_official_calls_with_disc_dup | grep -v DISC
}

# [shell - Remove duplicate entries using a Bash script - Stack Overflow](https://stackoverflow.com/questions/9377040/remove-duplicate-entries-using-a-bash-script/9377125#9377125 "shell - Remove duplicate entries using a Bash script - Stack Overflow")
function list_fw_official_packages()
{
    list_fw_official_calls_with_disc_dup | cut -f 1 -d " " | awk '!a[$0]++'
}

function list_fw_official_calls_in_package()
{
    list_fw_official_calls_dedup | grep "$1"
}

TOTAL_FW_CALL_COUNT=$( list_fw_official_calls_dedup | wc -l )

### C-level

function list_c_prototypes() {
    egrep -ih '^[a-z].* \*?fw_.*(.*).*;' include/cfwi/*.h
}

function prototype_line_to_bare_prototype
{
    sed -e 's/ __[^(]*([^)]*)//g' | sed -e 's/ __[^ ;]*//g'
}

function list_c_function_names() {
    list_c_prototypes | prototype_line_to_bare_prototype | sed -n "s/^.* \**\(fw_[^(]*\)(.*$/\1/p"
}

function list_fw_calls_c_style()
{
    list_c_function_names | sed "s/__[^ (]*$//" | sed 's/^fw_//' | uniq
}

TOTAL_C_DECLARED_FW_FUNCTION_NAMES=$( list_fw_calls_c_style | wc -l )

function list_c_covered_fw_calls() {
    list_c_function_names | sed "s/__fastcall//" | uniq
}

TOTAL_C_DECLARED_FW_CALL_COUNT=$( list_fw_calls_c_style | wc -l )

### Conversions

# When processing in bash, prefer to convert to c-style to avoid
# complexity with space non-separators.

function c_style_names_to_tradi_names()
{
    #    echo "$1" | sed 's/_/ /g' | tr '[a-z]' '[A-Z]'
    sed 's/_/ /g' | tr '[a-z]' '[A-Z]'
}

function tradi_names_to_c_style_names()
{
    sed 's/ /_/g' | tr '[A-Z]' '[a-z]'
}

### assembly

function list_asm_symbols()
{
    sed -n "s/^.*_\(fw_[^: ]*\).*$/\1/p" src/*.s
}

function list_asm_calls()
{
    list_asm_symbols | sed "s/__[^ (]*$//" | sed 's/^fw_//' | uniq
}




### no-wrappers

function nowrappers_lines()
{
    grep "^.*_fw_[a-z_]* *== *0x.*$" src/fw_nowrapperneeded.s
}

function list_fw_nowrapper_symbols()
{
    sed -n "s|^.*_\(fw_[a-z_]*\) *== *0x.*$|\1|p" src/fw_nowrapperneeded.s
}

TOTAL_FW_NOWRAPPER_COUNT=$( nowrappers_lines | wc -l )

### wrappers

function list_fw_wrapper_files()
{
    ls -1b src/fw_*.s | grep -v fw_nowrapperneeded
}

TOTAL_FW_WRAPPER_COUNT=$( list_fw_wrapper_files | wc -l )

function list_fw_wrapper_symbols()
{
    cat src/fw_*.s | sed -n "s|^.*\(_fw[^:]*\)::|\1|p"
}

### both

function list_c_covered_fw_calls_with_and_without_wrapper()
{
    list_c_function_names | sed -n "s/^\(.*\)__fastcall$/\1/p"
}

TOTAL_FW_TWICE_COVERED_COUNT=$( list_c_covered_fw_calls_with_and_without_wrapper | wc -l )

########################################################################


function in_package_count()
{
    egrep -i "(^|_)${PACKAGE}_" | wc -l
}


function report_implementation_asm()
{
    SYMBOL="$1"
    SYMBOL_CALL_NAME="$( echo ${SYMBOL} | sed 's/__.*//' )"
    ASM_SYMBOL="_${SYMBOL}"

    declare -a ERRORS

    declare -a OUTPUTS
    
    IMPLEMENTATIONS=0

    FILES_CONTAINING=( $( egrep -l "^\s*${ASM_SYMBOL}(::| *==)" src/*.s || true ) )
    FILES_CONTAINING_COUNT=${#FILES_CONTAINING[@]}
    
    case ${FILES_CONTAINING_COUNT} in
	0)
	    ERRORS+=( "No implementation: $ASM_SYMBOL" )
	    ;;
	1)
	    true
	    ;;
	*)
	    ERRORS+=( "Several occurrences: $FILES_CONTAINING_COUNT" )
    esac

    set +u
    
    for FILE_CONTAINING in "${FILES_CONTAINING[@]}"
    do
	if [[ "${FILE_CONTAINING}" == "src/fw_nowrapperneeded.s" ]]
	then
	    OUTPUTS+=( "<div class=\"direct\"><code>$( grep $ASM_SYMBOL $FILE_CONTAINING )</code></div>" )
	    continue
	fi

	if [[ "${FILE_CONTAINING}" != "src/${SYMBOL_CALL_NAME}.s" ]]
	then
	    ERRORS+=( "Not in expected file: $FILE_CONTAINING" )
	fi

	RELFILE=src/${SYMBOL_CALL_NAME}.rel
	
	SIZE=$( sed -n "s|^A _CODE size \([0-9A-F]*\) flags 0 addr 0$|\1|p" <"$RELFILE" )

	if [[ -n "$SIZE" ]]
	then
	    OUTPUTS+=( "<div class=\"wrapper\"><a href="${FILE_CONTAINING}"><code>$ASM_SYMBOL</code></a> (wrapper, $( printf %d 0x$SIZE ) bytes)</div>" )
	fi
	
   done

    set -u
    
    echo "<td>"

    set +u
    
    for ERROR in "${ERRORS[@]}"
    do
	echo "<div class=\"error\">${ERROR}</div"
    done

    for OUTPUT in "${OUTPUTS[@]}"
    do
	echo "<div class=\"output\">${OUTPUT}</div"
    done

    set -u
    
    echo "</td>"
}
