[SCM] Lisaac compiler branch, mildred-coverage-rebase, updated. lisaac-0.12-644-g0314edc
Mildred Ki'Lya
silkensedai at online.fr
Sat Aug 14 17:27:20 UTC 2010
The following commit has been merged in the mildred-coverage-rebase branch:
commit e080c680038b84a6922ee3ac7cc1a523cf51e765
Author: Mildred Ki'Lya <silkensedai at online.fr>
Date: Tue Mar 9 01:12:42 2010 +0100
Improved coverage
- New optimized file format
- File is written when the program exit only, and when running, it only updates
data structures in memory (it just increment a number)
- We can make a difference between dead code not compiled by Lisaac and code
that did not run
- HTML reports improved
diff --git a/src/any.li b/src/any.li
index ce61667..0dd66ad 100644
--- a/src/any.li
+++ b/src/any.li
@@ -234,7 +234,7 @@ Section Public
- output_decl:STRING := STRING.create 60000;
- output_glob:STRING := STRING.create 10000;
- output_code:STRING := STRING.create 4_000_000;
- - output_coverage:STRING := [ -? { is_coverage }; ] NULL;
+ - output_coverage:STRING := [ -? { is_coverage }; ] NULL; // TODO: Mildred: remove
- title txt:STRING_CONSTANT in buf:STRING <-
(
diff --git a/src/external/call_null.li b/src/code_life/cov_instr.li
similarity index 57%
copy from src/external/call_null.li
copy to src/code_life/cov_instr.li
index 7f9ac01..06648ce 100644
--- a/src/external/call_null.li
+++ b/src/code_life/cov_instr.li
@@ -20,13 +20,12 @@
///////////////////////////////////////////////////////////////////////////////
Section Header
- + name := CALL_NULL;
+ + name := COV_INSTR;
- - copyright := "2003-2007 Benoit Sonntag";
+ - copyright := "2010 Mildred Ki'Lya";
-
- - author := "Sonntag Benoit (bsonntag at loria.fr)";
- - comment := "Call on NULL";
+ - author := "Mildred Ki'Lya <http://ki.lya.online.fr>";
+ - comment := "Coverage recorder instruction";
Section Inherit
@@ -34,65 +33,85 @@ Section Inherit
Section Private
- - warned_list :FAST_ARRAY(POSITION) <-
- (
- warned_list := FAST_ARRAY(POSITION).create_with_capacity 8
- );
+ - next_seq_num :INTEGER := 0;
- - warned :BOOLEAN <- warned_list.fast_has position;
+ + seq_num :INTEGER := -1;
+
+ - all_coverage :FAST_ARRAY(COV_INSTR) := FAST_ARRAY(COV_INSTR).create 1024;
Section Public
- - my_copy:SELF <- Self;
+ - lower :INTEGER <- 0;
+ - upper :INTEGER <- next_seq_num - 1;
+ - item i:INTEGER :COV_INSTR <-
+ ( + j :INTEGER;
+ + res :COV_INSTR;
+ j := all_coverage.lower;
+ {(j < all_coverage.upper) && {res = NULL}}.while_do {
+ (all_coverage.item j != NULL).if {
+ (all_coverage.item j.seq_num = i).if {
+ res := all_coverage.item j;
+ };
+ };
+ j := j + 1;
+ };
+ res
+ );
- - is_necessary:BOOLEAN;
+ - count :INTEGER := 0;
- - create p:POSITION :SELF <-
- ( + result :SELF;
- is_warn_null.if {
- result := clone;
- result.set_position p;
- } else {
- result := SELF;
- };
- result
+ + last_position :POSITION;
+
+ - set_last_position p:POSITION <-
+ (
+ last_position := p;
);
- //
- // Remove
- //
+ - create (p1, p2 :POSITION) :SELF <-
+ (
+ clone.make (p1, p2)
+ );
- - remove; // Nothing.
+ - make (p1, p2 :POSITION) :SELF <-
+ (
+ position := p1;
+ last_position := p2;
+ count := count + 1;
+ Self
+ );
//
- // Execute
+ //
//
- - execute:INSTR <- Self;
+ - my_copy:SELF <- Self;
//
- // Genere.
+ // Execute.
//
- - genere buffer:STRING <-
- ( + code:STRING_CONSTANT;
- (debug_level_option != 0).if {
- code :=
- "lisaac_stack_print(top_context); \
- \print_string(\"Call on NULL\\n\"); \
- \die_with_code(1)";
+ - remove; // NOP
+
+ - execute:INSTR <-
+ ( + result :INSTR;
+ is_coverage.if {
+ result := Self;
} else {
- code :=
- "print_string(\"Call on NULL\\n\
- \(Use `-D' option)\\n\"); \
- \die_with_code(1)";
+ count := count - 1;
};
- buffer.append code;
- is_necessary := TRUE;
- ((is_warn_null) && {! warned}).if {
- warning_error (position, "Possible call on NULL");
- warned_list.add_last position;
+ result
+ );
+
+ - genere buffer:STRING <-
+ (
+ (seq_num = -1).if {
+ seq_num := next_seq_num;
+ next_seq_num := next_seq_num + 1;
+ all_coverage.add_last Self;
};
+ buffer.append "++lisaac_coverage_table[";
+ seq_num.append_in buffer;
+ buffer.append "]";
);
//
@@ -101,14 +120,5 @@ Section Public
- display buffer:STRING <-
(
- buffer.append "Call on NULL";
+ buffer.append "coverage";
);
-
-
-
-
-
-
-
-
-
diff --git a/src/item/itm_list.li b/src/item/itm_list.li
index 3662544..279e6ca 100644
--- a/src/item/itm_list.li
+++ b/src/item/itm_list.li
@@ -51,6 +51,8 @@ Section Public
- is_check_local:INTEGER;
+ + last_position :POSITION;
+
//
// Constructor
//
@@ -88,6 +90,23 @@ Section Public
code := c;
);
+ - set_last_position p:POSITION <-
+ (
+ last_position := p;
+ ((is_coverage) && {! p.prototype.is_lip}).if {
+ (coverage_all_lists = NULL).if {
+ coverage_all_lists := FAST_ARRAY(POSITION).create 16192;
+ };
+ coverage_all_lists.add_last position;
+ coverage_all_lists.add_last p;
+ };
+ );
+
+Section LISAAC
+
+ - coverage_all_lists :FAST_ARRAY(POSITION) <-
+ ( coverage_all_lists := FAST_ARRAY(POSITION).create 16192 );
+
Section Public
- is_affect:POSITION <-
@@ -112,7 +131,7 @@ Section Public
);
- insert_code_coverage_hook last_position:POSITION in lst:FAST_ARRAY(ITM_CODE) <-
- [
+ [ // TODO: Mildred: remove this slot
-? { lst != NULL };
]
(
@@ -171,6 +190,9 @@ Section Public
};
};
// Append code.
+ is_coverage.if {
+ list_current.add_last (COV_INSTR.create (position, last_position));
+ };
(code.lower).to (code.upper) do { j:INTEGER;
i := code.item j.to_run;
list_current.add_last i;
diff --git a/src/lisaac.li b/src/lisaac.li
index 305127b..a1818f7 100644
--- a/src/lisaac.li
+++ b/src/lisaac.li
@@ -491,7 +491,7 @@ Section Private
\} \n\n";
};
is_coverage.if {
- buf.append "char *__Lisaac_proto_file_names[";
+ buf.append "char *__lisaac_proto_file_names[";
buf.append (PROTOTYPE.prototype_list.count.to_string);
buf.append "]={\n";
(PROTOTYPE.prototype_list.lower).to (PROTOTYPE.prototype_list.upper-1) do {
@@ -506,15 +506,67 @@ Section Private
buf.append (proto.filename);
buf.append "\"\n};\n\n";
title "CODE COVERAGE HOOKS" in buf;
+ buf.append "static int lisaac_coverage_block_info_length = ";
+ COV_INSTR.count.append_in output_code;
+ buf.append ";\nstatic struct { \n\
+ \ int proto_index;\n\
+ \ int start_line;\n\
+ \ int start_col;\n\
+ \ int stop_line;\n\
+ \ int stop_col;\n\
+ \} lisaac_coverage_block_info[";
+ COV_INSTR.count.append_in output_code;
+ buf.append "]={\n";
+ COV_INSTR.lower.to (COV_INSTR.upper) do { i:INTEGER;
+ + instr:COV_INSTR;
+ + p1, p2 :POSITION;
+ instr := COV_INSTR.item i;
+ (instr != NULL).if {
+ p1 := instr.position;
+ p2 := instr.last_position;
+ buf.append " {";
+ p1.prototype.index.append_in buf;
+ buf.append ", ";
+ p1.line.append_in buf;
+ buf.append ", ";
+ p1.column.append_in buf;
+ buf.append ", ";
+ p2.line.append_in buf;
+ buf.append ", ";
+ p2.column.append_in buf;
+ buf.append "},\n";
+ } else {
+ buf.append " {0, 0, 0, 0, 0} /* instr = NULL */,\n";
+ };
+ };
+ buf.remove_last 2;
+ buf.append "\n};\n\n";
buf.append
- "static void lisaac_coverage_hook(unsigned long start, unsigned long stop)\n\
- \{\n\
- \ fprintf (lisaac_coverage_file, \"COV:%d:%d:%d:%d:%s\\n\",\n\
- \ start >> 17, (start >> 9) & 0xFF,\n\
- \ stop >> 17, (stop >> 9) & 0xFF,\n\
- \ __Lisaac_proto_file_names[start & 0x1FF]);\n\
- \}\n\
- \\n";
+ "static void lisaac_coverage_exit()\n\
+ \{\n\
+ \ int current_proto = -1;\n\
+ \ int i;\n\
+ \ \n\
+ \ \n\
+ \ FILE* f = fopen(lisaac_coverage_file, \"a\");\n\
+ \ for (i = 0; i < lisaac_coverage_block_info_length; ++i)\n\
+ \ {\n\
+ \ if (current_proto != lisaac_coverage_block_info[i].proto_index)\n\
+ \ {\n\
+ \ current_proto = lisaac_coverage_block_info[i].proto_index;\n\
+ \ fprintf (f, \"FILE:%s\\n\", __lisaac_proto_file_names[current_proto]);\n\
+ \ }\n\
+ \ fprintf (f, \"COVERAGE:%d:%d:%d:%d:%d\\n\",\n\
+ \ lisaac_coverage_table[i],\n\
+ \ lisaac_coverage_block_info[i].start_line,\n\
+ \ lisaac_coverage_block_info[i].start_col,\n\
+ \ lisaac_coverage_block_info[i].stop_line,\n\
+ \ lisaac_coverage_block_info[i].stop_col);\n\
+ \ }\n\
+ \ fflush(f);\n\
+ \ fclose(f);\n\
+ \}\n\
+ \\n";
};
);
@@ -663,6 +715,7 @@ Section Public
};
is_coverage.if {
output_decl.append "#include <stdio.h>\n";
+ output_decl.append "#include <stdlib.h>\n";
};
output_decl.append
"int arg_count;\n\
@@ -720,8 +773,13 @@ Section Public
is_coverage.if {
output_code.append "\
\\n/* Code Coverage Hooks */\n\
- \static FILE* lisaac_coverage_file = NULL;\n\
- \static void lisaac_coverage_hook(unsigned long start, unsigned long stop);\n\
+ \static unsigned int lisaac_coverage_table[";
+ COV_INSTR.count.append_in output_code;
+ output_code.append "];\n\
+ \static const char *lisaac_coverage_file = \"";
+ output_code.append output_name;
+ output_code.append ".cov\";\n\
+ \static void lisaac_coverage_exit();\n\
\\n";
};
@@ -743,20 +801,17 @@ Section Public
};
output_code.append "{\n";
is_coverage.if {
- output_code.append "lisaac_coverage_file = fopen(\"";
- output_code.append output_name;
- output_code.append ".cov\", \"a\");\n";
- output_code.append " fprintf (lisaac_coverage_file, \"# COV:BEGIN_LINE:COL:END_LINE:COL:FILENAME\\n\");\n";
+ output_code.append
+ " if (atexit(lisaac_coverage_exit)) {\n\
+ \ fprintf(stderr, \"cannot set code coverage exit function\\n\");\n\
+ \ exit(EXIT_FAILURE);\n\
+ \ }\n";
};
indent.append " ";
profil_current := NULL;
list_main.genere_extern output_code;
- is_coverage.if {
- output_code.append "fflush(lisaac_coverage_file);\n";
- output_code.append "fclose(lisaac_coverage_file);\n";
- };
(is_java).if_false {
output_code.append " return(0);\n";
};
@@ -805,6 +860,32 @@ Section Public
FS_MIN.close file_output;
is_coverage.if {
+ + current_proto :PROTOTYPE;
+ + k:INTEGER;
+ string_tmp2.clear;
+ k := ITM_LIST.coverage_all_lists.lower;
+ {k < ITM_LIST.coverage_all_lists.upper}.while_do {
+ + p1, p2 :POSITION;
+ p1 := ITM_LIST.coverage_all_lists.item (k);
+ p2 := ITM_LIST.coverage_all_lists.item (k+1);
+ ? { p1.prototype = p2.prototype };
+ (p1.prototype != current_proto).if {
+ current_proto := p1.prototype;
+ string_tmp2.append "FILE:";
+ string_tmp2.append (current_proto.filename);
+ string_tmp2.add_last '\n';
+ };
+ string_tmp2.append "LIST:";
+ p1.line.append_in string_tmp2;
+ string_tmp2.add_last ':';
+ p1.column.append_in string_tmp2;
+ string_tmp2.add_last ':';
+ p2.line.append_in string_tmp2;
+ string_tmp2.add_last ':';
+ p2.column.append_in string_tmp2;
+ string_tmp2.add_last '\n';
+ k := k + 2;
+ };
string_tmp.copy output_name;
string_tmp.append ".cov";
(! FS_MIN.make_file string_tmp).if {
@@ -814,7 +895,7 @@ Section Public
die_with_code exit_failure_code;
};
f := FS_MIN.open_write string_tmp;
- FS_MIN.write f with output_coverage size (output_coverage.count);
+ FS_MIN.write f with string_tmp2 size (string_tmp2.count);
FS_MIN.close f;
};
diff --git a/src/parser.li b/src/parser.li
index 1b62fcb..d526f08 100644
--- a/src/parser.li
+++ b/src/parser.li
@@ -1940,6 +1940,7 @@ Section Private
+ result_id:STRING_CONSTANT;
+ pos : POSITION;
+ read_space;
pos := current_position; // Get the position before consuming the tokens
(read_this_keyword (ALIAS_STR.variable_self)).if {
@@ -2086,7 +2087,7 @@ Section Private
result.add_last e;
};
read_space;
- last_group.insert_code_coverage_hook current_position in result;
+ last_group.set_last_position current_position;
ALIAS_ARRAY(ITM_CODE).copy result
);
@@ -2154,13 +2155,12 @@ Section Private
}.do_while {continue};
read_space;
- pos := current_position;
+ result.set_last_position current_position;
(! read_character ']').if {
warning_error (current_position,"Added ']'.");
};
- result.insert_code_coverage_hook pos in lst;
e := ITM_PROTOTYPE.create current_position type (ITM_TYPE_SIMPLE.type_void);
lst.add_last e;
//
diff --git a/tools/licoverage b/tools/licoverage
index 0d81094..fde7115 100755
--- a/tools/licoverage
+++ b/tools/licoverage
@@ -130,13 +130,13 @@ my %all_starts; # Array of block id indexed by filename, start l
my %all_stops; # Array of block id indexed by filename, stop line and column
sub common_dir {
- my $prefix = shift;
- for (@_) {
- while (! /^$prefix/) {
- $prefix =~ s|/[^/]+/?$||;
- }
+ my $prefix = shift;
+ for (@_) {
+ while (! /^$prefix/) {
+ $prefix =~ s|^(.*/)?[^/]+/?$|$1|;
}
- return $prefix;
+ }
+ return $prefix;
}
sub phtml {
@@ -166,6 +166,7 @@ sub new_block {
'filename', $proto_file, # File name
'id', $id, # File id (simple file name)
'count', 0, # How many blocks in the file
+ 'living', 0, # How many living blocks
'covered', 0, # How many covered blocks
'blocks', [] # List of all block ids
}
@@ -182,7 +183,8 @@ sub new_block {
'start', [$start_line, $start_col], # Start line and column
'stop', [$stop_line, $stop_col], # Stop line and column
'filename', $proto_file, # Proto filename
- 'count', 0 # How many time executed
+ 'count', 0, # How many time executed
+ 'alive', 0 # If the block is alive
};
$all_starts{$proto_file}[$start_line][$start_col] = $block_id;
$all_stops {$proto_file}[$stop_line] [$stop_col] = $block_id;
@@ -196,7 +198,16 @@ sub new_block {
return $block_id;
}
+sub is_excluded {
+ my ($file) = @_;
+ foreach my $exclude (@excludes) {
+ return 1 if ($file =~ m/$exclude/);
+ }
+ return 0;
+}
+
sub process_files {
+ my $current_file;
foreach my $filename (@_) {
my $FILE;
if ($filename ne '-') {
@@ -207,23 +218,55 @@ sub process_files {
my $lineno=0;
while (my $line = <$FILE>) {
$lineno++;
+ unless ($lineno % 1000) {
+ print "...On the ${lineno}th line in $filename\n";
+ }
next if substr($line, 0, 1) eq '#';
chop $line;
@_ = split(':', $line);
my $line_type = shift @_;
- if ($line_type eq "COV" or $line_type eq "CODE") {
+ if ($line_type eq "FILE") {
+ $current_file = join(':', @_);
+ } elsif ($line_type eq "LIST") {
my $start_line = shift @_;
my $start_col = shift @_;
my $stop_line = shift @_;
my $stop_col = shift @_;
- my $proto_file = join(':', @_);
- my $skip = 0;
- foreach my $exclude (@excludes) {
- $skip = ($proto_file =~ m/$exclude/);
+ my $proto_file = $current_file;
+ next if is_excluded ($proto_file);
+ my $block_id = new_block($start_line, $start_col, $stop_line, $stop_col, $proto_file);
+ } elsif ($line_type eq "COVERAGE") {
+ my $cov_count = shift @_;
+ my $start_line = shift @_;
+ my $start_col = shift @_;
+ my $stop_line = shift @_;
+ my $stop_col = shift @_;
+ my $proto_file = $current_file;
+ next if is_excluded ($proto_file);
+ my $block_id = new_block($start_line, $start_col, $stop_line, $stop_col, $proto_file);
+ if (not $all_blocks{$block_id}->{alive}) {
+ $all_blocks{$block_id}->{alive} = 1;
+ $all_files{$proto_file}->{living}++;
+ }
+ if ($cov_count) {
+ if (not $all_blocks{$block_id}->{count}) {
+ $all_files{$proto_file}->{covered}++;
+ }
+ $all_blocks{$block_id}->{count} += $cov_count;
}
- next if $skip;
+ } elsif ($line_type eq "COV" or $line_type eq "CODE") {
+ my $start_line = shift @_;
+ my $start_col = shift @_;
+ my $stop_line = shift @_;
+ my $stop_col = shift @_;
+ my $proto_file = join(':', @_);
+ next if is_excluded ($proto_file);
my $block_id = new_block($start_line, $start_col, $stop_line, $stop_col, $proto_file);
if ($line_type eq "COV") {
+ if (not $all_blocks{$block_id}->{alive}) {
+ $all_blocks{$block_id}->{alive} = 1;
+ $all_files{$proto_file}->{living}++;
+ }
if (not $all_blocks{$block_id}->{count}) {
$all_files{$proto_file}->{covered}++;
}
@@ -250,11 +293,15 @@ sub generate_html {
while (my ($id, $file) = each(%all_files)) {
my $html_file = "coverage_".$file->{id}.".html";
$vars_index->{files}->[$i++] = {
- shortname => phtml(substr($file->{filename}, length($common_dir)+1)),
- block_count => $file->{count},
- block_covered => $file->{covered},
- percent_covered => sprintf("% 3.2f", 100 * $file->{covered}/$file->{count}),
- url => phtml($html_file)
+ shortname => phtml(substr($file->{filename}, length($common_dir))),
+ block_count => $file->{count},
+ block_living => $file->{living},
+ block_covered => $file->{covered},
+ block_dead => $file->{count} - $file->{living},
+ percent_covered => sprintf("% 3.2f", $file->{count} ? (100 * $file->{covered}/$file->{count}) : 100),
+ percent_covered_living => sprintf("% 3.2f", $file->{living} ? (100 * $file->{covered}/$file->{living}) : 0),
+ percent_covered_dead => sprintf("% 3.2f", $file->{count} ? (100 * ($file->{count} - $file->{living})/$file->{count}) : 0),
+ url => phtml($html_file)
};
open SRC, '<', $file->{filename};
my $source_code;
@@ -263,19 +310,32 @@ sub generate_html {
$lineno++;
my @characters = split //, $line;
my $colno = 0;
+ $source_code .= '<br /><span lineno="'.$lineno.'"></span>';
foreach my $char (@characters) {
my $stop = $all_stops {$file->{filename}}[$lineno][$colno];
my $start = $all_starts{$file->{filename}}[$lineno][$colno];
+ my $after = "";
if ($start){
my @classes = ('block');
+ my $extra = "";
if ($all_blocks{$start}->{count}) {
$classes[@classes] = 'covered';
- } else {
+ $after='<span coveragecount="'.$all_blocks{$start}->{count}.'"></span>';
+ } elsif ($all_blocks{$start}->{alive}) {
$classes[@classes] = 'not-covered';
+ } else {
+ $classes[@classes] = 'dead';
}
- $source_code .= '<span class="'.join(' ', @classes).'">'
+ $source_code .= '<span class="'.join(' ', @classes).'"'.$extra.'>'
+ }
+ if ($char eq ' ') {
+ $source_code .= " ";
+ } elsif ($char eq "\t") {
+ $source_code .= " ";
+ } else {
+ $source_code .= phtml($char);
}
- $source_code .= phtml($char);
+ $source_code .= $after;
if ($stop){
$source_code .= '</span>'
}
@@ -301,7 +361,7 @@ sub generate_html {
sub generate_summary {
while (my ($id, $file) = each(%all_files)) {
my $proto_file = $file->{filename};
- print substr($proto_file, length($common_dir)+1);
+ print substr($proto_file, length($common_dir));
my $percent = 100 * $file->{covered}/$file->{count};
printf(": % 3.2f%% covered", $percent);
print " ($file->{covered}/$file->{count})\n"
@@ -356,18 +416,33 @@ __END__
<thead>
<tr>
<th>File</th>
- <th colspan="6">Coverage</th>
+ <th colspan="5">Whole Code Coverage</th>
+ <th colspan="5">Living Code Coverage</th>
+ <th colspan="5">Dead code</th>
</tr>
</thead>
<tbody>
[% FOREACH file IN files %]
<tr>
<td><a href="[% file.url %]">[% file.shortname %]</a></td>
+ <!-- whole code -->
<td class="numeric">[% file.percent_covered %]%</td>
<td><div class="progressbar"><div style="width: [% file.percent_covered %]px;"></div></div></td>
- <td class="left">[% file.block_covered %]</td>
+ <td class="right">[% file.block_covered %]</td>
+ <td>/</td>
+ <td class="left">[% file.block_count %]</td>
+ <!-- living code -->
+ <td class="numeric">[% file.percent_covered_living %]%</td>
+ <td><div class="progressbar"><div style="width: [% file.percent_covered_living %]px;"></div></div></td>
+ <td class="right">[% file.block_covered %]</td>
+ <td>/</td>
+ <td class="left">[% file.block_living %]</td>
+ <!-- dead code -->
+ <td class="numeric">[% file.percent_covered_dead %]%</td>
+ <td><div class="progressbar"><div style="width: [% file.percent_covered_dead %]px;"></div></div></td>
+ <td class="right">[% file.block_dead %]</td>
<td>/</td>
- <td class="right">[% file.block_count %]</td>
+ <td class="left">[% file.block_count %]</td>
</tr>
[% END %]
</tbody>
@@ -385,15 +460,38 @@ __END__
<title>Code coverage for [% shortname %]</title>
<style>
.covered {
+ background-color: palegreen;
+ }
+ [coveragecount]:before {
+ font-size: 0.7em;
+ padding-left: 0.25em;
+ padding-right: 0.25em;
+ vertical-align: middle;
+ content: attr(coveragecount);
background-color: lightgreen;
+ border: solid thin darkgreen;
+ -moz-border-radius: 0.25em;
+ }
+ [lineno]:after {
+ content: attr(lineno) ": ";
+ color: grey;
+ display: block;
+ float: left;
+ width: 5em;
+ text-align: right;
+ vertical-align: bottom;
+ padding-right: .5em;
}
.not-covered {
- background-color: coral;
+ background-color: tomato;
+ }
+ .dead {
+ background-color: lightgrey;
}
</style>
</head>
<body>
<h1>Code coverage for [% shortname %]</h1>
- <pre>[% code %]</pre>
+ <code>[% code %]</code>
</body>
</html>
\ No newline at end of file
--
Lisaac compiler
More information about the Lisaac-commits
mailing list