| #!/usr/bin/perl -w | |
| # | |
| # Extract #define symbol information from C header files. | |
| # | |
| # Copyright 2002 Alexandre Julliard | |
| # | |
| # list of symbols (regexps) to skip for each header | |
| %skip_list = | |
| ( | |
| "winnt.h" => [ "APIENTRY", "APIPRIVATE", "CALLBACK", "CONST", "EXTERN_C", "PASCAL", | |
| "VOID", "DUMMY(STRUCT|UNION)NAME.*", "STDAPI.*", "STDMETHOD.*", "WINAPI.*", | |
| "WINE_.*", "_*(cdecl|CDECL|pascal|export|fastcall|stdcall)", | |
| "MEM_SYSTEM", "_GET_CONTEXT", "_QUAD_.*", | |
| "CONTEXT_(ALPHA|R4000|SPARC|X86|i386|i486)" ], | |
| "winbase.h" => [ "(Fill|Move|Zero|Copy)Memory" ], | |
| "wingdi.h" => [ "PROFILE_LINKED", "PROFILE_EMBEDDED", "GetCharWidth[AW]" ], | |
| "winuser.h" => [ "OemToAnsi[AW]", "OemToAnsiBuff[AW]", "AnsiToOem[AW]", "AnsiToOemBuff[AW]", | |
| "Ansi(Next|Prev|Lower|Upper|LowerBuff|UpperBuff)[AW]", "GetNextWindow" ], | |
| "winsock2.h" => [ "WSAEVENT", "LPWSAEVENT", "WSAOVERLAPPED", "WS_.*" ] | |
| ); | |
| @header_list = | |
| ( | |
| "windef.h", | |
| "winnt.h", | |
| "winbase.h", | |
| "wingdi.h", | |
| "winuser.h", | |
| "winerror.h", | |
| "winnls.h", | |
| "winreg.h", | |
| "winsock2.h", | |
| "winspool.h", | |
| "winver.h", | |
| "wincon.h", | |
| ); | |
| $include_dir = "../../include"; | |
| @list = ($#ARGV >= 0) ? @ARGV : @header_list; | |
| foreach $basename (@list) | |
| { | |
| my $skip = $skip_list{$basename}; | |
| my $result = "include/" . $basename; | |
| $result =~ s!\.h$!.pm!; | |
| my $package = $basename; | |
| $package =~ s/\.h$//; | |
| open INPUT, "$include_dir/$basename" or die "Cannot open $include_dir/$basename"; | |
| open OUTPUT, ">sym.c" or die "Cannot create sym.c"; | |
| print "Building $result\n"; | |
| print OUTPUT <<EOF; | |
| #include <stdio.h> | |
| #include <stdlib.h> | |
| #include <limits.h> | |
| EOF | |
| foreach $inc (@header_list) { print OUTPUT "#include <$inc>\n"; } | |
| print OUTPUT <<EOF; | |
| int main() | |
| { | |
| printf( "# Automatically generated by make_symbols; DO NOT EDIT!! \\n" ); | |
| printf( "#\\n" ); | |
| printf( "# Perl definitions for header file $basename\\n" ); | |
| printf( "#\\n\\n" ); | |
| printf( "\\n" ); | |
| printf( "package $package;\\n" ); | |
| printf( "\\n" ); | |
| printf( "use strict;\\n" ); | |
| printf( "\\n" ); | |
| printf( "use vars qw(\$VERSION \@ISA \@EXPORT \@EXPORT_OK);\\n" ); | |
| printf( "\\n" ); | |
| printf( "require Exporter;\\n" ); | |
| printf( "\\n" ); | |
| printf( "\@ISA = qw(Exporter);\\n" ); | |
| printf( "\@EXPORT = qw(\\n" ); | |
| EOF | |
| my %symbols = (); | |
| while (<INPUT>) | |
| { | |
| # extract all #defines | |
| next unless (/^\s*\#\s*define\s+([A-Za-z0-9_]+)\s+(.*)$/); | |
| my ($name,$value) = ($1,$2); | |
| # skip empty value | |
| next if ($value eq ""); | |
| # skip the WINELIB defines | |
| next if ($value =~ /WINELIB_NAME_AW/); | |
| # skip macros containing multiple values | |
| next if ($value =~ /{.*}/); | |
| # check against regexps to skip | |
| next if (grep { $name =~ /^$_$/ } @$skip); | |
| $symbols{$name} = $value; | |
| } | |
| foreach $sym (sort keys %symbols) | |
| { | |
| printf OUTPUT " printf(\" $sym\\n\");\n"; | |
| } | |
| printf OUTPUT " printf(\");\\n\");\n"; | |
| printf OUTPUT " printf(\"\@EXPORT_OK = qw();\\n\");\n"; | |
| printf OUTPUT " printf(\"\\n\");\n"; | |
| foreach $sym (sort keys %symbols) | |
| { | |
| printf OUTPUT " printf(\"use constant $sym => %%d;\\n\", (int)($sym));\n"; | |
| } | |
| printf OUTPUT " printf(\"\\n\");\n"; | |
| printf OUTPUT " printf(\"1;\\n\");\n"; | |
| print OUTPUT " exit(0);\n}\n"; | |
| close OUTPUT; | |
| #print "cc -I../../include -o sym sym.c\n"; | |
| if (system( "cc -I../../include -o sym sym.c" )) { die "Could not compile sym.c"; } | |
| #print "./sym >$result\n"; | |
| if (system( "./sym >$result" )) { die "Could not run ./sym\n"; } | |
| unlink "sym","sym.c"; | |
| } |