|  | #!/usr/bin/perl -w | 
|  |  | 
|  | use strict; | 
|  |  | 
|  | ## Copyright (C) 2015  Intel Corporation                         ## | 
|  | #                                                                ## | 
|  | ## This software falls under the GNU General Public License.     ## | 
|  | ## Please read the COPYING file for more information             ## | 
|  | # | 
|  | # | 
|  | # This software reads a XML file and a list of valid interal | 
|  | # references to replace Docbook tags with links. | 
|  | # | 
|  | # The list of "valid internal references" must be one-per-line in the following format: | 
|  | #      API-struct-foo | 
|  | #      API-enum-bar | 
|  | #      API-my-function | 
|  | # | 
|  | # The software walks over the XML file looking for xml tags representing possible references | 
|  | # to the Document. Each reference will be cross checked against the "Valid Internal Reference" list. If | 
|  | # the referece is found it replaces its content by a <link> tag. | 
|  | # | 
|  | # usage: | 
|  | # kernel-doc-xml-ref -db filename | 
|  | #		     xml filename > outputfile | 
|  |  | 
|  | # read arguments | 
|  | if ($#ARGV != 2) { | 
|  | usage(); | 
|  | } | 
|  |  | 
|  | #Holds the database filename | 
|  | my $databasefile; | 
|  | my @database; | 
|  |  | 
|  | #holds the inputfile | 
|  | my $inputfile; | 
|  | my $errors = 0; | 
|  |  | 
|  | my %highlights = ( | 
|  | "<function>(.*?)</function>", | 
|  | "\"<function>\" . convert_function(\$1, \$line) . \"</function>\"", | 
|  | "<structname>(.*?)</structname>", | 
|  | "\"<structname>\" . convert_struct(\$1) . \"</structname>\"", | 
|  | "<funcdef>(.*?)<function>(.*?)</function></funcdef>", | 
|  | "\"<funcdef>\" . convert_param(\$1) . \"<function>\$2</function></funcdef>\"", | 
|  | "<paramdef>(.*?)<parameter>(.*?)</parameter></paramdef>", | 
|  | "\"<paramdef>\" . convert_param(\$1) . \"<parameter>\$2</parameter></paramdef>\""); | 
|  |  | 
|  | while($ARGV[0] =~ m/^-(.*)/) { | 
|  | my $cmd = shift @ARGV; | 
|  | if ($cmd eq "-db") { | 
|  | $databasefile = shift @ARGV | 
|  | } else { | 
|  | usage(); | 
|  | } | 
|  | } | 
|  | $inputfile = shift @ARGV; | 
|  |  | 
|  | sub open_database { | 
|  | open (my $handle, '<', $databasefile) or die "Cannot open $databasefile"; | 
|  | chomp(my @lines = <$handle>); | 
|  | close $handle; | 
|  |  | 
|  | @database = @lines; | 
|  | } | 
|  |  | 
|  | sub process_file { | 
|  | open_database(); | 
|  |  | 
|  | my $dohighlight; | 
|  | foreach my $pattern (keys %highlights) { | 
|  | $dohighlight .=  "\$line =~ s:$pattern:$highlights{$pattern}:eg;\n"; | 
|  | } | 
|  |  | 
|  | open(FILE, $inputfile) or die("Could not open $inputfile") or die ("Cannot open $inputfile"); | 
|  | foreach my $line (<FILE>)  { | 
|  | eval $dohighlight; | 
|  | print $line; | 
|  | } | 
|  | } | 
|  |  | 
|  | sub trim($_) | 
|  | { | 
|  | my $str = $_[0]; | 
|  | $str =~ s/^\s+|\s+$//g; | 
|  | return $str | 
|  | } | 
|  |  | 
|  | sub has_key_defined($_) | 
|  | { | 
|  | if ( grep( /^$_[0]$/, @database)) { | 
|  | return 1; | 
|  | } | 
|  | return 0; | 
|  | } | 
|  |  | 
|  | # Gets a <function> content and add it a hyperlink if possible. | 
|  | sub convert_function($_) | 
|  | { | 
|  | my $arg = $_[0]; | 
|  | my $key = $_[0]; | 
|  |  | 
|  | my $line = $_[1]; | 
|  |  | 
|  | $key = trim($key); | 
|  |  | 
|  | $key =~ s/[^A-Za-z0-9]/-/g; | 
|  | $key = "API-" . $key; | 
|  |  | 
|  | # We shouldn't add links to <funcdef> prototype | 
|  | if (!has_key_defined($key) || $line =~ m/\s+<funcdef/i) { | 
|  | return $arg; | 
|  | } | 
|  |  | 
|  | my $head = $arg; | 
|  | my $tail = ""; | 
|  | if ($arg =~ /(.*?)( ?)$/) { | 
|  | $head = $1; | 
|  | $tail = $2; | 
|  | } | 
|  | return "<link linkend=\"$key\">$head</link>$tail"; | 
|  | } | 
|  |  | 
|  | # Converting a struct text to link | 
|  | sub convert_struct($_) | 
|  | { | 
|  | my $arg = $_[0]; | 
|  | my $key = $_[0]; | 
|  | $key =~ s/(struct )?(\w)/$2/g; | 
|  | $key =~ s/[^A-Za-z0-9]/-/g; | 
|  | $key = "API-struct-" . $key; | 
|  |  | 
|  | if (!has_key_defined($key)) { | 
|  | return $arg; | 
|  | } | 
|  |  | 
|  | my ($head, $tail) = split_pointer($arg); | 
|  | return "<link linkend=\"$key\">$head</link>$tail"; | 
|  | } | 
|  |  | 
|  | # Identify "object *" elements | 
|  | sub split_pointer($_) | 
|  | { | 
|  | my $arg = $_[0]; | 
|  | if ($arg =~ /(.*?)( ?\* ?)/) { | 
|  | return ($1, $2); | 
|  | } | 
|  | return ($arg, ""); | 
|  | } | 
|  |  | 
|  | sub convert_param($_) | 
|  | { | 
|  | my $type = $_[0]; | 
|  | my $keyname = convert_key_name($type); | 
|  |  | 
|  | if (!has_key_defined($keyname)) { | 
|  | return $type; | 
|  | } | 
|  |  | 
|  | my ($head, $tail) = split_pointer($type); | 
|  | return "<link linkend=\"$keyname\">$head</link>$tail"; | 
|  |  | 
|  | } | 
|  |  | 
|  | # DocBook links are in the API-<TYPE>-<STRUCT-NAME> format | 
|  | # This method gets an element and returns a valid DocBook reference for it. | 
|  | sub convert_key_name($_) | 
|  | { | 
|  | #Pattern $2 is optional and might be uninitialized | 
|  | no warnings 'uninitialized'; | 
|  |  | 
|  | my $str = $_[0]; | 
|  | $str =~ s/(const|static)? ?(struct)? ?([a-zA-Z0-9_]+) ?(\*|&)?/$2 $3/g ; | 
|  |  | 
|  | # trim | 
|  | $str =~ s/^\s+|\s+$//g; | 
|  |  | 
|  | # spaces and _ to - | 
|  | $str =~ s/[^A-Za-z0-9]/-/g; | 
|  |  | 
|  | return "API-" . $str; | 
|  | } | 
|  |  | 
|  | sub usage { | 
|  | print "Usage: $0 -db database filename\n"; | 
|  | print "         xml source file(s) > outputfile\n"; | 
|  | exit 1; | 
|  | } | 
|  |  | 
|  | # starting point | 
|  | process_file(); | 
|  |  | 
|  | if ($errors) { | 
|  | print STDERR "$errors errors\n"; | 
|  | } | 
|  |  | 
|  | exit($errors); |