7 my $class = ref($proto) || $proto;
11 my $options = \
${$self->{OPTIONS
}};
12 my $output = \
${$self->{OUTPUT
}};
13 my $name = \
${$self->{NAME
}};
23 } split(/\n/, `find $path -name \\*.api`);
25 foreach my $file (@files) {
27 $module =~ s/.*?\/([^\/]*?
)\
.api
$/$1/;
28 $self->parse_api_file($file,$module);
37 my $options = \
${$self->{OPTIONS
}};
38 my $output = \
${$self->{OUTPUT
}};
39 my $allowed_kind = \
%{$self->{ALLOWED_KIND
}};
40 my $allowed_modules = \
%{$self->{ALLOWED_MODULES
}};
41 my $allowed_modules_limited = \
%{$self->{ALLOWED_MODULES_LIMITED
}};
42 my $allowed_modules_unlimited = \
%{$self->{ALLOWED_MODULES_UNLIMITED
}};
43 my $translate_argument = \
%{$self->{TRANSLATE_ARGUMENT
}};
52 if($$options->progress) {
53 $$output->progress("$file");
56 open(IN
, "< $file") || die "$file: $!\n";
59 s/^\s*?(.*?)\s*$/$1/; # remove whitespace at begin and end of line
60 s/^(.*?)\s*#.*$/$1/; # remove comments
61 /^$/ && next; # skip empty lines
68 $$allowed_kind{$kind} = 1;
71 } elsif(/^--extension/) {
74 } elsif(defined($kind)) {
77 if(defined($module)) {
78 if($$allowed_modules_unlimited{$type}) {
79 $$output->write("$file: type ($type) already specificed as an unlimited type\n");
80 } elsif(!$$allowed_modules{$type}{$module}) {
81 $$allowed_modules{$type}{$module} = 1;
82 $$allowed_modules_limited{$type} = 1;
84 $$output->write("$file: type ($type) already specificed\n");
87 $$allowed_modules_unlimited{$type} = 1;
90 $$allowed_modules_limited{$type} = 1;
92 if(defined($$translate_argument{$type}) && $$translate_argument{$type} ne $kind) {
93 $$output->write("$file: type ($type) respecified as different kind ($kind != $$translate_argument{$type})\n");
95 $$translate_argument{$type} = $kind;
98 $$output->write("$file: file must begin with %<type> statement\n");
105 sub get_spec_file_type
{
107 my $class = ref($proto) || $proto;
113 open(IN
, "< $file") || die "$file: $!\n";
116 if(/^type\s*(\w+)/) {
126 sub read_spec_files
{
128 my $class = ref($proto) || $proto;
131 my $file_type = shift;
132 my $win16api = shift;
133 my $win32api = shift;
137 if(&$file_type($_) eq "library") {
142 } split(/\n/, `find $path -name \\*.spec`);
144 foreach my $file (@files) {
145 my $type = 'winapi'->get_spec_file_type($file);
146 if($type eq "win16") {
147 $win16api->parse_spec_file($file);
148 } elsif($type eq "win32") {
149 $win32api->parse_spec_file($file);
154 sub parse_spec_file
{
157 my $options = \
${$self->{OPTIONS
}};
158 my $output = \
${$self->{OUTPUT
}};
159 my $function_arguments = \
%{$self->{FUNCTION_ARGUMENTS
}};
160 my $function_calling_convention = \
%{$self->{FUNCTION_CALLING_CONVENTION
}};
161 my $function_stub = \
%{$self->{FUNCTION_STUB
}};
162 my $function_module = \
%{$self->{FUNCTION_MODULE
}};
163 my $modules = \
%{$self->{MODULES
}};
171 if($$options->progress) {
172 $$output->progress("$file");
175 open(IN
, "< $file") || die "$file: $!\n";
179 while($lookahead || defined($_ = <IN
>)) {
186 if(/^name\s*(\S*)/) { $module = $1; }
187 if(/^type\s*(\w+)/) { $type = $1; }
188 if(/^\d+|@/) { $header = 0; $lookahead = 1; }
193 if(/^(\d+|@)\s+(pascal|pascal16|stdcall|cdecl|register|interrupt|varargs)\s+(\S+)\s*\(\s*(.*?)\s*\)\s*(\S+)$/) {
194 my $calling_convention = $2;
195 my $external_name = $3;
197 my $internal_name = $5;
201 # FIXME: Internal name existing more than once not handled properly
202 $$function_arguments{$internal_name} = $arguments;
203 $$function_calling_convention{$internal_name} = $calling_convention;
204 if(!$$function_module{$internal_name}) {
205 $$function_module{$internal_name} = "$module";
206 } elsif($$function_module{$internal_name} !~ /$module/) {
207 $$function_module{$internal_name} .= " & $module";
210 if($$options->spec_mismatch) {
211 if($external_name eq "@") {
212 if($internal_name !~ /^\U$module\E_$ordinal$/) {
213 $$output->write("$file: $external_name: the internal name ($internal_name) mismatch\n");
216 my $name = $external_name;
222 $name2 =~ s/^(?:_|Rtl|k32|K32)//;
225 $name3 =~ s/^INT_Int[0-9a-f]{2}Handler$/BUILTIN_DefaultIntHandler/;
228 $name4 =~ s/^(VxDCall)\d$/$1/;
230 # FIXME: This special case is becuase of a very ugly kludge that should be fixed IMHO
232 $name5 =~ s/^(.*?16)_(.*?)$/$1_fn$2/;
234 if(uc($internal_name) ne uc($external_name) &&
235 $internal_name !~ /(\Q$name\E|\Q$name1\E|\Q$name2\E|\Q$name3\E|\Q$name4\E|\Q$name5\E)/)
237 $$output->write("$file: $external_name: internal name ($internal_name) mismatch\n");
241 } elsif(/^(\d+|@)\s+stub\s+(\S+)$/) {
242 my $external_name = $2;
247 if($type eq "win16") {
248 $internal_name = $external_name . "16";
250 $internal_name = $external_name;
253 # FIXME: Internal name existing more than once not handled properly
254 $$function_stub{$internal_name} = 1;
255 if(!$$function_module{$internal_name}) {
256 $$function_module{$internal_name} = "$module";
257 } elsif($$function_module{$internal_name} !~ /$module/) {
258 $$function_module{$internal_name} .= " & $module";
260 } elsif(/^(\d+|@)\s+(equate|long|word|extern|forward)/) {
263 my $next_line = <IN
>;
264 if(!defined($next_line) || $next_line =~ /^\s*\d|@/) {
265 die "$file: $.: syntax error: '$_'\n";
272 if(defined($ordinal)) {
273 if($ordinal ne "@" && $ordinals{$ordinal}) {
274 $$output->write("$file: ordinal redefined: $_\n");
276 $ordinals{$ordinal}++;
281 $$modules{$module}++;
286 my $name = \
${$self->{NAME
}};
291 sub is_allowed_kind
{
293 my $allowed_kind = \
%{$self->{ALLOWED_KIND
}};
297 return $$allowed_kind{$kind};
303 sub is_limited_type
{
305 my $allowed_modules_limited = \
%{$self->{ALLOWED_MODULES_LIMITED
}};
309 return $$allowed_modules_limited{$type};
312 sub allowed_type_in_module
{
314 my $allowed_modules = \
%{$self->{ALLOWED_MODULES
}};
315 my $allowed_modules_limited = \
%{$self->{ALLOWED_MODULES_LIMITED
}};
318 my @modules = split(/ \& /, shift);
320 if(!$$allowed_modules_limited{$type}) { return 1; }
322 foreach my $module (@modules) {
323 if($$allowed_modules{$type}{$module}) { return 1; }
329 sub type_used_in_module
{
331 my $used_modules = \
%{$self->{USED_MODULES
}};
334 my @modules = split(/ \& /, shift);
336 foreach my $module (@modules) {
337 $$used_modules{$type}{$module} = 1;
345 my $used_modules = \
%{$self->{USED_MODULES
}};
346 my $allowed_modules = \
%{$self->{ALLOWED_MODULES
}};
349 foreach my $type (sort(keys(%$allowed_modules))) {
350 foreach my $module (sort(keys(%{$$allowed_modules{$type}}))) {
351 if(!$$used_modules{$type}{$module}) {
352 $$not_used{$module}{$type} = 1;
359 sub types_unlimited_used_in_modules
{
362 my $output = \
${$self->{OUTPUT
}};
363 my $used_modules = \
%{$self->{USED_MODULES
}};
364 my $allowed_modules = \
%{$self->{ALLOWED_MODULES
}};
365 my $allowed_modules_unlimited = \
%{$self->{ALLOWED_MODULES_UNLIMITED
}};
368 foreach my $type (sort(keys(%$allowed_modules_unlimited))) {
371 foreach my $module (sort(keys(%{$$used_modules{$type}}))) {
373 push @modules, $module;
376 foreach my $module (@modules) {
377 $$used_types{$type}{$module} = 1;
384 sub translate_argument
{
386 my $translate_argument = \
%{$self->{TRANSLATE_ARGUMENT
}};
388 my $argument = shift;
390 return $$translate_argument{$argument};
393 sub all_declared_types
{
395 my $translate_argument = \
%{$self->{TRANSLATE_ARGUMENT
}};
397 return sort(keys(%$translate_argument));
402 my $type_found = \
%{$self->{TYPE_FOUND
}};
406 $$type_found{$name}++;
411 my $type_found= \
%{$self->{TYPE_FOUND
}};
415 return $$type_found{$name};
420 my $modules = \
%{$self->{MODULES
}};
422 return sort(keys(%$modules));
427 my $function_calling_convention = \
%{$self->{FUNCTION_CALLING_CONVENTION
}};
429 return sort(keys(%$function_calling_convention));
432 sub all_functions_stub
{
434 my $function_stub = \
%{$self->{FUNCTION_STUB
}};
436 return sort(keys(%$function_stub));
439 sub all_functions_found
{
441 my $function_found = \
%{$self->{FUNCTION_FOUND
}};
443 return sort(keys(%$function_found));
446 sub function_calling_convention
{
448 my $function_calling_convention = \
%{$self->{FUNCTION_CALLING_CONVENTION
}};
452 return $$function_calling_convention{$name};
457 my $function_calling_convention = \
%{$self->{FUNCTION_CALLING_CONVENTION
}};
461 return $$function_calling_convention{$name};
464 sub is_shared_function
{
466 my $function_shared = \
%{$self->{FUNCTION_SHARED
}};
470 return $$function_shared{$name};
473 sub found_shared_function
{
475 my $function_shared = \
%{$self->{FUNCTION_SHARED
}};
479 $$function_shared{$name} = 1;
482 sub function_arguments
{
484 my $function_arguments = \
%{$self->{FUNCTION_ARGUMENTS
}};
488 return $$function_arguments{$name};
491 sub function_module
{
493 my $function_module = \
%{$self->{FUNCTION_MODULE
}};
497 return $$function_module{$name};
502 my $function_stub = \
%{$self->{FUNCTION_STUB
}};
506 return $$function_stub{$name};
511 my $function_found = \
%{$self->{FUNCTION_FOUND
}};
515 $$function_found{$name}++;
520 my $function_found = \
%{$self->{FUNCTION_FOUND
}};
524 return $$function_found{$name};