1#!/usr/bin/perl -w 2 3use strict; 4 5## Copyright (C) 2015 Intel Corporation ## 6# ## 7## This software falls under the GNU General Public License. ## 8## Please read the COPYING file for more information ## 9# 10# 11# This software reads a XML file and a list of valid interal 12# references to replace Docbook tags with links. 13# 14# The list of "valid internal references" must be one-per-line in the following format: 15# API-struct-foo 16# API-enum-bar 17# API-my-function 18# 19# The software walks over the XML file looking for xml tags representing possible references 20# to the Document. Each reference will be cross checked against the "Valid Internal Reference" list. If 21# the referece is found it replaces its content by a <link> tag. 22# 23# usage: 24# kernel-doc-xml-ref -db filename 25# xml filename > outputfile 26 27# read arguments 28if ($#ARGV != 2) { 29 usage(); 30} 31 32#Holds the database filename 33my $databasefile; 34my @database; 35 36#holds the inputfile 37my $inputfile; 38my $errors = 0; 39 40my %highlights = ( 41 "<function>(.*?)</function>", 42 "\"<function>\" . convert_function(\$1, \$line) . \"</function>\"", 43 "<structname>(.*?)</structname>", 44 "\"<structname>\" . convert_struct(\$1) . \"</structname>\"", 45 "<funcdef>(.*?)<function>(.*?)</function></funcdef>", 46 "\"<funcdef>\" . convert_param(\$1) . \"<function>\$2</function></funcdef>\"", 47 "<paramdef>(.*?)<parameter>(.*?)</parameter></paramdef>", 48 "\"<paramdef>\" . convert_param(\$1) . \"<parameter>\$2</parameter></paramdef>\""); 49 50while($ARGV[0] =~ m/^-(.*)/) { 51 my $cmd = shift @ARGV; 52 if ($cmd eq "-db") { 53 $databasefile = shift @ARGV 54 } else { 55 usage(); 56 } 57} 58$inputfile = shift @ARGV; 59 60sub open_database { 61 open (my $handle, '<', $databasefile) or die "Cannot open $databasefile"; 62 chomp(my @lines = <$handle>); 63 close $handle; 64 65 @database = @lines; 66} 67 68sub process_file { 69 open_database(); 70 71 my $dohighlight; 72 foreach my $pattern (keys %highlights) { 73 $dohighlight .= "\$line =~ s:$pattern:$highlights{$pattern}:eg;\n"; 74 } 75 76 open(FILE, $inputfile) or die("Could not open $inputfile") or die ("Cannot open $inputfile"); 77 foreach my $line (<FILE>) { 78 eval $dohighlight; 79 print $line; 80 } 81} 82 83sub trim($_) 84{ 85 my $str = $_[0]; 86 $str =~ s/^\s+|\s+$//g; 87 return $str 88} 89 90sub has_key_defined($_) 91{ 92 if ( grep( /^$_[0]$/, @database)) { 93 return 1; 94 } 95 return 0; 96} 97 98# Gets a <function> content and add it a hyperlink if possible. 99sub convert_function($_) 100{ 101 my $arg = $_[0]; 102 my $key = $_[0]; 103 104 my $line = $_[1]; 105 106 $key = trim($key); 107 108 $key =~ s/[^A-Za-z0-9]/-/g; 109 $key = "API-" . $key; 110 111 # We shouldn't add links to <funcdef> prototype 112 if (!has_key_defined($key) || $line =~ m/\s+<funcdef/i) { 113 return $arg; 114 } 115 116 my $head = $arg; 117 my $tail = ""; 118 if ($arg =~ /(.*?)( ?)$/) { 119 $head = $1; 120 $tail = $2; 121 } 122 return "<link linkend=\"$key\">$head</link>$tail"; 123} 124 125# Converting a struct text to link 126sub convert_struct($_) 127{ 128 my $arg = $_[0]; 129 my $key = $_[0]; 130 $key =~ s/(struct )?(\w)/$2/g; 131 $key =~ s/[^A-Za-z0-9]/-/g; 132 $key = "API-struct-" . $key; 133 134 if (!has_key_defined($key)) { 135 return $arg; 136 } 137 138 my ($head, $tail) = split_pointer($arg); 139 return "<link linkend=\"$key\">$head</link>$tail"; 140} 141 142# Identify "object *" elements 143sub split_pointer($_) 144{ 145 my $arg = $_[0]; 146 if ($arg =~ /(.*?)( ?\* ?)/) { 147 return ($1, $2); 148 } 149 return ($arg, ""); 150} 151 152sub convert_param($_) 153{ 154 my $type = $_[0]; 155 my $keyname = convert_key_name($type); 156 157 if (!has_key_defined($keyname)) { 158 return $type; 159 } 160 161 my ($head, $tail) = split_pointer($type); 162 return "<link linkend=\"$keyname\">$head</link>$tail"; 163 164} 165 166# DocBook links are in the API-<TYPE>-<STRUCT-NAME> format 167# This method gets an element and returns a valid DocBook reference for it. 168sub convert_key_name($_) 169{ 170 #Pattern $2 is optional and might be uninitialized 171 no warnings 'uninitialized'; 172 173 my $str = $_[0]; 174 $str =~ s/(const|static)? ?(struct)? ?([a-zA-Z0-9_]+) ?(\*|&)?/$2 $3/g ; 175 176 # trim 177 $str =~ s/^\s+|\s+$//g; 178 179 # spaces and _ to - 180 $str =~ s/[^A-Za-z0-9]/-/g; 181 182 return "API-" . $str; 183} 184 185sub usage { 186 print "Usage: $0 -db database filename\n"; 187 print " xml source file(s) > outputfile\n"; 188 exit 1; 189} 190 191# starting point 192process_file(); 193 194if ($errors) { 195 print STDERR "$errors errors\n"; 196} 197 198exit($errors); 199