15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#!/usr/bin/perl -w
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#
33551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#   Copyright (c) International Business Machines  Corp., 2002,2012
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#   This program is free software;  you can redistribute it and/or modify
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#   it under the terms of the GNU General Public License as published by
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#   the Free Software Foundation; either version 2 of the License, or (at
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#   your option) any later version.
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#   This program is distributed in the hope that it will be useful, but
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#   WITHOUT ANY WARRANTY;  without even the implied warranty of
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#   General Public License for more details. 
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#   You should have received a copy of the GNU General Public License
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#   along with this program;  if not, write to the Free Software
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# genhtml
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#   This script generates HTML output from .info files as created by the
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#   geninfo script. Call it with --help and refer to the genhtml man page
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#   to get information on usage and available options.
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# History:
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#   2002-08-23 created by Peter Oberparleiter <Peter.Oberparleiter@de.ibm.com>
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#                         IBM Lab Boeblingen
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#        based on code by Manoj Iyer <manjo@mail.utexas.edu> and
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#                         Megan Bock <mbock@us.ibm.com>
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#                         IBM Austin
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#   2002-08-27 / Peter Oberparleiter: implemented frame view
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#   2002-08-29 / Peter Oberparleiter: implemented test description filtering
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#                so that by default only descriptions for test cases which
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#                actually hit some source lines are kept
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#   2002-09-05 / Peter Oberparleiter: implemented --no-sourceview
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#   2002-09-05 / Mike Kobler: One of my source file paths includes a "+" in
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#                the directory name.  I found that genhtml.pl died when it
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#                encountered it. I was able to fix the problem by modifying
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#                the string with the escape character before parsing it.
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#   2002-10-26 / Peter Oberparleiter: implemented --num-spaces
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#   2003-04-07 / Peter Oberparleiter: fixed bug which resulted in an error
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#                when trying to combine .info files containing data without
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#                a test name
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#   2003-04-10 / Peter Oberparleiter: extended fix by Mike to also cover
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#                other special characters
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#   2003-04-30 / Peter Oberparleiter: made info write to STDERR, not STDOUT
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#   2003-07-10 / Peter Oberparleiter: added line checksum support
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#   2004-08-09 / Peter Oberparleiter: added configuration file support
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#   2005-03-04 / Cal Pierog: added legend to HTML output, fixed coloring of
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#                "good coverage" background
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#   2006-03-18 / Marcus Boerger: added --custom-intro, --custom-outro and
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#                overwrite --no-prefix if --prefix is present
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#   2006-03-20 / Peter Oberparleiter: changes to custom_* function (rename
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#                to html_prolog/_epilog, minor modifications to implementation),
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#                changed prefix/noprefix handling to be consistent with current
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#                logic
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#   2006-03-20 / Peter Oberparleiter: added --html-extension option
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#   2008-07-14 / Tom Zoerner: added --function-coverage command line option;
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#                added function table to source file page
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#   2008-08-13 / Peter Oberparleiter: modified function coverage
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#                implementation (now enabled per default),
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#                introduced sorting option (enabled per default)
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)use strict;
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)use File::Basename; 
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)use Getopt::Long;
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)use Digest::MD5 qw(md5_base64);
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# Global constants
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)our $title		= "LCOV - code coverage report";
753551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)our $lcov_version	= 'LCOV version 1.10';
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)our $lcov_url		= "http://ltp.sourceforge.net/coverage/lcov.php";
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)our $tool_name		= basename($0);
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# Specify coverage rate limits (in %) for classifying file entries
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# HI:   $hi_limit <= rate <= 100          graph color: green
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# MED: $med_limit <= rate <  $hi_limit    graph color: orange
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# LO:          0  <= rate <  $med_limit   graph color: red
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
843551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)# For line coverage/all coverage types if not specified
853551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)our $hi_limit = 90;
863551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)our $med_limit = 75;
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# For function coverage
893551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)our $fn_hi_limit;
903551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)our $fn_med_limit;
913551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
923551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)# For branch coverage
933551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)our $br_hi_limit;
943551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)our $br_med_limit;
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# Width of overview image
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)our $overview_width = 80;
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# Resolution of overview navigation: this number specifies the maximum
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# difference in lines between the position a user selected from the overview
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# and the position the source code window is scrolled to.
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)our $nav_resolution = 4;
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# Clicking a line in the overview image should show the source code view at
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# a position a bit further up so that the requested line is not the first
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# line in the window. This number specifies that offset in lines.
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)our $nav_offset = 10;
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# Clicking on a function name should show the source code at a position a
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# few lines before the first line of code of that function. This number
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# specifies that offset in lines.
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)our $func_offset = 2;
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1143551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)our $overview_title = "top level";
1153551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
1163551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)# Width for line coverage information in the source code view
1173551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)our $line_field_width = 12;
1183551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
1193551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)# Width for branch coverage information in the source code view
1203551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)our $br_field_width = 16;
1213551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
1223551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)# Internal Constants
1233551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
1243551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)# Header types
1253551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)our $HDR_DIR		= 0;
1263551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)our $HDR_FILE		= 1;
1273551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)our $HDR_SOURCE		= 2;
1283551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)our $HDR_TESTDESC	= 3;
1293551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)our $HDR_FUNC		= 4;
1303551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
1313551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)# Sort types
1323551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)our $SORT_FILE		= 0;
1333551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)our $SORT_LINE		= 1;
1343551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)our $SORT_FUNC		= 2;
1353551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)our $SORT_BRANCH	= 3;
1363551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
1373551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)# Fileview heading types
1383551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)our $HEAD_NO_DETAIL	= 1;
1393551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)our $HEAD_DETAIL_HIDDEN	= 2;
1403551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)our $HEAD_DETAIL_SHOWN	= 3;
1413551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
1423551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)# Offsets for storing branch coverage data in vectors
1433551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)our $BR_BLOCK		= 0;
1443551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)our $BR_BRANCH		= 1;
1453551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)our $BR_TAKEN		= 2;
1463551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)our $BR_VEC_ENTRIES	= 3;
1473551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)our $BR_VEC_WIDTH	= 32;
1483551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
1493551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)# Additional offsets used when converting branch coverage data to HTML
1503551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)our $BR_LEN	= 3;
1513551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)our $BR_OPEN	= 4;
1523551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)our $BR_CLOSE	= 5;
1533551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
1543551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)# Branch data combination types
1553551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)our $BR_SUB = 0;
1563551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)our $BR_ADD = 1;
1573551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
1583551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)# Error classes which users may specify to ignore during processing
1593551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)our $ERROR_SOURCE	= 0;
1603551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)our %ERROR_ID = (
1613551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	"source" => $ERROR_SOURCE,
1623551c9c881056c480085172ff9840cab31610854Torne (Richard Coles));
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# Data related prototypes
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)sub print_usage(*);
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)sub gen_html();
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)sub html_create($$);
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)sub process_dir($);
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)sub process_file($$$);
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)sub info(@);
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)sub read_info_file($);
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)sub get_info_entry($);
1733551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)sub set_info_entry($$$$$$$$$;$$$$$$);
1743551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)sub get_prefix($@);
1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)sub shorten_prefix($);
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)sub get_dir_list(@);
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)sub get_relative_base_path($);
1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)sub read_testfile($);
1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)sub get_date_string();
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)sub create_sub_dir($);
1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)sub subtract_counts($$);
1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)sub add_counts($$);
1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)sub apply_baseline($$);
1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)sub remove_unused_descriptions();
1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)sub get_found_and_hit($);
1863551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)sub get_affecting_tests($$$);
1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)sub combine_info_files($$);
1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)sub merge_checksums($$$);
1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)sub combine_info_entries($$$);
1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)sub apply_prefix($$);
1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)sub system_no_output($@);
1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)sub read_config($);
1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)sub apply_config($);
1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)sub get_html_prolog($);
1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)sub get_html_epilog($);
1963551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)sub write_dir_page($$$$$$$$$$$$$$$$$);
1973551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)sub classify_rate($$$$);
1983551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)sub br_taken_add($$);
1993551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)sub br_taken_sub($$);
2003551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)sub br_ivec_len($);
2013551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)sub br_ivec_get($$);
2023551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)sub br_ivec_push($$$$);
2033551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)sub combine_brcount($$$);
2043551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)sub get_br_found_and_hit($);
2053551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)sub warn_handler($);
2063551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)sub die_handler($);
2073551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)sub parse_ignore_errors(@);
2083551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)sub rate($$;$$$);
2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# HTML related prototypes
2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)sub escape_html($);
2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)sub get_bar_graph_code($$$);
2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)sub write_png_files();
2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)sub write_htaccess_file();
2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)sub write_css_file();
2183551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)sub write_description_file($$$$$$$);
2193551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)sub write_function_table(*$$$$$$$$$$);
2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)sub write_html(*$);
2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)sub write_html_prolog(*$$);
2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)sub write_html_epilog(*$;$);
2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2253551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)sub write_header(*$$$$$$$$$$);
2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)sub write_header_prolog(*$);
2273551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)sub write_header_line(*@);
2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)sub write_header_epilog(*$);
2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2303551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)sub write_file_table(*$$$$$$$);
2313551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)sub write_file_table_prolog(*$@);
2323551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)sub write_file_table_entry(*$$$@);
2333551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)sub write_file_table_detail_entry(*$@);
2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)sub write_file_table_epilog(*);
2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)sub write_test_table_prolog(*$);
2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)sub write_test_table_entry(*$$);
2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)sub write_test_table_epilog(*);
2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2403551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)sub write_source($$$$$$$);
2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)sub write_source_prolog(*);
2423551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)sub write_source_line(*$$$$$$);
2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)sub write_source_epilog(*);
2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)sub write_frameset(*$$$);
2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)sub write_overview_line(*$$$);
2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)sub write_overview(*$$$$);
2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# External prototype (defined in genpng)
2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)sub gen_png($$$@);
2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# Global variables & initialization
2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)our %info_data;		# Hash containing all data from .info file
2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)our $dir_prefix;	# Prefix to remove from all sub directories
2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)our %test_description;	# Hash containing test descriptions if available
2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)our $date = get_date_string();
2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)our @info_filenames;	# List of .info files to use as data source
2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)our $test_title;	# Title for output as written to each page header
2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)our $output_directory;	# Name of directory in which to store output
2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)our $base_filename;	# Optional name of file containing baseline data
2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)our $desc_filename;	# Name of file containing test descriptions
2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)our $css_filename;	# Optional name of external stylesheet file to use
2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)our $quiet;		# If set, suppress information messages
2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)our $help;		# Help option flag
2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)our $version;		# Version option flag
2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)our $show_details;	# If set, generate detailed directory view
2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)our $no_prefix;		# If set, do not remove filename prefix
2703551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)our $func_coverage;	# If set, generate function coverage statistics
2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)our $no_func_coverage;	# Disable func_coverage
2723551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)our $br_coverage;	# If set, generate branch coverage statistics
2733551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)our $no_br_coverage;	# Disable br_coverage
2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)our $sort = 1;		# If set, provide directory listings with sorted entries
2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)our $no_sort;		# Disable sort
2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)our $frames;		# If set, use frames for source code view
2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)our $keep_descriptions;	# If set, do not remove unused test case descriptions
2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)our $no_sourceview;	# If set, do not create a source code view for each file
2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)our $highlight;		# If set, highlight lines covered by converted data only
2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)our $legend;		# If set, include legend in output
2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)our $tab_size = 8;	# Number of spaces to use in place of tab
2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)our $config;		# Configuration file contents
2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)our $html_prolog_file;	# Custom HTML prolog file (up to and including <body>)
2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)our $html_epilog_file;	# Custom HTML epilog file (from </body> onwards)
2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)our $html_prolog;	# Actual HTML prolog
2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)our $html_epilog;	# Actual HTML epilog
2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)our $html_ext = "html";	# Extension for generated HTML files
2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)our $html_gzip = 0;	# Compress with gzip
2893551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)our $demangle_cpp = 0;	# Demangle C++ function names
2903551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)our @opt_ignore_errors;	# Ignore certain error classes during processing
2913551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)our @ignore;
2923551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)our $opt_config_file;	# User-specified configuration file location
2933551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)our %opt_rc;
2943551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)our $charset = "UTF-8";	# Default charset for HTML pages
2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)our @fileview_sortlist;
2963551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)our @fileview_sortname = ("", "-sort-l", "-sort-f", "-sort-b");
2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)our @funcview_sortlist;
2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)our @rate_name = ("Lo", "Med", "Hi");
2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)our @rate_png = ("ruby.png", "amber.png", "emerald.png");
3003551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)our $lcov_func_coverage = 1;
3013551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)our $lcov_branch_coverage = 0;
3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)our $cwd = `pwd`;	# Current working directory
3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)chomp($cwd);
3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)our $tool_dir = dirname($0);	# Directory where genhtml tool is installed
3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#
3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# Code entry point
3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#
3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)$SIG{__WARN__} = \&warn_handler;
3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)$SIG{__DIE__} = \&die_handler;
3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3153551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)# Prettify version string
3163551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)$lcov_version =~ s/\$\s*Revision\s*:?\s*(\S+)\s*\$/$1/;
3173551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# Add current working directory if $tool_dir is not already an absolute path
3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)if (! ($tool_dir =~ /^\/(.*)$/))
3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	$tool_dir = "$cwd/$tool_dir";
3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3243551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)# Check command line for a configuration file name
3253551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)Getopt::Long::Configure("pass_through", "no_auto_abbrev");
3263551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)GetOptions("config-file=s" => \$opt_config_file,
3273551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	   "rc=s%" => \%opt_rc);
3283551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)Getopt::Long::Configure("default");
3293551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# Read configuration file if available
3313551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)if (defined($opt_config_file)) {
3323551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	$config = read_config($opt_config_file);
3333551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)} elsif (defined($ENV{"HOME"}) && (-r $ENV{"HOME"}."/.lcovrc"))
3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	$config = read_config($ENV{"HOME"}."/.lcovrc");
3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)elsif (-r "/etc/lcovrc")
3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	$config = read_config("/etc/lcovrc");
3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3423551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)if ($config || %opt_rc)
3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
3443551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	# Copy configuration file and --rc values to variables
3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	apply_config({
3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		"genhtml_css_file"		=> \$css_filename,
3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		"genhtml_hi_limit"		=> \$hi_limit,
3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		"genhtml_med_limit"		=> \$med_limit,
3493551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)		"genhtml_line_field_width"	=> \$line_field_width,
3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		"genhtml_overview_width"	=> \$overview_width,
3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		"genhtml_nav_resolution"	=> \$nav_resolution,
3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		"genhtml_nav_offset"		=> \$nav_offset,
3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		"genhtml_keep_descriptions"	=> \$keep_descriptions,
3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		"genhtml_no_prefix"		=> \$no_prefix,
3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		"genhtml_no_source"		=> \$no_sourceview,
3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		"genhtml_num_spaces"		=> \$tab_size,
3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		"genhtml_highlight"		=> \$highlight,
3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		"genhtml_legend"		=> \$legend,
3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		"genhtml_html_prolog"		=> \$html_prolog_file,
3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		"genhtml_html_epilog"		=> \$html_epilog_file,
3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		"genhtml_html_extension"	=> \$html_ext,
3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		"genhtml_html_gzip"		=> \$html_gzip,
3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		"genhtml_function_hi_limit"	=> \$fn_hi_limit,
3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		"genhtml_function_med_limit"	=> \$fn_med_limit,
3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		"genhtml_function_coverage"	=> \$func_coverage,
3663551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)		"genhtml_branch_hi_limit"	=> \$br_hi_limit,
3673551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)		"genhtml_branch_med_limit"	=> \$br_med_limit,
3683551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)		"genhtml_branch_coverage"	=> \$br_coverage,
3693551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)		"genhtml_branch_field_width"	=> \$br_field_width,
3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		"genhtml_sort"			=> \$sort,
3713551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)		"genhtml_charset"		=> \$charset,
3723551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)		"lcov_function_coverage"	=> \$lcov_func_coverage,
3733551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)		"lcov_branch_coverage"		=> \$lcov_branch_coverage,
3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		});
3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3773551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)# Copy related values if not specified
3783551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)$fn_hi_limit	= $hi_limit if (!defined($fn_hi_limit));
3793551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)$fn_med_limit	= $med_limit if (!defined($fn_med_limit));
3803551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)$br_hi_limit	= $hi_limit if (!defined($br_hi_limit));
3813551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)$br_med_limit	= $med_limit if (!defined($br_med_limit));
3823551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)$func_coverage	= $lcov_func_coverage if (!defined($func_coverage));
3833551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)$br_coverage	= $lcov_branch_coverage if (!defined($br_coverage));
3843551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# Parse command line options
3863551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)if (!GetOptions("output-directory|o=s"	=> \$output_directory,
3873551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)		"title|t=s"		=> \$test_title,
3883551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)		"description-file|d=s"	=> \$desc_filename,
3893551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)		"keep-descriptions|k"	=> \$keep_descriptions,
3903551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)		"css-file|c=s"		=> \$css_filename,
3913551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)		"baseline-file|b=s"	=> \$base_filename,
3923551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)		"prefix|p=s"		=> \$dir_prefix,
3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		"num-spaces=i"		=> \$tab_size,
3945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		"no-prefix"		=> \$no_prefix,
3955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		"no-sourceview"		=> \$no_sourceview,
3963551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)		"show-details|s"	=> \$show_details,
3973551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)		"frames|f"		=> \$frames,
3985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		"highlight"		=> \$highlight,
3995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		"legend"		=> \$legend,
4003551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)		"quiet|q"		=> \$quiet,
4015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		"help|h|?"		=> \$help,
4023551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)		"version|v"		=> \$version,
4035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		"html-prolog=s"		=> \$html_prolog_file,
4045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		"html-epilog=s"		=> \$html_epilog_file,
4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		"html-extension=s"	=> \$html_ext,
4065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		"html-gzip"		=> \$html_gzip,
4075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		"function-coverage"	=> \$func_coverage,
4085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		"no-function-coverage"	=> \$no_func_coverage,
4093551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)		"branch-coverage"	=> \$br_coverage,
4103551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)		"no-branch-coverage"	=> \$no_br_coverage,
4115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		"sort"			=> \$sort,
4125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		"no-sort"		=> \$no_sort,
4133551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)		"demangle-cpp"		=> \$demangle_cpp,
4143551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)		"ignore-errors=s"	=> \@opt_ignore_errors,
4153551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)		"config-file=s"		=> \$opt_config_file,
4163551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)		"rc=s%"			=> \%opt_rc,
4175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		))
4185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
4195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	print(STDERR "Use $tool_name --help to get usage information\n");
4205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	exit(1);
4215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} else {
4225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	# Merge options
4235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if ($no_func_coverage) {
4245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		$func_coverage = 0;
4255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
4263551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	if ($no_br_coverage) {
4273551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)		$br_coverage = 0;
4283551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	}
4295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	# Merge sort options
4315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if ($no_sort) {
4325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		$sort = 0;
4335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
4345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)@info_filenames = @ARGV;
4375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# Check for help option
4395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)if ($help)
4405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
4415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	print_usage(*STDOUT);
4425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	exit(0);
4435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# Check for version option
4465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)if ($version)
4475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
4485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	print("$tool_name: $lcov_version\n");
4495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	exit(0);
4505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4523551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)# Determine which errors the user wants us to ignore
4533551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)parse_ignore_errors(@opt_ignore_errors);
4543551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
4555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# Check for info filename
4565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)if (!@info_filenames)
4575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
4585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	die("No filename specified\n".
4595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    "Use $tool_name --help to get usage information\n");
4605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# Generate a title if none is specified
4635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)if (!$test_title)
4645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
4655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (scalar(@info_filenames) == 1)
4665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	{
4675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		# Only one filename specified, use it as title
4685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		$test_title = basename($info_filenames[0]);
4695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
4705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	else
4715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	{
4725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		# More than one filename specified, used default title
4735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		$test_title = "unnamed";
4745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
4755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# Make sure css_filename is an absolute path (in case we're changing
4785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# directories)
4795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)if ($css_filename)
4805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
4815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (!($css_filename =~ /^\/(.*)$/))
4825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	{
4835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		$css_filename = $cwd."/".$css_filename;
4845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
4855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# Make sure tab_size is within valid range
4885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)if ($tab_size < 1)
4895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
4905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	print(STDERR "ERROR: invalid number of spaces specified: ".
4915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		     "$tab_size!\n");
4925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	exit(1);
4935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# Get HTML prolog and epilog
4965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)$html_prolog = get_html_prolog($html_prolog_file);
4975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)$html_epilog = get_html_epilog($html_epilog_file);
4985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# Issue a warning if --no-sourceview is enabled together with --frames
5005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)if ($no_sourceview && defined($frames))
5015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
5025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	warn("WARNING: option --frames disabled because --no-sourceview ".
5035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	     "was specified!\n");
5045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	$frames = undef;
5055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# Issue a warning if --no-prefix is enabled together with --prefix
5085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)if ($no_prefix && defined($dir_prefix))
5095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
5105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	warn("WARNING: option --prefix disabled because --no-prefix was ".
5115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	     "specified!\n");
5125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	$dir_prefix = undef;
5135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5153551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)@fileview_sortlist = ($SORT_FILE);
5163551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)@funcview_sortlist = ($SORT_FILE);
5173551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
5185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)if ($sort) {
5193551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	push(@fileview_sortlist, $SORT_LINE);
5203551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	push(@fileview_sortlist, $SORT_FUNC) if ($func_coverage);
5213551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	push(@fileview_sortlist, $SORT_BRANCH) if ($br_coverage);
5223551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	push(@funcview_sortlist, $SORT_LINE);
5235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)if ($frames)
5265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
5275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	# Include genpng code needed for overview image generation
5285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	do("$tool_dir/genpng");
5295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5313551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)# Ensure that the c++filt tool is available when using --demangle-cpp
5323551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)if ($demangle_cpp)
5333551c9c881056c480085172ff9840cab31610854Torne (Richard Coles){
5343551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	if (system_no_output(3, "c++filt", "--version")) {
5353551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)		die("ERROR: could not find c++filt tool needed for ".
5363551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)		    "--demangle-cpp\n");
5373551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	}
5383551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)}
5393551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
5405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# Make sure output_directory exists, create it if necessary
5415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)if ($output_directory)
5425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
5435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	stat($output_directory);
5445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (! -e _)
5465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	{
5473551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)		create_sub_dir($output_directory);
5485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
5495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# Do something
5525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)gen_html();
5535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)exit(0);
5555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#
5595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# print_usage(handle)
5605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#
5615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# Print usage information.
5625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#
5635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)sub print_usage(*)
5655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
5665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	local *HANDLE = $_[0];
5675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	print(HANDLE <<END_OF_USAGE);
5695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)Usage: $tool_name [OPTIONS] INFOFILE(S)
5705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)Create HTML output for coverage data found in INFOFILE. Note that INFOFILE
5725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)may also be a list of filenames.
5735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)Misc:
5755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  -h, --help                        Print this help, then exit
5765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  -v, --version                     Print version number, then exit
5775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  -q, --quiet                       Do not print progress messages
5783551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      --config-file FILENAME        Specify configuration file location
5793551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      --rc SETTING=VALUE            Override configuration file setting
5803551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      --ignore-errors ERRORS        Continue after ERRORS (source)
5815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)Operation:
5835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  -o, --output-directory OUTDIR     Write HTML output to OUTDIR
5845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  -s, --show-details                Generate detailed directory view
5855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  -d, --description-file DESCFILE   Read test case descriptions from DESCFILE
5865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  -k, --keep-descriptions           Do not remove unused test descriptions
5875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  -b, --baseline-file BASEFILE      Use BASEFILE as baseline file
5885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  -p, --prefix PREFIX               Remove PREFIX from all directory names
5895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      --no-prefix                   Do not remove prefix from directory names
5905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      --(no-)function-coverage      Enable (disable) function coverage display
5913551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      --(no-)branch-coverage        Enable (disable) branch coverage display
5925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)HTML output:
5945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  -f, --frames                      Use HTML frames for source code view
5955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  -t, --title TITLE                 Display TITLE in header of all pages
5965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  -c, --css-file CSSFILE            Use external style sheet file CSSFILE
5975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      --no-source                   Do not create source code view
5985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      --num-spaces NUM              Replace tabs with NUM spaces in source view
5995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      --highlight                   Highlight lines with converted-only data
6005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      --legend                      Include color legend in HTML output
6015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      --html-prolog FILE            Use FILE as HTML prolog for generated pages
6025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      --html-epilog FILE            Use FILE as HTML epilog for generated pages
6035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      --html-extension EXT          Use EXT as filename extension for pages
6045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      --html-gzip                   Use gzip to compress HTML
6055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      --(no-)sort                   Enable (disable) sorted coverage views
6063551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      --demangle-cpp                Demangle C++ function names
6075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)For more information see: $lcov_url
6095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)END_OF_USAGE
6105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	;
6115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#
6155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# get_rate(found, hit)
6165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#
6175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# Return a relative value for the specified found&hit values
6185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# which is used for sorting the corresponding entries in a
6195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# file list.
6205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#
6215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)sub get_rate($$)
6235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
6245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	my ($found, $hit) = @_;
6255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if ($found == 0) {
6275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		return 10000;
6285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
6295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return int($hit * 1000 / $found) * 10 + 2 - (1 / $found);
6305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#
6343551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)# get_overall_line(found, hit, name_singular, name_plural)
6353551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#
6363551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)# Return a string containing overall information for the specified
6373551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)# found/hit data.
6383551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#
6393551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
6403551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)sub get_overall_line($$$$)
6413551c9c881056c480085172ff9840cab31610854Torne (Richard Coles){
6423551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	my ($found, $hit, $name_sn, $name_pl) = @_;
6433551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	my $name;
6443551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
6453551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	return "no data found" if (!defined($found) || $found == 0);
6463551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	$name = ($found == 1) ? $name_sn : $name_pl;
6473551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	return rate($hit, $found, "% ($hit of $found $name)");
6483551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)}
6493551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
6503551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
6513551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#
6523551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)# print_overall_rate(ln_do, ln_found, ln_hit, fn_do, fn_found, fn_hit, br_do
6533551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#                    br_found, br_hit)
6543551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#
6553551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)# Print overall coverage rates for the specified coverage types.
6563551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#
6573551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
6583551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)sub print_overall_rate($$$$$$$$$)
6593551c9c881056c480085172ff9840cab31610854Torne (Richard Coles){
6603551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	my ($ln_do, $ln_found, $ln_hit, $fn_do, $fn_found, $fn_hit,
6613551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	    $br_do, $br_found, $br_hit) = @_;
6623551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
6633551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	info("Overall coverage rate:\n");
6643551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	info("  lines......: %s\n",
6653551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	     get_overall_line($ln_found, $ln_hit, "line", "lines"))
6663551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)		if ($ln_do);
6673551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	info("  functions..: %s\n",
6683551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	     get_overall_line($fn_found, $fn_hit, "function", "functions"))
6693551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)		if ($fn_do);
6703551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	info("  branches...: %s\n",
6713551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	     get_overall_line($br_found, $br_hit, "branch", "branches"))
6723551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)		if ($br_do);
6733551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)}
6743551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
6753551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
6763551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#
6775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# gen_html()
6785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#
6795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# Generate a set of HTML pages from contents of .info file INFO_FILENAME.
6805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# Files will be written to the current directory. If provided, test case
6815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# descriptions will be read from .tests file TEST_FILENAME and included
6825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# in ouput.
6835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#
6845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# Die on error.
6855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#
6865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)sub gen_html()
6885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
6895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	local *HTML_HANDLE;
6905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	my %overview;
6915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	my %base_data;
6925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	my $lines_found;
6935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	my $lines_hit;
6945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	my $fn_found;
6955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	my $fn_hit;
6963551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	my $br_found;
6973551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	my $br_hit;
6985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	my $overall_found = 0;
6995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	my $overall_hit = 0;
7005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	my $total_fn_found = 0;
7015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	my $total_fn_hit = 0;
7023551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	my $total_br_found = 0;
7033551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	my $total_br_hit = 0;
7045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	my $dir_name;
7055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	my $link_name;
7065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	my @dir_list;
7075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	my %new_info;
7085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	# Read in all specified .info files
7105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	foreach (@info_filenames)
7115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	{
7125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		%new_info = %{read_info_file($_)};
7135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		# Combine %new_info with %info_data
7155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		%info_data = %{combine_info_files(\%info_data, \%new_info)};
7165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
7175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	info("Found %d entries.\n", scalar(keys(%info_data)));
7195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	# Read and apply baseline data if specified
7215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if ($base_filename)
7225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	{
7235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		# Read baseline file
7245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		info("Reading baseline file $base_filename\n");
7255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		%base_data = %{read_info_file($base_filename)};
7265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		info("Found %d entries.\n", scalar(keys(%base_data)));
7275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		# Apply baseline
7295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		info("Subtracting baseline data.\n");
7305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		%info_data = %{apply_baseline(\%info_data, \%base_data)};
7315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
7325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	@dir_list = get_dir_list(keys(%info_data));
7345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if ($no_prefix)
7365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	{
7375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		# User requested that we leave filenames alone
7385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		info("User asked not to remove filename prefix\n");
7395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
7405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	elsif (!defined($dir_prefix))
7415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	{
7425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		# Get prefix common to most directories in list
7433551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)		$dir_prefix = get_prefix(1, keys(%info_data));
7445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		if ($dir_prefix)
7465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		{
7475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			info("Found common filename prefix \"$dir_prefix\"\n");
7485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		}
7495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		else
7505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		{
7515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			info("No common filename prefix found!\n");
7525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			$no_prefix=1;
7535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		}
7545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
7555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	else
7565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	{
7575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		info("Using user-specified filename prefix \"".
7585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		     "$dir_prefix\"\n");
7595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
7605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	# Read in test description file if specified
7625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if ($desc_filename)
7635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	{
7645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		info("Reading test description file $desc_filename\n");
7655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		%test_description = %{read_testfile($desc_filename)};
7665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		# Remove test descriptions which are not referenced
7685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		# from %info_data if user didn't tell us otherwise
7695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		if (!$keep_descriptions)
7705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		{
7715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			remove_unused_descriptions();
7725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		}
7735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
7745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	# Change to output directory if specified
7765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if ($output_directory)
7775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	{
7785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		chdir($output_directory)
7795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			or die("ERROR: cannot change to directory ".
7805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			"$output_directory!\n");
7815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
7825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	info("Writing .css and .png files.\n");
7845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	write_css_file();
7855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	write_png_files();
7865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if ($html_gzip)
7885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	{
7895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		info("Writing .htaccess file.\n");
7905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		write_htaccess_file();
7915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
7925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	info("Generating output.\n");
7945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	# Process each subdirectory and collect overview information
7965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	foreach $dir_name (@dir_list)
7975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	{
7983551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)		($lines_found, $lines_hit, $fn_found, $fn_hit,
7993551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)		 $br_found, $br_hit)
8005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			= process_dir($dir_name);
8015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8023551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)		# Handle files in root directory gracefully
8033551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)		$dir_name = "root" if ($dir_name eq "");
8043551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
8055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		# Remove prefix if applicable
8065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		if (!$no_prefix && $dir_prefix)
8075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		{
8085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			# Match directory names beginning with $dir_prefix
8095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			$dir_name = apply_prefix($dir_name, $dir_prefix);
8105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		}
8115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		# Generate name for directory overview HTML page
8135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		if ($dir_name =~ /^\/(.*)$/)
8145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		{
8155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			$link_name = substr($dir_name, 1)."/index.$html_ext";
8165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		}
8175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		else
8185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		{
8195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			$link_name = $dir_name."/index.$html_ext";
8205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		}
8215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		$overview{$dir_name} = [$lines_found, $lines_hit, $fn_found,
8233551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)					$fn_hit, $br_found, $br_hit, $link_name,
8245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)					get_rate($lines_found, $lines_hit),
8253551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)					get_rate($fn_found, $fn_hit),
8263551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)					get_rate($br_found, $br_hit)];
8275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		$overall_found	+= $lines_found;
8285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		$overall_hit	+= $lines_hit;
8295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		$total_fn_found	+= $fn_found;
8305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		$total_fn_hit	+= $fn_hit;
8313551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)		$total_br_found	+= $br_found;
8323551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)		$total_br_hit	+= $br_hit;
8335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
8345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	# Generate overview page
8365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	info("Writing directory view page.\n");
8375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	# Create sorted pages
8395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	foreach (@fileview_sortlist) {
8405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		write_dir_page($fileview_sortname[$_], ".", "", $test_title,
8415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			       undef, $overall_found, $overall_hit,
8423551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)			       $total_fn_found, $total_fn_hit, $total_br_found,
8433551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)			       $total_br_hit, \%overview, {}, {}, {}, 0, $_);
8445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
8455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	# Check if there are any test case descriptions to write out
8475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (%test_description)
8485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	{
8495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		info("Writing test case description file.\n");
8505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		write_description_file( \%test_description,
8515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)					$overall_found, $overall_hit,
8523551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)					$total_fn_found, $total_fn_hit,
8533551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)					$total_br_found, $total_br_hit);
8545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
8555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8563551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	print_overall_rate(1, $overall_found, $overall_hit,
8573551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)			   $func_coverage, $total_fn_found, $total_fn_hit,
8583551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)			   $br_coverage, $total_br_found, $total_br_hit);
8595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8603551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	chdir($cwd);
8615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
8625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#
8645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# html_create(handle, filename)
8655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#
8665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)sub html_create($$)
8685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
8695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	my $handle = $_[0];
8705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	my $filename = $_[1];
8715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if ($html_gzip)
8735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	{
8743551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)		open($handle, "|-", "gzip -c >'$filename'")
8755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			or die("ERROR: cannot open $filename for writing ".
8765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			       "(gzip)!\n");
8775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
8785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	else
8795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	{
8803551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)		open($handle, ">", $filename)
8815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			or die("ERROR: cannot open $filename for writing!\n");
8825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
8835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
8845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8853551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)sub write_dir_page($$$$$$$$$$$$$$$$$)
8865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
8875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	my ($name, $rel_dir, $base_dir, $title, $trunc_dir, $overall_found,
8883551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	    $overall_hit, $total_fn_found, $total_fn_hit, $total_br_found,
8893551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	    $total_br_hit, $overview, $testhash, $testfnchash, $testbrhash,
8903551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	    $view_type, $sort_type) = @_;
8915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	# Generate directory overview page including details
8935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	html_create(*HTML_HANDLE, "$rel_dir/index$name.$html_ext");
8945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (!defined($trunc_dir)) {
8955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		$trunc_dir = "";
8965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
8973551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	$title .= " - " if ($trunc_dir ne "");
8985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	write_html_prolog(*HTML_HANDLE, $base_dir, "LCOV - $title$trunc_dir");
8995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	write_header(*HTML_HANDLE, $view_type, $trunc_dir, $rel_dir,
9005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		     $overall_found, $overall_hit, $total_fn_found,
9013551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)		     $total_fn_hit, $total_br_found, $total_br_hit, $sort_type);
9025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	write_file_table(*HTML_HANDLE, $base_dir, $overview, $testhash,
9033551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)			 $testfnchash, $testbrhash, $view_type, $sort_type);
9045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	write_html_epilog(*HTML_HANDLE, $base_dir);
9055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	close(*HTML_HANDLE);
9065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
9075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#
9105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# process_dir(dir_name)
9115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#
9125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)sub process_dir($)
9145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
9155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	my $abs_dir = $_[0];
9165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	my $trunc_dir;
9175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	my $rel_dir = $abs_dir;
9185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	my $base_dir;
9195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	my $filename;
9205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	my %overview;
9215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	my $lines_found;
9225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	my $lines_hit;
9235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	my $fn_found;
9245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	my $fn_hit;
9253551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	my $br_found;
9263551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	my $br_hit;
9275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	my $overall_found=0;
9285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	my $overall_hit=0;
9295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	my $total_fn_found=0;
9305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	my $total_fn_hit=0;
9313551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	my $total_br_found = 0;
9323551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	my $total_br_hit = 0;
9335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	my $base_name;
9345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	my $extension;
9355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	my $testdata;
9365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	my %testhash;
9375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	my $testfncdata;
9385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	my %testfnchash;
9393551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	my $testbrdata;
9403551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	my %testbrhash;
9415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	my @sort_list;
9425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	local *HTML_HANDLE;
9435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	# Remove prefix if applicable
9455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (!$no_prefix)
9465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	{
9475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		# Match directory name beginning with $dir_prefix
9485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		$rel_dir = apply_prefix($rel_dir, $dir_prefix);
9495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
9505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	$trunc_dir = $rel_dir;
9525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	# Remove leading /
9545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if ($rel_dir =~ /^\/(.*)$/)
9555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	{
9565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		$rel_dir = substr($rel_dir, 1);
9575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
9585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9593551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	# Handle files in root directory gracefully
9603551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	$rel_dir = "root" if ($rel_dir eq "");
9613551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	$trunc_dir = "root" if ($trunc_dir eq "");
9623551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
9635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	$base_dir = get_relative_base_path($rel_dir);
9645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	create_sub_dir($rel_dir);
9665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	# Match filenames which specify files in this directory, not including
9685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	# sub-directories
9695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	foreach $filename (grep(/^\Q$abs_dir\E\/[^\/]*$/,keys(%info_data)))
9705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	{
9715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		my $page_link;
9725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		my $func_link;
9735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9743551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)		($lines_found, $lines_hit, $fn_found, $fn_hit, $br_found,
9753551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)		 $br_hit, $testdata, $testfncdata, $testbrdata) =
9763551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)			process_file($trunc_dir, $rel_dir, $filename);
9775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		$base_name = basename($filename);
9795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		if ($no_sourceview) {
9815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			$page_link = "";
9825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		} elsif ($frames) {
9835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			# Link to frameset page
9845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			$page_link = "$base_name.gcov.frameset.$html_ext";
9855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		} else {
9865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			# Link directory to source code view page
9875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			$page_link = "$base_name.gcov.$html_ext";
9885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		}
9895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		$overview{$base_name} = [$lines_found, $lines_hit, $fn_found,
9903551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)					 $fn_hit, $br_found, $br_hit,
9913551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)					 $page_link,
9925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)					 get_rate($lines_found, $lines_hit),
9933551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)					 get_rate($fn_found, $fn_hit),
9943551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)					 get_rate($br_found, $br_hit)];
9955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		$testhash{$base_name} = $testdata;
9975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		$testfnchash{$base_name} = $testfncdata;
9983551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)		$testbrhash{$base_name} = $testbrdata;
9995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		$overall_found	+= $lines_found;
10015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		$overall_hit	+= $lines_hit;
10025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		$total_fn_found += $fn_found;
10045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		$total_fn_hit   += $fn_hit;
10053551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
10063551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)		$total_br_found += $br_found;
10073551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)		$total_br_hit   += $br_hit;
10085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
10095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	# Create sorted pages
10115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	foreach (@fileview_sortlist) {
10125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		# Generate directory overview page (without details)	
10135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		write_dir_page($fileview_sortname[$_], $rel_dir, $base_dir,
10145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			       $test_title, $trunc_dir, $overall_found,
10155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			       $overall_hit, $total_fn_found, $total_fn_hit,
10163551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)			       $total_br_found, $total_br_hit, \%overview, {},
10173551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)			       {}, {}, 1, $_);
10185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		if (!$show_details) {
10195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			next;
10205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		}
10215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		# Generate directory overview page including details
10225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		write_dir_page("-detail".$fileview_sortname[$_], $rel_dir,
10235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			       $base_dir, $test_title, $trunc_dir,
10245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			       $overall_found, $overall_hit, $total_fn_found,
10253551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)			       $total_fn_hit, $total_br_found, $total_br_hit,
10263551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)			       \%overview, \%testhash, \%testfnchash,
10273551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)			       \%testbrhash, 1, $_);
10285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
10295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	# Calculate resulting line counts
10313551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	return ($overall_found, $overall_hit, $total_fn_found, $total_fn_hit,
10323551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)		$total_br_found, $total_br_hit);
10335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
10345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#
10375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# get_converted_lines(testdata)
10385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#
10395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# Return hash of line numbers of those lines which were only covered in
10405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# converted data sets.
10415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#
10425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)sub get_converted_lines($)
10445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
10455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	my $testdata = $_[0];
10465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	my $testcount;
10475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	my %converted;
10485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	my %nonconverted;
10495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	my $hash;
10505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	my $testcase;
10515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	my $line;
10525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	my %result;
10535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	# Get a hash containing line numbers with positive counts both for
10565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	# converted and original data sets
10575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	foreach $testcase (keys(%{$testdata}))
10585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	{
10595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		# Check to see if this is a converted data set
10605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		if ($testcase =~ /,diff$/)
10615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		{
10625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			$hash = \%converted;
10635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		}
10645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		else
10655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		{
10665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			$hash = \%nonconverted;
10675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		}
10685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		$testcount = $testdata->{$testcase};
10705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		# Add lines with a positive count to hash
10715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		foreach $line (keys%{$testcount})
10725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		{
10735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			if ($testcount->{$line} > 0)
10745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			{
10755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)				$hash->{$line} = 1;
10765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			}
10775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		}
10785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
10795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	# Combine both hashes to resulting list
10815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	foreach $line (keys(%converted))
10825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	{
10835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		if (!defined($nonconverted{$line}))
10845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		{
10855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			$result{$line} = 1;
10865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		}
10875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
10885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return \%result;
10905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
10915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10933551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)sub write_function_page($$$$$$$$$$$$$$$$$$)
10945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
10955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	my ($base_dir, $rel_dir, $trunc_dir, $base_name, $title,
10963551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	    $lines_found, $lines_hit, $fn_found, $fn_hit, $br_found, $br_hit,
10973551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	    $sumcount, $funcdata, $sumfnccount, $testfncdata, $sumbrcount,
10983551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	    $testbrdata, $sort_type) = @_;
10995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	my $pagetitle;
11005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	my $filename;
11015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	# Generate function table for this file
11035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if ($sort_type == 0) {
11045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		$filename = "$rel_dir/$base_name.func.$html_ext";
11055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	} else {
11065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		$filename = "$rel_dir/$base_name.func-sort-c.$html_ext";
11075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
11085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	html_create(*HTML_HANDLE, $filename);
11095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	$pagetitle = "LCOV - $title - $trunc_dir/$base_name - functions";
11105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	write_html_prolog(*HTML_HANDLE, $base_dir, $pagetitle);
11115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	write_header(*HTML_HANDLE, 4, "$trunc_dir/$base_name",
11125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		     "$rel_dir/$base_name", $lines_found, $lines_hit,
11133551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)		     $fn_found, $fn_hit, $br_found, $br_hit, $sort_type);
11145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	write_function_table(*HTML_HANDLE, "$base_name.gcov.$html_ext",
11155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			     $sumcount, $funcdata,
11163551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)			     $sumfnccount, $testfncdata, $sumbrcount,
11173551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)			     $testbrdata, $base_name,
11185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			     $base_dir, $sort_type);
11195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	write_html_epilog(*HTML_HANDLE, $base_dir, 1);
11205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	close(*HTML_HANDLE);
11215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
11225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#
11255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# process_file(trunc_dir, rel_dir, filename)
11265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#
11275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)sub process_file($$$)
11295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
11305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	info("Processing file ".apply_prefix($_[2], $dir_prefix)."\n");
11315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	my $trunc_dir = $_[0];
11335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	my $rel_dir = $_[1];
11345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	my $filename = $_[2];
11355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	my $base_name = basename($filename);
11365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	my $base_dir = get_relative_base_path($rel_dir);
11375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	my $testdata;
11385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	my $testcount;
11395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	my $sumcount;
11405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	my $funcdata;
11415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	my $checkdata;
11425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	my $testfncdata;
11435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	my $sumfnccount;
11443551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	my $testbrdata;
11453551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	my $sumbrcount;
11465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	my $lines_found;
11475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	my $lines_hit;
11485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	my $fn_found;
11495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	my $fn_hit;
11503551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	my $br_found;
11513551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	my $br_hit;
11525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	my $converted;
11535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	my @source;
11545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	my $pagetitle;
11555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	local *HTML_HANDLE;
11565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	($testdata, $sumcount, $funcdata, $checkdata, $testfncdata,
11583551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	 $sumfnccount, $testbrdata, $sumbrcount, $lines_found, $lines_hit,
11593551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	 $fn_found, $fn_hit, $br_found, $br_hit)
11605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		= get_info_entry($info_data{$filename});
11615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	# Return after this point in case user asked us not to generate
11635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	# source code view
11645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if ($no_sourceview)
11655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	{
11663551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)		return ($lines_found, $lines_hit, $fn_found, $fn_hit,
11673551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)			$br_found, $br_hit, $testdata, $testfncdata,
11683551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)			$testbrdata);
11695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
11705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	$converted = get_converted_lines($testdata);
11725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	# Generate source code view for this file
11735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	html_create(*HTML_HANDLE, "$rel_dir/$base_name.gcov.$html_ext");
11745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	$pagetitle = "LCOV - $test_title - $trunc_dir/$base_name";
11755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	write_html_prolog(*HTML_HANDLE, $base_dir, $pagetitle);
11765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	write_header(*HTML_HANDLE, 2, "$trunc_dir/$base_name",
11775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		     "$rel_dir/$base_name", $lines_found, $lines_hit,
11783551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)		     $fn_found, $fn_hit, $br_found, $br_hit, 0);
11795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	@source = write_source(*HTML_HANDLE, $filename, $sumcount, $checkdata,
11803551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)			       $converted, $funcdata, $sumbrcount);
11815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	write_html_epilog(*HTML_HANDLE, $base_dir, 1);
11835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	close(*HTML_HANDLE);
11845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if ($func_coverage) {
11865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		# Create function tables
11875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		foreach (@funcview_sortlist) {
11885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			write_function_page($base_dir, $rel_dir, $trunc_dir,
11895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)					    $base_name, $test_title,
11905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)					    $lines_found, $lines_hit,
11913551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)					    $fn_found, $fn_hit, $br_found,
11923551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)					    $br_hit, $sumcount,
11935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)					    $funcdata, $sumfnccount,
11943551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)					    $testfncdata, $sumbrcount,
11953551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)					    $testbrdata, $_);
11965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		}
11975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
11985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	# Additional files are needed in case of frame output
12005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (!$frames)
12015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	{
12023551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)		return ($lines_found, $lines_hit, $fn_found, $fn_hit,
12033551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)			$br_found, $br_hit, $testdata, $testfncdata,
12043551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)			$testbrdata);
12055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
12065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	# Create overview png file
12085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	gen_png("$rel_dir/$base_name.gcov.png", $overview_width, $tab_size,
12095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		@source);
12105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	# Create frameset page
12125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	html_create(*HTML_HANDLE,
12135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    "$rel_dir/$base_name.gcov.frameset.$html_ext");
12145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	write_frameset(*HTML_HANDLE, $base_dir, $base_name, $pagetitle);
12155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	close(*HTML_HANDLE);
12165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	# Write overview frame
12185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	html_create(*HTML_HANDLE,
12195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    "$rel_dir/$base_name.gcov.overview.$html_ext");
12205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	write_overview(*HTML_HANDLE, $base_dir, $base_name, $pagetitle,
12215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		       scalar(@source));
12225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	close(*HTML_HANDLE);
12235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12243551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	return ($lines_found, $lines_hit, $fn_found, $fn_hit, $br_found,
12253551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)		$br_hit, $testdata, $testfncdata, $testbrdata);
12265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
12275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#
12305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# read_info_file(info_filename)
12315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#
12325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# Read in the contents of the .info file specified by INFO_FILENAME. Data will
12335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# be returned as a reference to a hash containing the following mappings:
12345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#
12355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# %result: for each filename found in file -> \%data
12365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#
12375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# %data: "test"  -> \%testdata
12385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#        "sum"   -> \%sumcount
12395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#        "func"  -> \%funcdata
12405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#        "found" -> $lines_found (number of instrumented lines found in file)
12415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#	 "hit"   -> $lines_hit (number of executed lines in file)
12425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#        "check" -> \%checkdata
12435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#        "testfnc" -> \%testfncdata
12445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#        "sumfnc"  -> \%sumfnccount
12453551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#        "testbr"  -> \%testbrdata
12463551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#        "sumbr"   -> \%sumbrcount
12475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#
12485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# %testdata   : name of test affecting this file -> \%testcount
12495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# %testfncdata: name of test affecting this file -> \%testfnccount
12503551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)# %testbrdata:  name of test affecting this file -> \%testbrcount
12515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#
12525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# %testcount   : line number   -> execution count for a single test
12535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# %testfnccount: function name -> execution count for a single test
12543551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)# %testbrcount : line number   -> branch coverage data for a single test
12555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# %sumcount    : line number   -> execution count for all tests
12565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# %sumfnccount : function name -> execution count for all tests
12573551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)# %sumbrcount  : line number   -> branch coverage data for all tests
12585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# %funcdata    : function name -> line number
12595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# %checkdata   : line number   -> checksum of source code line
12603551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)# $brdata      : vector of items: block, branch, taken
12615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# 
12625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# Note that .info file sections referring to the same file and test name
12635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# will automatically be combined by adding all execution counts.
12645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#
12655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# Note that if INFO_FILENAME ends with ".gz", it is assumed that the file
12665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# is compressed using GZIP. If available, GUNZIP will be used to decompress
12675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# this file.
12685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#
12695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# Die on error.
12705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#
12715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)sub read_info_file($)
12735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
12745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	my $tracefile = $_[0];		# Name of tracefile
12755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	my %result;			# Resulting hash: file -> data
12765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	my $data;			# Data handle for current entry
12775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	my $testdata;			#       "             "
12785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	my $testcount;			#       "             "
12795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	my $sumcount;			#       "             "
12805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	my $funcdata;			#       "             "
12815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	my $checkdata;			#       "             "
12825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	my $testfncdata;
12835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	my $testfnccount;
12845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	my $sumfnccount;
12853551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	my $testbrdata;
12863551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	my $testbrcount;
12873551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	my $sumbrcount;
12885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	my $line;			# Current line read from .info file
12895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	my $testname;			# Current test name
12905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	my $filename;			# Current filename
12915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	my $hitcount;			# Count for lines hit
12925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	my $count;			# Execution count of current line
12935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	my $negative;			# If set, warn about negative counts
12945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	my $changed_testname;		# If set, warn about changed testname
12955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	my $line_checksum;		# Checksum of current line
12963551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	my $br_found;
12973551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	my $br_hit;
12985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	local *INFO_HANDLE;		# Filehandle for .info file
12995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	info("Reading data file $tracefile\n");
13015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	# Check if file exists and is readable
13035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	stat($_[0]);
13045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (!(-r _))
13055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	{
13065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		die("ERROR: cannot read file $_[0]!\n");
13075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
13085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	# Check if this is really a plain file
13105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (!(-f _))
13115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	{
13125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		die("ERROR: not a plain file: $_[0]!\n");
13135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
13145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	# Check for .gz extension
13165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if ($_[0] =~ /\.gz$/)
13175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	{
13185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		# Check for availability of GZIP tool
13195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		system_no_output(1, "gunzip" ,"-h")
13205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			and die("ERROR: gunzip command not available!\n");
13215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		# Check integrity of compressed file
13235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		system_no_output(1, "gunzip", "-t", $_[0])
13245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			and die("ERROR: integrity check failed for ".
13255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)				"compressed file $_[0]!\n");
13265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		# Open compressed file
13283551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)		open(INFO_HANDLE, "-|", "gunzip -c '$_[0]'")
13295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			or die("ERROR: cannot start gunzip to decompress ".
13305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			       "file $_[0]!\n");
13315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
13325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	else
13335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	{
13345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		# Open decompressed file
13353551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)		open(INFO_HANDLE, "<", $_[0])
13365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			or die("ERROR: cannot read file $_[0]!\n");
13375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
13385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	$testname = "";
13405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	while (<INFO_HANDLE>)
13415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	{
13425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		chomp($_);
13435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		$line = $_;
13445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		# Switch statement
13465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		foreach ($line)
13475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		{
13483551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)			/^TN:([^,]*)(,diff)?/ && do
13495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			{
13505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)				# Test name information found
13515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)				$testname = defined($1) ? $1 : "";
13525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)				if ($testname =~ s/\W/_/g)
13535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)				{
13545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)					$changed_testname = 1;
13555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)				}
13563551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)				$testname .= $2 if (defined($2));
13575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)				last;
13585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			};
13595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			/^[SK]F:(.*)/ && do
13615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			{
13625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)				# Filename information found
13635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)				# Retrieve data for new entry
13645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)				$filename = $1;
13655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)				$data = $result{$filename};
13675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)				($testdata, $sumcount, $funcdata, $checkdata,
13683551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)				 $testfncdata, $sumfnccount, $testbrdata,
13693551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)				 $sumbrcount) =
13705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)					get_info_entry($data);
13715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)				if (defined($testname))
13735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)				{
13745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)					$testcount = $testdata->{$testname};
13755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)					$testfnccount = $testfncdata->{$testname};
13763551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)					$testbrcount = $testbrdata->{$testname};
13775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)				}
13785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)				else
13795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)				{
13805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)					$testcount = {};
13815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)					$testfnccount = {};
13823551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)					$testbrcount = {};
13835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)				}
13845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)				last;
13855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			};
13865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			/^DA:(\d+),(-?\d+)(,[^,\s]+)?/ && do
13885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			{
13895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)				# Fix negative counts
13905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)				$count = $2 < 0 ? 0 : $2;
13915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)				if ($2 < 0)
13925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)				{
13935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)					$negative = 1;
13945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)				}
13955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)				# Execution count found, add to structure
13965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)				# Add summary counts
13975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)				$sumcount->{$1} += $count;
13985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)				# Add test-specific counts
14005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)				if (defined($testname))
14015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)				{
14025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)					$testcount->{$1} += $count;
14035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)				}
14045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)				# Store line checksum if available
14065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)				if (defined($3))
14075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)				{
14085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)					$line_checksum = substr($3, 1);
14095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)					# Does it match a previous definition
14115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)					if (defined($checkdata->{$1}) &&
14125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)					    ($checkdata->{$1} ne
14135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)					     $line_checksum))
14145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)					{
14155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)						die("ERROR: checksum mismatch ".
14165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)						    "at $filename:$1\n");
14175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)					}
14185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)					$checkdata->{$1} = $line_checksum;
14205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)				}
14215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)				last;
14225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			};
14235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			/^FN:(\d+),([^,]+)/ && do
14255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			{
14263551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)				last if (!$func_coverage);
14273551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
14285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)				# Function data found, add to structure
14295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)				$funcdata->{$2} = $1;
14305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)				# Also initialize function call data
14325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)				if (!defined($sumfnccount->{$2})) {
14335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)					$sumfnccount->{$2} = 0;
14345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)				}
14355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)				if (defined($testname))
14365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)				{
14375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)					if (!defined($testfnccount->{$2})) {
14385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)						$testfnccount->{$2} = 0;
14395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)					}
14405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)				}
14415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)				last;
14425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			};
14435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			/^FNDA:(\d+),([^,]+)/ && do
14455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			{
14463551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)				last if (!$func_coverage);
14475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)				# Function call count found, add to structure
14485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)				# Add summary counts
14495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)				$sumfnccount->{$2} += $1;
14505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)				# Add test-specific counts
14525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)				if (defined($testname))
14535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)				{
14545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)					$testfnccount->{$2} += $1;
14555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)				}
14565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)				last;
14575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			};
14583551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
14593551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)			/^BRDA:(\d+),(\d+),(\d+),(\d+|-)/ && do {
14603551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)				# Branch coverage data found
14613551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)				my ($line, $block, $branch, $taken) =
14623551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)				   ($1, $2, $3, $4);
14633551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
14643551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)				last if (!$br_coverage);
14653551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)				$sumbrcount->{$line} =
14663551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)					br_ivec_push($sumbrcount->{$line},
14673551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)						     $block, $branch, $taken);
14683551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
14693551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)				# Add test-specific counts
14703551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)				if (defined($testname)) {
14713551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)					$testbrcount->{$line} =
14723551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)						br_ivec_push(
14733551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)							$testbrcount->{$line},
14743551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)							$block, $branch,
14753551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)							$taken);
14763551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)				}
14773551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)				last;
14783551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)			};
14793551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
14805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			/^end_of_record/ && do
14815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			{
14825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)				# Found end of section marker
14835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)				if ($filename)
14845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)				{
14855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)					# Store current section data
14865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)					if (defined($testname))
14875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)					{
14885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)						$testdata->{$testname} =
14895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)							$testcount;
14905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)						$testfncdata->{$testname} =
14915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)							$testfnccount;
14923551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)						$testbrdata->{$testname} =
14933551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)							$testbrcount;
14945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)					}	
14955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)					set_info_entry($data, $testdata,
14975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)						       $sumcount, $funcdata,
14985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)						       $checkdata, $testfncdata,
14993551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)						       $sumfnccount,
15003551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)						       $testbrdata,
15013551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)						       $sumbrcount);
15025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)					$result{$filename} = $data;
15035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)					last;
15045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)				}
15055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			};
15065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			# default
15085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			last;
15095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		}
15105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
15115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	close(INFO_HANDLE);
15125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	# Calculate lines_found and lines_hit for each file
15145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	foreach $filename (keys(%result))
15155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	{
15165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		$data = $result{$filename};
15175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		($testdata, $sumcount, undef, undef, $testfncdata,
15193551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)		 $sumfnccount, $testbrdata, $sumbrcount) =
15203551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)			get_info_entry($data);
15215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		# Filter out empty files
15235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		if (scalar(keys(%{$sumcount})) == 0)
15245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		{
15255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			delete($result{$filename});
15265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			next;
15275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		}
15285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		# Filter out empty test cases
15295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		foreach $testname (keys(%{$testdata}))
15305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		{
15315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			if (!defined($testdata->{$testname}) ||
15325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			    scalar(keys(%{$testdata->{$testname}})) == 0)
15335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			{
15345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)				delete($testdata->{$testname});
15355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)				delete($testfncdata->{$testname});
15365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			}
15375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		}
15385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		$data->{"found"} = scalar(keys(%{$sumcount}));
15405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		$hitcount = 0;
15415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		foreach (keys(%{$sumcount}))
15435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		{
15445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			if ($sumcount->{$_} > 0) { $hitcount++; }
15455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		}
15465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		$data->{"hit"} = $hitcount;
15485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		# Get found/hit values for function call data
15505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		$data->{"f_found"} = scalar(keys(%{$sumfnccount}));
15515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		$hitcount = 0;
15525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		foreach (keys(%{$sumfnccount})) {
15545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			if ($sumfnccount->{$_} > 0) {
15555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)				$hitcount++;
15565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			}
15575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		}
15585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		$data->{"f_hit"} = $hitcount;
15593551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
15603551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)		# Get found/hit values for branch data
15613551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)		($br_found, $br_hit) = get_br_found_and_hit($sumbrcount);
15623551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
15633551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)		$data->{"b_found"} = $br_found;
15643551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)		$data->{"b_hit"} = $br_hit;
15655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
15665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (scalar(keys(%result)) == 0)
15685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	{
15695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		die("ERROR: no valid records found in tracefile $tracefile\n");
15705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
15715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if ($negative)
15725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	{
15735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		warn("WARNING: negative counts found in tracefile ".
15745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		     "$tracefile\n");
15755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
15765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if ($changed_testname)
15775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	{
15785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		warn("WARNING: invalid characters removed from testname in ".
15795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		     "tracefile $tracefile\n");
15805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
15815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return(\%result);
15835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
15845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#
15875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# get_info_entry(hash_ref)
15885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#
15895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# Retrieve data from an entry of the structure generated by read_info_file().
15905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# Return a list of references to hashes:
15915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# (test data hash ref, sum count hash ref, funcdata hash ref, checkdata hash
15925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#  ref, testfncdata hash ref, sumfnccount hash ref, lines found, lines hit,
15935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#  functions found, functions hit)
15945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#
15955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)sub get_info_entry($)
15975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
15985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	my $testdata_ref = $_[0]->{"test"};
15995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	my $sumcount_ref = $_[0]->{"sum"};
16005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	my $funcdata_ref = $_[0]->{"func"};
16015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	my $checkdata_ref = $_[0]->{"check"};
16025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	my $testfncdata = $_[0]->{"testfnc"};
16035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	my $sumfnccount = $_[0]->{"sumfnc"};
16043551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	my $testbrdata = $_[0]->{"testbr"};
16053551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	my $sumbrcount = $_[0]->{"sumbr"};
16065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	my $lines_found = $_[0]->{"found"};
16075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	my $lines_hit = $_[0]->{"hit"};
16085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	my $fn_found = $_[0]->{"f_found"};
16095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	my $fn_hit = $_[0]->{"f_hit"};
16103551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	my $br_found = $_[0]->{"b_found"};
16113551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	my $br_hit = $_[0]->{"b_hit"};
16125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return ($testdata_ref, $sumcount_ref, $funcdata_ref, $checkdata_ref,
16143551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)		$testfncdata, $sumfnccount, $testbrdata, $sumbrcount,
16153551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)		$lines_found, $lines_hit, $fn_found, $fn_hit,
16163551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)		$br_found, $br_hit);
16175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
16185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#
16215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# set_info_entry(hash_ref, testdata_ref, sumcount_ref, funcdata_ref,
16223551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#                checkdata_ref, testfncdata_ref, sumfcncount_ref,
16233551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#                testbrdata_ref, sumbrcount_ref[,lines_found,
16243551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#                lines_hit, f_found, f_hit, $b_found, $b_hit])
16255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#
16265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# Update the hash referenced by HASH_REF with the provided data references.
16275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#
16285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16293551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)sub set_info_entry($$$$$$$$$;$$$$$$)
16305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
16315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	my $data_ref = $_[0];
16325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	$data_ref->{"test"} = $_[1];
16345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	$data_ref->{"sum"} = $_[2];
16355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	$data_ref->{"func"} = $_[3];
16365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	$data_ref->{"check"} = $_[4];
16375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	$data_ref->{"testfnc"} = $_[5];
16385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	$data_ref->{"sumfnc"} = $_[6];
16393551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	$data_ref->{"testbr"} = $_[7];
16403551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	$data_ref->{"sumbr"} = $_[8];
16413551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
16423551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	if (defined($_[9])) { $data_ref->{"found"} = $_[9]; }
16433551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	if (defined($_[10])) { $data_ref->{"hit"} = $_[10]; }
16443551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	if (defined($_[11])) { $data_ref->{"f_found"} = $_[11]; }
16453551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	if (defined($_[12])) { $data_ref->{"f_hit"} = $_[12]; }
16463551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	if (defined($_[13])) { $data_ref->{"b_found"} = $_[13]; }
16473551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	if (defined($_[14])) { $data_ref->{"b_hit"} = $_[14]; }
16485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
16495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#
16525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# add_counts(data1_ref, data2_ref)
16535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#
16545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# DATA1_REF and DATA2_REF are references to hashes containing a mapping
16555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#
16565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#   line number -> execution count
16575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#
16585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# Return a list (RESULT_REF, LINES_FOUND, LINES_HIT) where RESULT_REF
16595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# is a reference to a hash containing the combined mapping in which
16605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# execution counts are added.
16615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#
16625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)sub add_counts($$)
16645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
16655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	my %data1 = %{$_[0]};	# Hash 1
16665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	my %data2 = %{$_[1]};	# Hash 2
16675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	my %result;		# Resulting hash
16685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	my $line;		# Current line iteration scalar
16695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	my $data1_count;	# Count of line in hash1
16705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	my $data2_count;	# Count of line in hash2
16715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	my $found = 0;		# Total number of lines found
16725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	my $hit = 0;		# Number of lines with a count > 0
16735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	foreach $line (keys(%data1))
16755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	{
16765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		$data1_count = $data1{$line};
16775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		$data2_count = $data2{$line};
16785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		# Add counts if present in both hashes
16805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		if (defined($data2_count)) { $data1_count += $data2_count; }
16815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		# Store sum in %result
16835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		$result{$line} = $data1_count;
16845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		$found++;
16865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		if ($data1_count > 0) { $hit++; }
16875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
16885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	# Add lines unique to data2
16905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	foreach $line (keys(%data2))
16915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	{
16925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		# Skip lines already in data1
16935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		if (defined($data1{$line})) { next; }
16945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		# Copy count from data2
16965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		$result{$line} = $data2{$line};
16975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		$found++;
16995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		if ($result{$line} > 0) { $hit++; }
17005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
17015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return (\%result, $found, $hit);
17035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
17045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#
17075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# merge_checksums(ref1, ref2, filename)
17085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#
17095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# REF1 and REF2 are references to hashes containing a mapping
17105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#
17115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#   line number -> checksum
17125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#
17135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# Merge checksum lists defined in REF1 and REF2 and return reference to
17145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# resulting hash. Die if a checksum for a line is defined in both hashes
17155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# but does not match.
17165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#
17175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)sub merge_checksums($$$)
17195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
17205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	my $ref1 = $_[0];
17215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	my $ref2 = $_[1];
17225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	my $filename = $_[2];
17235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	my %result;
17245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	my $line;
17255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	foreach $line (keys(%{$ref1}))
17275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	{
17285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		if (defined($ref2->{$line}) &&
17295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    ($ref1->{$line} ne $ref2->{$line}))
17305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		{
17315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			die("ERROR: checksum mismatch at $filename:$line\n");
17325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		}
17335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		$result{$line} = $ref1->{$line};
17345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
17355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	foreach $line (keys(%{$ref2}))
17375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	{
17385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		$result{$line} = $ref2->{$line};
17395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
17405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return \%result;
17425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
17435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#
17465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# merge_func_data(funcdata1, funcdata2, filename)
17475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#
17485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)sub merge_func_data($$$)
17505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
17515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	my ($funcdata1, $funcdata2, $filename) = @_;
17525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	my %result;
17535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	my $func;
17545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17553551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	if (defined($funcdata1)) {
17563551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)		%result = %{$funcdata1};
17573551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	}
17585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	foreach $func (keys(%{$funcdata2})) {
17605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		my $line1 = $result{$func};
17615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		my $line2 = $funcdata2->{$func};
17625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		if (defined($line1) && ($line1 != $line2)) {
17645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			warn("WARNING: function data mismatch at ".
17655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			     "$filename:$line2\n");
17665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			next;
17675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		}
17685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		$result{$func} = $line2;
17695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
17705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return \%result;
17725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
17735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#
17765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# add_fnccount(fnccount1, fnccount2)
17775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#
17785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# Add function call count data. Return list (fnccount_added, f_found, f_hit)
17795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#
17805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)sub add_fnccount($$)
17825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
17835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	my ($fnccount1, $fnccount2) = @_;
17845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	my %result;
17855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	my $fn_found;
17865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	my $fn_hit;
17875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	my $function;
17885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17893551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	if (defined($fnccount1)) {
17903551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)		%result = %{$fnccount1};
17913551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	}
17925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	foreach $function (keys(%{$fnccount2})) {
17935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		$result{$function} += $fnccount2->{$function};
17945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
17955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	$fn_found = scalar(keys(%result));
17965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	$fn_hit = 0;
17975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	foreach $function (keys(%result)) {
17985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		if ($result{$function} > 0) {
17995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			$fn_hit++;
18005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		}
18015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
18025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
18035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return (\%result, $fn_found, $fn_hit);
18045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
18055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
18065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#
18075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# add_testfncdata(testfncdata1, testfncdata2)
18085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#
18095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# Add function call count data for several tests. Return reference to
18105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# added_testfncdata.
18115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#
18125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
18135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)sub add_testfncdata($$)
18145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
18155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	my ($testfncdata1, $testfncdata2) = @_;
18165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	my %result;
18175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	my $testname;
18185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
18195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	foreach $testname (keys(%{$testfncdata1})) {
18205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		if (defined($testfncdata2->{$testname})) {
18215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			my $fnccount;
18225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
18235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			# Function call count data for this testname exists
18245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			# in both data sets: add
18255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			($fnccount) = add_fnccount(
18265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)				$testfncdata1->{$testname},
18275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)				$testfncdata2->{$testname});
18285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			$result{$testname} = $fnccount;
18295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			next;
18305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		}
18315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		# Function call count data for this testname is unique to
18325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		# data set 1: copy
18335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		$result{$testname} = $testfncdata1->{$testname};
18345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
18355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
18365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	# Add count data for testnames unique to data set 2
18375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	foreach $testname (keys(%{$testfncdata2})) {
18385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		if (!defined($result{$testname})) {
18395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			$result{$testname} = $testfncdata2->{$testname};
18405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		}
18415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
18425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return \%result;
18435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
18445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
18453551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
18463551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#
18473551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)# brcount_to_db(brcount)
18483551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#
18493551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)# Convert brcount data to the following format:
18503551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#
18513551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)# db:          line number    -> block hash
18523551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)# block hash:  block number   -> branch hash
18533551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)# branch hash: branch number  -> taken value
18543551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#
18553551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
18563551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)sub brcount_to_db($)
18573551c9c881056c480085172ff9840cab31610854Torne (Richard Coles){
18583551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	my ($brcount) = @_;
18593551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	my $line;
18603551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	my $db;
18613551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
18623551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	# Add branches from first count to database
18633551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	foreach $line (keys(%{$brcount})) {
18643551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)		my $brdata = $brcount->{$line};
18653551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)		my $i;
18663551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)		my $num = br_ivec_len($brdata);
18673551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
18683551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)		for ($i = 0; $i < $num; $i++) {
18693551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)			my ($block, $branch, $taken) = br_ivec_get($brdata, $i);
18703551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
18713551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)			$db->{$line}->{$block}->{$branch} = $taken;
18723551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)		}
18733551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	}
18743551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
18753551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	return $db;
18763551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)}
18773551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
18783551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
18793551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#
18803551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)# db_to_brcount(db)
18813551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#
18823551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)# Convert branch coverage data back to brcount format.
18833551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#
18843551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
18853551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)sub db_to_brcount($)
18863551c9c881056c480085172ff9840cab31610854Torne (Richard Coles){
18873551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	my ($db) = @_;
18883551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	my $line;
18893551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	my $brcount = {};
18903551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	my $br_found = 0;
18913551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	my $br_hit = 0;
18923551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
18933551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	# Convert database back to brcount format
18943551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	foreach $line (sort({$a <=> $b} keys(%{$db}))) {
18953551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)		my $ldata = $db->{$line};
18963551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)		my $brdata;
18973551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)		my $block;
18983551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
18993551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)		foreach $block (sort({$a <=> $b} keys(%{$ldata}))) {
19003551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)			my $bdata = $ldata->{$block};
19013551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)			my $branch;
19023551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
19033551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)			foreach $branch (sort({$a <=> $b} keys(%{$bdata}))) {
19043551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)				my $taken = $bdata->{$branch};
19053551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
19063551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)				$br_found++;
19073551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)				$br_hit++ if ($taken ne "-" && $taken > 0);
19083551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)				$brdata = br_ivec_push($brdata, $block,
19093551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)						       $branch, $taken);
19103551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)			}
19113551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)		}
19123551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)		$brcount->{$line} = $brdata;
19133551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	}
19143551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
19153551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	return ($brcount, $br_found, $br_hit);
19163551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)}
19173551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
19183551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
19193551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#
19203551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)# combine_brcount(brcount1, brcount2, type)
19213551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#
19223551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)# If add is BR_ADD, add branch coverage data and return list (brcount_added,
19233551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)# br_found, br_hit). If add is BR_SUB, subtract the taken values of brcount2
19243551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)# from brcount1 and return (brcount_sub, br_found, br_hit).
19253551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#
19263551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
19273551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)sub combine_brcount($$$)
19283551c9c881056c480085172ff9840cab31610854Torne (Richard Coles){
19293551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	my ($brcount1, $brcount2, $type) = @_;
19303551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	my $line;
19313551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	my $block;
19323551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	my $branch;
19333551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	my $taken;
19343551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	my $db;
19353551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	my $br_found = 0;
19363551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	my $br_hit = 0;
19373551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	my $result;
19383551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
19393551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	# Convert branches from first count to database
19403551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	$db = brcount_to_db($brcount1);
19413551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	# Combine values from database and second count
19423551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	foreach $line (keys(%{$brcount2})) {
19433551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)		my $brdata = $brcount2->{$line};
19443551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)		my $num = br_ivec_len($brdata);
19453551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)		my $i;
19463551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
19473551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)		for ($i = 0; $i < $num; $i++) {
19483551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)			($block, $branch, $taken) = br_ivec_get($brdata, $i);
19493551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)			my $new_taken = $db->{$line}->{$block}->{$branch};
19503551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
19513551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)			if ($type == $BR_ADD) {
19523551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)				$new_taken = br_taken_add($new_taken, $taken);
19533551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)			} elsif ($type == $BR_SUB) {
19543551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)				$new_taken = br_taken_sub($new_taken, $taken);
19553551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)			}
19563551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)			$db->{$line}->{$block}->{$branch} = $new_taken
19573551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)				if (defined($new_taken));
19583551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)		}
19593551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	}
19603551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	# Convert database back to brcount format
19613551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	($result, $br_found, $br_hit) = db_to_brcount($db);
19623551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
19633551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	return ($result, $br_found, $br_hit);
19643551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)}
19653551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
19663551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
19673551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#
19683551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)# add_testbrdata(testbrdata1, testbrdata2)
19693551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#
19703551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)# Add branch coverage data for several tests. Return reference to
19713551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)# added_testbrdata.
19723551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#
19733551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
19743551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)sub add_testbrdata($$)
19753551c9c881056c480085172ff9840cab31610854Torne (Richard Coles){
19763551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	my ($testbrdata1, $testbrdata2) = @_;
19773551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	my %result;
19783551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	my $testname;
19793551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
19803551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	foreach $testname (keys(%{$testbrdata1})) {
19813551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)		if (defined($testbrdata2->{$testname})) {
19823551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)			my $brcount;
19833551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
19843551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)			# Branch coverage data for this testname exists
19853551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)			# in both data sets: add
19863551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)			($brcount) = combine_brcount($testbrdata1->{$testname},
19873551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)					 $testbrdata2->{$testname}, $BR_ADD);
19883551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)			$result{$testname} = $brcount;
19893551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)			next;
19903551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)		}
19913551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)		# Branch coverage data for this testname is unique to
19923551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)		# data set 1: copy
19933551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)		$result{$testname} = $testbrdata1->{$testname};
19943551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	}
19953551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
19963551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	# Add count data for testnames unique to data set 2
19973551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	foreach $testname (keys(%{$testbrdata2})) {
19983551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)		if (!defined($result{$testname})) {
19993551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)			$result{$testname} = $testbrdata2->{$testname};
20003551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)		}
20013551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	}
20023551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	return \%result;
20033551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)}
20043551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
20053551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
20065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#
20075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# combine_info_entries(entry_ref1, entry_ref2, filename)
20085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#
20095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# Combine .info data entry hashes referenced by ENTRY_REF1 and ENTRY_REF2.
20105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# Return reference to resulting hash.
20115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#
20125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
20135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)sub combine_info_entries($$$)
20145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
20155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	my $entry1 = $_[0];	# Reference to hash containing first entry
20165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	my $testdata1;
20175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	my $sumcount1;
20185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	my $funcdata1;
20195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	my $checkdata1;
20205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	my $testfncdata1;
20215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	my $sumfnccount1;
20223551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	my $testbrdata1;
20233551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	my $sumbrcount1;
20245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
20255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	my $entry2 = $_[1];	# Reference to hash containing second entry
20265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	my $testdata2;
20275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	my $sumcount2;
20285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	my $funcdata2;
20295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	my $checkdata2;
20305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	my $testfncdata2;
20315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	my $sumfnccount2;
20323551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	my $testbrdata2;
20333551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	my $sumbrcount2;
20345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
20355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	my %result;		# Hash containing combined entry
20365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	my %result_testdata;
20375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	my $result_sumcount = {};
20385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	my $result_funcdata;
20395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	my $result_testfncdata;
20405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	my $result_sumfnccount;
20413551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	my $result_testbrdata;
20423551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	my $result_sumbrcount;
20435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	my $lines_found;
20445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	my $lines_hit;
20455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	my $fn_found;
20465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	my $fn_hit;
20473551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	my $br_found;
20483551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	my $br_hit;
20495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
20505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	my $testname;
20515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	my $filename = $_[2];
20525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
20535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	# Retrieve data
20545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	($testdata1, $sumcount1, $funcdata1, $checkdata1, $testfncdata1,
20553551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	 $sumfnccount1, $testbrdata1, $sumbrcount1) = get_info_entry($entry1);
20565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	($testdata2, $sumcount2, $funcdata2, $checkdata2, $testfncdata2,
20573551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	 $sumfnccount2, $testbrdata2, $sumbrcount2) = get_info_entry($entry2);
20585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
20595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	# Merge checksums
20605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	$checkdata1 = merge_checksums($checkdata1, $checkdata2, $filename);
20615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
20625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	# Combine funcdata
20635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	$result_funcdata = merge_func_data($funcdata1, $funcdata2, $filename);
20645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
20655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	# Combine function call count data
20665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	$result_testfncdata = add_testfncdata($testfncdata1, $testfncdata2);
20675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	($result_sumfnccount, $fn_found, $fn_hit) =
20685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		add_fnccount($sumfnccount1, $sumfnccount2);
20695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	
20703551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	# Combine branch coverage data
20713551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	$result_testbrdata = add_testbrdata($testbrdata1, $testbrdata2);
20723551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	($result_sumbrcount, $br_found, $br_hit) =
20733551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)		combine_brcount($sumbrcount1, $sumbrcount2, $BR_ADD);
20743551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
20755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	# Combine testdata
20765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	foreach $testname (keys(%{$testdata1}))
20775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	{
20785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		if (defined($testdata2->{$testname}))
20795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		{
20805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			# testname is present in both entries, requires
20815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			# combination
20825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			($result_testdata{$testname}) =
20835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)				add_counts($testdata1->{$testname},
20845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)					   $testdata2->{$testname});
20855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		}
20865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		else
20875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		{
20885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			# testname only present in entry1, add to result
20895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			$result_testdata{$testname} = $testdata1->{$testname};
20905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		}
20915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
20925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		# update sum count hash
20935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		($result_sumcount, $lines_found, $lines_hit) =
20945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			add_counts($result_sumcount,
20955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)				   $result_testdata{$testname});
20965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
20975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
20985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	foreach $testname (keys(%{$testdata2}))
20995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	{
21005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		# Skip testnames already covered by previous iteration
21015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		if (defined($testdata1->{$testname})) { next; }
21025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
21035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		# testname only present in entry2, add to result hash
21045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		$result_testdata{$testname} = $testdata2->{$testname};
21055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
21065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		# update sum count hash
21075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		($result_sumcount, $lines_found, $lines_hit) =
21085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			add_counts($result_sumcount,
21095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)				   $result_testdata{$testname});
21105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
21115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	
21125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	# Calculate resulting sumcount
21135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
21145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	# Store result
21155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	set_info_entry(\%result, \%result_testdata, $result_sumcount,
21165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		       $result_funcdata, $checkdata1, $result_testfncdata,
21173551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)		       $result_sumfnccount, $result_testbrdata,
21183551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)		       $result_sumbrcount, $lines_found, $lines_hit,
21193551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)		       $fn_found, $fn_hit, $br_found, $br_hit);
21205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
21215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return(\%result);
21225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
21235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
21245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
21255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#
21265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# combine_info_files(info_ref1, info_ref2)
21275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#
21285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# Combine .info data in hashes referenced by INFO_REF1 and INFO_REF2. Return
21295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# reference to resulting hash.
21305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#
21315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
21325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)sub combine_info_files($$)
21335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
21345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	my %hash1 = %{$_[0]};
21355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	my %hash2 = %{$_[1]};
21365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	my $filename;
21375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
21385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	foreach $filename (keys(%hash2))
21395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	{
21405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		if ($hash1{$filename})
21415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		{
21425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			# Entry already exists in hash1, combine them
21435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			$hash1{$filename} =
21445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)				combine_info_entries($hash1{$filename},
21455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)						     $hash2{$filename},
21465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)						     $filename);
21475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		}
21485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		else
21495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		{
21505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			# Entry is unique in both hashes, simply add to
21515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			# resulting hash
21525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			$hash1{$filename} = $hash2{$filename};
21535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		}
21545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
21555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
21565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return(\%hash1);
21575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
21585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
21595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
21605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#
21613551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)# get_prefix(min_dir, filename_list)
21625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#
21635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# Search FILENAME_LIST for a directory prefix which is common to as many
21645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# list entries as possible, so that removing this prefix will minimize the
21653551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)# sum of the lengths of all resulting shortened filenames while observing
21663551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)# that no filename has less than MIN_DIR parent directories.
21675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#
21685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
21693551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)sub get_prefix($@)
21705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
21713551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	my ($min_dir, @filename_list) = @_;
21725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	my %prefix;			# mapping: prefix -> sum of lengths
21735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	my $current;			# Temporary iteration variable
21745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
21755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	# Find list of prefixes
21765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	foreach (@filename_list)
21775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	{
21785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		# Need explicit assignment to get a copy of $_ so that
21795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		# shortening the contained prefix does not affect the list
21803551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)		$current = $_;
21815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		while ($current = shorten_prefix($current))
21825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		{
21833551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)			$current .= "/";
21843551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
21855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			# Skip rest if the remaining prefix has already been
21865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			# added to hash
21873551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)			if (exists($prefix{$current})) { last; }
21885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
21895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			# Initialize with 0
21905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			$prefix{$current}="0";
21915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		}
21925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
21935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
21945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
21953551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	# Remove all prefixes that would cause filenames to have less than
21963551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	# the minimum number of parent directories
21973551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	foreach my $filename (@filename_list) {
21983551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)		my $dir = dirname($filename);
21993551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
22003551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)		for (my $i = 0; $i < $min_dir; $i++) {
22013551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)			delete($prefix{$dir."/"});
22023551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)			$dir = shorten_prefix($dir);
22033551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)		}
22043551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	}
22053551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
22063551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	# Check if any prefix remains
22073551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	return undef if (!%prefix);
22083551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
22095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	# Calculate sum of lengths for all prefixes
22105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	foreach $current (keys(%prefix))
22115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	{
22125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		foreach (@filename_list)
22135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		{
22145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			# Add original length
22155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			$prefix{$current} += length($_);
22165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
22175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			# Check whether prefix matches
22185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			if (substr($_, 0, length($current)) eq $current)
22195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			{
22205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)				# Subtract prefix length for this filename
22215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)				$prefix{$current} -= length($current);
22225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			}
22235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		}
22245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
22255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
22265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	# Find and return prefix with minimal sum
22275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	$current = (keys(%prefix))[0];
22285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
22295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	foreach (keys(%prefix))
22305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	{
22315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		if ($prefix{$_} < $prefix{$current})
22325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		{
22335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			$current = $_;
22345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		}
22355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
22365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
22373551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	$current =~ s/\/$//;
22383551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
22395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return($current);
22405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
22415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
22425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
22435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#
22445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# shorten_prefix(prefix)
22455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#
22465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# Return PREFIX shortened by last directory component.
22475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#
22485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
22495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)sub shorten_prefix($)
22505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
22515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	my @list = split("/", $_[0]);
22525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
22535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	pop(@list);
22545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return join("/", @list);
22555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
22565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
22575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
22585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
22595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#
22605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# get_dir_list(filename_list)
22615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#
22625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# Return sorted list of directories for each entry in given FILENAME_LIST.
22635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#
22645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
22655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)sub get_dir_list(@)
22665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
22675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	my %result;
22685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
22695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	foreach (@_)
22705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	{
22715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		$result{shorten_prefix($_)} = "";
22725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
22735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
22745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return(sort(keys(%result)));
22755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
22765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
22775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
22785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#
22795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# get_relative_base_path(subdirectory)
22805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#
22815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# Return a relative path string which references the base path when applied
22825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# in SUBDIRECTORY.
22835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#
22845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# Example: get_relative_base_path("fs/mm") -> "../../"
22855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#
22865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
22875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)sub get_relative_base_path($)
22885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
22895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	my $result = "";
22905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	my $index;
22915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
22925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	# Make an empty directory path a special case
22935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (!$_[0]) { return(""); }
22945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
22955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	# Count number of /s in path
22965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	$index = ($_[0] =~ s/\//\//g);
22975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
22985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	# Add a ../ to $result for each / in the directory path + 1
22995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	for (; $index>=0; $index--)
23005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	{
23015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		$result .= "../";
23025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
23035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
23045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return $result;
23055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
23065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
23075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
23085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#
23095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# read_testfile(test_filename)
23105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#
23115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# Read in file TEST_FILENAME which contains test descriptions in the format:
23125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#
23135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#   TN:<whitespace><test name>
23145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#   TD:<whitespace><test description>
23155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#
23165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# for each test case. Return a reference to a hash containing a mapping
23175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#
23185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#   test name -> test description.
23195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#
23205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# Die on error.
23215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#
23225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
23235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)sub read_testfile($)
23245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
23255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	my %result;
23265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	my $test_name;
23275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	my $changed_testname;
23285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	local *TEST_HANDLE;
23295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
23303551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	open(TEST_HANDLE, "<", $_[0])
23315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		or die("ERROR: cannot open $_[0]!\n");
23325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
23335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	while (<TEST_HANDLE>)
23345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	{
23355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		chomp($_);
23365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
23375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		# Match lines beginning with TN:<whitespace(s)>
23385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		if (/^TN:\s+(.*?)\s*$/)
23395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		{
23405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			# Store name for later use
23415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			$test_name = $1;
23425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			if ($test_name =~ s/\W/_/g)
23435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			{
23445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)				$changed_testname = 1;
23455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			}
23465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		}
23475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
23485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		# Match lines beginning with TD:<whitespace(s)>
23495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		if (/^TD:\s+(.*?)\s*$/)
23505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		{
23515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			# Check for empty line
23525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			if ($1)
23535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			{
23545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)				# Add description to hash
23555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)				$result{$test_name} .= " $1";
23565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			}
23575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			else
23585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			{
23595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)				# Add empty line
23605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)				$result{$test_name} .= "\n\n";
23615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			}
23625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		}
23635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
23645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
23655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	close(TEST_HANDLE);
23665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
23675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if ($changed_testname)
23685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	{
23695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		warn("WARNING: invalid characters removed from testname in ".
23705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		     "descriptions file $_[0]\n");
23715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
23725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
23735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return \%result;
23745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
23755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
23765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
23775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#
23785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# escape_html(STRING)
23795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#
23805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# Return a copy of STRING in which all occurrences of HTML special characters
23815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# are escaped.
23825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#
23835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
23845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)sub escape_html($)
23855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
23865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	my $string = $_[0];
23875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
23885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (!$string) { return ""; }
23895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
23905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	$string =~ s/&/&amp;/g;		# & -> &amp;
23915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	$string =~ s/</&lt;/g;		# < -> &lt;
23925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	$string =~ s/>/&gt;/g;		# > -> &gt;
23935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	$string =~ s/\"/&quot;/g;	# " -> &quot;
23945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
23955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	while ($string =~ /^([^\t]*)(\t)/)
23965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	{
23975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		my $replacement = " "x($tab_size - (length($1) % $tab_size));
23985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		$string =~ s/^([^\t]*)(\t)/$1$replacement/;
23995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
24005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
24015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	$string =~ s/\n/<br>/g;		# \n -> <br>
24025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
24035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return $string;
24045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
24055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
24065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
24075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#
24085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# get_date_string()
24095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#
24105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# Return the current date in the form: yyyy-mm-dd
24115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#
24125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
24135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)sub get_date_string()
24145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
24155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	my $year;
24165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	my $month;
24175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	my $day;
24185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
24195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	($year, $month, $day) = (localtime())[5, 4, 3];
24205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
24215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return sprintf("%d-%02d-%02d", $year+1900, $month+1, $day);
24225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
24235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
24245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
24255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#
24265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# create_sub_dir(dir_name)
24275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#
24285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# Create subdirectory DIR_NAME if it does not already exist, including all its
24295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# parent directories.
24305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#
24315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# Die on error.
24325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#
24335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
24345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)sub create_sub_dir($)
24355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
24363551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	my ($dir) = @_;
24373551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
24383551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	system("mkdir", "-p" ,$dir)
24393551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)		and die("ERROR: cannot create directory $dir!\n");
24405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
24415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
24425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
24435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#
24445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# write_description_file(descriptions, overall_found, overall_hit,
24453551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#                        total_fn_found, total_fn_hit, total_br_found,
24463551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#                        total_br_hit)
24475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#
24485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# Write HTML file containing all test case descriptions. DESCRIPTIONS is a
24495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# reference to a hash containing a mapping
24505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#
24515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#   test case name -> test case description
24525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#
24535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# Die on error.
24545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#
24555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
24563551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)sub write_description_file($$$$$$$)
24575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
24585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	my %description = %{$_[0]};
24595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	my $found = $_[1];
24605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	my $hit = $_[2];
24615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	my $fn_found = $_[3];
24625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	my $fn_hit = $_[4];
24633551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	my $br_found = $_[5];
24643551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	my $br_hit = $_[6];
24655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	my $test_name;
24665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	local *HTML_HANDLE;
24675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
24685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	html_create(*HTML_HANDLE,"descriptions.$html_ext");
24695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	write_html_prolog(*HTML_HANDLE, "", "LCOV - test case descriptions");
24705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	write_header(*HTML_HANDLE, 3, "", "", $found, $hit, $fn_found,
24713551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)		     $fn_hit, $br_found, $br_hit, 0);
24725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
24735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	write_test_table_prolog(*HTML_HANDLE,
24745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			 "Test case descriptions - alphabetical list");
24755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
24765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	foreach $test_name (sort(keys(%description)))
24775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	{
24785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		write_test_table_entry(*HTML_HANDLE, $test_name,
24795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)				       escape_html($description{$test_name}));
24805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
24815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
24825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	write_test_table_epilog(*HTML_HANDLE);
24835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	write_html_epilog(*HTML_HANDLE, "");
24845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
24855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	close(*HTML_HANDLE);
24865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
24875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
24885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
24895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
24905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#
24915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# write_png_files()
24925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#
24935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# Create all necessary .png files for the HTML-output in the current
24945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# directory. .png-files are used as bar graphs.
24955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#
24965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# Die on error.
24975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#
24985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
24995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)sub write_png_files()
25005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
25015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	my %data;
25025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	local *PNG_HANDLE;
25035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
25045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	$data{"ruby.png"} =
25055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		[0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, 0x00, 0x00, 
25065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, 0x00, 0x00, 0x00, 0x01, 
25075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		 0x00, 0x00, 0x00, 0x01, 0x01, 0x03, 0x00, 0x00, 0x00, 0x25, 
25085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		 0xdb, 0x56, 0xca, 0x00, 0x00, 0x00, 0x07, 0x74, 0x49, 0x4d, 
25095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		 0x45, 0x07, 0xd2, 0x07, 0x11, 0x0f, 0x18, 0x10, 0x5d, 0x57, 
25105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		 0x34, 0x6e, 0x00, 0x00, 0x00, 0x09, 0x70, 0x48, 0x59, 0x73, 
25115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		 0x00, 0x00, 0x0b, 0x12, 0x00, 0x00, 0x0b, 0x12, 0x01, 0xd2, 
25125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		 0xdd, 0x7e, 0xfc, 0x00, 0x00, 0x00, 0x04, 0x67, 0x41, 0x4d, 
25135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		 0x41, 0x00, 0x00, 0xb1, 0x8f, 0x0b, 0xfc, 0x61, 0x05, 0x00, 
25145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		 0x00, 0x00, 0x06, 0x50, 0x4c, 0x54, 0x45, 0xff, 0x35, 0x2f, 
25155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		 0x00, 0x00, 0x00, 0xd0, 0x33, 0x9a, 0x9d, 0x00, 0x00, 0x00, 
25165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		 0x0a, 0x49, 0x44, 0x41, 0x54, 0x78, 0xda, 0x63, 0x60, 0x00, 
25175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		 0x00, 0x00, 0x02, 0x00, 0x01, 0xe5, 0x27, 0xde, 0xfc, 0x00, 
25185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		 0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 
25195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		 0x82];
25205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	$data{"amber.png"} =
25215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		[0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, 0x00, 0x00, 
25225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, 0x00, 0x00, 0x00, 0x01, 
25235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		 0x00, 0x00, 0x00, 0x01, 0x01, 0x03, 0x00, 0x00, 0x00, 0x25, 
25245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		 0xdb, 0x56, 0xca, 0x00, 0x00, 0x00, 0x07, 0x74, 0x49, 0x4d, 
25255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		 0x45, 0x07, 0xd2, 0x07, 0x11, 0x0f, 0x28, 0x04, 0x98, 0xcb, 
25265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		 0xd6, 0xe0, 0x00, 0x00, 0x00, 0x09, 0x70, 0x48, 0x59, 0x73, 
25275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		 0x00, 0x00, 0x0b, 0x12, 0x00, 0x00, 0x0b, 0x12, 0x01, 0xd2, 
25285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		 0xdd, 0x7e, 0xfc, 0x00, 0x00, 0x00, 0x04, 0x67, 0x41, 0x4d, 
25295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		 0x41, 0x00, 0x00, 0xb1, 0x8f, 0x0b, 0xfc, 0x61, 0x05, 0x00, 
25305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		 0x00, 0x00, 0x06, 0x50, 0x4c, 0x54, 0x45, 0xff, 0xe0, 0x50, 
25315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		 0x00, 0x00, 0x00, 0xa2, 0x7a, 0xda, 0x7e, 0x00, 0x00, 0x00, 
25325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		 0x0a, 0x49, 0x44, 0x41, 0x54, 0x78, 0xda, 0x63, 0x60, 0x00, 
25335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	  	 0x00, 0x00, 0x02, 0x00, 0x01, 0xe5, 0x27, 0xde, 0xfc, 0x00, 
25345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		 0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 
25355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		 0x82];
25365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	$data{"emerald.png"} =
25375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		[0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, 0x00, 0x00, 
25385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, 0x00, 0x00, 0x00, 0x01, 
25395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		 0x00, 0x00, 0x00, 0x01, 0x01, 0x03, 0x00, 0x00, 0x00, 0x25, 
25405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		 0xdb, 0x56, 0xca, 0x00, 0x00, 0x00, 0x07, 0x74, 0x49, 0x4d, 
25415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		 0x45, 0x07, 0xd2, 0x07, 0x11, 0x0f, 0x22, 0x2b, 0xc9, 0xf5, 
25425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		 0x03, 0x33, 0x00, 0x00, 0x00, 0x09, 0x70, 0x48, 0x59, 0x73, 
25435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		 0x00, 0x00, 0x0b, 0x12, 0x00, 0x00, 0x0b, 0x12, 0x01, 0xd2, 
25445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		 0xdd, 0x7e, 0xfc, 0x00, 0x00, 0x00, 0x04, 0x67, 0x41, 0x4d, 
25455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		 0x41, 0x00, 0x00, 0xb1, 0x8f, 0x0b, 0xfc, 0x61, 0x05, 0x00, 
25465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		 0x00, 0x00, 0x06, 0x50, 0x4c, 0x54, 0x45, 0x1b, 0xea, 0x59, 
25475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		 0x0a, 0x0a, 0x0a, 0x0f, 0xba, 0x50, 0x83, 0x00, 0x00, 0x00, 
25485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		 0x0a, 0x49, 0x44, 0x41, 0x54, 0x78, 0xda, 0x63, 0x60, 0x00, 
25495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		 0x00, 0x00, 0x02, 0x00, 0x01, 0xe5, 0x27, 0xde, 0xfc, 0x00, 
25505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		 0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 
25515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		 0x82];
25525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	$data{"snow.png"} =
25535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		[0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, 0x00, 0x00, 
25545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, 0x00, 0x00, 0x00, 0x01, 
25555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		 0x00, 0x00, 0x00, 0x01, 0x01, 0x03, 0x00, 0x00, 0x00, 0x25, 
25565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		 0xdb, 0x56, 0xca, 0x00, 0x00, 0x00, 0x07, 0x74, 0x49, 0x4d, 
25575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		 0x45, 0x07, 0xd2, 0x07, 0x11, 0x0f, 0x1e, 0x1d, 0x75, 0xbc, 
25585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		 0xef, 0x55, 0x00, 0x00, 0x00, 0x09, 0x70, 0x48, 0x59, 0x73, 
25595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		 0x00, 0x00, 0x0b, 0x12, 0x00, 0x00, 0x0b, 0x12, 0x01, 0xd2, 
25605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		 0xdd, 0x7e, 0xfc, 0x00, 0x00, 0x00, 0x04, 0x67, 0x41, 0x4d, 
25615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		 0x41, 0x00, 0x00, 0xb1, 0x8f, 0x0b, 0xfc, 0x61, 0x05, 0x00, 
25625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		 0x00, 0x00, 0x06, 0x50, 0x4c, 0x54, 0x45, 0xff, 0xff, 0xff, 
25635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		 0x00, 0x00, 0x00, 0x55, 0xc2, 0xd3, 0x7e, 0x00, 0x00, 0x00, 
25645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		 0x0a, 0x49, 0x44, 0x41, 0x54, 0x78, 0xda, 0x63, 0x60, 0x00, 
25655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		 0x00, 0x00, 0x02, 0x00, 0x01, 0xe5, 0x27, 0xde, 0xfc, 0x00, 
25665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		 0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 
25675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		 0x82];
25685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	$data{"glass.png"} =
25695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		[0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, 0x00, 0x00, 
25705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, 0x00, 0x00, 0x00, 0x01, 
25715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		 0x00, 0x00, 0x00, 0x01, 0x01, 0x03, 0x00, 0x00, 0x00, 0x25, 
25725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		 0xdb, 0x56, 0xca, 0x00, 0x00, 0x00, 0x04, 0x67, 0x41, 0x4d, 
25735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		 0x41, 0x00, 0x00, 0xb1, 0x8f, 0x0b, 0xfc, 0x61, 0x05, 0x00, 
25745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		 0x00, 0x00, 0x06, 0x50, 0x4c, 0x54, 0x45, 0xff, 0xff, 0xff, 
25755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		 0x00, 0x00, 0x00, 0x55, 0xc2, 0xd3, 0x7e, 0x00, 0x00, 0x00, 
25765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		 0x01, 0x74, 0x52, 0x4e, 0x53, 0x00, 0x40, 0xe6, 0xd8, 0x66, 
25775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		 0x00, 0x00, 0x00, 0x01, 0x62, 0x4b, 0x47, 0x44, 0x00, 0x88, 
25785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		 0x05, 0x1d, 0x48, 0x00, 0x00, 0x00, 0x09, 0x70, 0x48, 0x59, 
25795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		 0x73, 0x00, 0x00, 0x0b, 0x12, 0x00, 0x00, 0x0b, 0x12, 0x01, 
25805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		 0xd2, 0xdd, 0x7e, 0xfc, 0x00, 0x00, 0x00, 0x07, 0x74, 0x49, 
25815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		 0x4d, 0x45, 0x07, 0xd2, 0x07, 0x13, 0x0f, 0x08, 0x19, 0xc4, 
25825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		 0x40, 0x56, 0x10, 0x00, 0x00, 0x00, 0x0a, 0x49, 0x44, 0x41, 
25835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		 0x54, 0x78, 0x9c, 0x63, 0x60, 0x00, 0x00, 0x00, 0x02, 0x00, 
25845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		 0x01, 0x48, 0xaf, 0xa4, 0x71, 0x00, 0x00, 0x00, 0x00, 0x49, 
25855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82];
25865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	$data{"updown.png"} =
25875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		[0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, 0x00, 0x00, 
25885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, 0x00, 0x00, 0x00, 0x0a, 
25895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		 0x00, 0x00, 0x00, 0x0e, 0x08, 0x06, 0x00, 0x00, 0x00, 0x16, 
25905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		 0xa3, 0x8d, 0xab, 0x00, 0x00, 0x00, 0x3c, 0x49, 0x44, 0x41, 
25915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		 0x54, 0x28, 0xcf, 0x63, 0x60, 0x40, 0x03, 0xff, 0xa1, 0x00, 
25925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		 0x5d, 0x9c, 0x11, 0x5d, 0x11, 0x8a, 0x24, 0x23, 0x23, 0x23, 
25935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		 0x86, 0x42, 0x6c, 0xa6, 0x20, 0x2b, 0x66, 0xc4, 0xa7, 0x08, 
25945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		 0x59, 0x31, 0x23, 0x21, 0x45, 0x30, 0xc0, 0xc4, 0x30, 0x60, 
25955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		 0x80, 0xfa, 0x6e, 0x24, 0x3e, 0x78, 0x48, 0x0a, 0x70, 0x62, 
25965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		 0xa2, 0x90, 0x81, 0xd8, 0x44, 0x01, 0x00, 0xe9, 0x5c, 0x2f, 
25975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		 0xf5, 0xe2, 0x9d, 0x0f, 0xf9, 0x00, 0x00, 0x00, 0x00, 0x49, 
25985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82] if ($sort);
25995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	foreach (keys(%data))
26005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	{
26013551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)		open(PNG_HANDLE, ">", $_)
26025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			or die("ERROR: cannot create $_!\n");
26035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		binmode(PNG_HANDLE);
26045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		print(PNG_HANDLE map(chr,@{$data{$_}}));
26055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		close(PNG_HANDLE);
26065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
26075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
26085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
26095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
26105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#
26115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# write_htaccess_file()
26125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#
26135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
26145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)sub write_htaccess_file()
26155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
26165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	local *HTACCESS_HANDLE;
26175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	my $htaccess_data;
26185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
26193551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	open(*HTACCESS_HANDLE, ">", ".htaccess")
26205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		or die("ERROR: cannot open .htaccess for writing!\n");
26215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
26225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	$htaccess_data = (<<"END_OF_HTACCESS")
26235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)AddEncoding x-gzip .html
26245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)END_OF_HTACCESS
26255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	;
26265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
26275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	print(HTACCESS_HANDLE $htaccess_data);
26285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	close(*HTACCESS_HANDLE);
26295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
26305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
26315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
26325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#
26335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# write_css_file()
26345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#
26355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# Write the cascading style sheet file gcov.css to the current directory.
26365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# This file defines basic layout attributes of all generated HTML pages.
26375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#
26385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
26395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)sub write_css_file()
26405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
26415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	local *CSS_HANDLE;
26425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
26435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	# Check for a specified external style sheet file
26445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if ($css_filename)
26455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	{
26465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		# Simply copy that file
26475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		system("cp", $css_filename, "gcov.css")
26485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			and die("ERROR: cannot copy file $css_filename!\n");
26495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		return;
26505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
26515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
26523551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	open(CSS_HANDLE, ">", "gcov.css")
26535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		or die ("ERROR: cannot open gcov.css for writing!\n");
26545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
26555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
26565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	# *************************************************************
26575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
26585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	my $css_data = ($_=<<"END_OF_CSS")
26595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	/* All views: initial background and text color */
26605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	body
26615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	{
26625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	  color: #000000;
26635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	  background-color: #FFFFFF;
26645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
26655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	
26665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	/* All views: standard link format*/
26675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	a:link
26685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	{
26695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	  color: #284FA8;
26705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	  text-decoration: underline;
26715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
26725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	
26735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	/* All views: standard link - visited format */
26745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	a:visited
26755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	{
26765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	  color: #00CB40;
26775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	  text-decoration: underline;
26785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
26795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	
26805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	/* All views: standard link - activated format */
26815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	a:active
26825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	{
26835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	  color: #FF0040;
26845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	  text-decoration: underline;
26855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
26865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	
26875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	/* All views: main title format */
26885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	td.title
26895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	{
26905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	  text-align: center;
26915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	  padding-bottom: 10px;
26925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	  font-family: sans-serif;
26935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	  font-size: 20pt;
26945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	  font-style: italic;
26955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	  font-weight: bold;
26965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
26975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	
26985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	/* All views: header item format */
26995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	td.headerItem
27005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	{
27015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	  text-align: right;
27025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	  padding-right: 6px;
27035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	  font-family: sans-serif;
27045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	  font-weight: bold;
27055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	  vertical-align: top;
27065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	  white-space: nowrap;
27075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
27085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	
27095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	/* All views: header item value format */
27105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	td.headerValue
27115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	{
27125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	  text-align: left;
27135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	  color: #284FA8;
27145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	  font-family: sans-serif;
27155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	  font-weight: bold;
27165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	  white-space: nowrap;
27175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
27185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
27195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	/* All views: header item coverage table heading */
27205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	td.headerCovTableHead
27215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	{
27225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	  text-align: center;
27235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	  padding-right: 6px;
27245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	  padding-left: 6px;
27255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	  padding-bottom: 0px;
27265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	  font-family: sans-serif;
27275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	  font-size: 80%;
27285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	  white-space: nowrap;
27295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
27305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	
27315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	/* All views: header item coverage table entry */
27325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	td.headerCovTableEntry
27335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	{
27345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	  text-align: right;
27355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	  color: #284FA8;
27365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	  font-family: sans-serif;
27375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	  font-weight: bold;
27385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	  white-space: nowrap;
27395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	  padding-left: 12px;
27405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	  padding-right: 4px;
27415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	  background-color: #DAE7FE;
27425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
27435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	
27445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	/* All views: header item coverage table entry for high coverage rate */
27455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	td.headerCovTableEntryHi
27465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	{
27475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	  text-align: right;
27485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	  color: #000000;
27495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	  font-family: sans-serif;
27505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	  font-weight: bold;
27515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	  white-space: nowrap;
27525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	  padding-left: 12px;
27535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	  padding-right: 4px;
27545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	  background-color: #A7FC9D;
27555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
27565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	
27575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	/* All views: header item coverage table entry for medium coverage rate */
27585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	td.headerCovTableEntryMed
27595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	{
27605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	  text-align: right;
27615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	  color: #000000;
27625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	  font-family: sans-serif;
27635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	  font-weight: bold;
27645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	  white-space: nowrap;
27655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	  padding-left: 12px;
27665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	  padding-right: 4px;
27675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	  background-color: #FFEA20;
27685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
27695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	
27705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	/* All views: header item coverage table entry for ow coverage rate */
27715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	td.headerCovTableEntryLo
27725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	{
27735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	  text-align: right;
27745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	  color: #000000;
27755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	  font-family: sans-serif;
27765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	  font-weight: bold;
27775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	  white-space: nowrap;
27785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	  padding-left: 12px;
27795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	  padding-right: 4px;
27805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	  background-color: #FF0000;
27815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
27825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	
27835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	/* All views: header legend value for legend entry */
27845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	td.headerValueLeg
27855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	{
27865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	  text-align: left;
27875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	  color: #000000;
27885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	  font-family: sans-serif;
27895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	  font-size: 80%;
27905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	  white-space: nowrap;
27915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	  padding-top: 4px;
27925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
27935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	
27945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	/* All views: color of horizontal ruler */
27955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	td.ruler
27965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	{
27975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	  background-color: #6688D4;
27985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
27995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	
28005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	/* All views: version string format */
28015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	td.versionInfo
28025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	{
28035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	  text-align: center;
28045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	  padding-top: 2px;
28055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	  font-family: sans-serif;
28065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	  font-style: italic;
28075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
28085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	
28095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	/* Directory view/File view (all)/Test case descriptions:
28105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	   table headline format */
28115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	td.tableHead
28125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	{
28135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	  text-align: center;
28145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	  color: #FFFFFF;
28155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	  background-color: #6688D4;
28165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	  font-family: sans-serif;
28175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	  font-size: 120%;
28185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	  font-weight: bold;
28195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	  white-space: nowrap;
28205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	  padding-left: 4px;
28215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	  padding-right: 4px;
28225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
28235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
28245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	span.tableHeadSort
28255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	{
28265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	  padding-right: 4px;
28275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
28285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	
28295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	/* Directory view/File view (all): filename entry format */
28305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	td.coverFile
28315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	{
28325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	  text-align: left;
28335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	  padding-left: 10px;
28345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	  padding-right: 20px; 
28355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	  color: #284FA8;
28365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	  background-color: #DAE7FE;
28375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	  font-family: monospace;
28385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
28395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	
28405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	/* Directory view/File view (all): bar-graph entry format*/
28415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	td.coverBar
28425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	{
28435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	  padding-left: 10px;
28445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	  padding-right: 10px;
28455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	  background-color: #DAE7FE;
28465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
28475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	
28485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	/* Directory view/File view (all): bar-graph outline color */
28495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	td.coverBarOutline
28505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	{
28515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	  background-color: #000000;
28525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
28535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	
28545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	/* Directory view/File view (all): percentage entry for files with
28555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	   high coverage rate */
28565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	td.coverPerHi
28575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	{
28585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	  text-align: right;
28595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	  padding-left: 10px;
28605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	  padding-right: 10px;
28615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	  background-color: #A7FC9D;
28625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	  font-weight: bold;
28633551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	  font-family: sans-serif;
28645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
28655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	
28665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	/* Directory view/File view (all): line count entry for files with
28675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	   high coverage rate */
28685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	td.coverNumHi
28695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	{
28705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	  text-align: right;
28715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	  padding-left: 10px;
28725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	  padding-right: 10px;
28735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	  background-color: #A7FC9D;
28745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	  white-space: nowrap;
28753551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	  font-family: sans-serif;
28765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
28775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	
28785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	/* Directory view/File view (all): percentage entry for files with
28795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	   medium coverage rate */
28805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	td.coverPerMed
28815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	{
28825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	  text-align: right;
28835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	  padding-left: 10px;
28845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	  padding-right: 10px;
28855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	  background-color: #FFEA20;
28865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	  font-weight: bold;
28873551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	  font-family: sans-serif;
28885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
28895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	
28905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	/* Directory view/File view (all): line count entry for files with
28915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	   medium coverage rate */
28925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	td.coverNumMed
28935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	{
28945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	  text-align: right;
28955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	  padding-left: 10px;
28965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	  padding-right: 10px;
28975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	  background-color: #FFEA20;
28985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	  white-space: nowrap;
28993551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	  font-family: sans-serif;
29005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
29015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	
29025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	/* Directory view/File view (all): percentage entry for files with
29035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	   low coverage rate */
29045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	td.coverPerLo
29055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	{
29065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	  text-align: right;
29075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	  padding-left: 10px;
29085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	  padding-right: 10px;
29095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	  background-color: #FF0000;
29105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	  font-weight: bold;
29113551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	  font-family: sans-serif;
29125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
29135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	
29145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	/* Directory view/File view (all): line count entry for files with
29155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	   low coverage rate */
29165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	td.coverNumLo
29175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	{
29185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	  text-align: right;
29195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	  padding-left: 10px;
29205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	  padding-right: 10px;
29215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	  background-color: #FF0000;
29225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	  white-space: nowrap;
29233551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	  font-family: sans-serif;
29245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
29255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	
29265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	/* File view (all): "show/hide details" link format */
29275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	a.detail:link
29285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	{
29295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	  color: #B8D0FF;
29303551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	  font-size:80%;
29315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
29325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	
29335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	/* File view (all): "show/hide details" link - visited format */
29345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	a.detail:visited
29355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	{
29365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	  color: #B8D0FF;
29373551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	  font-size:80%;
29385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
29395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	
29405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	/* File view (all): "show/hide details" link - activated format */
29415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	a.detail:active
29425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	{
29435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	  color: #FFFFFF;
29443551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	  font-size:80%;
29455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
29465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	
29475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	/* File view (detail): test name entry */
29485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	td.testName
29495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	{
29505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	  text-align: right;
29515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	  padding-right: 10px;
29525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	  background-color: #DAE7FE;
29533551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	  font-family: sans-serif;
29545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
29555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	
29565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	/* File view (detail): test percentage entry */
29575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	td.testPer
29585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	{
29595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	  text-align: right;
29605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	  padding-left: 10px;
29615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	  padding-right: 10px; 
29625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	  background-color: #DAE7FE;
29633551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	  font-family: sans-serif;
29645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
29655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	
29665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	/* File view (detail): test lines count entry */
29675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	td.testNum
29685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	{
29695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	  text-align: right;
29705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	  padding-left: 10px;
29715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	  padding-right: 10px; 
29725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	  background-color: #DAE7FE;
29733551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	  font-family: sans-serif;
29745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
29755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	
29765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	/* Test case descriptions: test name format*/
29775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	dt
29785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	{
29795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	  font-family: sans-serif;
29805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	  font-weight: bold;
29815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
29825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	
29835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	/* Test case descriptions: description table body */
29845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	td.testDescription
29855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	{
29865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	  padding-top: 10px;
29875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	  padding-left: 30px;
29885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	  padding-bottom: 10px;
29895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	  padding-right: 30px;
29905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	  background-color: #DAE7FE;
29915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
29925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	
29935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	/* Source code view: function entry */
29945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	td.coverFn
29955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	{
29965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	  text-align: left;
29975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	  padding-left: 10px;
29985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	  padding-right: 20px; 
29995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	  color: #284FA8;
30005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	  background-color: #DAE7FE;
30015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	  font-family: monospace;
30025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
30035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
30045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	/* Source code view: function entry zero count*/
30055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	td.coverFnLo
30065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	{
30075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	  text-align: right;
30085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	  padding-left: 10px;
30095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	  padding-right: 10px;
30105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	  background-color: #FF0000;
30115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	  font-weight: bold;
30123551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	  font-family: sans-serif;
30135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
30145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
30155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	/* Source code view: function entry nonzero count*/
30165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	td.coverFnHi
30175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	{
30185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	  text-align: right;
30195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	  padding-left: 10px;
30205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	  padding-right: 10px;
30215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	  background-color: #DAE7FE;
30225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	  font-weight: bold;
30233551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	  font-family: sans-serif;
30245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
30255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
30265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	/* Source code view: source code format */
30275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	pre.source
30285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	{
30295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	  font-family: monospace;
30305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	  white-space: pre;
30313551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	  margin-top: 2px;
30325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
30335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	
30345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	/* Source code view: line number format */
30355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	span.lineNum
30365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	{
30375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	  background-color: #EFE383;
30385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
30395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	
30405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	/* Source code view: format for lines which were executed */
30415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	td.lineCov,
30425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	span.lineCov
30435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	{
30445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	  background-color: #CAD7FE;
30455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
30465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	
30475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	/* Source code view: format for Cov legend */
30485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	span.coverLegendCov
30495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	{
30505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	  padding-left: 10px;
30515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	  padding-right: 10px;
30525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	  padding-bottom: 2px;
30535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	  background-color: #CAD7FE;
30545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
30555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	
30565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	/* Source code view: format for lines which were not executed */
30575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	td.lineNoCov,
30585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	span.lineNoCov
30595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	{
30605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	  background-color: #FF6230;
30615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
30625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	
30635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	/* Source code view: format for NoCov legend */
30645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	span.coverLegendNoCov
30655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	{
30665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	  padding-left: 10px;
30675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	  padding-right: 10px;
30685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	  padding-bottom: 2px;
30693551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	  background-color: #FF6230;
30705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
30715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	
30725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	/* Source code view (function table): standard link - visited format */
30735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	td.lineNoCov > a:visited,
30745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	td.lineCov > a:visited
30755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	{  
30765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	  color: black;
30775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	  text-decoration: underline;
30785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}  
30795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	
30805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	/* Source code view: format for lines which were executed only in a
30815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	   previous version */
30825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	span.lineDiffCov
30835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	{
30845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	  background-color: #B5F7AF;
30855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
30865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	
30873551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	/* Source code view: format for branches which were executed
30883551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	 * and taken */
30893551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	span.branchCov
30905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	{
30913551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	  background-color: #CAD7FE;
30925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
30935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
30943551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	/* Source code view: format for branches which were executed
30953551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	 * but not taken */
30963551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	span.branchNoCov
30973551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	{
30983551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	  background-color: #FF6230;
30993551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	}
31005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
31013551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	/* Source code view: format for branches which were not executed */
31023551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	span.branchNoExec
31033551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	{
31043551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	  background-color: #FF6230;
31053551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	}
31065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
31073551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	/* Source code view: format for the source code heading line */
31083551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	pre.sourceHeading
31093551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	{
31103551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	  white-space: pre;
31113551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	  font-family: monospace;
31123551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	  font-weight: bold;
31133551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	  margin: 0px;
31143551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	}
31155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
31163551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	/* All views: header legend value for low rate */
31173551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	td.headerValueLegL
31183551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	{
31193551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	  font-family: sans-serif;
31203551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	  text-align: center;
31213551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	  white-space: nowrap;
31223551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	  padding-left: 4px;
31233551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	  padding-right: 2px;
31243551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	  background-color: #FF0000;
31253551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	  font-size: 80%;
31263551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	}
31275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
31283551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	/* All views: header legend value for med rate */
31293551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	td.headerValueLegM
31303551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	{
31313551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	  font-family: sans-serif;
31323551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	  text-align: center;
31333551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	  white-space: nowrap;
31343551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	  padding-left: 2px;
31353551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	  padding-right: 2px;
31363551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	  background-color: #FFEA20;
31373551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	  font-size: 80%;
31383551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	}
31395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
31403551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	/* All views: header legend value for hi rate */
31413551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	td.headerValueLegH
31423551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	{
31433551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	  font-family: sans-serif;
31443551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	  text-align: center;
31453551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	  white-space: nowrap;
31463551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	  padding-left: 2px;
31473551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	  padding-right: 4px;
31483551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	  background-color: #A7FC9D;
31493551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	  font-size: 80%;
31503551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	}
31513551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
31523551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	/* All views except source code view: legend format for low coverage */
31533551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	span.coverLegendCovLo
31543551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	{
31553551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	  padding-left: 10px;
31563551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	  padding-right: 10px;
31573551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	  padding-top: 2px;
31583551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	  background-color: #FF0000;
31593551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	}
31603551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
31613551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	/* All views except source code view: legend format for med coverage */
31623551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	span.coverLegendCovMed
31633551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	{
31643551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	  padding-left: 10px;
31653551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	  padding-right: 10px;
31663551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	  padding-top: 2px;
31673551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	  background-color: #FFEA20;
31683551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	}
31693551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
31703551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	/* All views except source code view: legend format for hi coverage */
31713551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	span.coverLegendCovHi
31723551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	{
31733551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	  padding-left: 10px;
31743551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	  padding-right: 10px;
31753551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	  padding-top: 2px;
31763551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	  background-color: #A7FC9D;
31773551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	}
31783551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)END_OF_CSS
31793551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	;
31803551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
31813551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	# *************************************************************
31823551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
31833551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
31843551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	# Remove leading tab from all lines
31853551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	$css_data =~ s/^\t//gm;
31863551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
31873551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	print(CSS_HANDLE $css_data);
31883551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
31893551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	close(CSS_HANDLE);
31903551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)}
31913551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
31923551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
31933551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#
31943551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)# get_bar_graph_code(base_dir, cover_found, cover_hit)
31953551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#
31965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# Return a string containing HTML code which implements a bar graph display
31975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# for a coverage rate of cover_hit * 100 / cover_found.
31985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#
31995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
32005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)sub get_bar_graph_code($$$)
32015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
32023551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	my ($base_dir, $found, $hit) = @_;
32035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	my $rate;
32045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	my $alt;
32055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	my $width;
32065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	my $remainder;
32075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	my $png_name;
32085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	my $graph_code;
32095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
32105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	# Check number of instrumented lines
32115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if ($_[1] == 0) { return ""; }
32125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
32133551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	$alt		= rate($hit, $found, "%");
32143551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	$width		= rate($hit, $found, undef, 0);
32153551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	$remainder	= 100 - $width;
32165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
32175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	# Decide which .png file to use
32183551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	$png_name = $rate_png[classify_rate($found, $hit, $med_limit,
32195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)					    $hi_limit)];
32205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
32215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if ($width == 0)
32225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	{
32235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		# Zero coverage
32245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		$graph_code = (<<END_OF_HTML)
32255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	        <table border=0 cellspacing=0 cellpadding=1><tr><td class="coverBarOutline"><img src="$_[0]snow.png" width=100 height=10 alt="$alt"></td></tr></table>
32265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)END_OF_HTML
32275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		;
32285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
32295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	elsif ($width == 100)
32305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	{
32315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		# Full coverage
32325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		$graph_code = (<<END_OF_HTML)
32335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		<table border=0 cellspacing=0 cellpadding=1><tr><td class="coverBarOutline"><img src="$_[0]$png_name" width=100 height=10 alt="$alt"></td></tr></table>
32345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)END_OF_HTML
32355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		;
32365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
32375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	else
32385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	{
32395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		# Positive coverage
32405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		$graph_code = (<<END_OF_HTML)
32415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		<table border=0 cellspacing=0 cellpadding=1><tr><td class="coverBarOutline"><img src="$_[0]$png_name" width=$width height=10 alt="$alt"><img src="$_[0]snow.png" width=$remainder height=10 alt="$alt"></td></tr></table>
32425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)END_OF_HTML
32435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		;
32445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
32455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
32465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	# Remove leading tabs from all lines
32475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	$graph_code =~ s/^\t+//gm;
32485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	chomp($graph_code);
32495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
32505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return($graph_code);
32515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
32525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
32535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#
32545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# sub classify_rate(found, hit, med_limit, high_limit)
32555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#
32565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# Return 0 for low rate, 1 for medium rate and 2 for hi rate.
32575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#
32585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
32595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)sub classify_rate($$$$)
32605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
32615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	my ($found, $hit, $med, $hi) = @_;
32625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	my $rate;
32635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
32645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if ($found == 0) {
32655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		return 2;
32665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
32673551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	$rate = rate($hit, $found);
32685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if ($rate < $med) {
32695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		return 0;
32705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	} elsif ($rate < $hi) {
32715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		return 1;
32725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
32735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return 2;
32745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
32755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
32765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
32775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#
32785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# write_html(filehandle, html_code)
32795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#
32805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# Write out HTML_CODE to FILEHANDLE while removing a leading tabulator mark
32815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# in each line of HTML_CODE.
32825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#
32835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
32845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)sub write_html(*$)
32855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
32865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	local *HTML_HANDLE = $_[0];
32875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	my $html_code = $_[1];
32885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
32895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	# Remove leading tab from all lines
32905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	$html_code =~ s/^\t//gm;
32915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
32925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	print(HTML_HANDLE $html_code)
32935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		or die("ERROR: cannot write HTML data ($!)\n");
32945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
32955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
32965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
32975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#
32985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# write_html_prolog(filehandle, base_dir, pagetitle)
32995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#
33005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# Write an HTML prolog common to all HTML files to FILEHANDLE. PAGETITLE will
33015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# be used as HTML page title. BASE_DIR contains a relative path which points
33025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# to the base directory.
33035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#
33045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
33055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)sub write_html_prolog(*$$)
33065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
33075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	my $basedir = $_[1];
33085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	my $pagetitle = $_[2];
33095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	my $prolog;
33105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
33115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	$prolog = $html_prolog;
33125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	$prolog =~ s/\@pagetitle\@/$pagetitle/g;
33135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	$prolog =~ s/\@basedir\@/$basedir/g;
33145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
33155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	write_html($_[0], $prolog);
33165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
33175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
33185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
33195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#
33205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# write_header_prolog(filehandle, base_dir)
33215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#
33225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# Write beginning of page header HTML code.
33235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#
33245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
33255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)sub write_header_prolog(*$)
33265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
33275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	# *************************************************************
33285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
33295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	write_html($_[0], <<END_OF_HTML)
33305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	  <table width="100%" border=0 cellspacing=0 cellpadding=0>
33315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    <tr><td class="title">$title</td></tr>
33325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    <tr><td class="ruler"><img src="$_[1]glass.png" width=3 height=3 alt=""></td></tr>
33335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
33345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    <tr>
33355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	      <td width="100%">
33365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	        <table cellpadding=1 border=0 width="100%">
33375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)END_OF_HTML
33385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	;
33395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
33405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	# *************************************************************
33415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
33425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
33435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
33445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#
33453551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)# write_header_line(handle, content)
33465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#
33473551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)# Write a header line with the specified table contents.
33485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#
33495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
33503551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)sub write_header_line(*@)
33515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
33523551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	my ($handle, @content) = @_;
33533551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	my $entry;
33545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
33553551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	write_html($handle, "          <tr>\n");
33563551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	foreach $entry (@content) {
33573551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)		my ($width, $class, $text, $colspan) = @{$entry};
33585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
33593551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)		if (defined($width)) {
33603551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)			$width = " width=\"$width\"";
33613551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)		} else {
33623551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)			$width = "";
33633551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)		}
33643551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)		if (defined($class)) {
33653551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)			$class = " class=\"$class\"";
33663551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)		} else {
33673551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)			$class = "";
33683551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)		}
33693551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)		if (defined($colspan)) {
33703551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)			$colspan = " colspan=\"$colspan\"";
33713551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)		} else {
33723551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)			$colspan = "";
33733551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)		}
33743551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)		$text = "" if (!defined($text));
33753551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)		write_html($handle,
33763551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)			   "            <td$width$class$colspan>$text</td>\n");
33773551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	}
33783551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	write_html($handle, "          </tr>\n");
33795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
33805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
33815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
33825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#
33835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# write_header_epilog(filehandle, base_dir)
33845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#
33855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# Write end of page header HTML code.
33865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#
33875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
33885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)sub write_header_epilog(*$)
33895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
33905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	# *************************************************************
33915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
33925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	write_html($_[0], <<END_OF_HTML)
33933551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	          <tr><td><img src="$_[1]glass.png" width=3 height=3 alt=""></td></tr>
33945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	        </table>
33955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	      </td>
33965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    </tr>
33973551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
33985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    <tr><td class="ruler"><img src="$_[1]glass.png" width=3 height=3 alt=""></td></tr>
33995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	  </table>
34005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
34015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)END_OF_HTML
34025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	;
34035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
34045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	# *************************************************************
34055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
34065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
34075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
34085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#
34093551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)# write_file_table_prolog(handle, file_heading, ([heading, num_cols], ...))
34105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#
34115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# Write heading for file table.
34125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#
34135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
34143551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)sub write_file_table_prolog(*$@)
34155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
34163551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	my ($handle, $file_heading, @columns) = @_;
34173551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	my $num_columns = 0;
34183551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	my $file_width;
34193551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	my $col;
34203551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	my $width;
34215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
34223551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	$width = 20 if (scalar(@columns) == 1);
34233551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	$width = 10 if (scalar(@columns) == 2);
34243551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	$width = 8 if (scalar(@columns) > 2);
34255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
34263551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	foreach $col (@columns) {
34273551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)		my ($heading, $cols) = @{$col};
34285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
34293551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)		$num_columns += $cols;
34303551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	}
34313551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	$file_width = 100 - $num_columns * $width;
34325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
34333551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	# Table definition
34343551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	write_html($handle, <<END_OF_HTML);
34355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	  <center>
34365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	  <table width="80%" cellpadding=1 cellspacing=1 border=0>
34375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
34385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    <tr>
34393551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	      <td width="$file_width%"><br></td>
34403551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)END_OF_HTML
34413551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	# Empty first row
34423551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	foreach $col (@columns) {
34433551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)		my ($heading, $cols) = @{$col};
34443551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
34453551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)		while ($cols-- > 0) {
34463551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)			write_html($handle, <<END_OF_HTML);
34473551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	      <td width="$width%"></td>
34483551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)END_OF_HTML
34493551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)		}
34503551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	}
34513551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	# Next row
34523551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	write_html($handle, <<END_OF_HTML);
34535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    </tr>
34545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
34555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    <tr>
34563551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	      <td class="tableHead">$file_heading</td>
34573551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)END_OF_HTML
34583551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	# Heading row
34593551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	foreach $col (@columns) {
34603551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)		my ($heading, $cols) = @{$col};
34613551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)		my $colspan = "";
34623551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
34633551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)		$colspan = " colspan=$cols" if ($cols > 1);
34643551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)		write_html($handle, <<END_OF_HTML);
34653551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	      <td class="tableHead"$colspan>$heading</td>
34663551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)END_OF_HTML
34673551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	}
34683551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	write_html($handle, <<END_OF_HTML);
34695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    </tr>
34705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)END_OF_HTML
34715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
34725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
34735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
34743551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)# write_file_table_entry(handle, base_dir, filename, page_link,
34753551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#			 ([ found, hit, med_limit, hi_limit, graph ], ..)
34765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#
34775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# Write an entry of the file table.
34785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#
34795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
34803551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)sub write_file_table_entry(*$$$@)
34815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
34823551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	my ($handle, $base_dir, $filename, $page_link, @entries) = @_;
34835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	my $file_code;
34843551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	my $entry;
34853551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	my $esc_filename = escape_html($filename);
34865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
34875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	# Add link to source if provided
34885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (defined($page_link) && $page_link ne "") {
34893551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)		$file_code = "<a href=\"$page_link\">$esc_filename</a>";
34905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	} else {
34913551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)		$file_code = $esc_filename;
34925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
34935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
34943551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	# First column: filename
34953551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	write_html($handle, <<END_OF_HTML);
34965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    <tr>
34975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	      <td class="coverFile">$file_code</td>
34983551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)END_OF_HTML
34993551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	# Columns as defined
35003551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	foreach $entry (@entries) {
35013551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)		my ($found, $hit, $med, $hi, $graph) = @{$entry};
35023551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)		my $bar_graph;
35033551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)		my $class;
35043551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)		my $rate;
35053551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
35063551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)		# Generate bar graph if requested
35073551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)		if ($graph) {
35083551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)			$bar_graph = get_bar_graph_code($base_dir, $found,
35093551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)							$hit);
35103551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)			write_html($handle, <<END_OF_HTML);
35115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	      <td class="coverBar" align="center">
35125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	        $bar_graph
35135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	      </td>
35145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)END_OF_HTML
35153551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)		}
35163551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)		# Get rate color and text
35173551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)		if ($found == 0) {
35183551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)			$rate = "-";
35193551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)			$class = "Hi";
35203551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)		} else {
35213551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)			$rate = rate($hit, $found, "&nbsp;%");
35223551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)			$class = $rate_name[classify_rate($found, $hit,
35233551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)					    $med, $hi)];
35243551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)		}
35253551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)		write_html($handle, <<END_OF_HTML);
35263551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	      <td class="coverPer$class">$rate</td>
35273551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	      <td class="coverNum$class">$hit / $found</td>
35285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)END_OF_HTML
35293551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	}
35303551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	# End of row
35313551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)        write_html($handle, <<END_OF_HTML);
35325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    </tr>
35335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)END_OF_HTML
35345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
35355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
35365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
35375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#
35383551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)# write_file_table_detail_entry(filehandle, test_name, ([found, hit], ...))
35395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#
35405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# Write entry for detail section in file table.
35415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#
35425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
35433551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)sub write_file_table_detail_entry(*$@)
35445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
35453551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	my ($handle, $test, @entries) = @_;
35463551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	my $entry;
35475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
35483551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	if ($test eq "") {
35493551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)		$test = "<span style=\"font-style:italic\">&lt;unnamed&gt;</span>";
35503551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	} elsif ($test =~ /^(.*),diff$/) {
35513551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)		$test = $1." (converted)";
35525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
35533551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	# Testname
35543551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	write_html($handle, <<END_OF_HTML);
35555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    <tr>
35563551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	      <td class="testName" colspan=2>$test</td>
35575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)END_OF_HTML
35583551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	# Test data
35593551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	foreach $entry (@entries) {
35603551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)		my ($found, $hit) = @{$entry};
35613551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)		my $rate = rate($hit, $found, "&nbsp;%");
35623551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
35633551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)		write_html($handle, <<END_OF_HTML);
35643551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	      <td class="testPer">$rate</td>
35653551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	      <td class="testNum">$hit&nbsp;/&nbsp;$found</td>
35665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)END_OF_HTML
35673551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	}
35683551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
35693551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)        write_html($handle, <<END_OF_HTML);
35705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    </tr>
35715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
35725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)END_OF_HTML
35735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
35745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	# *************************************************************
35755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
35765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
35775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
35785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#
35795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# write_file_table_epilog(filehandle)
35805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#
35815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# Write end of file table HTML code.
35825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#
35835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
35845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)sub write_file_table_epilog(*)
35855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
35865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	# *************************************************************
35875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
35885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	write_html($_[0], <<END_OF_HTML)
35895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	  </table>
35905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	  </center>
35915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	  <br>
35925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
35935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)END_OF_HTML
35945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	;
35955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
35965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	# *************************************************************
35975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
35985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
35995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
36005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#
36015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# write_test_table_prolog(filehandle, table_heading)
36025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#
36035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# Write heading for test case description table.
36045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#
36055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
36065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)sub write_test_table_prolog(*$)
36075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
36085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	# *************************************************************
36095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
36105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	write_html($_[0], <<END_OF_HTML)
36115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	  <center>
36125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	  <table width="80%" cellpadding=2 cellspacing=1 border=0>
36135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
36145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    <tr>
36155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	      <td><br></td>
36165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    </tr>
36175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
36185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    <tr>
36195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	      <td class="tableHead">$_[1]</td>
36205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    </tr>
36215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
36225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    <tr>
36235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	      <td class="testDescription">
36245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	        <dl>
36255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)END_OF_HTML
36265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	;
36275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
36285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	# *************************************************************
36295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
36305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
36315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
36325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#
36335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# write_test_table_entry(filehandle, test_name, test_description)
36345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#
36355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# Write entry for the test table.
36365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#
36375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
36385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)sub write_test_table_entry(*$$)
36395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
36405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	# *************************************************************
36415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
36425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	write_html($_[0], <<END_OF_HTML)
36435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          <dt>$_[1]<a name="$_[1]">&nbsp;</a></dt>
36445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          <dd>$_[2]<br><br></dd>
36455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)END_OF_HTML
36465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	;
36475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
36485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	# *************************************************************
36495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
36505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
36515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
36525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#
36535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# write_test_table_epilog(filehandle)
36545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#
36555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# Write end of test description table HTML code.
36565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#
36575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
36585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)sub write_test_table_epilog(*)
36595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
36605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	# *************************************************************
36615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
36625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	write_html($_[0], <<END_OF_HTML)
36635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	        </dl>
36645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	      </td>
36655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    </tr>
36665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	  </table>
36675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	  </center>
36685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	  <br>
36695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
36705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)END_OF_HTML
36715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	;
36725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
36735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	# *************************************************************
36745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
36755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
36765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
36773551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)sub fmt_centered($$)
36783551c9c881056c480085172ff9840cab31610854Torne (Richard Coles){
36793551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	my ($width, $text) = @_;
36803551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	my $w0 = length($text);
36813551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	my $w1 = int(($width - $w0) / 2);
36823551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	my $w2 = $width - $w0 - $w1;
36833551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
36843551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	return (" "x$w1).$text.(" "x$w2);
36853551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)}
36863551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
36873551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
36885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#
36895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# write_source_prolog(filehandle)
36905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#
36915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# Write start of source code table.
36925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#
36935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
36945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)sub write_source_prolog(*)
36955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
36963551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	my $lineno_heading = "         ";
36973551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	my $branch_heading = "";
36983551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	my $line_heading = fmt_centered($line_field_width, "Line data");
36993551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	my $source_heading = " Source code";
37003551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
37013551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	if ($br_coverage) {
37023551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)		$branch_heading = fmt_centered($br_field_width, "Branch data").
37033551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)				  " ";
37043551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	}
37055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	# *************************************************************
37065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
37075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	write_html($_[0], <<END_OF_HTML)
37085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	  <table cellpadding=0 cellspacing=0 border=0>
37095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    <tr>
37105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	      <td><br></td>
37115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    </tr>
37125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    <tr>
37133551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	      <td>
37143551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)<pre class="sourceHeading">${lineno_heading}${branch_heading}${line_heading} ${source_heading}</pre>
37153551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)<pre class="source">
37165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)END_OF_HTML
37175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	;
37185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
37195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	# *************************************************************
37205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
37215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
37225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
37235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#
37243551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)# get_branch_blocks(brdata)
37253551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#
37263551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)# Group branches that belong to the same basic block.
37273551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#
37283551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)# Returns: [block1, block2, ...]
37293551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)# block:   [branch1, branch2, ...]
37303551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)# branch:  [block_num, branch_num, taken_count, text_length, open, close]
37313551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#
37323551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
37333551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)sub get_branch_blocks($)
37343551c9c881056c480085172ff9840cab31610854Torne (Richard Coles){
37353551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	my ($brdata) = @_;
37363551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	my $last_block_num;
37373551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	my $block = [];
37383551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	my @blocks;
37393551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	my $i;
37403551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	my $num = br_ivec_len($brdata);
37413551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
37423551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	# Group branches
37433551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	for ($i = 0; $i < $num; $i++) {
37443551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)		my ($block_num, $branch, $taken) = br_ivec_get($brdata, $i);
37453551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)		my $br;
37463551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
37473551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)		if (defined($last_block_num) && $block_num != $last_block_num) {
37483551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)			push(@blocks, $block);
37493551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)			$block = [];
37503551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)		}
37513551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)		$br = [$block_num, $branch, $taken, 3, 0, 0];
37523551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)		push(@{$block}, $br);
37533551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)		$last_block_num = $block_num;
37543551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	}
37553551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	push(@blocks, $block) if (scalar(@{$block}) > 0);
37563551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
37573551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	# Add braces to first and last branch in group
37583551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	foreach $block (@blocks) {
37593551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)		$block->[0]->[$BR_OPEN] = 1;
37603551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)		$block->[0]->[$BR_LEN]++;
37613551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)		$block->[scalar(@{$block}) - 1]->[$BR_CLOSE] = 1;
37623551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)		$block->[scalar(@{$block}) - 1]->[$BR_LEN]++;
37633551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	}
37643551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
37653551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	return @blocks;
37663551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)}
37673551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
37683551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#
37693551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)# get_block_len(block)
37703551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#
37713551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)# Calculate total text length of all branches in a block of branches.
37723551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#
37733551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
37743551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)sub get_block_len($)
37753551c9c881056c480085172ff9840cab31610854Torne (Richard Coles){
37763551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	my ($block) = @_;
37773551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	my $len = 0;
37783551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	my $branch;
37793551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
37803551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	foreach $branch (@{$block}) {
37813551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)		$len += $branch->[$BR_LEN];
37823551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	}
37833551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
37843551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	return $len;
37853551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)}
37863551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
37873551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
37883551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#
37893551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)# get_branch_html(brdata)
37903551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#
37913551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)# Return a list of HTML lines which represent the specified branch coverage
37923551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)# data in source code view.
37933551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#
37943551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
37953551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)sub get_branch_html($)
37963551c9c881056c480085172ff9840cab31610854Torne (Richard Coles){
37973551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	my ($brdata) = @_;
37983551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	my @blocks = get_branch_blocks($brdata);
37993551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	my $block;
38003551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	my $branch;
38013551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	my $line_len = 0;
38023551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	my $line = [];	# [branch2|" ", branch|" ", ...]
38033551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	my @lines;	# [line1, line2, ...]
38043551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	my @result;
38053551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
38063551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	# Distribute blocks to lines
38073551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	foreach $block (@blocks) {
38083551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)		my $block_len = get_block_len($block);
38093551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
38103551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)		# Does this block fit into the current line?
38113551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)		if ($line_len + $block_len <= $br_field_width) {
38123551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)			# Add it
38133551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)			$line_len += $block_len;
38143551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)			push(@{$line}, @{$block});
38153551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)			next;
38163551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)		} elsif ($block_len <= $br_field_width) {
38173551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)			# It would fit if the line was empty - add it to new
38183551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)			# line
38193551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)			push(@lines, $line);
38203551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)			$line_len = $block_len;
38213551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)			$line = [ @{$block} ];
38223551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)			next;
38233551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)		}
38243551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)		# Split the block into several lines
38253551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)		foreach $branch (@{$block}) {
38263551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)			if ($line_len + $branch->[$BR_LEN] >= $br_field_width) {
38273551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)				# Start a new line
38283551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)				if (($line_len + 1 <= $br_field_width) &&
38293551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)				    scalar(@{$line}) > 0 &&
38303551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)				    !$line->[scalar(@$line) - 1]->[$BR_CLOSE]) {
38313551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)					# Try to align branch symbols to be in
38323551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)					# one # row
38333551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)					push(@{$line}, " ");
38343551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)				}
38353551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)				push(@lines, $line);
38363551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)				$line_len = 0;
38373551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)				$line = [];
38383551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)			}
38393551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)			push(@{$line}, $branch);
38403551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)			$line_len += $branch->[$BR_LEN];
38413551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)		}
38423551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	}
38433551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	push(@lines, $line);
38443551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
38453551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	# Convert to HTML
38463551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	foreach $line (@lines) {
38473551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)		my $current = "";
38483551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)		my $current_len = 0;
38493551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
38503551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)		foreach $branch (@$line) {
38513551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)			# Skip alignment space
38523551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)			if ($branch eq " ") {
38533551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)				$current .= " ";
38543551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)				$current_len++;
38553551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)				next;
38563551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)			}
38573551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
38583551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)			my ($block_num, $br_num, $taken, $len, $open, $close) =
38593551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)			   @{$branch};
38603551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)			my $class;
38613551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)			my $title;
38623551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)			my $text;
38633551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
38643551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)			if ($taken eq '-') {
38653551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)				$class	= "branchNoExec";
38663551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)				$text	= " # ";
38673551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)				$title	= "Branch $br_num was not executed";
38683551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)			} elsif ($taken == 0) {
38693551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)				$class	= "branchNoCov";
38703551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)				$text	= " - ";
38713551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)				$title	= "Branch $br_num was not taken";
38723551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)			} else {
38733551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)				$class	= "branchCov";
38743551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)				$text	= " + ";
38753551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)				$title	= "Branch $br_num was taken $taken ".
38763551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)					  "time";
38773551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)				$title .= "s" if ($taken > 1);
38783551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)			}
38793551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)			$current .= "[" if ($open);
38803551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)			$current .= "<span class=\"$class\" title=\"$title\">";
38813551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)			$current .= $text."</span>";
38823551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)			$current .= "]" if ($close);
38833551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)			$current_len += $len;
38843551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)		}
38853551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
38863551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)		# Right-align result text
38873551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)		if ($current_len < $br_field_width) {
38883551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)			$current = (" "x($br_field_width - $current_len)).
38893551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)				   $current;
38903551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)		}
38913551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)		push(@result, $current);
38923551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	}
38933551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
38943551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	return @result;
38953551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)}
38963551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
38973551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
38983551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#
38993551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)# format_count(count, width)
39003551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#
39013551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)# Return a right-aligned representation of count that fits in width characters.
39023551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#
39033551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
39043551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)sub format_count($$)
39053551c9c881056c480085172ff9840cab31610854Torne (Richard Coles){
39063551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	my ($count, $width) = @_;
39073551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	my $result;
39083551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	my $exp;
39093551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
39103551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	$result = sprintf("%*.0f", $width, $count);
39113551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	while (length($result) > $width) {
39123551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)		last if ($count < 10);
39133551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)		$exp++;
39143551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)		$count = int($count/10);
39153551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)		$result = sprintf("%*s", $width, ">$count*10^$exp");
39163551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	}
39173551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	return $result;
39183551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)}
39193551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
39203551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#
39215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# write_source_line(filehandle, line_num, source, hit_count, converted,
39223551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#                   brdata, add_anchor)
39235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#
39245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# Write formatted source code line. Return a line in a format as needed
39255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# by gen_png()
39265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#
39275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
39283551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)sub write_source_line(*$$$$$$)
39295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
39303551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	my ($handle, $line, $source, $count, $converted, $brdata,
39313551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	    $add_anchor) = @_;
39325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	my $source_format;
39333551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	my $count_format;
39345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	my $result;
39355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	my $anchor_start = "";
39365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	my $anchor_end = "";
39373551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	my $count_field_width = $line_field_width - 1;
39383551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	my @br_html;
39393551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	my $html;
39405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
39413551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	# Get branch HTML data for this line
39423551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	@br_html = get_branch_html($brdata) if ($br_coverage);
39433551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
39443551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	if (!defined($count)) {
39455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		$result		= "";
39465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		$source_format	= "";
39473551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)		$count_format	= " "x$count_field_width;
39485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
39493551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	elsif ($count == 0) {
39503551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)		$result		= $count;
39515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		$source_format	= '<span class="lineNoCov">';
39523551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)		$count_format	= format_count($count, $count_field_width);
39535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
39543551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	elsif ($converted && defined($highlight)) {
39553551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)		$result		= "*".$count;
39565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		$source_format	= '<span class="lineDiffCov">';
39573551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)		$count_format	= format_count($count, $count_field_width);
39585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
39593551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	else {
39603551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)		$result		= $count;
39615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		$source_format	= '<span class="lineCov">';
39623551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)		$count_format	= format_count($count, $count_field_width);
39635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
39643551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	$result .= ":".$source;
39655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
39665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	# Write out a line number navigation anchor every $nav_resolution
39675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	# lines if necessary
39683551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	if ($add_anchor)
39695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	{
39705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		$anchor_start	= "<a name=\"$_[1]\">";
39715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		$anchor_end	= "</a>";
39725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
39735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
39745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
39755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	# *************************************************************
39765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
39773551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	$html = $anchor_start;
39783551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	$html .= "<span class=\"lineNum\">".sprintf("%8d", $line)." </span>";
39793551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	$html .= shift(@br_html).":" if ($br_coverage);
39803551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	$html .= "$source_format$count_format : ";
39813551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	$html .= escape_html($source);
39823551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	$html .= "</span>" if ($source_format);
39833551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	$html .= $anchor_end."\n";
39843551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
39853551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	write_html($handle, $html);
39863551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
39873551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	if ($br_coverage) {
39883551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)		# Add lines for overlong branch information
39893551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)		foreach (@br_html) {
39903551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)			write_html($handle, "<span class=\"lineNum\">".
39913551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)				   "         </span>$_\n");
39923551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)		}
39933551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	}
39945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	# *************************************************************
39955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
39965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return($result);
39975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
39985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
39995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
40005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#
40015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# write_source_epilog(filehandle)
40025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#
40035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# Write end of source code table.
40045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#
40055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
40065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)sub write_source_epilog(*)
40075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
40085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	# *************************************************************
40095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
40105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	write_html($_[0], <<END_OF_HTML)
40115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	</pre>
40125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	      </td>
40135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    </tr>
40145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	  </table>
40155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	  <br>
40165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
40175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)END_OF_HTML
40185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	;
40195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
40205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	# *************************************************************
40215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
40225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
40235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
40245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#
40255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# write_html_epilog(filehandle, base_dir[, break_frames])
40265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#
40275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# Write HTML page footer to FILEHANDLE. BREAK_FRAMES should be set when
40285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# this page is embedded in a frameset, clicking the URL link will then
40295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# break this frameset.
40305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#
40315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
40325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)sub write_html_epilog(*$;$)
40335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
40345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	my $basedir = $_[1];
40355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	my $break_code = "";
40365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	my $epilog;
40375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
40385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (defined($_[2]))
40395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	{
40405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		$break_code = " target=\"_parent\"";
40415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
40425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
40435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	# *************************************************************
40445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
40455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	write_html($_[0], <<END_OF_HTML)
40465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	  <table width="100%" border=0 cellspacing=0 cellpadding=0>
40473551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	    <tr><td class="ruler"><img src="$_[1]glass.png" width=3 height=3 alt=""></td></tr>
40483551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	    <tr><td class="versionInfo">Generated by: <a href="$lcov_url"$break_code>$lcov_version</a></td></tr>
40495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	  </table>
40505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	  <br>
40515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)END_OF_HTML
40525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	;
40535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
40545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	$epilog = $html_epilog;
40555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	$epilog =~ s/\@basedir\@/$basedir/g;
40565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
40575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	write_html($_[0], $epilog);
40585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
40595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
40605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
40615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#
40625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# write_frameset(filehandle, basedir, basename, pagetitle)
40635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#
40645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#
40655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
40665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)sub write_frameset(*$$$)
40675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
40685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	my $frame_width = $overview_width + 40;
40695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
40705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	# *************************************************************
40715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
40725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	write_html($_[0], <<END_OF_HTML)
40735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Frameset//EN">
40745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
40755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	<html lang="en">
40765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
40775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	<head>
40783551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	  <meta http-equiv="Content-Type" content="text/html; charset=$charset">
40795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	  <title>$_[3]</title>
40805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	  <link rel="stylesheet" type="text/css" href="$_[1]gcov.css">
40815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	</head>
40825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
40835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	<frameset cols="$frame_width,*">
40845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	  <frame src="$_[2].gcov.overview.$html_ext" name="overview">
40855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	  <frame src="$_[2].gcov.$html_ext" name="source">
40865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	  <noframes>
40875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    <center>Frames not supported by your browser!<br></center>
40885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	  </noframes>
40895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	</frameset>
40905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
40915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	</html>
40925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)END_OF_HTML
40935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	;
40945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
40955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	# *************************************************************
40965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
40975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
40985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
40995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#
41005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# sub write_overview_line(filehandle, basename, line, link)
41015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#
41025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#
41035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
41045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)sub write_overview_line(*$$$)
41055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
41065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	my $y1 = $_[2] - 1;
41075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	my $y2 = $y1 + $nav_resolution - 1;
41085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	my $x2 = $overview_width - 1;
41095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
41105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	# *************************************************************
41115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
41125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	write_html($_[0], <<END_OF_HTML)
41135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    <area shape="rect" coords="0,$y1,$x2,$y2" href="$_[1].gcov.$html_ext#$_[3]" target="source" alt="overview">
41145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)END_OF_HTML
41155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	;
41165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
41175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	# *************************************************************
41185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
41195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
41205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
41215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#
41225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# write_overview(filehandle, basedir, basename, pagetitle, lines)
41235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#
41245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#
41255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
41265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)sub write_overview(*$$$$)
41275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
41285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	my $index;
41295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	my $max_line = $_[4] - 1;
41305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	my $offset;
41315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
41325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	# *************************************************************
41335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
41345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	write_html($_[0], <<END_OF_HTML)
41355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
41365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
41375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	<html lang="en">
41385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
41395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	<head>
41405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	  <title>$_[3]</title>
41413551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	  <meta http-equiv="Content-Type" content="text/html; charset=$charset">
41425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	  <link rel="stylesheet" type="text/css" href="$_[1]gcov.css">
41435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	</head>
41445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
41455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	<body>
41465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	  <map name="overview">
41475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)END_OF_HTML
41485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	;
41495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
41505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	# *************************************************************
41515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
41525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	# Make $offset the next higher multiple of $nav_resolution
41535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	$offset = ($nav_offset + $nav_resolution - 1) / $nav_resolution;
41545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	$offset = sprintf("%d", $offset ) * $nav_resolution;
41555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
41565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	# Create image map for overview image
41575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	for ($index = 1; $index <= $_[4]; $index += $nav_resolution)
41585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	{
41595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		# Enforce nav_offset
41605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		if ($index < $offset + 1)
41615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		{
41625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			write_overview_line($_[0], $_[2], $index, 1);
41635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		}
41645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		else
41655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		{
41665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			write_overview_line($_[0], $_[2], $index, $index - $offset);
41675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		}
41685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
41695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
41705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	# *************************************************************
41715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
41725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	write_html($_[0], <<END_OF_HTML)
41735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	  </map>
41745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
41755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	  <center>
41765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	  <a href="$_[2].gcov.$html_ext#top" target="source">Top</a><br><br>
41775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	  <img src="$_[2].gcov.png" width=$overview_width height=$max_line alt="Overview" border=0 usemap="#overview">
41785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	  </center>
41795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	</body>
41805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	</html>
41815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)END_OF_HTML
41825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	;
41835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
41845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	# *************************************************************
41855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
41865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
41875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
41883551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)sub max($$)
41895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
41903551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	my ($a, $b) = @_;
41915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
41923551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	return $a if ($a > $b);
41933551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	return $b;
41945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
41955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
41965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
41975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#
41985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# write_header(filehandle, type, trunc_file_name, rel_file_name, lines_found,
41995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# lines_hit, funcs_found, funcs_hit, sort_type)
42005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#
42015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# Write a complete standard page header. TYPE may be (0, 1, 2, 3, 4)
42025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# corresponding to (directory view header, file view header, source view
42035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# header, test case description header, function view header)
42045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#
42055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
42063551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)sub write_header(*$$$$$$$$$$)
42075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
42085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	local *HTML_HANDLE = $_[0];
42095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	my $type = $_[1];
42105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	my $trunc_name = $_[2];
42115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	my $rel_filename = $_[3];
42125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	my $lines_found = $_[4];
42135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	my $lines_hit = $_[5];
42145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	my $fn_found = $_[6];
42155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	my $fn_hit = $_[7];
42163551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	my $br_found = $_[8];
42173551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	my $br_hit = $_[9];
42183551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	my $sort_type = $_[10];
42195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	my $base_dir;
42205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	my $view;
42215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	my $test;
42225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	my $base_name;
42233551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	my $style;
42243551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	my $rate;
42253551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	my @row_left;
42263551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	my @row_right;
42273551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	my $num_rows;
42283551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	my $i;
42293551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	my $esc_trunc_name = escape_html($trunc_name);
42305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
42315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	$base_name = basename($rel_filename);
42325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
42335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	# Prepare text for "current view" field
42343551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	if ($type == $HDR_DIR)
42355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	{
42365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		# Main overview
42375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		$base_dir = "";
42385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		$view = $overview_title;
42395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
42403551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	elsif ($type == $HDR_FILE)
42415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	{
42425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		# Directory overview
42435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		$base_dir = get_relative_base_path($rel_filename);
42445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		$view = "<a href=\"$base_dir"."index.$html_ext\">".
42453551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)			"$overview_title</a> - $esc_trunc_name";
42465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
42473551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	elsif ($type == $HDR_SOURCE || $type == $HDR_FUNC)
42485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	{
42495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		# File view
42505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		my $dir_name = dirname($rel_filename);
42513551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)		my $esc_base_name = escape_html($base_name);
42523551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)		my $esc_dir_name = escape_html($dir_name);
42535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
42545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		$base_dir = get_relative_base_path($dir_name);
42555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		if ($frames)
42565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		{
42575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			# Need to break frameset when clicking any of these
42585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			# links
42595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			$view = "<a href=\"$base_dir"."index.$html_ext\" ".
42605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)				"target=\"_parent\">$overview_title</a> - ".
42615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)				"<a href=\"index.$html_ext\" target=\"_parent\">".
42623551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)				"$esc_dir_name</a> - $esc_base_name";
42635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		}
42645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		else
42655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		{
42665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			$view = "<a href=\"$base_dir"."index.$html_ext\">".
42675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)				"$overview_title</a> - ".
42685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)				"<a href=\"index.$html_ext\">".
42693551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)				"$esc_dir_name</a> - $esc_base_name";
42705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		}
42715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
42725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		# Add function suffix
42735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		if ($func_coverage) {
42743551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)			$view .= "<span style=\"font-size: 80%;\">";
42753551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)			if ($type == $HDR_SOURCE) {
42765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)				$view .= " (source / <a href=\"$base_name.func.$html_ext\">functions</a>)";
42773551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)			} elsif ($type == $HDR_FUNC) {
42785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)				$view .= " (<a href=\"$base_name.gcov.$html_ext\">source</a> / functions)";
42795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			}
42803551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)			$view .= "</span>";
42815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		}
42825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
42833551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	elsif ($type == $HDR_TESTDESC)
42845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	{
42855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		# Test description header
42865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		$base_dir = "";
42875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		$view = "<a href=\"$base_dir"."index.$html_ext\">".
42885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			"$overview_title</a> - test case descriptions";
42895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
42905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
42915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	# Prepare text for "test" field
42925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	$test = escape_html($test_title);
42935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
42945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	# Append link to test description page if available
42953551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	if (%test_description && ($type != $HDR_TESTDESC))
42965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	{
42973551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)		if ($frames && ($type == $HDR_SOURCE || $type == $HDR_FUNC))
42985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		{
42995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			# Need to break frameset when clicking this link
43003551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)			$test .= " ( <span style=\"font-size:80%;\">".
43013551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)				 "<a href=\"$base_dir".
43025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)				 "descriptions.$html_ext\" target=\"_parent\">".
43033551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)				 "view descriptions</a></span> )";
43045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		}
43055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		else
43065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		{
43073551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)			$test .= " ( <span style=\"font-size:80%;\">".
43083551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)				 "<a href=\"$base_dir".
43095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)				 "descriptions.$html_ext\">".
43103551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)				 "view descriptions</a></span> )";
43115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		}
43125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
43135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
43145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	# Write header
43155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	write_header_prolog(*HTML_HANDLE, $base_dir);
43163551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
43173551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	# Left row
43183551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	push(@row_left, [[ "10%", "headerItem", "Current view:" ],
43193551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)			 [ "35%", "headerValue", $view ]]);
43203551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	push(@row_left, [[undef, "headerItem", "Test:"],
43213551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)			 [undef, "headerValue", $test]]);
43223551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	push(@row_left, [[undef, "headerItem", "Date:"],
43233551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)			 [undef, "headerValue", $date]]);
43243551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
43253551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	# Right row
43263551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	if ($legend && ($type == $HDR_SOURCE || $type == $HDR_FUNC)) {
43273551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)		my $text = <<END_OF_HTML;
43283551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)            Lines:
43293551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)            <span class="coverLegendCov">hit</span>
43303551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)            <span class="coverLegendNoCov">not hit</span>
43313551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)END_OF_HTML
43323551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)		if ($br_coverage) {
43333551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)			$text .= <<END_OF_HTML;
43343551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)            | Branches:
43353551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)            <span class="coverLegendCov">+</span> taken
43363551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)            <span class="coverLegendNoCov">-</span> not taken
43373551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)            <span class="coverLegendNoCov">#</span> not executed
43383551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)END_OF_HTML
43393551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)		}
43403551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)		push(@row_left, [[undef, "headerItem", "Legend:"],
43413551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)				 [undef, "headerValueLeg", $text]]);
43423551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	} elsif ($legend && ($type != $HDR_TESTDESC)) {
43433551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)		my $text = <<END_OF_HTML;
43443551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	    Rating:
43453551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)            <span class="coverLegendCovLo" title="Coverage rates below $med_limit % are classified as low">low: &lt; $med_limit %</span>
43463551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)            <span class="coverLegendCovMed" title="Coverage rates between $med_limit % and $hi_limit % are classified as medium">medium: &gt;= $med_limit %</span>
43473551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)            <span class="coverLegendCovHi" title="Coverage rates of $hi_limit % and more are classified as high">high: &gt;= $hi_limit %</span>
43483551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)END_OF_HTML
43493551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)		push(@row_left, [[undef, "headerItem", "Legend:"],
43503551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)				 [undef, "headerValueLeg", $text]]);
43513551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	}
43523551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	if ($type == $HDR_TESTDESC) {
43533551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)		push(@row_right, [[ "55%" ]]);
43545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	} else {
43553551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)		push(@row_right, [["15%", undef, undef ],
43563551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)				  ["10%", "headerCovTableHead", "Hit" ],
43573551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)				  ["10%", "headerCovTableHead", "Total" ],
43583551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)				  ["15%", "headerCovTableHead", "Coverage"]]);
43593551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	}
43603551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	# Line coverage
43613551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	$style = $rate_name[classify_rate($lines_found, $lines_hit,
43623551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)					  $med_limit, $hi_limit)];
43633551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	$rate = rate($lines_hit, $lines_found, " %");
43643551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	push(@row_right, [[undef, "headerItem", "Lines:"],
43653551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)			  [undef, "headerCovTableEntry", $lines_hit],
43663551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)			  [undef, "headerCovTableEntry", $lines_found],
43673551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)			  [undef, "headerCovTableEntry$style", $rate]])
43683551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)			if ($type != $HDR_TESTDESC);
43693551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	# Function coverage
43703551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	if ($func_coverage) {
43713551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)		$style = $rate_name[classify_rate($fn_found, $fn_hit,
43723551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)						  $fn_med_limit, $fn_hi_limit)];
43733551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)		$rate = rate($fn_hit, $fn_found, " %");
43743551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)		push(@row_right, [[undef, "headerItem", "Functions:"],
43753551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)				  [undef, "headerCovTableEntry", $fn_hit],
43763551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)				  [undef, "headerCovTableEntry", $fn_found],
43773551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)				  [undef, "headerCovTableEntry$style", $rate]])
43783551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)			if ($type != $HDR_TESTDESC);
43793551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	}
43803551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	# Branch coverage
43813551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	if ($br_coverage) {
43823551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)		$style = $rate_name[classify_rate($br_found, $br_hit,
43833551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)						  $br_med_limit, $br_hi_limit)];
43843551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)		$rate = rate($br_hit, $br_found, " %");
43853551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)		push(@row_right, [[undef, "headerItem", "Branches:"],
43863551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)				  [undef, "headerCovTableEntry", $br_hit],
43873551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)				  [undef, "headerCovTableEntry", $br_found],
43883551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)				  [undef, "headerCovTableEntry$style", $rate]])
43893551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)			if ($type != $HDR_TESTDESC);
43903551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	}
43913551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
43923551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	# Print rows
43933551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	$num_rows = max(scalar(@row_left), scalar(@row_right));
43943551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	for ($i = 0; $i < $num_rows; $i++) {
43953551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)		my $left = $row_left[$i];
43963551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)		my $right = $row_right[$i];
43973551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
43983551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)		if (!defined($left)) {
43993551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)			$left = [[undef, undef, undef], [undef, undef, undef]];
44003551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)		}
44013551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)		if (!defined($right)) {
44023551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)			$right = [];
44035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		}
44043551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)		write_header_line(*HTML_HANDLE, @{$left},
44053551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)				  [ $i == 0 ? "5%" : undef, undef, undef],
44063551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)				  @{$right});
44075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
44083551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
44093551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	# Fourth line
44105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	write_header_epilog(*HTML_HANDLE, $base_dir);
44115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
44125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
44135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
44145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#
44155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# get_sorted_keys(hash_ref, sort_type)
44165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#
44175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
44185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)sub get_sorted_keys($$)
44195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
44205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	my ($hash, $type) = @_;
44215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
44223551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	if ($type == $SORT_FILE) {
44235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		# Sort by name
44245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		return sort(keys(%{$hash}));
44253551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	} elsif ($type == $SORT_LINE) {
44265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		# Sort by line coverage
44273551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)		return sort({$hash->{$a}[7] <=> $hash->{$b}[7]} keys(%{$hash}));
44283551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	} elsif ($type == $SORT_FUNC) {
44295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		# Sort by function coverage;
44303551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)		return sort({$hash->{$a}[8] <=> $hash->{$b}[8]}	keys(%{$hash}));
44313551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	} elsif ($type == $SORT_BRANCH) {
44323551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)		# Sort by br coverage;
44333551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)		return sort({$hash->{$a}[9] <=> $hash->{$b}[9]}	keys(%{$hash}));
44345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
44355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
44365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
44375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)sub get_sort_code($$$)
44385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
44395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	my ($link, $alt, $base) = @_;
44405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	my $png;
44415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	my $link_start;
44425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	my $link_end;
44435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
44445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (!defined($link)) {
44455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		$png = "glass.png";
44465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		$link_start = "";
44475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		$link_end = "";
44485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	} else {
44495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		$png = "updown.png";
44505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		$link_start = '<a href="'.$link.'">';
44515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		$link_end = "</a>";
44525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
44535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
44545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return ' <span class="tableHeadSort">'.$link_start.
44555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	       '<img src="'.$base.$png.'" width=10 height=14 '.
44565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	       'alt="'.$alt.'" title="'.$alt.'" border=0>'.$link_end.'</span>';
44575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
44585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
44595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)sub get_file_code($$$$)
44605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
44615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	my ($type, $text, $sort_button, $base) = @_;
44625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	my $result = $text;
44635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	my $link;
44645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
44655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if ($sort_button) {
44663551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)		if ($type == $HEAD_NO_DETAIL) {
44675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			$link = "index.$html_ext";
44685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		} else {
44695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			$link = "index-detail.$html_ext";
44705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		}
44715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
44725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	$result .= get_sort_code($link, "Sort by name", $base);
44735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
44745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return $result;
44755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
44765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
44775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)sub get_line_code($$$$$)
44785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
44795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	my ($type, $sort_type, $text, $sort_button, $base) = @_;
44805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	my $result = $text;
44815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	my $sort_link;
44825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
44833551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	if ($type == $HEAD_NO_DETAIL) {
44845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		# Just text
44855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		if ($sort_button) {
44865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			$sort_link = "index-sort-l.$html_ext";
44875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		}
44883551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	} elsif ($type == $HEAD_DETAIL_HIDDEN) {
44895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		# Text + link to detail view
44905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		$result .= ' ( <a class="detail" href="index-detail'.
44915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			   $fileview_sortname[$sort_type].'.'.$html_ext.
44925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			   '">show details</a> )';
44935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		if ($sort_button) {
44945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			$sort_link = "index-sort-l.$html_ext";
44955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		}
44965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	} else {
44975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		# Text + link to standard view
44985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		$result .= ' ( <a class="detail" href="index'.
44995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			   $fileview_sortname[$sort_type].'.'.$html_ext.
45005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			   '">hide details</a> )';
45015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		if ($sort_button) {
45025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			$sort_link = "index-detail-sort-l.$html_ext";
45035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		}
45045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
45055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	# Add sort button
45065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	$result .= get_sort_code($sort_link, "Sort by line coverage", $base);
45075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
45085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return $result;
45095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
45105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
45115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)sub get_func_code($$$$)
45125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
45135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	my ($type, $text, $sort_button, $base) = @_;
45145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	my $result = $text;
45155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	my $link;
45165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
45175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if ($sort_button) {
45183551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)		if ($type == $HEAD_NO_DETAIL) {
45195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			$link = "index-sort-f.$html_ext";
45205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		} else {
45215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			$link = "index-detail-sort-f.$html_ext";
45225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		}
45235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
45245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	$result .= get_sort_code($link, "Sort by function coverage", $base);
45255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return $result;
45265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
45275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
45283551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)sub get_br_code($$$$)
45293551c9c881056c480085172ff9840cab31610854Torne (Richard Coles){
45303551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	my ($type, $text, $sort_button, $base) = @_;
45313551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	my $result = $text;
45323551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	my $link;
45333551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
45343551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	if ($sort_button) {
45353551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)		if ($type == $HEAD_NO_DETAIL) {
45363551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)			$link = "index-sort-b.$html_ext";
45373551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)		} else {
45383551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)			$link = "index-detail-sort-b.$html_ext";
45393551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)		}
45403551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	}
45413551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	$result .= get_sort_code($link, "Sort by branch coverage", $base);
45423551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	return $result;
45433551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)}
45443551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
45455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#
45465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# write_file_table(filehandle, base_dir, overview, testhash, testfnchash,
45473551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#                  testbrhash, fileview, sort_type)
45485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#
45495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# Write a complete file table. OVERVIEW is a reference to a hash containing
45505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# the following mapping:
45515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#
45525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#   filename -> "lines_found,lines_hit,funcs_found,funcs_hit,page_link,
45535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#		 func_link"
45545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#
45555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# TESTHASH is a reference to the following hash:
45565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#
45575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#   filename -> \%testdata
45585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#   %testdata: name of test affecting this file -> \%testcount
45595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#   %testcount: line number -> execution count for a single test
45605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#
45615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# Heading of first column is "Filename" if FILEVIEW is true, "Directory name"
45625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# otherwise.
45635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#
45645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
45653551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)sub write_file_table(*$$$$$$$)
45665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
45675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	local *HTML_HANDLE = $_[0];
45685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	my $base_dir = $_[1];
45695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	my $overview = $_[2];
45705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	my $testhash = $_[3];
45715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	my $testfnchash = $_[4];
45723551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	my $testbrhash = $_[5];
45733551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	my $fileview = $_[6];
45743551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	my $sort_type = $_[7];
45755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	my $filename;
45765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	my $bar_graph;
45775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	my $hit;
45785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	my $found;
45795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	my $fn_found;
45805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	my $fn_hit;
45813551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	my $br_found;
45823551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	my $br_hit;
45835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	my $page_link;
45845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	my $testname;
45855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	my $testdata;
45865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	my $testfncdata;
45873551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	my $testbrdata;
45885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	my %affecting_tests;
45895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	my $line_code = "";
45905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	my $func_code;
45913551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	my $br_code;
45925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	my $file_code;
45933551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	my @head_columns;
45945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
45955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	# Determine HTML code for column headings
45965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (($base_dir ne "") && $show_details)
45975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	{
45985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		my $detailed = keys(%{$testhash});
45995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
46003551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)		$file_code = get_file_code($detailed ? $HEAD_DETAIL_HIDDEN :
46013551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)					$HEAD_NO_DETAIL,
46025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)					$fileview ? "Filename" : "Directory",
46033551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)					$sort && $sort_type != $SORT_FILE,
46043551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)					$base_dir);
46053551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)		$line_code = get_line_code($detailed ? $HEAD_DETAIL_SHOWN :
46063551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)					$HEAD_DETAIL_HIDDEN,
46073551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)					$sort_type,
46085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)					"Line Coverage",
46093551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)					$sort && $sort_type != $SORT_LINE,
46103551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)					$base_dir);
46113551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)		$func_code = get_func_code($detailed ? $HEAD_DETAIL_HIDDEN :
46123551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)					$HEAD_NO_DETAIL,
46133551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)					"Functions",
46143551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)					$sort && $sort_type != $SORT_FUNC,
46153551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)					$base_dir);
46163551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)		$br_code = get_br_code($detailed ? $HEAD_DETAIL_HIDDEN :
46173551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)					$HEAD_NO_DETAIL,
46183551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)					"Branches",
46193551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)					$sort && $sort_type != $SORT_BRANCH,
46203551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)					$base_dir);
46215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	} else {
46223551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)		$file_code = get_file_code($HEAD_NO_DETAIL,
46235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)					$fileview ? "Filename" : "Directory",
46243551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)					$sort && $sort_type != $SORT_FILE,
46253551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)					$base_dir);
46263551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)		$line_code = get_line_code($HEAD_NO_DETAIL, $sort_type, "Line Coverage",
46273551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)					$sort && $sort_type != $SORT_LINE,
46283551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)					$base_dir);
46293551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)		$func_code = get_func_code($HEAD_NO_DETAIL, "Functions",
46303551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)					$sort && $sort_type != $SORT_FUNC,
46313551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)					$base_dir);
46323551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)		$br_code = get_br_code($HEAD_NO_DETAIL, "Branches",
46333551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)					$sort && $sort_type != $SORT_BRANCH,
46343551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)					$base_dir);
46353551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	}
46363551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	push(@head_columns, [ $line_code, 3 ]);
46373551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	push(@head_columns, [ $func_code, 2]) if ($func_coverage);
46383551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	push(@head_columns, [ $br_code, 2]) if ($br_coverage);
46393551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
46403551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	write_file_table_prolog(*HTML_HANDLE, $file_code, @head_columns);
46415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
46425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	foreach $filename (get_sorted_keys($overview, $sort_type))
46435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	{
46443551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)		my @columns;
46453551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)		($found, $hit, $fn_found, $fn_hit, $br_found, $br_hit,
46463551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)		 $page_link) = @{$overview->{$filename}};
46473551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
46483551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)		# Line coverage
46493551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)		push(@columns, [$found, $hit, $med_limit, $hi_limit, 1]);
46503551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)		# Function coverage
46513551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)		if ($func_coverage) {
46523551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)			push(@columns, [$fn_found, $fn_hit, $fn_med_limit,
46533551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)					$fn_hi_limit, 0]);
46543551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)		}
46553551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)		# Branch coverage
46563551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)		if ($br_coverage) {
46573551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)			push(@columns, [$br_found, $br_hit, $br_med_limit,
46583551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)					$br_hi_limit, 0]);
46593551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)		}
46603551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)		write_file_table_entry(*HTML_HANDLE, $base_dir, $filename,
46613551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)				       $page_link, @columns);
46625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
46635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		$testdata = $testhash->{$filename};
46645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		$testfncdata = $testfnchash->{$filename};
46653551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)		$testbrdata = $testbrhash->{$filename};
46665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
46675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		# Check whether we should write test specific coverage
46685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		# as well
46695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		if (!($show_details && $testdata)) { next; }
46705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
46715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		# Filter out those tests that actually affect this file
46725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		%affecting_tests = %{ get_affecting_tests($testdata,
46733551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)					$testfncdata, $testbrdata) };
46745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
46755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		# Does any of the tests affect this file at all?
46765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		if (!%affecting_tests) { next; }
46775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
46785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		foreach $testname (keys(%affecting_tests))
46795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		{
46803551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)			my @results;
46813551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)			($found, $hit, $fn_found, $fn_hit, $br_found, $br_hit) =
46825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)				split(",", $affecting_tests{$testname});
46835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
46845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			# Insert link to description of available
46855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			if ($test_description{$testname})
46865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			{
46875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)				$testname = "<a href=\"$base_dir".
46885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)					    "descriptions.$html_ext#$testname\">".
46895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)					    "$testname</a>";
46905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			}
46915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
46923551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)			push(@results, [$found, $hit]);
46933551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)			push(@results, [$fn_found, $fn_hit]) if ($func_coverage);
46943551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)			push(@results, [$br_found, $br_hit]) if ($br_coverage);
46955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			write_file_table_detail_entry(*HTML_HANDLE, $testname,
46963551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)				@results);
46975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		}
46985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
46995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
47005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	write_file_table_epilog(*HTML_HANDLE);
47015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
47025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
47035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
47045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#
47055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# get_found_and_hit(hash)
47065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#
47075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# Return the count for entries (found) and entries with an execution count
47085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# greater than zero (hit) in a hash (linenumber -> execution count) as
47095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# a list (found, hit)
47105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#
47115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
47125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)sub get_found_and_hit($)
47135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
47145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	my %hash = %{$_[0]};
47155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	my $found = 0;
47165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	my $hit = 0;
47175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
47185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	# Calculate sum
47195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	$found = 0;
47205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	$hit = 0;
47215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			
47225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	foreach (keys(%hash))
47235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	{
47245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		$found++;
47255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		if ($hash{$_}>0) { $hit++; }
47265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
47275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
47285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return ($found, $hit);
47295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
47305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
47315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
47325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#
47335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# get_func_found_and_hit(sumfnccount)
47345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#
47355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# Return (f_found, f_hit) for sumfnccount
47365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#
47375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
47385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)sub get_func_found_and_hit($)
47395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
47405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	my ($sumfnccount) = @_;
47415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	my $function;
47425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	my $fn_found;
47435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	my $fn_hit;
47445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
47455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	$fn_found = scalar(keys(%{$sumfnccount}));
47465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	$fn_hit = 0;
47475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	foreach $function (keys(%{$sumfnccount})) {
47485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		if ($sumfnccount->{$function} > 0) {
47495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			$fn_hit++;
47505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		}
47515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
47525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return ($fn_found, $fn_hit);
47535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
47545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
47555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
47565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#
47573551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)# br_taken_to_num(taken)
47583551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#
47593551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)# Convert a branch taken value .info format to number format.
47603551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#
47613551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
47623551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)sub br_taken_to_num($)
47633551c9c881056c480085172ff9840cab31610854Torne (Richard Coles){
47643551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	my ($taken) = @_;
47653551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
47663551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	return 0 if ($taken eq '-');
47673551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	return $taken + 1;
47683551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)}
47693551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
47703551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
47713551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#
47723551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)# br_num_to_taken(taken)
47733551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#
47743551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)# Convert a branch taken value in number format to .info format.
47753551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#
47763551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
47773551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)sub br_num_to_taken($)
47783551c9c881056c480085172ff9840cab31610854Torne (Richard Coles){
47793551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	my ($taken) = @_;
47803551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
47813551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	return '-' if ($taken == 0);
47823551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	return $taken - 1;
47833551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)}
47843551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
47853551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
47863551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#
47873551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)# br_taken_add(taken1, taken2)
47883551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#
47893551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)# Return the result of taken1 + taken2 for 'branch taken' values.
47903551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#
47913551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
47923551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)sub br_taken_add($$)
47933551c9c881056c480085172ff9840cab31610854Torne (Richard Coles){
47943551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	my ($t1, $t2) = @_;
47953551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
47963551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	return $t1 if (!defined($t2));
47973551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	return $t2 if (!defined($t1));
47983551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	return $t1 if ($t2 eq '-');
47993551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	return $t2 if ($t1 eq '-');
48003551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	return $t1 + $t2;
48013551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)}
48023551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
48033551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
48043551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#
48053551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)# br_taken_sub(taken1, taken2)
48063551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#
48073551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)# Return the result of taken1 - taken2 for 'branch taken' values. Return 0
48083551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)# if the result would become negative.
48093551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#
48103551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
48113551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)sub br_taken_sub($$)
48123551c9c881056c480085172ff9840cab31610854Torne (Richard Coles){
48133551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	my ($t1, $t2) = @_;
48143551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
48153551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	return $t1 if (!defined($t2));
48163551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	return undef if (!defined($t1));
48173551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	return $t1 if ($t1 eq '-');
48183551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	return $t1 if ($t2 eq '-');
48193551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	return 0 if $t2 > $t1;
48203551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	return $t1 - $t2;
48213551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)}
48223551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
48233551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
48243551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#
48253551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)# br_ivec_len(vector)
48263551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#
48273551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)# Return the number of entries in the branch coverage vector.
48283551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#
48293551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
48303551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)sub br_ivec_len($)
48313551c9c881056c480085172ff9840cab31610854Torne (Richard Coles){
48323551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	my ($vec) = @_;
48333551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
48343551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	return 0 if (!defined($vec));
48353551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	return (length($vec) * 8 / $BR_VEC_WIDTH) / $BR_VEC_ENTRIES;
48363551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)}
48373551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
48383551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
48393551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#
48403551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)# br_ivec_get(vector, number)
48413551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#
48423551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)# Return an entry from the branch coverage vector.
48433551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#
48443551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
48453551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)sub br_ivec_get($$)
48463551c9c881056c480085172ff9840cab31610854Torne (Richard Coles){
48473551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	my ($vec, $num) = @_;
48483551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	my $block;
48493551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	my $branch;
48503551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	my $taken;
48513551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	my $offset = $num * $BR_VEC_ENTRIES;
48523551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
48533551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	# Retrieve data from vector
48543551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	$block	= vec($vec, $offset + $BR_BLOCK, $BR_VEC_WIDTH);
48553551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	$branch = vec($vec, $offset + $BR_BRANCH, $BR_VEC_WIDTH);
48563551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	$taken	= vec($vec, $offset + $BR_TAKEN, $BR_VEC_WIDTH);
48573551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
48583551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	# Decode taken value from an integer
48593551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	$taken = br_num_to_taken($taken);
48603551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
48613551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	return ($block, $branch, $taken);
48623551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)}
48633551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
48643551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
48653551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#
48663551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)# br_ivec_push(vector, block, branch, taken)
48673551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#
48683551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)# Add an entry to the branch coverage vector. If an entry with the same
48693551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)# branch ID already exists, add the corresponding taken values.
48703551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#
48713551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
48723551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)sub br_ivec_push($$$$)
48733551c9c881056c480085172ff9840cab31610854Torne (Richard Coles){
48743551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	my ($vec, $block, $branch, $taken) = @_;
48753551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	my $offset;
48763551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	my $num = br_ivec_len($vec);
48773551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	my $i;
48783551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
48793551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	$vec = "" if (!defined($vec));
48803551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
48813551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	# Check if branch already exists in vector
48823551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	for ($i = 0; $i < $num; $i++) {
48833551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)		my ($v_block, $v_branch, $v_taken) = br_ivec_get($vec, $i);
48843551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
48853551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)		next if ($v_block != $block || $v_branch != $branch);
48863551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
48873551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)		# Add taken counts
48883551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)		$taken = br_taken_add($taken, $v_taken);
48893551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)		last;
48903551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	}
48913551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
48923551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	$offset = $i * $BR_VEC_ENTRIES;
48933551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	$taken = br_taken_to_num($taken);
48943551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
48953551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	# Add to vector
48963551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	vec($vec, $offset + $BR_BLOCK, $BR_VEC_WIDTH) = $block;
48973551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	vec($vec, $offset + $BR_BRANCH, $BR_VEC_WIDTH) = $branch;
48983551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	vec($vec, $offset + $BR_TAKEN, $BR_VEC_WIDTH) = $taken;
48993551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
49003551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	return $vec;
49013551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)}
49023551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
49033551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
49043551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#
49053551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)# get_br_found_and_hit(sumbrcount)
49063551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#
49073551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)# Return (br_found, br_hit) for sumbrcount
49083551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#
49093551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
49103551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)sub get_br_found_and_hit($)
49113551c9c881056c480085172ff9840cab31610854Torne (Richard Coles){
49123551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	my ($sumbrcount) = @_;
49133551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	my $line;
49143551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	my $br_found = 0;
49153551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	my $br_hit = 0;
49163551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
49173551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	foreach $line (keys(%{$sumbrcount})) {
49183551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)		my $brdata = $sumbrcount->{$line};
49193551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)		my $i;
49203551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)		my $num = br_ivec_len($brdata);
49213551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
49223551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)		for ($i = 0; $i < $num; $i++) {
49233551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)			my $taken;
49243551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
49253551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)			(undef, undef, $taken) = br_ivec_get($brdata, $i);
49263551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
49273551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)			$br_found++;
49283551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)			$br_hit++ if ($taken ne "-" && $taken > 0);
49293551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)		}
49303551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	}
49313551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
49323551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	return ($br_found, $br_hit);
49333551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)}
49343551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
49353551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
49363551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#
49373551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)# get_affecting_tests(testdata, testfncdata, testbrdata)
49385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#
49395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# HASHREF contains a mapping filename -> (linenumber -> exec count). Return
49405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# a hash containing mapping filename -> "lines found, lines hit" for each
49415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# filename which has a nonzero hit count.
49425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#
49435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
49443551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)sub get_affecting_tests($$$)
49455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
49463551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	my ($testdata, $testfncdata, $testbrdata) = @_;
49475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	my $testname;
49485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	my $testcount;
49495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	my $testfnccount;
49503551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	my $testbrcount;
49515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	my %result;
49525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	my $found;
49535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	my $hit;
49545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	my $fn_found;
49555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	my $fn_hit;
49563551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	my $br_found;
49573551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	my $br_hit;
49585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
49595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	foreach $testname (keys(%{$testdata}))
49605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	{
49615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		# Get (line number -> count) hash for this test case
49625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		$testcount = $testdata->{$testname};
49635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		$testfnccount = $testfncdata->{$testname};
49643551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)		$testbrcount = $testbrdata->{$testname};
49655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
49665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		# Calculate sum
49675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		($found, $hit) = get_found_and_hit($testcount);
49685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		($fn_found, $fn_hit) = get_func_found_and_hit($testfnccount);
49693551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)		($br_found, $br_hit) = get_br_found_and_hit($testbrcount);
49705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
49715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		if ($hit>0)
49725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		{
49733551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)			$result{$testname} = "$found,$hit,$fn_found,$fn_hit,".
49743551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)					     "$br_found,$br_hit";
49755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		}
49765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
49775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
49785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return(\%result);
49795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
49805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
49815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
49825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)sub get_hash_reverse($)
49835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
49845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	my ($hash) = @_;
49855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	my %result;
49865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
49875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	foreach (keys(%{$hash})) {
49885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		$result{$hash->{$_}} = $_;
49895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
49905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
49915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return \%result;
49925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
49935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
49945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#
49955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# write_source(filehandle, source_filename, count_data, checksum_data,
49963551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#              converted_data, func_data, sumbrcount)
49975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#
49985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# Write an HTML view of a source code file. Returns a list containing
49995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# data as needed by gen_png().
50005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#
50015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# Die on error.
50025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#
50035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
50043551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)sub write_source($$$$$$$)
50055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
50065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	local *HTML_HANDLE = $_[0];
50075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	local *SOURCE_HANDLE;
50085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	my $source_filename = $_[1];
50095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	my %count_data;
50105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	my $line_number;
50115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	my @result;
50125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	my $checkdata = $_[3];
50135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	my $converted = $_[4];
50145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	my $funcdata  = $_[5];
50153551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	my $sumbrcount = $_[6];
50165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	my $datafunc = get_hash_reverse($funcdata);
50175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	my $add_anchor;
50183551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	my @file;
50195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
50205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if ($_[2])
50215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	{
50225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		%count_data = %{$_[2]};
50235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
50245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
50253551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	if (!open(SOURCE_HANDLE, "<", $source_filename)) {
50263551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)		my @lines;
50273551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)		my $last_line = 0;
50283551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
50293551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)		if (!$ignore[$ERROR_SOURCE]) {
50303551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)			die("ERROR: cannot read $source_filename\n");
50313551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)		}
50323551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
50333551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)		# Continue without source file
50343551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)		warn("WARNING: cannot read $source_filename!\n");
50353551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
50363551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)		@lines = sort( { $a <=> $b }  keys(%count_data));
50373551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)		if (@lines) {
50383551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)			$last_line = $lines[scalar(@lines) - 1];
50393551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)		}
50403551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)		return ( ":" ) if ($last_line < 1);
50413551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
50423551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)		# Simulate gcov behavior
50433551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)		for ($line_number = 1; $line_number <= $last_line;
50443551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)		     $line_number++) {
50453551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)			push(@file, "/* EOF */");
50463551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)		}
50473551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	} else {
50483551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)		@file = <SOURCE_HANDLE>;
50493551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	}
50505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	
50515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	write_source_prolog(*HTML_HANDLE);
50523551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	$line_number = 0;
50533551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	foreach (@file) {
50543551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)		$line_number++;
50555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		chomp($_);
50565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
50573551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)		# Also remove CR from line-end
50583551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)		s/\015$//;
50593551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
50605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		# Source code matches coverage data?
50615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		if (defined($checkdata->{$line_number}) &&
50625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    ($checkdata->{$line_number} ne md5_base64($_)))
50635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		{
50645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			die("ERROR: checksum mismatch  at $source_filename:".
50655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			    "$line_number\n");
50665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		}
50675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
50685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		$add_anchor = 0;
50695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		if ($frames) {
50705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			if (($line_number - 1) % $nav_resolution == 0) {
50715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)				$add_anchor = 1;
50725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			}
50735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		}
50745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		if ($func_coverage) {
50755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			if ($line_number == 1) {
50765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)				$add_anchor = 1;
50775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			} elsif (defined($datafunc->{$line_number +
50785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)						     $func_offset})) {
50795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)				$add_anchor = 1;
50805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			}
50815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		}
50825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		push (@result,
50835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		      write_source_line(HTML_HANDLE, $line_number,
50845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)					$_, $count_data{$line_number},
50855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)					$converted->{$line_number},
50863551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)					$sumbrcount->{$line_number}, $add_anchor));
50875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
50885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
50895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	close(SOURCE_HANDLE);
50905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	write_source_epilog(*HTML_HANDLE);
50915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return(@result);
50925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
50935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
50945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
50955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)sub funcview_get_func_code($$$)
50965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
50975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	my ($name, $base, $type) = @_;
50985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	my $result;
50995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	my $link;
51005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
51015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if ($sort && $type == 1) {
51025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		$link = "$name.func.$html_ext";
51035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
51045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	$result = "Function Name";
51055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	$result .= get_sort_code($link, "Sort by function name", $base);
51065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
51075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return $result;
51085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
51095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
51105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)sub funcview_get_count_code($$$)
51115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
51125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	my ($name, $base, $type) = @_;
51135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	my $result;
51145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	my $link;
51155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
51165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if ($sort && $type == 0) {
51175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		$link = "$name.func-sort-c.$html_ext";
51185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
51195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	$result = "Hit count";
51205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	$result .= get_sort_code($link, "Sort by hit count", $base);
51215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
51225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return $result;
51235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
51245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
51255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#
51265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# funcview_get_sorted(funcdata, sumfncdata, sort_type)
51275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#
51285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# Depending on the value of sort_type, return a list of functions sorted
51295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# by name (type 0) or by the associated call count (type 1).
51305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#
51315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
51325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)sub funcview_get_sorted($$$)
51335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
51345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	my ($funcdata, $sumfncdata, $type) = @_;
51355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
51365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if ($type == 0) {
51375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		return sort(keys(%{$funcdata}));
51385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
51395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return sort({$sumfncdata->{$b} <=> $sumfncdata->{$a}}
51405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    keys(%{$sumfncdata}));
51415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
51425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
51435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#
51445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# write_function_table(filehandle, source_file, sumcount, funcdata,
51453551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#		       sumfnccount, testfncdata, sumbrcount, testbrdata,
51463551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#		       base_name, base_dir, sort_type)
51475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#
51485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# Write an HTML table listing all functions in a source file, including
51495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# also function call counts and line coverages inside of each function.
51505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#
51515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# Die on error.
51525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#
51535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
51543551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)sub write_function_table(*$$$$$$$$$$)
51555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
51565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	local *HTML_HANDLE = $_[0];
51575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	my $source = $_[1];
51585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	my $sumcount = $_[2];
51595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	my $funcdata = $_[3];
51605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	my $sumfncdata = $_[4];
51615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	my $testfncdata = $_[5];
51623551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	my $sumbrcount = $_[6];
51633551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	my $testbrdata = $_[7];
51643551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	my $name = $_[8];
51653551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	my $base = $_[9];
51663551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	my $type = $_[10];
51675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	my $func;
51685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	my $func_code;
51695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	my $count_code;
51705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
51715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	# Get HTML code for headings
51725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	$func_code = funcview_get_func_code($name, $base, $type);
51735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	$count_code = funcview_get_count_code($name, $base, $type);
51745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	write_html(*HTML_HANDLE, <<END_OF_HTML)
51755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	  <center>
51765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	  <table width="60%" cellpadding=1 cellspacing=1 border=0>
51775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    <tr><td><br></td></tr>
51785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    <tr>
51795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	      <td width="80%" class="tableHead">$func_code</td>
51805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	      <td width="20%" class="tableHead">$count_code</td>
51815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    </tr>
51825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)END_OF_HTML
51835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	;
51845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	
51855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	# Get a sorted table
51865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	foreach $func (funcview_get_sorted($funcdata, $sumfncdata, $type)) {
51873551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)		if (!defined($funcdata->{$func}))
51883551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)		{
51893551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)			next;
51903551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)		}
51913551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
51925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		my $startline = $funcdata->{$func} - $func_offset;
51933551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)		my $name = $func;
51945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		my $count = $sumfncdata->{$name};
51955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		my $countstyle;
51965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
51973551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)		# Demangle C++ function names if requested
51983551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)		if ($demangle_cpp) {
51993551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)			$name = `c++filt "$name"`;
52003551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)			chomp($name);
52013551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)		}
52023551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)		# Escape any remaining special characters
52033551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)		$name = escape_html($name);
52045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		if ($startline < 1) {
52055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			$startline = 1;
52065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		}
52075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		if ($count == 0) {
52085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			$countstyle = "coverFnLo";
52095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		} else {
52105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			$countstyle = "coverFnHi";
52115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		}
52125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
52135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		write_html(*HTML_HANDLE, <<END_OF_HTML)
52145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    <tr>
52155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              <td class="coverFn"><a href="$source#$startline">$name</a></td>
52165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              <td class="$countstyle">$count</td>
52175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            </tr>
52185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)END_OF_HTML
52195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                ;
52205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
52215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	write_html(*HTML_HANDLE, <<END_OF_HTML)
52225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	  </table>
52235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	  <br>
52245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	  </center>
52255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)END_OF_HTML
52265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	;
52275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
52285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
52295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
52305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#
52315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# info(printf_parameter)
52325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#
52335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# Use printf to write PRINTF_PARAMETER to stdout only when the $quiet flag
52345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# is not set.
52355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#
52365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
52375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)sub info(@)
52385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
52395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (!$quiet)
52405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	{
52415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		# Print info string
52425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		printf(@_);
52435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
52445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
52455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
52465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
52475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#
52485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# subtract_counts(data_ref, base_ref)
52495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#
52505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
52515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)sub subtract_counts($$)
52525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
52535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	my %data = %{$_[0]};
52545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	my %base = %{$_[1]};
52555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	my $line;
52565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	my $data_count;
52575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	my $base_count;
52585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	my $hit = 0;
52595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	my $found = 0;
52605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
52615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	foreach $line (keys(%data))
52625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	{
52635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		$found++;
52645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		$data_count = $data{$line};
52655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		$base_count = $base{$line};
52665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
52675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		if (defined($base_count))
52685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		{
52695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			$data_count -= $base_count;
52705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
52715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			# Make sure we don't get negative numbers
52725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			if ($data_count<0) { $data_count = 0; }
52735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		}
52745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
52755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		$data{$line} = $data_count;
52765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		if ($data_count > 0) { $hit++; }
52775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
52785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
52795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return (\%data, $found, $hit);
52805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
52815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
52825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
52835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#
52845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# subtract_fnccounts(data, base)
52855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#
52865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# Subtract function call counts found in base from those in data.
52875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# Return (data, f_found, f_hit).
52885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#
52895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
52905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)sub subtract_fnccounts($$)
52915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
52923551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	my %data;
52933551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	my %base;
52945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	my $func;
52955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	my $data_count;
52965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	my $base_count;
52975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	my $fn_hit = 0;
52985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	my $fn_found = 0;
52995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
53003551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	%data = %{$_[0]} if (defined($_[0]));
53013551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	%base = %{$_[1]} if (defined($_[1]));
53025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	foreach $func (keys(%data)) {
53035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		$fn_found++;
53045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		$data_count = $data{$func};
53055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		$base_count = $base{$func};
53065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
53075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		if (defined($base_count)) {
53085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			$data_count -= $base_count;
53095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
53105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			# Make sure we don't get negative numbers
53115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			if ($data_count < 0) {
53125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)				$data_count = 0;
53135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			}
53145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		}
53155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
53165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		$data{$func} = $data_count;
53175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		if ($data_count > 0) {
53185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			$fn_hit++;
53195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		}
53205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
53215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
53225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return (\%data, $fn_found, $fn_hit);
53235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
53245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
53255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
53265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#
53275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# apply_baseline(data_ref, baseline_ref)
53285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#
53295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# Subtract the execution counts found in the baseline hash referenced by
53305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# BASELINE_REF from actual data in DATA_REF.
53315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#
53325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
53335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)sub apply_baseline($$)
53345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
53355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	my %data_hash = %{$_[0]};
53365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	my %base_hash = %{$_[1]};
53375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	my $filename;
53385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	my $testname;
53395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	my $data;
53405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	my $data_testdata;
53415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	my $data_funcdata;
53425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	my $data_checkdata;
53435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	my $data_testfncdata;
53443551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	my $data_testbrdata;
53455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	my $data_count;
53465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	my $data_testfnccount;
53473551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	my $data_testbrcount;
53485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	my $base;
53495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	my $base_checkdata;
53505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	my $base_sumfnccount;
53513551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	my $base_sumbrcount;
53525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	my $base_count;
53535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	my $sumcount;
53545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	my $sumfnccount;
53553551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	my $sumbrcount;
53565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	my $found;
53575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	my $hit;
53585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	my $fn_found;
53595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	my $fn_hit;
53603551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	my $br_found;
53613551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	my $br_hit;
53625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
53635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	foreach $filename (keys(%data_hash))
53645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	{
53655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		# Get data set for data and baseline
53665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		$data = $data_hash{$filename};
53675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		$base = $base_hash{$filename};
53685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
53695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		# Skip data entries for which no base entry exists
53705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		if (!defined($base))
53715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		{
53725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			next;
53735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		}
53745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
53755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		# Get set entries for data and baseline
53765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		($data_testdata, undef, $data_funcdata, $data_checkdata,
53773551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)		 $data_testfncdata, undef, $data_testbrdata) =
53783551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)			get_info_entry($data);
53795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		(undef, $base_count, undef, $base_checkdata, undef,
53803551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)		 $base_sumfnccount, undef, $base_sumbrcount) =
53813551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)			get_info_entry($base);
53825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
53835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		# Check for compatible checksums
53845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		merge_checksums($data_checkdata, $base_checkdata, $filename);
53855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
53865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		# sumcount has to be calculated anew
53875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		$sumcount = {};
53885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		$sumfnccount = {};
53893551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)		$sumbrcount = {};
53905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
53915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		# For each test case, subtract test specific counts
53925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		foreach $testname (keys(%{$data_testdata}))
53935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		{
53945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			# Get counts of both data and baseline
53955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			$data_count = $data_testdata->{$testname};
53965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			$data_testfnccount = $data_testfncdata->{$testname};
53973551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)			$data_testbrcount = $data_testbrdata->{$testname};
53985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
53995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			($data_count, undef, $hit) =
54005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)				subtract_counts($data_count, $base_count);
54015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			($data_testfnccount) =
54025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)				subtract_fnccounts($data_testfnccount,
54035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)						   $base_sumfnccount);
54043551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)			($data_testbrcount) =
54053551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)				combine_brcount($data_testbrcount,
54063551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)						 $base_sumbrcount, $BR_SUB);
54073551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
54085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
54095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			# Check whether this test case did hit any line at all
54105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			if ($hit > 0)
54115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			{
54125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)				# Write back resulting hash
54135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)				$data_testdata->{$testname} = $data_count;
54145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)				$data_testfncdata->{$testname} =
54155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)					$data_testfnccount;
54163551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)				$data_testbrdata->{$testname} =
54173551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)					$data_testbrcount;
54185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			}
54195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			else
54205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			{
54215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)				# Delete test case which did not impact this
54225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)				# file
54235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)				delete($data_testdata->{$testname});
54245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)				delete($data_testfncdata->{$testname});
54253551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)				delete($data_testbrdata->{$testname});
54265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			}
54275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
54285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			# Add counts to sum of counts
54295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			($sumcount, $found, $hit) =
54305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)				add_counts($sumcount, $data_count);
54315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			($sumfnccount, $fn_found, $fn_hit) =
54323551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)				add_fnccount($sumfnccount, $data_testfnccount);
54333551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)			($sumbrcount, $br_found, $br_hit) =
54343551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)				combine_brcount($sumbrcount, $data_testbrcount,
54353551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)						$BR_ADD);
54365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		}
54375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
54385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		# Write back resulting entry
54395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		set_info_entry($data, $data_testdata, $sumcount, $data_funcdata,
54405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			       $data_checkdata, $data_testfncdata, $sumfnccount,
54413551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)			       $data_testbrdata, $sumbrcount, $found, $hit,
54423551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)			       $fn_found, $fn_hit, $br_found, $br_hit);
54435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
54445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		$data_hash{$filename} = $data;
54455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
54465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
54475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return (\%data_hash);
54485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
54495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
54505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
54515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#
54525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# remove_unused_descriptions()
54535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#
54545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# Removes all test descriptions from the global hash %test_description which
54555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# are not present in %info_data.
54565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#
54575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
54585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)sub remove_unused_descriptions()
54595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
54605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	my $filename;		# The current filename
54615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	my %test_list;		# Hash containing found test names
54625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	my $test_data;		# Reference to hash test_name -> count_data
54635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	my $before;		# Initial number of descriptions
54645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	my $after;		# Remaining number of descriptions
54655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	
54665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	$before = scalar(keys(%test_description));
54675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
54685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	foreach $filename (keys(%info_data))
54695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	{
54705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		($test_data) = get_info_entry($info_data{$filename});
54715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		foreach (keys(%{$test_data}))
54725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		{
54735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			$test_list{$_} = "";
54745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		}
54755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
54765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
54775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	# Remove descriptions for tests which are not in our list
54785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	foreach (keys(%test_description))
54795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	{
54805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		if (!defined($test_list{$_}))
54815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		{
54825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			delete($test_description{$_});
54835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		}
54845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
54855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
54865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	$after = scalar(keys(%test_description));
54875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if ($after < $before)
54885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	{
54895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		info("Removed ".($before - $after).
54905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		     " unused descriptions, $after remaining.\n");
54915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
54925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
54935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
54945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
54955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#
54965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# apply_prefix(filename, prefix)
54975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#
54985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# If FILENAME begins with PREFIX, remove PREFIX from FILENAME and return
54995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# resulting string, otherwise return FILENAME.
55005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#
55015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)sub apply_prefix($$)
55035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
55045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	my $filename = $_[0];
55055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	my $prefix = $_[1];
55065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (defined($prefix) && ($prefix ne ""))
55085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	{
55095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		if ($filename =~ /^\Q$prefix\E\/(.*)$/)
55105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		{
55115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			return substr($filename, length($prefix) + 1);
55125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		}
55135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
55145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return $filename;
55165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
55175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#
55205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# system_no_output(mode, parameters)
55215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#
55225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# Call an external program using PARAMETERS while suppressing depending on
55235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# the value of MODE:
55245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#
55255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#   MODE & 1: suppress STDOUT
55265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#   MODE & 2: suppress STDERR
55275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#
55285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# Return 0 on success, non-zero otherwise.
55295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#
55305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)sub system_no_output($@)
55325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
55335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	my $mode = shift;
55345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	my $result;
55355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	local *OLD_STDERR;
55365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	local *OLD_STDOUT;
55375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	# Save old stdout and stderr handles
55393551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	($mode & 1) && open(OLD_STDOUT, ">>&", "STDOUT");
55403551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	($mode & 2) && open(OLD_STDERR, ">>&", "STDERR");
55415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	# Redirect to /dev/null
55433551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	($mode & 1) && open(STDOUT, ">", "/dev/null");
55443551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	($mode & 2) && open(STDERR, ">", "/dev/null");
55455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	system(@_);
55475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	$result = $?;
55485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	# Close redirected handles
55505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	($mode & 1) && close(STDOUT);
55515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	($mode & 2) && close(STDERR);
55525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	# Restore old handles
55543551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	($mode & 1) && open(STDOUT, ">>&", "OLD_STDOUT");
55553551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	($mode & 2) && open(STDERR, ">>&", "OLD_STDERR");
55565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return $result;
55585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
55595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#
55625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# read_config(filename)
55635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#
55645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# Read configuration file FILENAME and return a reference to a hash containing
55655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# all valid key=value pairs found.
55665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#
55675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)sub read_config($)
55695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
55705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	my $filename = $_[0];
55715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	my %result;
55725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	my $key;
55735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	my $value;
55745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	local *HANDLE;
55755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55763551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	if (!open(HANDLE, "<", $filename))
55775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	{
55785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		warn("WARNING: cannot read configuration file $filename\n");
55795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		return undef;
55805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
55815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	while (<HANDLE>)
55825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	{
55835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		chomp;
55845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		# Skip comments
55855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		s/#.*//;
55865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		# Remove leading blanks
55875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		s/^\s+//;
55885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		# Remove trailing blanks
55895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		s/\s+$//;
55905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		next unless length;
55915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		($key, $value) = split(/\s*=\s*/, $_, 2);
55925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		if (defined($key) && defined($value))
55935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		{
55945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			$result{$key} = $value;
55955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		}
55965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		else
55975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		{
55985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			warn("WARNING: malformed statement in line $. ".
55995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			     "of configuration file $filename\n");
56005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		}
56015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
56025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	close(HANDLE);
56035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return \%result;
56045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
56055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
56065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
56075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#
56085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# apply_config(REF)
56095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#
56105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# REF is a reference to a hash containing the following mapping:
56115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#
56125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#   key_string => var_ref
56135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#
56145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# where KEY_STRING is a keyword and VAR_REF is a reference to an associated
56153551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)# variable. If the global configuration hashes CONFIG or OPT_RC contain a value
56163551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)# for keyword KEY_STRING, VAR_REF will be assigned the value for that keyword. 
56175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#
56185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
56195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)sub apply_config($)
56205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
56215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	my $ref = $_[0];
56225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
56235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	foreach (keys(%{$ref}))
56245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	{
56253551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)		if (defined($opt_rc{$_})) {
56263551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)			${$ref->{$_}} = $opt_rc{$_};
56273551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)		} elsif (defined($config->{$_})) {
56285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			${$ref->{$_}} = $config->{$_};
56295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		}
56305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
56315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
56325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
56335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
56345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#
56355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# get_html_prolog(FILENAME)
56365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#
56375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# If FILENAME is defined, return contents of file. Otherwise return default
56385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# HTML prolog. Die on error.
56395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#
56405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
56415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)sub get_html_prolog($)
56425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
56435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	my $filename = $_[0];
56445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	my $result = "";
56455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
56465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (defined($filename))
56475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	{
56485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		local *HANDLE;
56495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
56503551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)		open(HANDLE, "<", $filename)
56515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			or die("ERROR: cannot open html prolog $filename!\n");
56525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		while (<HANDLE>)
56535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		{
56545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			$result .= $_;
56555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		}
56565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		close(HANDLE);
56575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
56585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	else
56595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	{
56605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		$result = <<END_OF_HTML
56615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
56625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
56635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)<html lang="en">
56645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
56655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)<head>
56663551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  <meta http-equiv="Content-Type" content="text/html; charset=$charset">
56675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  <title>\@pagetitle\@</title>
56685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  <link rel="stylesheet" type="text/css" href="\@basedir\@gcov.css">
56695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)</head>
56705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
56715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)<body>
56725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
56735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)END_OF_HTML
56745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		;
56755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
56765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
56775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return $result;
56785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
56795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
56805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
56815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#
56825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# get_html_epilog(FILENAME)
56835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#
56845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# If FILENAME is defined, return contents of file. Otherwise return default
56855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# HTML epilog. Die on error.
56865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#
56875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)sub get_html_epilog($)
56885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
56895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	my $filename = $_[0];
56905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	my $result = "";
56915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
56925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (defined($filename))
56935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	{
56945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		local *HANDLE;
56955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
56963551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)		open(HANDLE, "<", $filename)
56975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			or die("ERROR: cannot open html epilog $filename!\n");
56985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		while (<HANDLE>)
56995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		{
57005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			$result .= $_;
57015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		}
57025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		close(HANDLE);
57035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
57045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	else
57055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	{
57065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		$result = <<END_OF_HTML
57075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
57085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)</body>
57095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)</html>
57105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)END_OF_HTML
57115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		;
57125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
57135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
57145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return $result;
57155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
57165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
57175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
57185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)sub warn_handler($)
57195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
57205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	my ($msg) = @_;
57215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
57225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	warn("$tool_name: $msg");
57235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
57245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
57255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)sub die_handler($)
57265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
57275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	my ($msg) = @_;
57285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
57295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	die("$tool_name: $msg");
57305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
57313551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
57323551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#
57333551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)# parse_ignore_errors(@ignore_errors)
57343551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#
57353551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)# Parse user input about which errors to ignore.
57363551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#
57373551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
57383551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)sub parse_ignore_errors(@)
57393551c9c881056c480085172ff9840cab31610854Torne (Richard Coles){
57403551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	my (@ignore_errors) = @_;
57413551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	my @items;
57423551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	my $item;
57433551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
57443551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	return if (!@ignore_errors);
57453551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
57463551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	foreach $item (@ignore_errors) {
57473551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)		$item =~ s/\s//g;
57483551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)		if ($item =~ /,/) {
57493551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)			# Split and add comma-separated parameters
57503551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)			push(@items, split(/,/, $item));
57513551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)		} else {
57523551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)			# Add single parameter
57533551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)			push(@items, $item);
57543551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)		}
57553551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	}
57563551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	foreach $item (@items) {
57573551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)		my $item_id = $ERROR_ID{lc($item)};
57583551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
57593551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)		if (!defined($item_id)) {
57603551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)			die("ERROR: unknown argument for --ignore-errors: ".
57613551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)			    "$item\n");
57623551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)		}
57633551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)		$ignore[$item_id] = 1;
57643551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	}
57653551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)}
57663551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
57673551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#
57683551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)# rate(hit, found[, suffix, precision, width])
57693551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#
57703551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)# Return the coverage rate [0..100] for HIT and FOUND values. 0 is only
57713551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)# returned when HIT is 0. 100 is only returned when HIT equals FOUND.
57723551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)# PRECISION specifies the precision of the result. SUFFIX defines a
57733551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)# string that is appended to the result if FOUND is non-zero. Spaces
57743551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)# are added to the start of the resulting string until it is at least WIDTH
57753551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)# characters wide.
57763551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#
57773551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
57783551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)sub rate($$;$$$)
57793551c9c881056c480085172ff9840cab31610854Torne (Richard Coles){
57803551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)        my ($hit, $found, $suffix, $precision, $width) = @_;
57813551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)        my $rate; 
57823551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
57833551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	# Assign defaults if necessary
57843551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)        $precision	= 1	if (!defined($precision));
57853551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	$suffix		= ""	if (!defined($suffix));
57863551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	$width		= 0	if (!defined($width));
57873551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)        
57883551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)        return sprintf("%*s", $width, "-") if (!defined($found) || $found == 0);
57893551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)        $rate = sprintf("%.*f", $precision, $hit * 100 / $found);
57903551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
57913551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	# Adjust rates if necessary
57923551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)        if ($rate == 0 && $hit > 0) {
57933551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)		$rate = sprintf("%.*f", $precision, 1 / 10 ** $precision);
57943551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)        } elsif ($rate == 100 && $hit != $found) {
57953551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)		$rate = sprintf("%.*f", $precision, 100 - 1 / 10 ** $precision);
57963551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	}
57973551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
57983551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)	return sprintf("%*s", $width, $rate.$suffix);
57993551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)}
5800