-#!/usr/bin/awk -f
-# pmccabe2html - pmccabe to html converter
+# pmccabe2html - AWK script to convert pmccabe output to html -*- awk -*-
-# Copyright (C) 2007, 2008 Free Software Foundation, Inc.
+# Copyright (C) 2007-2014 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
# 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:
#
-# libidn-cyclo.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/" \
-# > tmp
-# mv tmp libidn-cyclo.html
+# 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'
# 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 {
+ # Portable lookup of present time.
+ "date +%s" | getline epoch_time
+ "date" | getline chronos_time
+
section_global_stats_p = 1
section_function_cyclo_p = 1
cyclo_simple_max = 10
cyclo_moderate_max = 20
cyclo_high_max = 50
- cut_dir = "/../"
source_file_link_tmpl = vcurl
# HTML options
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."
- css_url = "pmccabe.css"
+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_comment = "<!-- Generated by gnulib's pmccabe2html at " epoch_time " -->"
html_title = "Cyclomatic Complexity report for " package_name
# Wiki options
function html_fnc_table_complete (caption)
{
- html_fnc_table(caption, 1, 0, 1, 1, 1, 0, 1)
+ html_fnc_table(caption, 1, 1, 0, 1, 1, 0, 1)
}
function html_fnc_table_abbrev (caption)
{
- html_fnc_table(caption, 1, 0, 0, 0, 0, 0, 0)
+ html_fnc_table(caption, 1, 1, 0, 0, 1, 0, 0)
}
{
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,
+ 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,
+ 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>"
{
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\">"
print "</tr>"
}
-function html_fnc (fname,
+function html_fnc (nfun,
fname_p,
mcyclo_p,
cyclo_p,
first_line_p,
file_p)
{
+ fname = fnames[nfun]
+
# Function name
trclass = "function_entry_simple"
- if (mcyclo[fname] > cyclo_high_max)
+ if (mcyclo[nfun] > cyclo_high_max)
{
trclass="function_entry_untestable"
- }
- else if (mcyclo[fname] > cyclo_moderate_max)
+ }
+ else if (mcyclo[nfun] > cyclo_moderate_max)
{
trclass="function_entry_high"
}
- else if (mcyclo[fname] > cyclo_simple_max)
+ else if (mcyclo[nfun] > cyclo_simple_max)
{
trclass="function_entry_moderate"
}
if (fname_p)
{
print "<td class=\"function_entry_filename\">"
- if (mcyclo[fname] > cyclo_simple_max)
+ 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>"
{
# Modified cyclo
print "<td class=\"function_entry_cyclo\">"
- print mcyclo[fname]
+ print mcyclo[nfun]
print "</td>"
}
if (cyclo_p)
{
# Cyclo
print "<td class=\"function_entry_cyclo\">"
- print cyclo[fname]
+ print cyclo[nfun]
print "</td>"
}
if (num_statements_p)
{
# Number of statements
print "<td class=\"function_entry_number\">"
- print num_statements[fname]
+ print num_statements[nfun]
print "</td>"
}
if (num_lines_p)
{
# Number of lines
print "<td class=\"function_entry_number\">"
- print num_lines[fname]
+ print num_lines[nfun]
print "</td>"
}
if (first_line_p)
{
# First line
print "<td class=\"function_entry_number\">"
- print first_line[fname]
+ print first_line[nfun]
print "</td>"
}
if (file_p)
{
# Get href target
href = source_file_link_tmpl
- sub(/%FILENAME%/, file[fname], href)
+ sub(/%FILENAME%/, file[nfun], href)
}
# Source file
print "<td class=\"function_entry_filename\">"
if (href != "")
{
- print "<a href=\"" href "\">" file[fname] "</a>"
+ print "<a href=\"" href "\">" file[nfun] "</a>"
}
else
{
- print file[fname]
+ print file[nfun]
}
-
+
print "</td>"
print "</tr>"
- if (mcyclo[fname] > cyclo_simple_max)
+ if (mcyclo[nfun] > cyclo_simple_max)
{
print "<tr>"
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)
+
+ while ((getline codeline < (fname nfun "_fn.txt")) > 0)
{
- sub(/\\</, "<", codeline)
- sub(/\\>/, ">", codeline)
- sub(/&/, "&", codeline)
-
+ gsub(/&/, "\&", codeline) # Must come first.
+ gsub(/</, "\<", codeline)
+ gsub(/>/, "\>", codeline)
+
print codeline
}
- close(fname "_fn.txt")
- system("rm " fname "_fn.txt")
+ close(fname nfun "_fn.txt")
+ system("rm " "'" fname "'" nfun "_fn.txt")
print "</pre>"
print "</div>"
print "</td>"
function html_global_stats ()
{
- print "<div class=\"section_title\">Resume</div>"
+ print "<div class=\"section_title\">Summary</div>"
- print "<br/>"
- print "<table class=\"resume_table\">"
+ print "<table class=\"summary_table\">"
# Total number of functions
print "<tr>"
- print "<td class=\"resume_header_entry\">"
+ print "<td class=\"summary_header_entry\">"
print "Total number of functions"
print "</td>"
- print "<td class=\"resume_number_entry\">"
+ print "<td class=\"summary_number_entry\">"
print num_of_functions
print "</td>"
print "</tr>"
# Number of simple functions
print "<tr>"
- print "<td class=\"resume_header_entry\">"
+ print "<td class=\"summary_header_entry\">"
print "Number of low risk functions"
print "</td>"
- print "<td class=\"resume_number_entry\">"
+ print "<td class=\"summary_number_entry\">"
print num_of_simple_functions
print "</td>"
print "</tr>"
# Number of moderate functions
print "<tr>"
- print "<td class=\"resume_header_entry\">"
+ print "<td class=\"summary_header_entry\">"
print "Number of moderate risk functions"
print "</td>"
- print "<td class=\"resume_number_entry\">"
+ print "<td class=\"summary_number_entry\">"
print num_of_moderate_functions
print "</td>"
print "</tr>"
# Number of high functions
print "<tr>"
- print "<td class=\"resume_header_entry\">"
+ print "<td class=\"summary_header_entry\">"
print "Number of high risk functions"
print "</td>"
- print "<td class=\"resume_number_entry\">"
+ print "<td class=\"summary_number_entry\">"
print num_of_high_functions
print "</td>"
print "</tr>"
# Number of untestable functions
print "<tr>"
- print "<td class=\"resume_header_entry\">"
+ print "<td class=\"summary_header_entry\">"
print "Number of untestable functions"
print "</td>"
- print "<td class=\"resume_number_entry\">"
+ print "<td class=\"summary_number_entry\">"
print num_of_untestable_functions
print "</td>"
print "</tr>"
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 "Simple module, without much risk"
print "</td>"
print "</tr>"
- # Moderate
+ # Moderate
print "<tr>"
print "<td class=\"ranges_entry_moderate\">"
print " "
function wiki_global_stats ()
{
- print "{| class=\"cyclo_resume_table\""
+ print "{| class=\"cyclo_summary_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
+ 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_resume_header_entry\" | Number of low risk functions"
- print "| class=\"cyclo_resume_number_entry\" |" num_of_simple_functions
+ 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_resume_header_entry\" | Number of moderate risk functions"
- print "| class=\"cyclo_resume_number_entry\" |" num_of_moderate_functions
+ 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_resume_header_entry\" | Number of high risk functions"
- print "| class=\"cyclo_resume_number_entry\" |" num_of_high_functions
+ 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_resume_header_entry\" | Number of untestable functions"
- print "| class=\"cyclo_resume_number_entry\" |" num_of_untestable_functions
+ print "| class=\"cyclo_summary_header_entry\" | Number of untestable functions"
+ print "| class=\"cyclo_summary_number_entry\" |" num_of_untestable_functions
print "|}"
}
print "==Details for all functions=="
print "Used ranges:"
-
+
print "{| class =\"cyclo_ranges_table\""
print "|-"
print "| class=\"cyclo_ranges_header_entry\" | "
function wiki_fnc_table_complete (caption)
{
- wiki_fnc_table(caption, 1, 0, 1, 1, 1, 0, 1)
+ wiki_fnc_table(caption, 1, 1, 0, 1, 1, 0, 1)
}
function wiki_fnc_table_abbrev (caption)
{
print "|+" caption
}
- wiki_fnc_header(fname_p,
- mcyclo_p,
- cyclo_p,
- num_statements_p,
- num_lines_p,
- first_line_p,
+ 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,
+ 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 (fname,
+function wiki_fnc (nfnc,
fname_p,
mcyclo_p,
cyclo_p,
first_line_p,
file_p)
{
+ fname = fnames[nfnc]
+
# Function name
trclass = "cyclo_function_entry_simple"
- if (mcyclo[fname] > cyclo_high_max)
+ if (mcyclo[nfnc] > cyclo_high_max)
{
trclass="cyclo_function_entry_untestable"
- }
- else if (mcyclo[fname] > cyclo_moderate_max)
+ }
+ else if (mcyclo[nfnc] > cyclo_moderate_max)
{
trclass="cyclo_function_entry_high"
}
- else if (mcyclo[fname] > cyclo_simple_max)
+ else if (mcyclo[nfnc] > cyclo_simple_max)
{
trclass="cyclo_function_entry_moderate"
}
if (mcyclo_p)
{
# Modified cyclo
- print "| class=\"cyclo_function_entry_cyclo\" |" mcyclo[fname]
+ print "| class=\"cyclo_function_entry_cyclo\" |" mcyclo[nfnc]
}
if (cyclo_p)
{
# Cyclo
- print "| class=\"cyclo_function_entry_cyclo\" |" cyclo[fname]
+ print "| class=\"cyclo_function_entry_cyclo\" |" cyclo[nfnc]
}
if (num_statements_p)
{
# Number of statements
- print "| class=\"cyclo_function_entry_number\" |" num_statements[fname]
+ print "| class=\"cyclo_function_entry_number\" |" num_statements[nfnc]
}
if (num_lines_p)
{
# Number of lines
- print "| class=\"cyclo_function_entry_number\" |" num_lines[fname]
+ print "| class=\"cyclo_function_entry_number\" |" num_lines[nfnc]
}
if (first_line_p)
{
# First line
- print "| class=\"cyclo_function_entry_number\" |" first_line[fname]
+ print "| class=\"cyclo_function_entry_number\" |" first_line[nfnc]
}
if (file_p)
{
{
# Get href target
href = source_file_link_tmpl
- sub(/%FILENAME%/, file[fname], href)
+ sub(/%FILENAME%/, file[nfnc], href)
}
-
+
# Source file
print "| class=\"cyclo_function_entry_filename\" |" \
- ((href != "") ? "[" href " " file[fname] "]" : "[" file[fname] "]")
+ ((href != "") ? "[" href " " file[nfnc] "]" : "[" file[nfnc] "]")
}
}
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
+ 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[function_name] = tmpfilename
+ file[nfuncs] = tmpfilename
- if (mcyclo[function_name] > cyclo_simple_max)
+ 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[function_name]) &&
- (num_line < first_line[function_name] + num_lines[function_name]))
+ if ((num_line >= first_line[nfuncs]) &&
+ (num_line < first_line[nfuncs] + num_lines[nfuncs]))
{
- print codeline > (function_name "_fn.txt")
+ print codeline > (function_name nfuncs "_fn.txt")
}
}
- close (function_name "_fn.txt")
+ close (function_name nfuncs "_fn.txt")
close(filepath)
}
}
# Print prolog
- if ((output_lang == "html") &&
+ if ((output_lang == "html") &&
(html_prolog != ""))
{
print html_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>"
+ print "<p>Report generated at: <span class=\"report_timestamp\">" chronos_time "</span></p>"
}
if (output_lang == "wiki")
{
print "==" package_name " Cyclomatic Complexity Report=="
- print "Report generated at: '''" strftime() "'''"
+ print "Report generated at: '''" chronos_time "'''"
}
if (section_global_stats_p)
wiki_function_cyclo()
}
}
-
+
# Print epilog
- if ((output_lang == "html") &&
+ if ((output_lang == "html") &&
(html_epilog != ""))
{
print html_epilog