+sub output {
+ my ($podname, $header, $dochash, $footer) = @_;
+ my $filename = "pod/$podname.pod";
+ open my $fh, '>', $filename or die "Can't open $filename: $!";
+
+ print $fh <<"_EOH_", $header;
+-*- buffer-read-only: t -*-
+
+!!!!!!! DO NOT EDIT THIS FILE !!!!!!!
+This file is built by $0 extracting documentation from the C source
+files.
+
+_EOH_
+
+ my $key;
+ # case insensitive sort, with fallback for determinacy
+ for $key (sort { uc($a) cmp uc($b) || $a cmp $b } keys %$dochash) {
+ my $section = $dochash->{$key};
+ print $fh "\n=head1 $key\n\n=over 8\n\n";
+ # Again, fallback for determinacy
+ for my $key (sort { uc($a) cmp uc($b) || $a cmp $b } keys %$section) {
+ docout($fh, $key, $section->{$key});
+ }
+ print $fh "\n=back\n";
+ }
+
+ print $fh $footer, <<'_EOF_';
+=cut
+
+ ex: set ro:
+_EOF_
+
+ close $fh or die "Can't close $filename: $!";
+}
+
+if (@ARGV) {
+ my $workdir = shift;
+ chdir $workdir
+ or die "Couldn't chdir to '$workdir': $!";
+}
+
+open IN, "embed.fnc" or die $!;
+
+while (<IN>) {
+ chomp;
+ next if /^:/;
+ while (s|\\\s*$||) {
+ $_ .= <IN>;
+ chomp;
+ }
+ s/\s+$//;
+ next if /^\s*(#|$)/;
+
+ my ($flags, $retval, $func, @args) = split /\s*\|\s*/, $_;
+
+ next unless $func;
+
+ s/\b(NN|NULLOK)\b\s+//g for @args;
+ $func =~ s/\t//g; # clean up fields from embed.pl
+ $retval =~ s/\t//;
+
+ $funcflags{$func} = {
+ flags => $flags,
+ retval => $retval,
+ args => \@args,
+ };
+}
+