Merge pull request #3477 from Unity-Technologies/create-delegate-exception
[mono.git] / docs / exdoc
1 #!/usr/bin/perl
2
3 if ($ARGV[0] eq "-h"){
4     $sourcedir = $ARGV[1];
5     $dir = $sourcedir;
6     $html = 1;
7     shift @ARGV;
8     shift @ARGV;
9 }
10 open (FILE, "$dir/api-style.css" || die "Did not find $dir/api-style.css");
11 while (<FILE>){
12     $css = $css . $_;
13 }
14
15 if ($ARGV[0] eq "-t"){
16     $dir = $ARGV[1];
17     shift @ARGV;
18 }
19
20 if ($html){
21     opendir (D, "$sourcedir/sources/") || die "Can not open $dir";
22     while ($n = readdir (D)){
23         if ($n =~ /mono-api-.*\.html$/){
24             open (IN, "$sourcedir/sources/$n") || die "Can not open $n";
25             $files[$filecount] = $n;
26             while (<IN>){
27                 @files_content[$filecount] .= $_;
28                 if (/name="api:(.*?)"/){
29                     $_ =~ s/.*name="api:(\w+?)".*/\1/;
30                     $apis[$filecount] .= "$_";
31                 }
32             }
33             $filecount++;
34             close IN;
35         }
36     }
37 }
38
39 while (<ARGV>){
40         if (/\/\*\* *\n/){
41                 &process_doc;
42         } else {
43                 #print "IGNORING: $_";
44         }
45 }
46
47 if ($html){
48     for ($f = 0; $f < $filecount; $f++){
49         $name = $files[$f];
50         open (OUT, "> $dir/html/$name") || die "Can not create $dir/html/$name";
51         print "Merging: $name\n";
52         print OUT<<EOF;
53 <?xml version="1.0" encoding="utf-8"?>
54 <html xmlns="http://www.w3.org/1999/xhtml">
55 <head>
56     <title>$name</title>
57     <style type="text/css">
58 $css
59    </style>
60 </head>
61 <body>
62 <div class="mapi-docs">
63 EOF
64         @a = split (/\n/, $files_content[$f]);
65         $strikeextra = "";
66         $api_shown = 0;
67         for ($ai = 0; $ai < $#a; $ai++){
68             $line = $a[$ai];
69             
70             ($api,$caption) = $line =~  /<h4><a name=\"api:(\w+)\">(\w+)<\/a><\/h4>/;
71             if ($api ne ""){
72                 if ($api_shown == 1){
73                     print OUT "</div> <!-- class=mapi -->\n\n";
74                     if ($deprecated{$api}){
75                         $strike = "mapi-strike";
76                         $strikeextra = "</div><br><div class='mapi-deprecated'><b>Deprecated:</b> " . $deprecated{$api};
77                     } else {
78                         $strike = "";
79                         $strikeextra = "";
80                     }
81                 }
82                 $api_shown = 1;
83                 $proto = $prototype{$api};
84                 if ($proto eq ""){
85                     $proto = "$api";
86                 }
87
88                 print OUT<<EOF;
89 <a name="api:$api"></a>
90 <div class="mapi">
91     <div class="mapi-entry $strike"><code>$api$strikeextra</code></div>
92     <div class="mapi-height-container">
93         <div class="mapi-ptr-container"></div>
94         <div class="mapi-description">
95             <div class="mapi-ptr"></div>
96
97             <div class="mapi-declaration mapi-section">Syntax</div>
98             <div class="mapi-prototype">$proto</div>
99             <p>
100 EOF
101                 $ppars = $arguments{$api};
102                 if ($ppars ne "" && (!($ppars =~ /^[ \t]+$/))){
103                     print OUT "            <div class=\"mapi-section\">Parameters</div>\n";
104                     print OUT "            <table class=\"mapi-parameters\"><tbody>".${arguments{$api}}."</tbody></table>";
105                 }
106             
107                 &opt_print ("Return value", $returns{$api}, 0);
108                 &opt_print ("Description", $bodies{$api}, 0);
109                 print OUT "        </div><!--mapi-description-->\n    </div><!--height container-->\n";
110             } else {
111                 if ($line =~ /@API_IDX@/){
112                     $apis_toc = &create_toc ($apis[$f]);
113                     $line =~ s/\@API_IDX\@/$apis_toc/;
114                 }
115                 if ($line =~ /^<h4/){
116                     print OUT "</div>\n";
117                     $api_shown = 0;
118                 }
119                 if ($line =~ /`/){
120                 }
121                 print OUT "$line\n";
122             }
123         }
124         print OUT<<EOF;
125    </div>
126 </body>
127 </html>
128 EOF
129         close OUT;
130         system ("$ENV{runtimedir}/mono-wrapper convert.exe $dir/html/$name $dir/html/x-$name");
131
132
133         # clean up the mess that AgilityPack does, it CDATAs our CSS
134         open HACK, "$dir/html/x-$name" || die "Could not open $dir/html/x-$name";
135         open HACKOUT, ">$dir/deploy/$name" || die "Could not open output";
136
137         $line = 0;
138         $doprint = 0;
139         while (<HACK>){
140             print HACKOUT $last if ($doprint);
141             $line++;
142             s/^\/\/<!\[CDATA\[//;
143             s/^\/\/\]\]>\/\///;
144
145             # Remove the junk <span> wrapper generated by AgilityPack
146             if ($line==1){
147                 s/<span>//;
148             }
149             if (/<style type/){
150                 # Replace the CSS in the XHTML output with the original CSS
151                 print HACKOUT $_;
152                 print HACKOUT $css;
153                 while (<HACK>){
154                     last if (/<\/style>/);
155                 }
156             }
157             $last = $_;
158             $doprint = 1;
159         }
160         if (!($last =~ /span/)){
161             print HACKOUT $last;
162         }
163
164         #system ("cp.exe $dir/html/$name $dir/deploy/$name");
165     }
166 }
167
168 sub process_doc {
169         $doc = "";
170         $func = <>;
171         chop $func;
172         $func =~ s/^ \* //;
173         $func =~ s/:$//;
174         print "Function: $func\n" if (!$html);
175         $args = "";
176         $inbody = 0;
177         $returns = "";
178         $body = "";
179         $functions[$fn++] = $func;
180         $deprecated = 0;
181         # Process arguments
182         while (<>){
183             s/NULL/<code>NULL<\/code>/g;
184             s/TRUE/<code>TRUE<\/code>/g;
185             s/FALSE/<code>FALSE<\/code>/g;
186             if (/^ \*\*?\//){
187                     $body =~ s/@(\w+)/<i>\1<\/i>/g;
188                     $returns =~ s/@(\w+)/<i>\1<\/i>/g;
189                     $args =~ s/@(\w+)/<i>\1<\/i>/g;
190
191                     $body =~ s/#(\w+)/<code>\1<\/code>/g;
192                     $returns =~ s/#(\w+)/<code>\1<\/code>/g;
193                     $args =~ s/#(\w+)/<code>\1<\/code>/g;
194
195                     $returns =~ s/\`([:.\w\*]+)\`/<code>\1<\/code>/g;
196                     $args =~ s/\`([:.\w\*]+)\`/<code>\1<\/code>/g;
197                     $body =~ s/\`([:.\w\*]+)\`/<code>\1<\/code>/g;
198                     
199                     $body =~ s/\n/ /;
200                     $bodies{$func} = $body;
201                     $arguments{$func} = $args;
202                     $deprecated{$func} = $deprecated;
203                     $returns{$func} = $returns;
204                     $proto = "";
205                     while (<>){
206                         $proto .= $_;
207                         last if (/\{/);
208                     }
209                     $proto =~ s/{//;
210                     # clean it up a little, remove newlines, empty space at end
211                     $proto =~ s/ +$//;
212                     # Turn "Type * xxx" into "Type* xxx"
213                     $proto =~ s/^(\w+)\W+\*/\1\*/;
214                     $prototype{$func} = $proto;
215                     return;
216                 }
217                 chop;
218                 s/^\ \*//;
219                 $_ = "<p>" if (/^\s*$/);
220                                 
221                 if ($inbody == 0){
222                     if (/\s*(\w+):(.*)/){
223                         if ($1 eq "deprecated"){
224                             $deprecated = $2;
225                         } else {
226                             #$args .= "<dt><i>$1:</i></dt><dd>$2</dd>";
227                             $args .= "<tr><td><i>$1</i><td>$2</td></td></tr>";
228                         }
229                     } else {
230                         
231                         $body = "\t$_\n";
232
233                         $inbody = 1;
234                     }
235                 } elsif ($inbody == 1) {
236                     if (/Returns?:/){
237                         s/Returns?://;
238                         $returns = "\t$_\n";
239                         $inbody = 2;
240                     } else {
241                         $body .= "\n\t$_";
242                     }
243                 } else {
244                     $returns .= "\n\t$_";
245                 }
246                    
247         }
248 }
249
250 sub create_toc {
251     my ($apis_listed) = @_;
252     my $type_size = 0;
253     my $name_size = 0;
254     my $ret, $xname, $args, $line;
255     $apis_toc = "";
256
257
258     # Try to align things, so compute type size, method size, and arguments
259     foreach $line (split /\n/, $apis_listed){
260         $p = $prototype{$line};
261         ($ret, $xname, $args) = $p =~ /(.*)\n(\w+)[ \t](.*)/;
262         $tl = length ($ret);
263         $pl = length ($xname);
264
265         $type_size = $tl if ($tl > $type_size);
266         $name_size = $pl if ($pl > $name_size);
267     }
268
269     $type_size++;
270     $name_size++;
271
272     foreach $line (split /\n/, $apis_listed){
273         chop;
274         $p = $prototype{$line};
275         ($ret, $xname, $args) = $p =~ /(.*)\n(\w+)[ \t](.*)/;
276         if ($xname eq ""){
277             $xname = $line;
278         }
279         
280         $rspace = " " x ($type_size - length ($ret));
281         $nspace = " " x ($name_size - length ($xname));
282         $args = &format ($args, length ($ret . $rspace . $xname . $nspace), 60);
283         $apis_toc .= "$ret$rspace<a href=\"\#api:$line\">$xname</a>$nspace$args\n";
284     }
285     return $apis_toc;
286 }
287
288 #
289 # Formats the rest of the arguments in a way that will fit in N columns
290 #
291 sub format {
292     my ($args, $size, $limit) = @_;
293     my $sret = "";
294
295 #    return $args if ((length (args) + size) < $limit);
296     
297     $remain = $limit - $size;
298     @sa = split /,/, $args;
299     $linelen = $size;
300     foreach $arg (@sa){
301         if ($sret eq ""){
302             $sret = $arg . ", ";
303             $linelen += length ($sret);
304         } else {
305             if ($linelen + length ($arg) < $limit){
306                 $sret .= "FITS" . $arg . ", ";
307             } else {
308                 $newline = " " x ($size) . $arg . ", ";
309                 $linelen = length ($newline);
310                 $sret .= "\n" . $newline;
311             }
312         }
313     }
314     $sret =~ s/, $/;/;
315     return $sret;
316 }
317
318 sub opt_print {
319     my ($caption, $opttext, $quote) = @_;
320
321     if ($opttext ne "" && (!($opttext =~ /^[ \t]+$/))){
322         print OUT "             <div class=\"mapi-section\">$caption</div>\n";
323         print OUT "             <div>$opttext</div>\n";
324     }
325 }