198 lines · 4.2 KB · Text
RawDownload
#!/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 argumentsif ($#ARGV != 2) {	usage();} #Holds the database filenamemy $databasefile;my @database; #holds the inputfilemy $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 linksub 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 *" elementssub 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 pointprocess_file(); if ($errors) {	print STDERR "$errors errors\n";} exit($errors);