linux/scripts/kernel-doc-xml-ref
<<
>>
Prefs
   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