kernel-doc-xml-ref 4.2 KB

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