]>
git.cameronkatri.com Git - mandoc.git/blob - regress/regress.pl
3 # $Id: regress.pl,v 1.15 2020/07/21 15:14:20 schwarze Exp $
5 # Copyright (c) 2017, 2018, 2019, 2020 Ingo Schwarze <schwarze@openbsd.org>
7 # Permission to use, copy, modify, and distribute this software for any
8 # purpose with or without fee is hereby granted, provided that the above
9 # copyright notice and this permission notice appear in all copies.
11 # THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
12 # WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
13 # MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
14 # ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
15 # WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
16 # ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
17 # OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
22 # Used because open(3p) and open2(3p) provide no way for handling
23 # STDERR of the child process, neither for appending it to STDOUT,
24 # nor for piping it into the Perl program.
25 use IPC
::Open3
qw(open3);
27 # Define this at one place such that it can easily be changed
28 # if diff(1) does not support the -a option.
29 my @diff = qw(diff -au);
30 system @diff, '/dev/null', '/dev/null' and @diff = qw(diff -u);
32 # --- utility functions ------------------------------------------------
36 print STDERR
"usage: $0 [directory[:test] [modifier ...]]\n";
40 # Modifier arguments provided on the command line,
41 # inspected by the main program and by the utility functions.
44 # Run a command and send STDOUT and STDERR to a file.
45 # 1st argument: path to the output file
46 # 2nd argument: command name
47 # The remaining arguments are passed to the command.
50 print "@_\n" if $targets{verbose
};
52 open OUT_FH
, '>', $outfile or die "$outfile: $!";
53 my $pid = open3
undef, ">&OUT_FH", undef, @_;
59 # Simlar, but filter the output as needed for the lint test.
62 print "@_\n" if $targets{verbose
};
63 open my $outfd, '>', $outfile or die "$outfile: $!";
65 my $pid = open3
undef, $infd, undef, @_;
67 s/^mandoc: [^:]+\//mandoc
: /;
76 # Simlar, but filter the output as needed for the html test.
79 print "@_\n" if $targets{verbose
};
80 open my $outfd, '>', $outfile or die "$outfile: $!";
82 my $pid = open3
undef, $infd, undef, @_;
86 if (!$state && s/.*<math class="eqn">//) {
89 } elsif (/BEGINTEST/) {
96 if ($state eq 'math') {
99 print $outfd "$_\n" if length;
104 print $outfd "$_\n" if $state;
115 push @failures, [@_];
119 # --- process command line arguments -----------------------------------
121 my $onlytest = shift // '';
123 /^(all|ascii|tag|man|utf8|html|markdown|lint|clean|verbose)$/
124 or usage
"$_: invalid modifier";
128 unless $targets{ascii
} || $targets{tag
} || $targets{man
} ||
129 $targets{utf8
} || $targets{html
} || $targets{markdown
} ||
130 $targets{lint
} || $targets{clean
};
131 $targets{ascii
} = $targets{tag
} = $targets{man
} = $targets{utf8
} =
132 $targets{html
} = $targets{markdown
} = $targets{lint
} = 1
136 # --- parse Makefiles --------------------------------------------------
138 sub parse_makefile
($%) {
139 my ($filename, $vars) = @_;
140 open my $fh, '<', $filename or die "$filename: $!";
144 last if /^# OpenBSD only/;
146 next if /^\.include/;
147 /^(\w+)\s*([?+]?)=\s*(.*)/
148 or die "$filename: parse error: $_";
152 $val =~ s/\$\{(\w+)\}/$vars->{$1}/;
153 $val = "$vars->{$var} $val" if $opt eq '+';
155 unless $opt eq '?' && defined $vars->{$var};
160 my (@regress_tests, @utf8_tests, @lint_tests, @html_tests);
161 my (%tag_tests, %skip_ascii, %skip_man, %skip_markdown);
162 foreach my $module (qw(roff char mdoc man tbl eqn)) {
164 parse_makefile
"$module/Makefile", \
%modvars;
165 foreach my $subdir (split ' ', $modvars{SUBDIR
}) {
166 my %subvars = (MOPTS
=> '');
167 parse_makefile
"$module/$subdir/Makefile", \
%subvars;
168 parse_makefile
"$module/Makefile.inc", \
%subvars;
169 delete $subvars{GOPTS
};
170 delete $subvars{SKIP_GROFF
};
171 delete $subvars{SKIP_GROFF_ASCII
};
172 my @mopts = split ' ', $subvars{MOPTS
};
173 delete $subvars{MOPTS
};
174 my @regress_testnames;
175 if (defined $subvars{TAG_TARGETS
}) {
176 $tag_tests{"$module/$subdir/$_"} = 1
177 for split ' ', $subvars{TAG_TARGETS
};
178 delete $subvars{TAG_TARGETS
};
180 if (defined $subvars{REGRESS_TARGETS
}) {
181 push @regress_testnames,
182 split ' ', $subvars{REGRESS_TARGETS
};
183 push @regress_tests, {
184 NAME
=> "$module/$subdir/$_",
186 } foreach @regress_testnames;
187 delete $subvars{REGRESS_TARGETS
};
189 if (defined $subvars{UTF8_TARGETS
}) {
191 NAME
=> "$module/$subdir/$_",
193 } foreach split ' ', $subvars{UTF8_TARGETS
};
194 delete $subvars{UTF8_TARGETS
};
196 if (defined $subvars{HTML_TARGETS
}) {
198 NAME
=> "$module/$subdir/$_",
200 } foreach split ' ', $subvars{HTML_TARGETS
};
201 delete $subvars{HTML_TARGETS
};
203 if (defined $subvars{LINT_TARGETS
}) {
205 NAME
=> "$module/$subdir/$_",
207 } foreach split ' ', $subvars{LINT_TARGETS
};
208 delete $subvars{LINT_TARGETS
};
210 if (defined $subvars{SKIP_ASCII
}) {
211 for (split ' ', $subvars{SKIP_ASCII
}) {
212 $skip_ascii{"$module/$subdir/$_"} = 1;
213 $skip_man{"$module/$subdir/$_"} = 1;
215 delete $subvars{SKIP_ASCII
};
217 if (defined $subvars{SKIP_TMAN
}) {
218 $skip_man{"$module/$subdir/$_"} = 1
219 for split ' ', $subvars{SKIP_TMAN
};
220 delete $subvars{SKIP_TMAN
};
222 if (defined $subvars{SKIP_MARKDOWN
}) {
223 $skip_markdown{"$module/$subdir/$_"} = 1
224 for split ' ', $subvars{SKIP_MARKDOWN
};
225 delete $subvars{SKIP_MARKDOWN
};
228 my @vars = keys %subvars;
229 die "unknown var(s) @vars in dir $module/$subdir";
232 $skip_ascii{"$module/$subdir/$_"} = 1;
233 } @regress_testnames if $skip_ascii{"$module/$subdir/ALL"};
235 $skip_man{"$module/$subdir/$_"} = 1;
236 } @regress_testnames if $skip_man{"$module/$subdir/ALL"};
238 $skip_markdown{"$module/$subdir/$_"} = 1;
239 } @regress_testnames if $skip_markdown{"$module/$subdir/ALL"};
241 delete $modvars{SUBDIR
};
243 my @vars = keys %modvars;
244 die "unknown var(s) @vars in module $module";
248 # --- run targets ------------------------------------------------------
255 if ($targets{ascii
} || $targets{tag
} || $targets{man
}) {
256 print "Running ascii, tag, and man tests ";
257 print "...\n" if $targets{verbose
};
259 for my $test (@regress_tests) {
260 my $i = "$test->{NAME}.in";
261 my $o = "$test->{NAME}.mandoc_ascii";
262 my $w = "$test->{NAME}.out_ascii";
263 my $to = "$test->{NAME}.mandoc_tag";
264 my $tw = "$test->{NAME}.out_tag";
266 if ($targets{tag
} && $tag_tests{$test->{NAME
}} &&
267 $test->{NAME
} =~ /^$onlytest/) {
270 my @cmd = (qw(../man -l), @{$test->{MOPTS
}},
271 qw(-I os=OpenBSD -T ascii -O),
272 "outfilename=$o,tagfilename=$to", "$i");
273 print "@cmd\n" if $targets{verbose
};
275 and fail
$test->{NAME
}, 'tag:man';
276 system qw(sed -i), 's/ .*\// /', $to;
277 system @diff, $tw, $to
278 and fail
$test->{NAME
}, 'tag:diff';
279 print "." unless $targets{verbose
};
280 $diff_ascii = $targets{ascii
};
281 } elsif ($targets{ascii
} && !$skip_ascii{$test->{NAME
}} &&
282 $test->{NAME
} =~ /^$onlytest/) {
283 sysout
$o, '../mandoc', @{$test->{MOPTS
}},
284 qw(-I os=OpenBSD -T ascii), $i
285 and fail
$test->{NAME
}, 'ascii:mandoc';
292 and fail
$test->{NAME
}, 'ascii:diff';
293 print "." unless $targets{verbose
};
295 my $m = "$test->{NAME}.in_man";
296 my $mo = "$test->{NAME}.mandoc_man";
297 if ($targets{man
} && !$skip_man{$test->{NAME
}} &&
298 $test->{NAME
} =~ /^$onlytest/) {
301 sysout
$m, '../mandoc', @{$test->{MOPTS
}},
302 qw(-I os=OpenBSD -T man), $i
303 and fail
$test->{NAME
}, 'man:man';
304 sysout
$mo, '../mandoc', @{$test->{MOPTS
}},
305 qw(-man -I os=OpenBSD -T ascii -O mdoc), $m
306 and fail
$test->{NAME
}, 'man:mandoc';
307 system @diff, $w, $mo
308 and fail
$test->{NAME
}, 'man:diff';
309 print "." unless $targets{verbose
};
311 if ($targets{clean
}) {
312 print "rm $o $to $m $mo\n" if $targets{verbose
};
313 $count_rm += unlink $o, $to, $m, $mo;
316 if ($targets{ascii
} || $targets{tag
} || $targets{man
}) {
317 print "Number of ascii, tag, and man tests:" if $targets{verbose
};
318 print " $count_ascii + $count_tag + $count_man tests run.\n";
322 if ($targets{utf8
}) {
323 print "Running utf8 tests ";
324 print "...\n" if $targets{verbose
};
326 for my $test (@utf8_tests) {
327 my $i = "$test->{NAME}.in";
328 my $o = "$test->{NAME}.mandoc_utf8";
329 my $w = "$test->{NAME}.out_utf8";
330 if ($targets{utf8
} && $test->{NAME
} =~ /^$onlytest/o) {
333 sysout
$o, '../mandoc', @{$test->{MOPTS
}},
334 qw(-I os=OpenBSD -T utf8), $i
335 and fail
$test->{NAME
}, 'utf8:mandoc';
337 and fail
$test->{NAME
}, 'utf8:diff';
338 print "." unless $targets{verbose
};
340 if ($targets{clean
}) {
341 print "rm $o\n" if $targets{verbose
};
342 $count_rm += unlink $o;
345 if ($targets{utf8
}) {
346 print "Number of utf8 tests:" if $targets{verbose
};
347 print " $count_utf8 tests run.\n";
351 if ($targets{html
}) {
352 print "Running html tests ";
353 print "...\n" if $targets{verbose
};
355 for my $test (@html_tests) {
356 my $i = "$test->{NAME}.in";
357 my $o = "$test->{NAME}.mandoc_html";
358 my $w = "$test->{NAME}.out_html";
359 if ($targets{html
} && $test->{NAME
} =~ /^$onlytest/) {
362 syshtml
$o, '../mandoc', @{$test->{MOPTS
}},
364 and fail
$test->{NAME
}, 'html:mandoc';
366 and fail
$test->{NAME
}, 'html:diff';
367 print "." unless $targets{verbose
};
369 if ($targets{clean
}) {
370 print "rm $o\n" if $targets{verbose
};
371 $count_rm += unlink $o;
374 if ($targets{html
}) {
375 print "Number of html tests:" if $targets{verbose
};
376 print " $count_html tests run.\n";
379 my $count_markdown = 0;
380 if ($targets{markdown
}) {
381 print "Running markdown tests ";
382 print "...\n" if $targets{verbose
};
384 for my $test (@regress_tests) {
385 my $i = "$test->{NAME}.in";
386 my $o = "$test->{NAME}.mandoc_markdown";
387 my $w = "$test->{NAME}.out_markdown";
388 if ($targets{markdown
} && !$skip_markdown{$test->{NAME
}} &&
389 $test->{NAME
} =~ /^$onlytest/) {
392 sysout
$o, '../mandoc', @{$test->{MOPTS
}},
393 qw(-I os=OpenBSD -T markdown), $i
394 and fail
$test->{NAME
}, 'markdown:mandoc';
396 and fail
$test->{NAME
}, 'markdown:diff';
397 print "." unless $targets{verbose
};
399 if ($targets{clean
}) {
400 print "rm $o\n" if $targets{verbose
};
401 $count_rm += unlink $o;
404 if ($targets{markdown
}) {
405 print "Number of markdown tests:" if $targets{verbose
};
406 print " $count_markdown tests run.\n";
410 if ($targets{lint
}) {
411 print "Running lint tests ";
412 print "...\n" if $targets{verbose
};
414 for my $test (@lint_tests) {
415 my $i = "$test->{NAME}.in";
416 my $o = "$test->{NAME}.mandoc_lint";
417 my $w = "$test->{NAME}.out_lint";
418 if ($targets{lint
} && $test->{NAME
} =~ /^$onlytest/) {
421 syslint
$o, '../mandoc', @{$test->{MOPTS
}},
422 qw(-I os=OpenBSD -T lint -W all), $i
423 and fail
$test->{NAME
}, 'lint:mandoc';
425 and fail
$test->{NAME
}, 'lint:diff';
426 print "." unless $targets{verbose
};
428 if ($targets{clean
}) {
429 print "rm $o\n" if $targets{verbose
};
430 $count_rm += unlink $o;
433 if ($targets{lint
}) {
434 print "Number of lint tests:" if $targets{verbose
};
435 print " $count_lint tests run.\n";
438 # --- final report -----------------------------------------------------
441 print "\nNUMBER OF FAILED TESTS: ", scalar @failures,
442 " (of $count_total tests run.)\n";
443 print "@$_\n" for @failures;
447 print "\n" if $targets{verbose
};
448 if ($count_total == 1) {
449 print "Test succeeded.\n";
450 } elsif ($count_total) {
451 print "All $count_total tests OK:";
452 print " $count_ascii ascii" if $count_ascii;
453 print " $count_tag tag" if $count_tag;
454 print " $count_man man" if $count_man;
455 print " $count_utf8 utf8" if $count_utf8;
456 print " $count_html html" if $count_html;
457 print " $count_markdown markdown" if $count_markdown;
458 print " $count_lint lint" if $count_lint;
461 print "No tests were run.\n";
463 if ($targets{clean
}) {
465 print "Deleted $count_rm test output files.\n";
466 print "The tree is now clean.\n";
468 print "No test output files were found.\n";
469 print "The tree was already clean.\n";