| #!/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); |