Mercurial > hg > octave-kai > gnulib-hg
view build-aux/pmccabe2html @ 17476:6057744acd2c default tip master
autoupdate
author | Karl Berry <karl@freefriends.org> |
---|---|
date | Fri, 16 Aug 2013 06:32:22 -0700 |
parents | e542fd46ad6f |
children |
line wrap: on
line source
# pmccabe2html - AWK script to convert pmccabe output to html -*- awk -*- # Copyright (C) 2007-2013 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>. # Added support for C++ by Giuseppe Scrivano <gscrivano@gnu.org>. # Typical Invocation is from a Makefile.am: # # CYCLO_SOURCES = ${top_srcdir}/src/*.[ch] # # cyclo-$(PACKAGE).html: $(CYCLO_SOURCES) # $(PMCCABE) $(CYCLO_SOURCES) \ # | 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=$(PACKAGE).git;a=blob;f=%FILENAME%;hb=HEAD" \ # -v url="http://www.gnu.org/software/$(PACKAGE)/" \ # -v css=${top_srcdir}/build-aux/pmccabe.css \ # -v cut_dir=${top_srcdir}/ \ # > $@-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 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, 1, 0, 1, 1, 0, 1) } function html_fnc_table_abbrev (caption) { html_fnc_table(caption, 1, 1, 0, 0, 1, 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++) { html_fnc(nfnc, 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 (nfun, fname_p, mcyclo_p, cyclo_p, num_statements_p, num_lines_p, first_line_p, file_p) { fname = fnames[nfun] # Function name trclass = "function_entry_simple" if (mcyclo[nfun] > cyclo_high_max) { trclass="function_entry_untestable" } else if (mcyclo[nfun] > cyclo_moderate_max) { trclass="function_entry_high" } else if (mcyclo[nfun] > cyclo_simple_max) { trclass="function_entry_moderate" } print "<tr class=\"" trclass "\">" if (fname_p) { print "<td class=\"function_entry_filename\">" if (file_p && mcyclo[nfun] > 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[nfun] print "</td>" } if (cyclo_p) { # Cyclo print "<td class=\"function_entry_cyclo\">" print cyclo[nfun] print "</td>" } if (num_statements_p) { # Number of statements print "<td class=\"function_entry_number\">" print num_statements[nfun] print "</td>" } if (num_lines_p) { # Number of lines print "<td class=\"function_entry_number\">" print num_lines[nfun] print "</td>" } if (first_line_p) { # First line print "<td class=\"function_entry_number\">" print first_line[nfun] print "</td>" } if (file_p) { href = "" if (source_file_link_tmpl != "") { # Get href target href = source_file_link_tmpl sub(/%FILENAME%/, file[nfun], href) } # Source file print "<td class=\"function_entry_filename\">" if (href != "") { print "<a href=\"" href "\">" file[nfun] "</a>" } else { print file[nfun] } print "</td>" print "</tr>" if (mcyclo[nfun] > 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 nfun "_fn.txt")) > 0) { sub(/\\</, "<", codeline) sub(/\\>/, ">", codeline) sub(/&/, "&", codeline) print codeline } close(fname nfun "_fn.txt") system("rm " "'" fname "'" nfun "_fn.txt") print "</pre>" print "</div>" print "</td>" print "</tr>" } } } function html_global_stats () { print "<div class=\"section_title\">Summary</div>" print "<table class=\"summary_table\">" # Total number of functions print "<tr>" print "<td class=\"summary_header_entry\">" print "Total number of functions" print "</td>" print "<td class=\"summary_number_entry\">" print num_of_functions print "</td>" print "</tr>" # Number of simple functions print "<tr>" print "<td class=\"summary_header_entry\">" print "Number of low risk functions" print "</td>" print "<td class=\"summary_number_entry\">" print num_of_simple_functions print "</td>" print "</tr>" # Number of moderate functions print "<tr>" print "<td class=\"summary_header_entry\">" print "Number of moderate risk functions" print "</td>" print "<td class=\"summary_number_entry\">" print num_of_moderate_functions print "</td>" print "</tr>" # Number of high functions print "<tr>" print "<td class=\"summary_header_entry\">" print "Number of high risk functions" print "</td>" print "<td class=\"summary_number_entry\">" print num_of_high_functions print "</td>" print "</tr>" # Number of untestable functions print "<tr>" print "<td class=\"summary_header_entry\">" print "Number of untestable functions" print "</td>" print "<td class=\"summary_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 "<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_summary_table\"" # Total number of functions print "|-" print "| class=\"cyclo_summary_header_entry\" | Total number of functions" print "| class=\"cyclo_summary_number_entry\" |" num_of_functions # Number of simple functions print "|-" print "| class=\"cyclo_summary_header_entry\" | Number of low risk functions" print "| class=\"cyclo_summary_number_entry\" |" num_of_simple_functions # Number of moderate functions print "|-" print "| class=\"cyclo_summary_header_entry\" | Number of moderate risk functions" print "| class=\"cyclo_summary_number_entry\" |" num_of_moderate_functions # Number of high functions print "|-" print "| class=\"cyclo_summary_header_entry\" | Number of high risk functions" print "| class=\"cyclo_summary_number_entry\" |" num_of_high_functions # Number of untestable functions print "|-" print "| class=\"cyclo_summary_header_entry\" | Number of untestable functions" print "| class=\"cyclo_summary_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, 1, 0, 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++) { wiki_fnc(nfnc, 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 (nfnc, fname_p, mcyclo_p, cyclo_p, num_statements_p, num_lines_p, first_line_p, file_p) { fname = fnames[nfnc] # Function name trclass = "cyclo_function_entry_simple" if (mcyclo[nfnc] > cyclo_high_max) { trclass="cyclo_function_entry_untestable" } else if (mcyclo[nfnc] > cyclo_moderate_max) { trclass="cyclo_function_entry_high" } else if (mcyclo[nfnc] > 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[nfnc] } if (cyclo_p) { # Cyclo print "| class=\"cyclo_function_entry_cyclo\" |" cyclo[nfnc] } if (num_statements_p) { # Number of statements print "| class=\"cyclo_function_entry_number\" |" num_statements[nfnc] } if (num_lines_p) { # Number of lines print "| class=\"cyclo_function_entry_number\" |" num_lines[nfnc] } if (first_line_p) { # First line print "| class=\"cyclo_function_entry_number\" |" first_line[nfnc] } if (file_p) { href = "" if (source_file_link_tmpl != "") { # Get href target href = source_file_link_tmpl sub(/%FILENAME%/, file[nfnc], href) } # Source file print "| class=\"cyclo_function_entry_filename\" |" \ ((href != "") ? "[" href " " file[nfnc] "]" : "[" file[nfnc] "]") } } # Scan data from a line { function_name = $7 nfuncs++; fnames[nfuncs] = function_name mcyclo[nfuncs] = $1 cyclo[nfuncs] = $2 num_statements[nfuncs] = $3 first_line[nfuncs] = $4 num_lines[nfuncs] = $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[nfuncs] = tmpfilename if (mcyclo[nfuncs] > 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[nfuncs]) && (num_line < first_line[nfuncs] + num_lines[nfuncs])) { print codeline > (function_name nfuncs "_fn.txt") } } close (function_name nfuncs "_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