| #!/usr/bin/env perl | |
| use warnings; | |
| 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); |