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