3 #####################################################################################
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.
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)
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.
34 # * Handle to metafile copy on success, NULL on failure.
38 # * Copying to disk returns NULL even if successful.
40 # HMETAFILE32 WINAPI CopyMetaFile32A(
41 # HMETAFILE32 hSrcMetaFile, /* handle of metafile to copy */
42 # LPCSTR lpFilename /* filename if copying to a file */
45 #####################################################################################
46 # Output after processing with nroff -man
48 # CopyMetaFileA(3w) CopyMetaFileA(3w)
52 # CopyMetaFileA - CopyMetaFile32A (GDI32.23)
55 # HMETAFILE32 CopyMetaFileA
57 # HMETAFILE32 hSrcMetaFile,
62 # HMETAFILE32 hSrcMetaFile
63 # Handle of metafile to copy.
66 # Filename if copying to a file.
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.
74 # Handle to metafile copy on success, NULL on failure.
77 # Copying to disk returns NULL even if successful.
80 # GetMetaFileA(3w), GetMetaFileW(3w), CopyMetaFileW(3w),
81 # PlayMetaFile(3w), SetMetaFileBitsEx(3w), GetMetaFileBit-
84 #####################################################################################
88 my ($buffer,$apiref) = @_;
92 # join all the lines of the description together and highlight the headings
98 $desc = $desc.".SH $1\n.PP\n";
108 #seperate out all the parameters
110 $plist = join ( ' ', @$apiref );
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
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";
146 print MAN "$name_type\n";
148 for($i=0; $i<@params; $i++) {
149 $x = ($i == (@params-1)) ? "" : ",";
155 print MAN ".SH PARAMETERS\n";
157 for($i=0; $i<@params; $i++) {
158 print MAN " $params[$i]\n";
160 print MAN ".SH DESCRIPTION\n";
167 # extract the comments from source file
172 print "Processing $file\n";
174 open(SOURCE,"<$file") || die "Couldn't open the source file $file\n";
179 # find the start of the comment /**************
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]+)|@))\) *$/ ) {
195 elsif ($state == 1) {
196 #save the comment text into buffer, removing leading astericks
201 # find the end of the comment
203 @buffer = ( @buffer , $_ );
210 elsif ($state == 2) {
211 # check that the comment is followed by the declaration of
215 #check if the function's parameters end on this line
217 output_manpage(\@buffer, \@apidef);
228 elsif ($state == 4) {
229 @apidef = ( @apidef , $_ );
230 #find the end of the parameters list
232 output_manpage(\@buffer, \@apidef);
240 # generate a database of functions to have man pages created from the source
241 # creates funclist and funcdb
245 my $name,$type,$ord,$func;
247 open(SPEC,"<$spec") || die "Couldn't open the spec file $spec\n";
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;
272 ######################################################################
281 if($ARGV[0] eq "-o") { # extract output directory
287 if($ARGV[0] =~ s/^-S// ) { # extract man section
292 if($ARGV[0] =~ s/^-w// ) { # extract man section
294 @specfiles = ( @specfiles , $ARGV[0] );
298 if($ARGV[0] =~ s/^-T// ) {
299 die "FIXME: Only NROFF supported\n";
301 if($ARGV[0] =~ s/^-[LDiI]// ) { #compatible with C2MAN flags
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";
314 parse_spec($specfiles[0]);
318 #print "Functions: @funclist\n";
321 parse_source($ARGV[0]);