[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [Xen-devel] [PATCH 1/4] docs/html/: Initial cut of header documentation massager
On Tue, 2011-11-29 at 15:01 +0000, Ian Jackson wrote: > "xen-headers" generates HTML from header files. So far this generates > just some type cross-references, if you say > make -C docs html/hypercall/stamp > > An index page, proper wiring into the build system, and a few more > annotations in the headers, and will be forthcoming. > > Signed-off-by: Ian Jackson <ian.jackson@xxxxxxxxxxxxx> > [...] > +GetOptions("O|output-dir=s" => \$outdir, > + "D+" => \$debug, > + "T=s" => \$xtitle, > + "I=s" => sub { includeexclude(1, @_); }, > + "X=s" => sub { includeexclude(0, @_); }) Indentation is messed up (you've got a hard tab from somewhere). With that fixed: Acked-by: Ian Campbell <ian.campbell@xxxxxxxxxx> (insofar as I can review Perl code...) > + or die; > + > +die unless defined $outdir; > +@ARGV>=2 or die; > + > +my ($basedir,@indirs) = @ARGV; > + > +# general globals > +our $pass; > +our %sdef; > +# $sdef{$type}{$name} => { > +# DefLocs => { "$leaf_path:$lineno" => $leaf_opath ,... } > +# Xrefs => { "$leaf_path,$lineno" => "$xref", ... } > +# Used => 1 > +# } > +# $type might be Func Struct Union Enum EnumVal > + > +# provided by the find() function > +our $leaf; > +our $leaf_opath; > + > +# reset at the start of each file > +our $o; > +our $in_enum; > +our @pending_xrefs; > + > +sub compile_fglobs () { > + local ($_); > + my $f = "sub file_wanted (\$) {\n local (\$_) = \"/\$leaf\";\n"; > + foreach my $fglob (@fglobs) { > + $_ = $fglob->[0]; > + $_ = "**$_**" unless m/[?*]/; > + s/\W/\\$&/g; > + s,\\\*\\\*,.*,g; > + s,\\\*,[^/]*,g; > + s,\\\?,[^/],g; > + $f .= " return $fglob->[1] if m,$_,o;\n"; > + } > + $f .= " return 1;\n}\n1;\n"; > + debug(3, $f); > + eval $f or die "$@ "; > +} > + > +compile_fglobs(); > + > + > +sub warning { > + print STDERR "$leaf:$.: @_\n"; > +} > + > +sub debug { > + my $msglevel = scalar shift @_; > + return unless $debug >= $msglevel; > + print STDERR "DEBUG $pass $msglevel @_\n" or die $!; > +} > + > +sub in_enum ($$$) { $in_enum = [ @_ ]; } # [ $enumvalpfx, RefType, > $refnamepfx ] > + > +sub aelem ($$$) { > + my ($ntext,$ytext,$hparams) = @_; > + return $ntext unless $hparams =~ m/\S/; > + return "<a $hparams>$ytext</a>"; > +} > + > +sub defn ($$$;$) { > + my ($text,$type,$name,$hparams) = @_; > + $hparams='' if !defined $hparams; > + debug(2,"DEFN $. $type $name $hparams"); > + $sdef{$type}{$name}{DefLocs}{"$leaf:$."} = $leaf_opath; > + my $xrefs = $sdef{$type}{$name}{Xrefs}; > + push @pending_xrefs, values %$xrefs if $xrefs; > + $hparams .= " name=\"${type}_$name\"" if $sdef{$type}{$name}{Used}; > + return aelem($text, "<strong>$text</strong>", $hparams); > +} > + > +sub norm ($) { > + local ($_) = @_; > + my $no = ''; > + while (length) { > + if (s/^(?:\s|^\W)+//) { > + $no .= $&; > + } elsif (s/^(struct|union|enum)\s+(\w+)\b//) { > + $no .= ahref($&, (ucfirst $1), $2); > + } elsif (s/^\w+\b//) { > + $no .= ahref($&, 'Func', $&); > + } else { > + die "$_ ?"; > + } > + } > + return $no; > +} > + > +sub refhref ($$) { > + my ($type,$name) = @_; > + $sdef{$type}{$name}{Used} = 1; > + my $locs = $sdef{$type}{$name}{DefLocs}; > + return '' unless $locs; > + if ((scalar keys %$locs) != 1 && !$sdef{$type}{$name}{MultiWarned}) { > + warning("multiple definitions of $type $name: $_") > + foreach keys %$locs; > + $sdef{$type}{$name}{MultiWarned}=1; > + } > + my ($loc) = values %$locs; > + return "href=\"$loc#${type}_$name\""; > +} > + > +sub ahref ($$$) { > + my ($text,$type,$name) = @_; > + return aelem($text,$text, refhref($type,$name)); > +} > + > +sub defmacro ($) { > + my ($valname) = @_; > + if (!$in_enum) { > + return $valname; > + } elsif (substr($valname, 0, (length $in_enum->[0])) ne $in_enum->[0]) { > + warning("in enum expecting $in_enum->[0]* got $valname"); > + return $valname; > + } else { > + my $reftype = $in_enum->[1]; > + my $refname = $in_enum->[2].substr($valname, (length $in_enum->[0])); > + $sdef{$reftype}{$refname}{Xrefs}{$leaf,$.} = > + "[see <a href=\"$leaf_opath#EnumVal_$valname\">$valname</a>]"; > + $sdef{EnumVal}{$valname}{Used} = 1; > + return defn($valname,'EnumVal',$valname, refhref($reftype,$refname)); > + } > +} > + > +sub out_xrefs ($) { > + my ($linemapfunc) = @_; > + foreach my $xref (@pending_xrefs) { > + $o .= $linemapfunc->($xref); > + $o .= "\n"; > + } > + @pending_xrefs = (); > +} > + > +sub write_file ($$) { > + my ($opath, $odata) = @_; > + my $out = new IO::File "$opath.new", '>' or die "$opath $!"; > + print $out $odata or die $!; > + rename "$opath.new", "$opath" or die "$opath $!"; > +} > + > +sub process_file ($$) { > + my ($infile, $outfile) = @_; > + debug(1,"$pass $infile => $outfile"); > + my $in = new IO::File "$infile", '<' or die "$infile $!"; > + > + $o = ''; > + $in_enum = undef; > + @pending_xrefs = (); > + > + $o .= "<html><head><title>$leaf - $xtitle</title></head><body><pre>\n"; > + > + while (<$in>) { > + s/\&/\&/g; > + s/\</\</g; > + s/\>/\>/g; > + > + if (m/^(.*\`)[ \t]*$/) { > + my $lhs = $1; > + out_xrefs(sub { "$1 $_[0]"; }); > + } elsif (m/^\s*$/) { > + out_xrefs(sub { sprintf "/* %70s */", $_[0]; }); > + } > + > + # In case of comments, strip " /* ` " and " * ` "; > + my $lstripped = s,^ \s* /? \* \s* \` \ ,,x ? $&: ''; > + > + # Strip trailing whitespace and perhaps trailing "*/" or "*" > + s,(?: \s* \* /? )? \s* $,,x or die; > + my $rstripped = $&; > + > + # Now the actual functionality: > + > + debug(3,"$. $_"); > + > + if (!m/^(?: __attribute__ | __pragma__ )\b/x && > + s/^( (?: \w+\ )? ) (\w+[a-z]\w+) ( \( .*)$ > + / $1.defn($2,'Func',$2).norm($3) /xe) { > + } elsif (s/^((struct|union|enum) \ (\w+)) ( \s+ \{ .* )$ > + / defn($1,(ucfirst $2),$3).norm($4) /xe) { > + if ($2 eq 'enum') { > + if (m,/[/*] (\w+)\* \=\>\; (\w+)\*\(\),) { > + in_enum($1,'Func',$2) > + } elsif (m,/[/*] (\w+)\* \=\>\; (struct) (\w+)\*,) { > + in_enum($1,(ucfirst $2),$3); > + } > + } > + } elsif (s/^( \s* \#define \s+ ) (\w+) ( \s+\S ) > + / $1.defmacro($2).norm($3) /xe) { > + } else { > + if (m/^\s*\}/) { > + $in_enum = undef; > + } > + $_ = norm($_); > + } > + > + # Write the line out > + > + if ($pass == 2) { > + $o .= $lstripped; > + $o .= $_; > + $o .= $rstripped; > + } > + } > + > + warning("pending xrefs at end of file") if @pending_xrefs; > + > + if ($pass == 2) { > + $o .= "</pre></body></html>"; > + write_file($outfile, $o); > + } > +} > + > + > +foreach $pass (qw(1 2)) { > + find({ wanted => > + sub { > + return unless m/\.h$/; > + lstat $File::Find::name or die "$File::Find::name $!"; > + -f _ or die "$File::Find::name"; > + substr($File::Find::name, 0, 1+length $basedir) > + eq "$basedir/" > + or die "$File::Find::name $basedir"; > + $leaf = substr($File::Find::name, 1+length $basedir); > + if (!file_wanted()) { > + debug(1,"$pass $File::Find::name excluded"); > + return; > + } > + $leaf_opath = $leaf; > + $leaf_opath =~ s#/#,#g; > + $leaf_opath .= ".html"; > + process_file($File::Find::name, $outdir.'/'.$leaf_opath); > + }, > + no_chdir => 1, > + }, > + map { "$basedir/$_" } @indirs); > +} _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxxxxxxxx http://lists.xensource.com/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |