nativeapi.pm 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231
  1. #
  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
  16. # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
  17. #
  18. package nativeapi;
  19. use strict;
  20. use warnings 'all';
  21. use vars qw($VERSION @ISA @EXPORT @EXPORT_OK);
  22. require Exporter;
  23. @ISA = qw(Exporter);
  24. @EXPORT = qw();
  25. @EXPORT_OK = qw($nativeapi);
  26. use vars qw($nativeapi);
  27. use config qw(file_type $current_dir $wine_dir $winapi_dir);
  28. use options qw($options);
  29. use output qw($output);
  30. $nativeapi = 'nativeapi'->new;
  31. sub new($) {
  32. my $proto = shift;
  33. my $class = ref($proto) || $proto;
  34. my $self = {};
  35. bless ($self, $class);
  36. my $functions = \%{$self->{FUNCTIONS}};
  37. my $conditionals = \%{$self->{CONDITIONALS}};
  38. my $conditional_headers = \%{$self->{CONDITIONAL_HEADERS}};
  39. my $conditional_functions = \%{$self->{CONDITIONAL_FUNCTIONS}};
  40. my $api_file = "$winapi_dir/nativeapi.dat";
  41. my $configure_ac_file = "$wine_dir/configure.ac";
  42. my $config_h_in_file = "$wine_dir/include/config.h.in";
  43. $api_file =~ s/^\.\///;
  44. $configure_ac_file =~ s/^\.\///;
  45. $config_h_in_file =~ s/^\.\///;
  46. $$conditional_headers{"config.h"}++;
  47. $output->progress("$api_file");
  48. open(IN, "< $api_file") || die "Error: Can't open $api_file: $!\n";
  49. local $/ = "\n";
  50. while(<IN>) {
  51. s/^\s*(.*?)\s*$/$1/; # remove whitespace at begin and end of line
  52. s/^(.*?)\s*#.*$/$1/; # remove comments
  53. /^$/ && next; # skip empty lines
  54. $$functions{$_}++;
  55. }
  56. close(IN);
  57. $output->progress("$configure_ac_file");
  58. my $again = 0;
  59. open(IN, "< $configure_ac_file") || die "Error: Can't open $configure_ac_file: $!\n";
  60. local $/ = "\n";
  61. while($again || (defined($_ = <IN>))) {
  62. $again = 0;
  63. chomp;
  64. if(/^(.*?)\\$/) {
  65. my $current = $1;
  66. my $next = <IN>;
  67. if(defined($next)) {
  68. # remove trailing whitespace
  69. $current =~ s/\s+$//;
  70. # remove leading whitespace
  71. $next =~ s/^\s+//;
  72. $_ = $current . " " . $next;
  73. $again = 1;
  74. next;
  75. }
  76. }
  77. # remove leading and trailing whitespace
  78. s/^\s*(.*?)\s*$/$1/;
  79. # skip empty lines
  80. if(/^$/) { next; }
  81. # skip comments
  82. if(/^dnl/) { next; }
  83. if(/AC_CHECK_HEADERS\(\s*([^,\)]*)(?:,|\))?/) {
  84. my $headers = $1;
  85. $headers =~ s/^\s*\[\s*(.*?)\s*\]\s*$/$1/;
  86. foreach my $name (split(/\s+/, $headers)) {
  87. $$conditional_headers{$name}++;
  88. }
  89. } elsif(/AC_HEADER_STAT\(\)/) {
  90. # This checks for a bunch of standard headers
  91. # There's stdlib.h, string.h and sys/types.h too but we don't
  92. # want to force ifdefs for those at this point.
  93. foreach my $name ("sys/stat.h", "memory.h", "strings.h",
  94. "inttypes.h", "stdint.h", "unistd.h") {
  95. $$conditional_headers{$name}++;
  96. }
  97. } elsif(/AC_CHECK_FUNCS\(\s*([^,\)]*)(?:,|\))?/) {
  98. my $funcs = $1;
  99. $funcs =~ s/^\s*\[\s*(.*?)\s*\]\s*$/$1/;
  100. foreach my $name (split(/\s+/, $funcs)) {
  101. $$conditional_functions{$name}++;
  102. }
  103. } elsif(/AC_FUNC_ALLOCA/) {
  104. $$conditional_headers{"alloca.h"}++;
  105. } elsif (/AC_DEFINE\(\s*HAVE_(.*?)_H/) {
  106. my $name = lc($1);
  107. $name =~ s/_/\//;
  108. $name .= ".h";
  109. next if $name =~ m%correct/%;
  110. $$conditional_headers{$name}++;
  111. }
  112. }
  113. close(IN);
  114. $output->progress("$config_h_in_file");
  115. open(IN, "< $config_h_in_file") || die "Error: Can't open $config_h_in_file: $!\n";
  116. local $/ = "\n";
  117. while(<IN>) {
  118. # remove leading and trailing whitespace
  119. s/^\s*(.*?)\s*$/$1/;
  120. # skip empty lines
  121. if(/^$/) { next; }
  122. if(/^\#undef\s+(\S+)$/) {
  123. $$conditionals{$1}++;
  124. }
  125. }
  126. close(IN);
  127. $nativeapi = $self;
  128. return $self;
  129. }
  130. sub is_function($$) {
  131. my $self = shift;
  132. my $functions = \%{$self->{FUNCTIONS}};
  133. my $name = shift;
  134. return ($$functions{$name} || 0);
  135. }
  136. sub is_conditional($$) {
  137. my $self = shift;
  138. my $conditionals = \%{$self->{CONDITIONALS}};
  139. my $name = shift;
  140. return ($$conditionals{$name} || 0);
  141. }
  142. sub found_conditional($$) {
  143. my $self = shift;
  144. my $conditional_found = \%{$self->{CONDITIONAL_FOUND}};
  145. my $name = shift;
  146. $$conditional_found{$name}++;
  147. }
  148. sub is_conditional_header($$) {
  149. my $self = shift;
  150. my $conditional_headers = \%{$self->{CONDITIONAL_HEADERS}};
  151. my $name = shift;
  152. return ($$conditional_headers{$name} || 0);
  153. }
  154. sub is_conditional_function($$) {
  155. my $self = shift;
  156. my $conditional_functions = \%{$self->{CONDITIONAL_FUNCTIONS}};
  157. my $name = shift;
  158. return ($$conditional_functions{$name} || 0);
  159. }
  160. sub global_report($) {
  161. my $self = shift;
  162. my $output = \${$self->{OUTPUT}};
  163. my $conditional_found = \%{$self->{CONDITIONAL_FOUND}};
  164. my $conditionals = \%{$self->{CONDITIONALS}};
  165. my @messages;
  166. foreach my $name (sort(keys(%$conditionals))) {
  167. if($name =~ /^(?:const|inline|size_t)$/) { next; }
  168. if(0 && !$$conditional_found{$name}) {
  169. push @messages, "config.h.in: conditional $name not used\n";
  170. }
  171. }
  172. foreach my $message (sort(@messages)) {
  173. $output->write($message);
  174. }
  175. }
  176. 1;