#!/bin/bash # # Cours "Sémantique et Application à la Vérification de programmes" # # Josslin Giet 2021 # Ecole normale supérieure, Paris, France / CNRS / INRIA # shopt -s lastpipe RED="\e[91m" GREEN="\e[92m" BOLD="\e[1m" RESET="\e[0m" BLUE="\e[94m" fill=" " # Default solver path. You can change it if you need analyzer_path=$1 analyzer=$analyzer_path/analyzer options=$analyzer_path/options.txt result_folder="results" index_html="${result_folder}/index.html" nb_test=0 timeout=0 failure=0 completness=0 soundness=0 # max time allowed max_time="5s" all_opts="$2" if [ "$all_opts" != "" ]; then echo "Launching code with extra options: '${all_opts}'" fi # Pattern for failure in log patt_assert="line [0-9]*: Assertion failure" # Pattern for expêctyed failure in file patt_ko="assert.*//@KO" create_file() { file=$1 filename=$(basename $file) file_html="${result_folder}/${filename}.html" if [[ ! -e "$file_html" ]] then cat "scripts/header.html" > $file_html sed -i "s@TITLE@${filename}@" $file_html echo "" >> $file_html echo "" >> $file_html echo "" >> $file_html echo "

${filename}

" >> $file_html echo "
" >> $file_html cat $file >> $file_html echo "
" >> $file_html file_svg=$(basename ${file})".svg" echo "\"graph\"" >> $file_html fi } end_file() { # After the analysis the cfg.dot should correspond to the current test dot -Tsvg cfg.dot -o ${result_folder}/${filename}.svg cat "scripts/footer.html" >> $file_html } get_nth_line() { line=$1 file=$2 sed "${line}q;d" $file } treat_file() { file=$1 log=$2 expected_folder=$3 need_new_line=true sound_loc=0 compl_loc=0 col_sound="green" col_compl="green" # first, we compute the expected failures if [[ "$expected_folder" == "" ]] then nb_expected=$(grep -n "${patt_ko}" $file| wc -l) expected=$(grep -n "${patt_ko}" $file | grep -o "^[0-9]*") else file_folder=$(dirname $file) file=$(basename $file) res="${file_folder}/${expected_folder}/${file}.log" nb_expected=$(grep "${patt_assert}" $res | wc -l) expected=$(grep "${patt_assert}" $res | grep -o "line [0-9]*" | grep -o "[0-9]*") fi # then, we compute the failed assertions nb_failures=$(grep "${patt_assert}" $log| wc -l) failures=$(grep "${patt_assert}" $log | grep -o "line [0-9]*" | grep -o "[0-9]*") echo "

Expected: ${expected}

" >> $file_html echo "

Failures: ${failures}

" >> $file_html # echo -e "\nnb_expected: ${nb_expected}" # echo -e "expected:\n--\n${expected}\n--" # echo -e "nb_failures: ${nb_failures}" # echo -e "failures:\n--\n${failures}\n--" # Soundness part: for line number in expected, # we search for it in failures for nb in `seq 1 $nb_expected`; do cmd="echo \"${expected}\" | head -${nb} | tail -1" line_nb=$(eval "${cmd}") echo "${failures}" | grep -q "^${line_nb}$" found=$? if [[ $found -ne 0 ]] then line=$(get_nth_line $line_nb $file) col_sound="red" soundness=$((soundness+1)) sound_loc=$((sound_loc+1)) if [ "$need_new_line" = true ] then echo -e "\n${BOLD}${RED} SOUNDNESS ERRORS${RESET}" need_new_line=false else echo -e "${BOLD}${RED} SOUNDNESS ERRORS${RESET}" fi echo -e "${RED}missing fail assertions:${RESET}${line}" echo "

${line_nb}${line}

" >> $file_html fi done # Completness part: for each line number in failures, # we search for it in expected for nb in `seq 1 $nb_failures`; do cmd="echo \"${failures}\" | head -${nb} | tail -1" line_nb=$(eval "${cmd}") echo "${expected}" | grep -q "^${line_nb}$" found=$? if [[ $found -ne 0 ]] then completness=$((completness+1)) compl_loc=$((compl_loc+1)) col_compl="blue" line=$(grep "${patt_assert}" $log | head -${nb} | tail -1) if [ "$need_new_line" = true ] then echo -e "\n${BOLD}${BLUE} COMPLETNESS ERROR${RESET}" need_new_line=false else echo -e "${BOLD}${BLUE} COMPLETNESS ERROR${RESET}" fi echo -e "${BLUE}unexpected fail assertions:${RESET} ${line}" echo "

${line}

" >> $file_html fi done echo "

LOG

" >> $file_html echo "
" >> $file_html
  cat $log >> $file_html
  echo "
" >> $file_html if [ "$need_new_line" = false ] then echo -e "" fi echo -n "" >> $index_html echo -n "${sound_loc}, " >> $index_html echo -n "${compl_loc}" >> $index_html echo "" >> $index_html } treat_examples() { folder="examples/${1}" bench_name=$2 options="$3 $all_opts" # analyzer CLI options expected_folder=$4 # subfolder containing expected result bench_regexp="${folder}/*.c" nb_file=$(find $folder -iname "*.c" | wc -l) nb_test=$(( nb_test + nb_file )) if [[ $nb_file -eq 0 ]] then echo "bench ${bench_name}: No files found (${bench_regexp})" return fi echo "${bench_name} ${options}" >> $index_html for file in $(find "${folder}" -iname "*.c" | sort) do filename=$(basename $file) create_file $file echo "
${filename}
" >> $index_html echo "" >> $index_html solved=$(($solved+1)) echo -ne "\r\t$file $option $fill" opt_replaced=$(echo "${options}" | sed "s/ /_/g") log="${result_folder}/${filename}.${opt_replaced}.txt" echo "

${analyzer} ${options}

" >> $file_html timeout $max_time $analyzer $options $file > $log 2>&1 out=$? if [[ $out -eq 127 ]] then timeout=$((timeout+1)) echo "TO" >> $index_html echo "TO" >> $file_html echo -e "\n ${BOLD}${RED}TO ${RESET}\n" echo "

LOG

" >> $file_html echo "
" >> $file_html
      cat $log >> $file_html
      echo "
" >> $file_html elif [[ $out -ne 0 ]] then failure=$((failure+1)) echo "FAIL" >> $index_html echo "FAIL" >> $file_html echo -e "\n ${BOLD}${RED}FAILED ($out) ${RESET}\n" echo "

LOG

" >> $file_html echo "
" >> $file_html
      cat $log >> $file_html
      echo "
" >> $file_html else treat_file $file $log $expected_folder fi echo "" >> $index_html echo "" >> $index_html end_file $file done } print_end() { echo " " echo -e " test:\t${nb_test} (files: ${total})" if [[ $timeout != 0 ]] then echo -e " ${BOLD}Timeout${RED}\tKO (${timeout}) ${RESET}" fi if [[ $failure != 0 ]] then echo -e " ${BOLD}Failure${RED}\tKO (${failure}) ${RESET}" fi if [[ $soundness != 0 ]] then echo -e " ${BOLD}Soudness${RED}\tKO (${soundness}) ${RESET}" else echo -e " ${BOLD}Soudness${GREEN}\tOK ${RESET}" fi if [[ $completness != 0 ]] then echo -e " ${BOLD}Completness${RED}\tKO (${completness}) ${RESET}" else echo -e " ${BOLD}Completness${GREEN}\tOK ${RESET}" fi echo -e "${BOLD}${BLUE}Results written in${RESET}: ${index_html}" } mkdir ${result_folder} cat "scripts/header_main.html" > $index_html echo "

Overview

" >> $index_html echo "" >> $index_html total=$(find $bench -iname "*.c" | wc -l) solved=0 treat_examples "bool" "Boolean operations" "--domain constants" "" treat_examples "bool" "Boolean operations" "--domain interval" "" treat_examples "constant" "Constants operations" "--domain constants" "" treat_examples "constant_loop" "Constants loops" "--domain constants" "" treat_examples "constant" "Constants operations (I)" "--domain interval" "" treat_examples "interval" "Interval operations" "--domain interval" "" treat_examples "constant_loop" "Constants loops (I)" "--domain interval" "" treat_examples "interval_loop" "Interval loops" "--domain interval" "" treat_examples "sign" "Sign and misc." "--domain signs" "" treat_examples "congruence" "Congruence operations" "--domain congruence" "" treat_examples "disjunction" "Disjunctive analysis" "--domain congruence" "" treat_examples "karr" "Karr's domain" "--domain karr" "" echo "
" >> $index_html echo "" >> $index_html echo "" >> $index_html print_end