Implement EnumPrinterDataEx{A|W}.
[wine.git] / tools / c2man.pl
blobf1d211c0d289747e6aa45e4b1a0e028fee0d94cb
1 #!/usr/bin/perl
3 #####################################################################################
4 #
5 # c2man.pl v0.1 Copyright (C) 2000 Mike McCormack
7 # Genenerates Documents from C source code.
9 # Input is source code with specially formatted comments, output
10 # is man pages. The functionality is meant to be similar to c2man.
11 # The following is an example provided in the Wine documentation.
13 # TODO:
14 # Write code to generate HTML output with the -Th option.
15 # Need somebody who knows about TROFF to help touch up the man page generation.
16 # Parse spec files passed with -w option and generate pages for the functions
17 # in the spec files only.
18 # Modify Makefiles to pass multiple C files to speed up man page generation.
19 # Use nm on the shared libraries specified in the spec files to determine which
20 # source files should be parsed, and only parse them.(requires wine to be compiled)
22 #####################################################################################
23 # Input from C source file:
25 # /******************************************************************
26 # * CopyMetaFile32A (GDI32.23)
27 # *
28 # * Copies the metafile corresponding to hSrcMetaFile to either
29 # * a disk file, if a filename is given, or to a new memory based
30 # * metafile, if lpFileName is NULL.
31 # *
32 # * RETURNS
33 # *
34 # * Handle to metafile copy on success, NULL on failure.
35 # *
36 # * BUGS
37 # *
38 # * Copying to disk returns NULL even if successful.
39 # */
40 # HMETAFILE32 WINAPI CopyMetaFile32A(
41 # HMETAFILE32 hSrcMetaFile, /* handle of metafile to copy */
42 # LPCSTR lpFilename /* filename if copying to a file */
43 # ) { ... }
45 #####################################################################################
46 # Output after processing with nroff -man
48 # CopyMetaFileA(3w) CopyMetaFileA(3w)
51 # NAME
52 # CopyMetaFileA - CopyMetaFile32A (GDI32.23)
54 # SYNOPSIS
55 # HMETAFILE32 CopyMetaFileA
56 # (
57 # HMETAFILE32 hSrcMetaFile,
58 # LPCSTR lpFilename
59 # );
61 # PARAMETERS
62 # HMETAFILE32 hSrcMetaFile
63 # Handle of metafile to copy.
65 # LPCSTR lpFilename
66 # Filename if copying to a file.
68 # DESCRIPTION
69 # Copies the metafile corresponding to hSrcMetaFile to
70 # either a disk file, if a filename is given, or to a new
71 # memory based metafile, if lpFileName is NULL.
73 # RETURNS
74 # Handle to metafile copy on success, NULL on failure.
76 # BUGS
77 # Copying to disk returns NULL even if successful.
79 # SEE ALSO
80 # GetMetaFileA(3w), GetMetaFileW(3w), CopyMetaFileW(3w),
81 # PlayMetaFile(3w), SetMetaFileBitsEx(3w), GetMetaFileBit-
82 # sEx(3w)
84 #####################################################################################
86 sub output_manpage
88 my ($buffer,$apiref) = @_;
89 my $parameters;
90 my $desc;
92 # join all the lines of the description together and highlight the headings
93 for (@$buffer) {
94 s/\n//g;
95 s/^\s*//g;
96 s/\s*$//g;
97 if ( /^([A-Z]+)$/ ) {
98 $desc = $desc.".SH $1\n.PP\n";
100 elsif ( /^$/ ) {
101 $desc = "$desc\n";
103 else {
104 $desc = "$desc $_";
108 #seperate out all the parameters
110 $plist = join ( ' ', @$apiref );
112 $name_type = $plist;
113 $name_type =~ s/\n//g; # remove newlines
114 $name_type =~ s/\(.*$//;
115 $name_type =~ s/WINAPI//;
117 #check that this is a function that we want
118 if ( $funcdb{$apiname."ORD"} eq "" ) { return; }
119 print "Generating $apiname.$section\n";
121 $plist =~ s/\n//g; # remove newlines
122 $plist =~ s/^.*\(\s*//; # remove leading bracket and before
123 $plist =~ s/\s*\).*$//; # remove trailing bracket and leftovers
124 $plist =~ s/\s*,?\s*\/\*([^*]*)\*\// - $1,/g; # move the comma to the back
125 @params = split ( /,/ , $plist); # split parameters
126 for(@params) {
127 s/^\s*//;
128 s/\s*$//;
131 # figure the month and the year
132 @datetime = localtime;
133 @months = ( "January", "Febuary", "March", "April", "May", "June",
134 "July", "August", "September", "October", "November", "December" );
135 $date = "$months[$datetime[4]] $datetime[5]";
137 # create the manual page
138 $manfile = "$mandir/$apiname.$section";
139 open(MAN,">$manfile") || die "Couldn't create the man page file $manfile\n";
140 print MAN ".\\\" DO NOT MODIFY THIS FILE! It was generated by gendoc 1.0.\n";
141 print MAN ".TH $apiname \"$section\" \"$date\" \"Wine API\" \"The Wine Project\"\n";
142 print MAN ".SH NAME\n";
143 print MAN "$apiname ($apientry)\n";
144 print MAN ".SH SYNOPSIS\n";
145 print MAN ".PP\n";
146 print MAN "$name_type\n";
147 print MAN " (\n";
148 for($i=0; $i<@params; $i++) {
149 $x = ($i == (@params-1)) ? "" : ",";
150 $c = $params[$i];
151 $c =~ s/-.*//;
152 print MAN " $c$x\n";
154 print MAN " );\n";
155 print MAN ".SH PARAMETERS\n";
156 print MAN ".PP\n";
157 for($i=0; $i<@params; $i++) {
158 print MAN " $params[$i]\n";
160 print MAN ".SH DESCRIPTION\n";
161 print MAN ".PP\n";
162 print MAN $desc;
163 close(MAN);
167 # extract the comments from source file
169 sub parse_source
171 my $file = $_[0];
172 print "Processing $file\n";
174 open(SOURCE,"<$file") || die "Couldn't open the source file $file\n";
175 $state = 0;
176 while(<SOURCE>) {
177 if($state == 0 ) {
178 if ( /^\/\**$/ ) {
179 # find the start of the comment /**************
180 $state = 3;
181 @buffer = ();
184 elsif ($state == 3) {
185 #extract the wine API name and DLLNAME.XXX string
186 if ( / *([A-Za-z_0-9]+) *\(([A-Za-z0-9_]+\.(([0-9]+)|@))\) *$/ ) {
187 $apiname = $1;
188 $apientry = $2;
189 $state = 1;
191 else {
192 $state = 0;
195 elsif ($state == 1) {
196 #save the comment text into buffer, removing leading astericks
197 if ( /^ \*\// ) {
198 $state = 2;
200 else {
201 # find the end of the comment
202 if ( s/^ \*// ) {
203 @buffer = ( @buffer , $_ );
205 else {
206 $state = 0;
210 elsif ($state == 2) {
211 # check that the comment is followed by the declaration of
212 # a WINAPI function.
213 if ( /WINAPI/ ) {
214 @apidef = ( $_ );
215 #check if the function's parameters end on this line
216 if( /\)/ ) {
217 output_manpage(\@buffer, \@apidef);
218 $state = 0;
220 else {
221 $state = 4;
224 else {
225 $state = 0;
228 elsif ($state == 4) {
229 @apidef = ( @apidef , $_ );
230 #find the end of the parameters list
231 if( /\)/ ) {
232 output_manpage(\@buffer, \@apidef);
233 $state = 0;
237 close(SOURCE);
240 # generate a database of functions to have man pages created from the source
241 # creates funclist and funcdb
242 sub parse_spec
244 my $spec = $_[0];
245 my $name,$type,$ord,$func;
247 open(SPEC,"<$spec") || die "Couldn't open the spec file $spec\n";
248 while(<SPEC>)
250 if( /^#/ ) { next; }
251 if( /^name/ ) { next; }
252 if( /^type/ ) { next; }
253 if( /^init/ ) { next; }
254 if( /^rsrc/ ) { next; }
255 if( /^import/ ) { next; }
256 if( /^\s*$/ ) { next; }
257 if( /^\s*(([0-9]+)|@)/ ) {
258 s/\(.*\)//; #remove all the args
259 ($ord,$type,$name,$func) = split( /\s+/ );
260 if(( $type eq "stub" ) || ($type eq "forward")) {next;}
261 if( $func eq "" ) { next; }
262 @funclist = ( @funclist , $func );
263 $funcdb{$func."ORD"} = $ord;
264 $funcdb{$func."TYPE"} = $type;
265 $funcdb{$func."NAME"} = $name;
266 $funcdb{$func."SPEC"} = $spec;
269 close(SPEC);
272 ######################################################################
274 #main starts here
276 $mandir = "man3w";
277 $section = "3";
279 #process args
280 while(@ARGV) {
281 if($ARGV[0] eq "-o") { # extract output directory
282 shift @ARGV;
283 $mandir = $ARGV[0];
284 shift @ARGV;
285 next;
287 if($ARGV[0] =~ s/^-S// ) { # extract man section
288 $section = $ARGV[0];
289 shift @ARGV;
290 next;
292 if($ARGV[0] =~ s/^-w// ) { # extract man section
293 shift @ARGV;
294 @specfiles = ( @specfiles , $ARGV[0] );
295 shift @ARGV;
296 next;
298 if($ARGV[0] =~ s/^-T// ) {
299 die "FIXME: Only NROFF supported\n";
301 if($ARGV[0] =~ s/^-[LDiI]// ) { #compatible with C2MAN flags
302 shift @ARGV;
303 next;
305 last; # stop after there's no more flags
308 #print "manual section: $section\n";
309 #print "man directory : $mandir\n";
310 #print "input files : @ARGV\n";
311 #print "spec files : @specfiles\n";
313 while(@specfiles) {
314 parse_spec($specfiles[0]);
315 shift @specfiles;
318 #print "Functions: @funclist\n";
320 while(@ARGV) {
321 parse_source($ARGV[0]);
322 shift @ARGV;