diff options
Diffstat (limited to 'build-aux/pmccabe2html')
-rwxr-xr-x | build-aux/pmccabe2html | 902 |
1 files changed, 902 insertions, 0 deletions
diff --git a/build-aux/pmccabe2html b/build-aux/pmccabe2html new file mode 100755 index 0000000..fc47258 --- /dev/null +++ b/build-aux/pmccabe2html @@ -0,0 +1,902 @@ +#!/usr/bin/awk -f +# pmccabe2html - pmccabe to html converter + +# Copyright (C) 2007, 2008 Free Software Foundation, Inc. + +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see <http://www.gnu.org/licenses/>. + +# Written by Jose E. Marchesi <jemarch@gnu.org>. +# Adapted for gnulib by Simon Josefsson <simon@josefsson.org>. + +# Typical Invocation is from a Makefile.am: +# +# cyclo-libidn.html: +# $(PMCCABE) ${top_srcdir}/lib/*.[ch] \ +# | sort -nr \ +# | $(AWK) -f ${top_srcdir}/build-aux/pmccabe2html \ +# -v lang=html -v name="$(PACKAGE_NAME)" \ +# -v vcurl="http://git.savannah.gnu.org/gitweb/?p=libidn.git;a=blob;f=%FILENAME%;hb=HEAD" \ +# -v url="http://www.gnu.org/software/libidn/" \ +# -v css=../../build-aux/pmccabe.css \ +# > tmp +# mv tmp $@ +# +# The variables available are: +# lang output language, either 'html' or 'wiki' +# name project name +# url link to project's home page +# vcurl URL to version controlled source code browser, +# a %FILENAME% in the string is replaced with the relative +# source filename +# css CSS stylesheet filename, included verbatim in HTML output +# css_url link to CSS stylesheet, an URL + +# Prologue & configuration +BEGIN { + section_global_stats_p = 1 + section_function_cyclo_p = 1 + + # "html" or "wiki" + package_name = name + output_lang = lang + + # General Options + cyclo_simple_max = 10 + cyclo_moderate_max = 20 + cyclo_high_max = 50 + cut_dir = "/../" + source_file_link_tmpl = vcurl + + # HTML options + if (url != "") + { + html_prolog = "<a href=\"" url "\">Back to " package_name " Homepage</a><br/><br/>" + } + html_epilog = "<hr color=\"black\" size=\"2\"/> \ +Copyright (c) 2007, 2008 Free Software Foundation Inc." + html_doctype = "<!DOCTYPE html PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\" \ +\"http://www.w3.org/TR/html401/loose.dtd\">" + html_comment = "<!-- Generated by gnulib's pmccabe2html at " systime() " -->" + html_title = "Cyclomatic Complexity report for " package_name + + # Wiki options + wiki_prolog = "{{Note|This page has been automatically generated}}" + wiki_epilog = "" + + # Internal variables + nfuncs = 0; +} + +# Functions + +function build_stats() +{ + # Maximum modified cyclo + for (fcn in mcyclo) + { + num_of_functions++ + if (mcyclo[fcn] > max_mcyclo) + { + max_mcyclo = mcyclo[fcn] + } + + if (mcyclo[fcn] > cyclo_high_max) + { + num_of_untestable_functions++ + } + else if (mcyclo[fcn] > cyclo_moderate_max) + { + num_of_high_functions++ + } + else if (mcyclo[fcn] > cyclo_simple_max) + { + num_of_moderate_functions++ + } + else + { + num_of_simple_functions++ + } + } +} + +function html_fnc_table_complete (caption) +{ + html_fnc_table(caption, 1, 0, 1, 1, 1, 0, 1) +} + +function html_fnc_table_abbrev (caption) +{ + html_fnc_table(caption, 1, 0, 0, 0, 0, 0, 0) +} + + +function html_fnc_table (caption, + fname_p, + mcyclo_p, + cyclo_p, + num_statements_p, + num_lines_p, + first_line_p, + file_p) +{ + print "<table width=\"90%\" class=\"function_table\" cellpadding=\"0\" cellspacing=\"0\">" + if (caption != "") + { + print "<caption class=\"function_table_caption\">" caption "</caption>" + } + html_fnc_header(fname_p, + mcyclo_p, + cyclo_p, + num_statements_p, + num_lines_p, + first_line_p, + file_p) + for (nfnc = 1; nfnc < nfuncs; nfnc++) + { + fnc = fnames[nfnc] + html_fnc(fnc, + fname_p, + mcyclo_p, + cyclo_p, + num_statements_p, + num_lines_p, + first_line_p, + file_p) + } + print "</table>" +} + +function html_header () +{ + print html_doctype + print "<html>" + print html_comment + print "<head>" + print "<title>" html_title "</title>" + print "" + print "<meta name=\"description\" content=\"" html_title "\">" + print "<meta name=\"keywords\" content=\"" html_title "\">" + print "<meta name=\"resource-type\" content=\"document\">" + print "<meta name=\"distribution\" content=\"global\">" + print "<meta name=\"Generator\" content=\"pmccabe2html\">" + print "<meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\">" + print "<script language=\"javascript\" type=\"text/javascript\">" + print "function show_hide(idCapa, idButton, fuerzaVisibilidad)\ +{\ + var button = document.getElementById(idButton);\ + var capa = document.getElementById(idCapa);\ + if (capa)\ + {\ + if (fuerzaVisibilidad && fuerzaVisibilidad!=\"\") {\ + if (fuerzaVisibilidad==\"visible\") capa.style.display=\"\";\ + else capa.style.display=\"none\";\ + }\ + else\ + {\ + if (capa.style.display == \"none\") {\ + capa.style.display = \"\";\ + button.innerHTML = \"↑\";\ + } else {\ + capa.style.display = \"none\";\ + button.innerHTML = \"↓\"; \ + }\ + }\ + }\ +}" + print "</script>" + + + if (css_url != "") + { + print "<link rel=\"stylesheet\" href=\"" css_url "\" type =\"text/css\" media=\"screen\"/>" + } + if (css != "") + { + print "<style type =\"text/css\" media=\"screen\">" + print "<!--" + while ((getline cssline < css) > 0) + { + print cssline + } + print "-->" + print "</style />" + close(css) + } + print "</head>" + print "<body lang=\"en\" bgcolor=\"#FFFFFF\" text=\"#000000\" link=\"#0000FF\" \ +vlink=\"#800080\" alink=\"#FF0000\">" +} + +function html_footer () +{ + print "</body>" + print "</html>" +} + +function html_fnc_header (fname_p, + mcyclo_p, + cyclo_p, + num_statements_p, + num_lines_p, + first_line_p, + file_p) +{ + print "<tr class=\"function_table_header\">" + if (fname_p) + { + # Function name + print "<td class=\"function_table_header_entry\">" + print "" + print "</td>" + + print "<td class=\"function_table_header_entry\">" + print "Function Name" + print "</td>" + } + if (mcyclo_p) + { + # Modified cyclo + print "<td class=\"function_table_header_entry\">" + print "Modified Cyclo" + print "</td>" + } + if (cyclo_p) + { + # Cyclo + print "<td class=\"function_table_header_entry\">" + print "Cyclomatic" + print "<br/>" + print "Complexity" + print "</td>" + } + if (num_statements_p) + { + print "<td class=\"function_table_header_entry\">" + print "Number of" + print "<br/>" + print "Statements" + print "</td>" + } + if (num_lines_p) + { + print "<td class=\"function_table_header_entry\">" + print "Number of" + print "<br/>" + print "Lines" + print "</td>" + } + if (first_line_p) + { + print "<td class=\"function_table_header_entry\">" + print "First Line" + print "</td>" + } + if (file_p) + { + print "<td class=\"function_table_header_entry\">" + print "Source File" + print "</td>" + + } + print "</tr>" +} + +function html_fnc (fname, + fname_p, + mcyclo_p, + cyclo_p, + num_statements_p, + num_lines_p, + first_line_p, + file_p) +{ + # Function name + trclass = "function_entry_simple" + if (mcyclo[fname] > cyclo_high_max) + { + trclass="function_entry_untestable" + } + else if (mcyclo[fname] > cyclo_moderate_max) + { + trclass="function_entry_high" + } + else if (mcyclo[fname] > cyclo_simple_max) + { + trclass="function_entry_moderate" + } + + print "<tr class=\"" trclass "\">" + if (fname_p) + { + print "<td class=\"function_entry_filename\">" + if (mcyclo[fname] > cyclo_simple_max) + { + print "<a href=\"javascript:void(0);\" title=\"show/hide function source\" onClick=\"javascript:show_hide('" fname "_src', '" fname "_button')\">\ +<span id=\"" fname "_button\">↓</span></a>" + } + else + { + print " " + } + print "</td>" + + print "<td class=\"function_entry_name\">" + print fname + print "</td>" + } + if (mcyclo_p) + { + # Modified cyclo + print "<td class=\"function_entry_cyclo\">" + print mcyclo[fname] + print "</td>" + } + if (cyclo_p) + { + # Cyclo + print "<td class=\"function_entry_cyclo\">" + print cyclo[fname] + print "</td>" + } + if (num_statements_p) + { + # Number of statements + print "<td class=\"function_entry_number\">" + print num_statements[fname] + print "</td>" + } + if (num_lines_p) + { + # Number of lines + print "<td class=\"function_entry_number\">" + print num_lines[fname] + print "</td>" + } + if (first_line_p) + { + # First line + print "<td class=\"function_entry_number\">" + print first_line[fname] + print "</td>" + } + if (file_p) + { + href = "" + if (source_file_link_tmpl != "") + { + # Get href target + href = source_file_link_tmpl + sub(/%FILENAME%/, file[fname], href) + } + + # Source file + print "<td class=\"function_entry_filename\">" + if (href != "") + { + print "<a href=\"" href "\">" file[fname] "</a>" + } + else + { + print file[fname] + } + + print "</td>" + + + print "</tr>" + + if (mcyclo[fname] > cyclo_simple_max) + { + print "<tr>" + + num_columns = 1; + if (fname_p) { num_columns++ } + if (mcyclo_p) { num_columns++ } + if (cyclo_p) { num_columns++ } + if (num_statements_p) { num_columns++ } + if (num_lines_p) { num_columns++ } + if (first_line_p) { num_columns++ } + if (file_p) { num_columns++ } + + print "<td colspan=\"" num_columns "\" height=\"0\">" + print "<div id=\"" fname "_src\" class=\"function_src\" style=\"position: relative; display: none;\">" + print "<pre class=\"function_src\">" + while ((getline codeline < (fname "_fn.txt")) > 0) + { + sub(/\\</, "<", codeline) + sub(/\\>/, ">", codeline) + sub(/&/, "&", codeline) + + print codeline + } + close(fname "_fn.txt") + system("rm " fname "_fn.txt") + print "</pre>" + print "</div>" + print "</td>" + print "</tr>" + } + + } +} + +function html_global_stats () +{ + print "<div class=\"section_title\">Resume</div>" + + print "<br/>" + print "<table class=\"resume_table\">" + # Total number of functions + print "<tr>" + print "<td class=\"resume_header_entry\">" + print "Total number of functions" + print "</td>" + print "<td class=\"resume_number_entry\">" + print num_of_functions + print "</td>" + print "</tr>" + # Number of simple functions + print "<tr>" + print "<td class=\"resume_header_entry\">" + print "Number of low risk functions" + print "</td>" + print "<td class=\"resume_number_entry\">" + print num_of_simple_functions + print "</td>" + print "</tr>" + # Number of moderate functions + print "<tr>" + print "<td class=\"resume_header_entry\">" + print "Number of moderate risk functions" + print "</td>" + print "<td class=\"resume_number_entry\">" + print num_of_moderate_functions + print "</td>" + print "</tr>" + # Number of high functions + print "<tr>" + print "<td class=\"resume_header_entry\">" + print "Number of high risk functions" + print "</td>" + print "<td class=\"resume_number_entry\">" + print num_of_high_functions + print "</td>" + print "</tr>" + # Number of untestable functions + print "<tr>" + print "<td class=\"resume_header_entry\">" + print "Number of untestable functions" + print "</td>" + print "<td class=\"resume_number_entry\">" + print num_of_untestable_functions + print "</td>" + print "</tr>" + print "</table>" + print "<br/>" +} + +function html_function_cyclo () +{ + print "<div class=\"section_title\">Details for all functions</div>" + print "<p>Used ranges:</p>" + + print "<table class=\"ranges_table\">" + print "<tr>" + print "<td class=\"ranges_header_entry\">" + print " " + print "</td>" + print "<td class=\"ranges_header_entry\">" + print "Cyclomatic Complexity" + print "</td>" + print "<td class=\"ranges_header_entry\">" + print "Risk Evaluation" + print "</td>" + print "</tr>" + # Simple + print "<tr>" + print "<td class=\"ranges_entry_simple\">" + print " " + print "</td>" + print "<td class=\"ranges_entry\">" + print "0 - " cyclo_simple_max + print "</td>" + print "<td class=\"ranges_entry\">" + print "Simple module, without much risk" + print "</td>" + print "</tr>" + # Moderate + print "<tr>" + print "<td class=\"ranges_entry_moderate\">" + print " " + print "</td>" + print "<td class=\"ranges_entry\">" + print cyclo_simple_max + 1 " - " cyclo_moderate_max + print "</td>" + print "<td class=\"ranges_entry\">" + print "More complex module, moderate risk" + print "</td>" + print "</tr>" + # High + print "<tr>" + print "<td class=\"ranges_entry_high\">" + print " " + print "</td>" + print "<td class=\"ranges_entry\">" + print cyclo_moderate_max + 1 " - " cyclo_high_max + print "</td>" + print "<td class=\"ranges_entry\">" + print "Complex module, high risk" + print "</td>" + print "</tr>" + # Untestable + print "<tr>" + print "<td class=\"ranges_entry_untestable\">" + print " " + print "</td>" + print "<td class=\"ranges_entry\">" + print "greater than " cyclo_high_max + print "</td>" + print "<td class=\"ranges_entry\">" + print "Untestable module, very high risk" + print "</td>" + print "</tr>" + print "</table>" + print "<br/>" + html_fnc_table_complete("") +} + +function wiki_global_stats () +{ + print "{| class=\"cyclo_resume_table\"" + # Total number of functions + print "|-" + print "| class=\"cyclo_resume_header_entry\" | Total number of functions" + print "| class=\"cyclo_resume_number_entry\" |" num_of_functions + # Number of simple functions + print "|-" + print "| class=\"cyclo_resume_header_entry\" | Number of low risk functions" + print "| class=\"cyclo_resume_number_entry\" |" num_of_simple_functions + # Number of moderate functions + print "|-" + print "| class=\"cyclo_resume_header_entry\" | Number of moderate risk functions" + print "| class=\"cyclo_resume_number_entry\" |" num_of_moderate_functions + # Number of high functions + print "|-" + print "| class=\"cyclo_resume_header_entry\" | Number of high risk functions" + print "| class=\"cyclo_resume_number_entry\" |" num_of_high_functions + # Number of untestable functions + print "|-" + print "| class=\"cyclo_resume_header_entry\" | Number of untestable functions" + print "| class=\"cyclo_resume_number_entry\" |" num_of_untestable_functions + print "|}" +} + +function wiki_function_cyclo () +{ + print "==Details for all functions==" + + print "Used ranges:" + + print "{| class =\"cyclo_ranges_table\"" + print "|-" + print "| class=\"cyclo_ranges_header_entry\" | " + print "| class=\"cyclo_ranges_header_entry\" | Cyclomatic Complexity" + print "| class=\"cyclo_ranges_header_entry\" | Risk Evaluation" + # Simple + print "|-" + print "| class=\"cyclo_ranges_entry_simple\" | " + print "| class=\"cyclo_ranges_entry\" | 0 - " cyclo_simple_max + print "| class=\"cyclo_ranges_entry\" | Simple module, without much risk" + # Moderate + print "|-" + print "| class=\"cyclo_ranges_entry_moderate\" | " + print "| class=\"cyclo_ranges_entry\" |" cyclo_simple_max + 1 " - " cyclo_moderate_max + print "| class=\"cyclo_ranges_entry\" | More complex module, moderate risk" + # High + print "|-" + print "| class=\"cyclo_ranges_entry_high\" | " + print "| class=\"cyclo_ranges_entry\" |" cyclo_moderate_max + 1 " - " cyclo_high_max + print "| class=\"cyclo_ranges_entry\" | Complex module, high risk" + # Untestable + print "|-" + print "| class=\"cyclo_ranges_entry_untestable\" | " + print "| class=\"cyclo_ranges_entry\" | greater than " cyclo_high_max + print "| class=\"cyclo_ranges_entry\" | Untestable module, very high risk" + print "|}" + + print "" + print "" + wiki_fnc_table_complete("") +} + +function wiki_fnc_table_complete (caption) +{ + wiki_fnc_table(caption, 1, 0, 1, 1, 1, 0, 1) +} + +function wiki_fnc_table_abbrev (caption) +{ + wiki_fnc_table(caption, 1, 0, 0, 0, 0, 0, 0) +} + +function wiki_fnc_table (caption, + fname_p, + mcyclo_p, + cyclo_p, + num_statements_p, + num_lines_p, + first_line_p, + file_p) +{ + print "{| width=\"90%\" class=\"cyclo_function_table\" cellpadding=\"0\" cellspacing=\"0\">" + if (caption != "") + { + print "|+" caption + } + wiki_fnc_header(fname_p, + mcyclo_p, + cyclo_p, + num_statements_p, + num_lines_p, + first_line_p, + file_p) + for (nfnc = 1; nfnc < nfuncs; nfnc++) + { + fnc = fnames[nfnc] + wiki_fnc(fnc, + fname_p, + mcyclo_p, + cyclo_p, + num_statements_p, + num_lines_p, + first_line_p, + file_p) + } + print "|}" +} + +function wiki_fnc_header (fname_p, + mcyclo_p, + cyclo_p, + num_statements_p, + num_lines_p, + first_line_p, + file_p) +{ + if (fname_p) + { + # Function name + print "! class=\"cyclo_function_table_header_entry\" | Function Name" + } + if (mcyclo_p) + { + # Modified cyclo + print "! class=\"cyclo_function_table_header_entry\" | Modified Cyclo" + } + if (cyclo_p) + { + # Cyclo + print "! class=\"cyclo_function_table_header_entry\" | Cyclomatic Complexity" + } + if (num_statements_p) + { + print "! class=\"cyclo_function_table_header_entry\" | Number of Statements" + } + if (num_lines_p) + { + print "! class=\"cyclo_function_table_header_entry\" | Number of Lines" + } + if (first_line_p) + { + print "! class=\"cyclo_function_table_header_entry\" | First Line" + } + if (file_p) + { + print "! class=\"cyclo_function_table_header_entry\" | Source File" + } +} + +function wiki_fnc (fname, + fname_p, + mcyclo_p, + cyclo_p, + num_statements_p, + num_lines_p, + first_line_p, + file_p) +{ + # Function name + trclass = "cyclo_function_entry_simple" + if (mcyclo[fname] > cyclo_high_max) + { + trclass="cyclo_function_entry_untestable" + } + else if (mcyclo[fname] > cyclo_moderate_max) + { + trclass="cyclo_function_entry_high" + } + else if (mcyclo[fname] > cyclo_simple_max) + { + trclass="cyclo_function_entry_moderate" + } + + print "|- class=\"" trclass "\"" + if (fname_p) + { + print "| class=\"cyclo_function_entry_name\" |" fname + } + if (mcyclo_p) + { + # Modified cyclo + print "| class=\"cyclo_function_entry_cyclo\" |" mcyclo[fname] + } + if (cyclo_p) + { + # Cyclo + print "| class=\"cyclo_function_entry_cyclo\" |" cyclo[fname] + } + if (num_statements_p) + { + # Number of statements + print "| class=\"cyclo_function_entry_number\" |" num_statements[fname] + } + if (num_lines_p) + { + # Number of lines + print "| class=\"cyclo_function_entry_number\" |" num_lines[fname] + } + if (first_line_p) + { + # First line + print "| class=\"cyclo_function_entry_number\" |" first_line[fname] + } + if (file_p) + { + href = "" + if (source_file_link_tmpl != "") + { + # Get href target + href = source_file_link_tmpl + sub(/%FILENAME%/, file[fname], href) + } + + # Source file + print "| class=\"cyclo_function_entry_filename\" |" \ + ((href != "") ? "[" href " " file[fname] "]" : "[" file[fname] "]") + } +} + +# Scan data from a line +{ + function_name = $7 + + nfuncs++; + fnames[nfuncs] = function_name + mcyclo[function_name] = $1 + cyclo[function_name] = $2 + num_statements[function_name] = $3 + first_line[function_name] = $4 + num_lines[function_name] = $5 + + # Build the filename from the file_spec ($6) + begin_util_path = index($6, cut_dir) + tmpfilename = substr($6, begin_util_path + length(cut_dir)) + sub(/\([0-9]+\):/, "", tmpfilename) + file[function_name] = tmpfilename + + if (mcyclo[function_name] > cyclo_simple_max) + { + # Extract function contents to a fn_txt file + filepath = $6 + sub(/\([0-9]+\):/, "", filepath) + num_line = 0 + while ((getline codeline < filepath) > 0) + { + num_line++; + if ((num_line >= first_line[function_name]) && + (num_line < first_line[function_name] + num_lines[function_name])) + { + print codeline > (function_name "_fn.txt") + } + } + close (function_name "_fn.txt") + close(filepath) + } + + # Initial values for statistics variables + num_of_functions = 0 + max_mcyclo = 0 + max_function_length = 0 + num_of_simple_functions = 0 + num_of_moderate_functions = 0 + num_of_high_functions = 0 + num_of_untestable_functions = 0 +} + +# Epilogue +END { + # Print header (only for html) + if (output_lang == "html") + { + html_header() + } + + # Print prolog + if ((output_lang == "html") && + (html_prolog != "")) + { + print html_prolog + } + if ((output_lang == "wiki") && + (wiki_prolog != "")) + { + print wiki_prolog + } + + if (output_lang == "html") + { + print "<div class=\"page_title\">" package_name " Cyclomatic Complexity Report</div>" + print "<p>Report generated at: <span class=\"report_timestamp\">" strftime() "</div></p>" + } + if (output_lang == "wiki") + { + print "==" package_name " Cyclomatic Complexity Report==" + print "Report generated at: '''" strftime() "'''" + } + + if (section_global_stats_p) + { + build_stats() + + if (output_lang == "html") + { + html_global_stats() + } + if (output_lang == "wiki") + { + wiki_global_stats() + } + } + if (section_function_cyclo_p) + { + if (output_lang == "html") + { + html_function_cyclo() + } + if (output_lang == "wiki") + { + wiki_function_cyclo() + } + } + + # Print epilog + if ((output_lang == "html") && + (html_epilog != "")) + { + print html_epilog + } + if ((output_lang == "wiki") && + (wiki_epilog != "")) + { + print wiki_epilog + } + + # Print footer (html only) + if (output_lang == "html") + { + html_footer() + } +} + +# End of pmccabe2html |