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