blob: a168cfa6b745ffec34da97a9c54829546d2047be [file] [log] [blame]
Alexandre Julliard0799c1a2002-03-09 23:29:33 +00001#
2# Copyright 1999, 2000, 2001 Patrik Stridvall
3#
4# This library is free software; you can redistribute it and/or
5# modify it under the terms of the GNU Lesser General Public
6# License as published by the Free Software Foundation; either
7# version 2.1 of the License, or (at your option) any later version.
8#
9# This library is distributed in the hope that it will be useful,
10# but WITHOUT ANY WARRANTY; without even the implied warranty of
11# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12# Lesser General Public License for more details.
13#
14# You should have received a copy of the GNU Lesser General Public
15# License along with this library; if not, write to the Free Software
Jonathan Ernst360a3f92006-05-18 14:49:52 +020016# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
Alexandre Julliard0799c1a2002-03-09 23:29:33 +000017#
18
Patrik Stridvall7d0f2ba2001-02-12 03:44:41 +000019package winapi_documentation;
20
21use strict;
22
Patrik Stridvallb59a9c72001-07-12 22:22:05 +000023use config qw($current_dir $wine_dir);
Patrik Stridvall1c61b3b2001-07-23 23:20:56 +000024use modules qw($modules);
Patrik Stridvallbda50742001-07-14 00:48:41 +000025use nativeapi qw($nativeapi);
Patrik Stridvall1c61b3b2001-07-23 23:20:56 +000026use options qw($options);
27use output qw($output);
28use winapi qw($win16api $win32api @winapis);
Patrik Stridvallb59a9c72001-07-12 22:22:05 +000029
Patrik Stridvall7d0f2ba2001-02-12 03:44:41 +000030my %comment_width;
31my %comment_indent;
32my %comment_spacing;
33
Francois Gouget493d60f2004-10-07 18:53:56 +000034sub check_documentation($) {
Patrik Stridvall47a99e12001-07-08 20:33:20 +000035 local $_;
36
Patrik Stridvall7d0f2ba2001-02-12 03:44:41 +000037 my $function = shift;
38
Patrik Stridvallb59a9c72001-07-12 22:22:05 +000039 my $file = $function->file;
Patrik Stridvall7d0f2ba2001-02-12 03:44:41 +000040 my $external_name16 = $function->external_name16;
41 my $external_name32 = $function->external_name32;
42 my $internal_name = $function->internal_name;
Patrik Stridvallb59a9c72001-07-12 22:22:05 +000043 my $module16 = $function->module16;
44 my $module32 = $function->module32;
45 my $ordinal16 = $function->ordinal16;
46 my $ordinal32 = $function->ordinal32;
Patrik Stridvall7d0f2ba2001-02-12 03:44:41 +000047 my $documentation = $function->documentation;
Patrik Stridvall47a99e12001-07-08 20:33:20 +000048 my $documentation_line = $function->documentation_line;
Patrik Stridvall7d0f2ba2001-02-12 03:44:41 +000049
Patrik Stridvallc3e8ac32001-07-11 17:27:45 +000050 my $documentation_error = 0;
51 my $documentation_warning = 0;
Alexandre Julliard7cae5582002-06-01 02:55:48 +000052 if($options->documentation_name ||
Patrik Stridvall47a99e12001-07-08 20:33:20 +000053 $options->documentation_ordinal ||
Alexandre Julliard7cae5582002-06-01 02:55:48 +000054 $options->documentation_pedantic)
Patrik Stridvall47a99e12001-07-08 20:33:20 +000055 {
56 my @winapis = ($win16api, $win32api);
57 my @modules = ($module16, $module32);
58 my @external_names = ($external_name16, $external_name32);
Patrik Stridvallb59a9c72001-07-12 22:22:05 +000059 my @ordinals = ($ordinal16, $ordinal32);
Patrik Stridvall47a99e12001-07-08 20:33:20 +000060 while(
61 defined(my $winapi = shift @winapis) &&
62 defined(my $external_name = shift @external_names) &&
Patrik Stridvallb59a9c72001-07-12 22:22:05 +000063 defined(my $module = shift @modules) &&
64 defined(my $ordinal = shift @ordinals))
Patrik Stridvall7d0f2ba2001-02-12 03:44:41 +000065 {
Patrik Stridvallb59a9c72001-07-12 22:22:05 +000066 if($winapi->is_function_stub_in_module($module, $internal_name)) { next; }
Patrik Stridvall47a99e12001-07-08 20:33:20 +000067
68 my @external_name = split(/\s*\&\s*/, $external_name);
69 my @modules = split(/\s*\&\s*/, $module);
Patrik Stridvallb59a9c72001-07-12 22:22:05 +000070 my @ordinals = split(/\s*\&\s*/, $ordinal);
Patrik Stridvall47a99e12001-07-08 20:33:20 +000071
72 my $pedantic_failed = 0;
Alexandre Julliard7cae5582002-06-01 02:55:48 +000073 while(defined(my $external_name = shift @external_name) &&
74 defined(my $module = shift @modules) &&
75 defined(my $ordinal = shift @ordinals))
Patrik Stridvall47a99e12001-07-08 20:33:20 +000076 {
77 my $found_name = 0;
78 my $found_ordinal = 0;
Patrik Stridvall0704650f2002-07-19 00:31:05 +000079
80 $module =~ s/\.(acm|dll|drv|exe|ocx)$//; # FIXME: Kludge
Patrik Stridvall5379c792002-07-23 01:59:09 +000081 $module = "kernel" if $module eq "krnl386"; # FIXME: Kludge
82
Patrik Stridvall47a99e12001-07-08 20:33:20 +000083 foreach (split(/\n/, $documentation)) {
84 if(/^(\s*)\*(\s*)(\@|\S+)(\s*)([\(\[])(\w+)\.(\@|\d+)([\)\]])/) {
85 my $external_name2 = $3;
86 my $module2 = $6;
87 my $ordinal2 = $7;
88
Patrik Stridvallde306f22002-09-24 18:27:47 +000089 if ($winapi->function_wine_extension(lc($module2), $external_name2)) {
Patrik Stridvallc5f834c2003-08-08 21:04:17 +000090 # $output->write("documentation: $external_name2 (\U$module2\E.$ordinal2) is a Wine extension \\\n$documentation\n");
Patrik Stridvallde306f22002-09-24 18:27:47 +000091 }
Patrik Stridvall5379c792002-07-23 01:59:09 +000092
Alexandre Julliard7cae5582002-06-01 02:55:48 +000093 if(length($1) != 1 || length($2) < 1 ||
Patrik Stridvall47a99e12001-07-08 20:33:20 +000094 length($4) < 1 || $5 ne "(" || $8 ne ")")
95 {
96 $pedantic_failed = 1;
97 }
98
99 if($external_name eq $external_name2) {
100 $found_name = 1;
101 if("\U$module\E" eq $module2 &&
102 $ordinal eq $ordinal2)
103 {
104 $found_ordinal = 1;
105 }
106 }
107 }
108 }
Patrik Stridvallde306f22002-09-24 18:27:47 +0000109 if((($options->documentation_name && !$found_name) ||
110 ($options->documentation_ordinal && !$found_ordinal)) &&
Patrik Stridvallc5f834c2003-08-08 21:04:17 +0000111 !$winapi->is_function_stub($module, $external_name) &&
Patrik Stridvallde306f22002-09-24 18:27:47 +0000112 !$winapi->function_wine_extension($module, $external_name))
Patrik Stridvall47a99e12001-07-08 20:33:20 +0000113 {
Patrik Stridvallc3e8ac32001-07-11 17:27:45 +0000114 $documentation_error = 1;
Patrik Stridvall47a99e12001-07-08 20:33:20 +0000115 $output->write("documentation: expected $external_name (\U$module\E.$ordinal): \\\n$documentation\n");
116 }
Alexandre Julliard7cae5582002-06-01 02:55:48 +0000117
Patrik Stridvall47a99e12001-07-08 20:33:20 +0000118 }
119 if($options->documentation_pedantic && $pedantic_failed) {
Patrik Stridvallc3e8ac32001-07-11 17:27:45 +0000120 $documentation_warning = 1;
Patrik Stridvall47a99e12001-07-08 20:33:20 +0000121 $output->write("documentation: pedantic failed: \\\n$documentation\n");
Patrik Stridvall20ca0012001-06-19 03:34:52 +0000122 }
Patrik Stridvall7d0f2ba2001-02-12 03:44:41 +0000123 }
124 }
125
Patrik Stridvallc3e8ac32001-07-11 17:27:45 +0000126 if(!$documentation_error && $options->documentation_wrong) {
Patrik Stridvall47a99e12001-07-08 20:33:20 +0000127 foreach (split(/\n/, $documentation)) {
Francois Gouget8f3187b2007-06-12 17:50:20 +0200128 if (/^\s*\*\s*(\S+)\s*[\(\[]\s*(\w+(?:\.(?:DRV|EXE|OCX|VXD))?)\s*\.\s*([^\s\)\]]*)\s*[\)\]].*?$/) {
Patrik Stridvall47a99e12001-07-08 20:33:20 +0000129 my $external_name = $1;
130 my $module = $2;
131 my $ordinal = $3;
Patrik Stridvall7d0f2ba2001-02-12 03:44:41 +0000132
Patrik Stridvall9c391562004-02-20 19:57:42 +0000133 if ($ordinal eq "@") {
134 # Nothing
135 } elsif ($ordinal =~ /^\d+$/) {
Patrik Stridvall0704650f2002-07-19 00:31:05 +0000136 $ordinal = int($ordinal);
Patrik Stridvall9c391562004-02-20 19:57:42 +0000137 } elsif ($ordinal eq "init") {
138 $ordinal = 0;
139 } else {
Francois Gouget53914082007-02-20 15:50:49 +0100140 $output->write("documentation: invalid ordinal for $external_name (\U$module\E.$ordinal)\n");
Patrik Stridvall9c391562004-02-20 19:57:42 +0000141 next;
Patrik Stridvall0704650f2002-07-19 00:31:05 +0000142 }
143
Patrik Stridvall47a99e12001-07-08 20:33:20 +0000144 my $found = 0;
145 foreach my $entry2 (winapi::get_all_module_internal_ordinal($internal_name)) {
146 (my $external_name2, my $module2, my $ordinal2) = @$entry2;
Patrik Stridvallb59a9c72001-07-12 22:22:05 +0000147
Patrik Stridvall0704650f2002-07-19 00:31:05 +0000148 my $_module2 = $module2;
149 $_module2 =~ s/\.(acm|dll|drv|exe|ocx)$//; # FIXME: Kludge
Patrik Stridvall5379c792002-07-23 01:59:09 +0000150 $_module2 = "kernel" if $_module2 eq "krnl386"; # FIXME: Kludge
Patrik Stridvall0704650f2002-07-19 00:31:05 +0000151
Patrik Stridvall47a99e12001-07-08 20:33:20 +0000152 if($external_name eq $external_name2 &&
Patrik Stridvall0704650f2002-07-19 00:31:05 +0000153 lc($module) eq $_module2 &&
Patrik Stridvallb59a9c72001-07-12 22:22:05 +0000154 $ordinal eq $ordinal2 &&
155 ($external_name2 eq "@" ||
156 ($win16api->is_module($module2) && !$win16api->is_function_stub_in_module($module2, $external_name2)) ||
Patrik Stridvallde306f22002-09-24 18:27:47 +0000157 ($win32api->is_module($module2) && !$win32api->is_function_stub_in_module($module2, $external_name2))) ||
Patrik Stridvallb59a9c72001-07-12 22:22:05 +0000158 $modules->is_allowed_module_in_file($module2, "$current_dir/$file"))
Patrik Stridvall47a99e12001-07-08 20:33:20 +0000159 {
160 $found = 1;
Patrik Stridvall0704650f2002-07-19 00:31:05 +0000161 last;
Patrik Stridvall47a99e12001-07-08 20:33:20 +0000162 }
Patrik Stridvallde306f22002-09-24 18:27:47 +0000163
164
Patrik Stridvall47a99e12001-07-08 20:33:20 +0000165 }
Patrik Stridvall9c391562004-02-20 19:57:42 +0000166
Francois Gouget53914082007-02-20 15:50:49 +0100167 if (!$found && $external_name ne "DllMain" && $ordinal ne "0") {
168 $output->write("documentation: $external_name (\U$module\E.$ordinal) not declared in the spec file\n");
Patrik Stridvall7d0f2ba2001-02-12 03:44:41 +0000169 }
170 }
171 }
Patrik Stridvall7d0f2ba2001-02-12 03:44:41 +0000172 }
173
174 if($options->documentation_comment_indent) {
Patrik Stridvallc3e8ac32001-07-11 17:27:45 +0000175 foreach (split(/\n/, $documentation)) {
176 if(/^\s*\*(\s*)\S+(\s*)[\(\[]\s*\w+\s*\.\s*[^\s\)\]]*\s*[\)\]].*?$/) {
177 my $indent = $1;
178 my $spacing = $2;
Alexandre Julliard7cae5582002-06-01 02:55:48 +0000179
Patrik Stridvallc3e8ac32001-07-11 17:27:45 +0000180 $indent =~ s/\t/ /g;
181 $indent = length($indent);
Alexandre Julliard7cae5582002-06-01 02:55:48 +0000182
Patrik Stridvallc3e8ac32001-07-11 17:27:45 +0000183 $spacing =~ s/\t/ /g;
184 $spacing = length($spacing);
Alexandre Julliard7cae5582002-06-01 02:55:48 +0000185
Patrik Stridvallc3e8ac32001-07-11 17:27:45 +0000186 $comment_indent{$indent}++;
187 if($indent >= 20) {
188 $output->write("documentation: comment indent is $indent\n");
189 }
190 $comment_spacing{$spacing}++;
Patrik Stridvall7d0f2ba2001-02-12 03:44:41 +0000191 }
Patrik Stridvall7d0f2ba2001-02-12 03:44:41 +0000192 }
193 }
194
195 if($options->documentation_comment_width) {
196 if($documentation =~ /(^\/\*\*+)/) {
197 my $width = length($1);
198
199 $comment_width{$width}++;
200 if($width <= 65 || $width >= 81) {
201 $output->write("comment is $width columns wide\n");
202 }
203 }
204 }
205
206 if($options->documentation_arguments) {
Patrik Stridvall1c61b3b2001-07-23 23:20:56 +0000207 my $refargument_documentations = $function->argument_documentations;
208
209 if(defined($refargument_documentations)) {
210 my $n = 0;
211 for my $argument_documentation (@$refargument_documentations) {
212 $n++;
213 if($argument_documentation ne "") {
Patrik Stridvallc5f834c2003-08-08 21:04:17 +0000214 if($argument_documentation !~ /^\/\*\s+\[(?:in|out|in\/out|\?\?\?|I|O|I\/O)\].*?\*\/$/s) {
Patrik Stridvall1c61b3b2001-07-23 23:20:56 +0000215 $output->write("argument $n documentation: \\\n$argument_documentation\n");
216 }
Patrik Stridvall7d0f2ba2001-02-12 03:44:41 +0000217 }
218 }
219 }
220 }
221}
222
Francois Gouget493d60f2004-10-07 18:53:56 +0000223sub report_documentation() {
Patrik Stridvall7d0f2ba2001-02-12 03:44:41 +0000224 if($options->documentation_comment_indent) {
225 foreach my $indent (sort(keys(%comment_indent))) {
226 my $count = $comment_indent{$indent};
227 $output->write("*.c: $count functions have comment that is indented $indent\n");
228 }
229 }
230
231 if($options->documentation_comment_width) {
232 foreach my $width (sort(keys(%comment_width))) {
233 my $count = $comment_width{$width};
234 $output->write("*.c: $count functions have comments of width $width\n");
235 }
236 }
237}
238
2391;