kernel-doc-xml-ref 4.2 KB

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