[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/\&/\&amp;/g;
> +     s/\</\&lt;/g;
> +     s/\>/\&gt;/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+)\* \=\&gt\; (\w+)\*\(\),) { 
> +                 in_enum($1,'Func',$2)
> +             } elsif (m,/[/*] (\w+)\* \=\&gt\; (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


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.