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);
36 my $output = \
${$self->{OUTPUT
}};
37 my $allowed_kind = \
%{$self->{ALLOWED_KIND
}};
38 my $allowed_modules = \
%{$self->{ALLOWED_MODULES
}};
39 my $allowed_modules_limited = \
%{$self->{ALLOWED_MODULES_LIMITED
}};
40 my $allowed_modules_unlimited = \
%{$self->{ALLOWED_MODULES_UNLIMITED
}};
41 my $translate_argument = \
%{$self->{TRANSLATE_ARGUMENT
}};
50 $$output->progress("$file");
52 open(IN
, "< $file") || die "$file: $!\n";
55 s/^\s*?(.*?)\s*$/$1/; # remove whitespace at begin and end of line
56 s/^(.*?)\s*#.*$/$1/; # remove comments
57 /^$/ && next; # skip empty lines
64 $$allowed_kind{$kind} = 1;
67 } elsif(/^--extension/) {
70 } elsif(defined($kind)) {
73 if(defined($module)) {
74 if($$allowed_modules_unlimited{$type}) {
75 $$output->write("$file: type ($type) already specificed as an unlimited type\n");
76 } elsif(!$$allowed_modules{$type}{$module}) {
77 $$allowed_modules{$type}{$module} = 1;
78 $$allowed_modules_limited{$type} = 1;
80 $$output->write("$file: type ($type) already specificed\n");
83 $$allowed_modules_unlimited{$type} = 1;
86 $$allowed_modules_limited{$type} = 1;
88 if(defined($$translate_argument{$type}) && $$translate_argument{$type} ne $kind) {
89 $$output->write("$file: type ($type) respecified as different kind ($kind != $$translate_argument{$type})\n");
91 $$translate_argument{$type} = $kind;
94 $$output->write("$file: file must begin with %<type> statement\n");
101 sub get_spec_file_type
{
103 my $class = ref($proto) || $proto;
109 open(IN
, "< $file") || die "$file: $!\n";
112 if(/^type\s*(\w+)/) {
122 sub read_spec_files
{
124 my $class = ref($proto) || $proto;
127 my $win16api = shift;
128 my $win32api = shift;
133 } split(/\n/, `find $path -name \\*.spec`);
135 foreach my $file (@files) {
136 my $type = 'winapi'->get_spec_file_type($file);
137 if($type eq "win16") {
138 $win16api->parse_spec_file($file);
139 } elsif($type eq "win32") {
140 $win32api->parse_spec_file($file);
145 sub parse_spec_file
{
148 my $options = \
${$self->{OPTIONS
}};
149 my $output = \
${$self->{OUTPUT
}};
150 my $function_arguments = \
%{$self->{FUNCTION_ARGUMENTS
}};
151 my $function_calling_convention = \
%{$self->{FUNCTION_CALLING_CONVENTION
}};
152 my $function_stub = \
%{$self->{FUNCTION_STUB
}};
153 my $function_module = \
%{$self->{FUNCTION_MODULE
}};
161 $$output->progress("$file");
163 open(IN
, "< $file") || die "$file: $!\n";
167 while($lookahead || defined($_ = <IN
>)) {
174 if(/^name\s*(\S*)/) { $module = $1; }
175 if(/^type\s*(\w+)/) { $type = $1; }
176 if(/^\d+|@/) { $header = 0 };
181 if(/^(\d+|@)\s+(pascal|pascal16|stdcall|cdecl|register|interrupt|varargs)\s+(\S+)\s*\(\s*(.*?)\s*\)\s*(\S+)$/) {
182 my $calling_convention = $2;
183 my $external_name = $3;
185 my $internal_name = $5;
189 # FIXME: Internal name existing more than once not handled properly
190 $$function_arguments{$internal_name} = $arguments;
191 $$function_calling_convention{$internal_name} = $calling_convention;
192 if(!$$function_module{$internal_name}) {
193 $$function_module{$internal_name} = "$module";
194 } elsif($$function_module{$internal_name} !~ /$module/) {
195 $$function_module{$internal_name} .= " & $module";
198 if($$options->spec_mismatch) {
199 if($external_name eq "@") {
200 if($internal_name !~ /^\U$module\E_$ordinal$/) {
201 $$output->write("$file: $external_name: the internal name ($internal_name) mismatch\n");
204 my $name = $external_name;
210 $name2 =~ s/^(?:_|Rtl|k32|K32)//;
213 $name3 =~ s/^INT_Int[0-9a-f]{2}Handler$/BUILTIN_DefaultIntHandler/;
216 $name4 =~ s/^(VxDCall)\d$/$1/;
218 # FIXME: This special case is becuase of a very ugly kludge that should be fixed IMHO
220 $name5 =~ s/^(.*?16)_(.*?)$/$1_fn$2/;
222 if(uc($internal_name) ne uc($external_name) &&
223 $internal_name !~ /(\Q$name\E|\Q$name1\E|\Q$name2\E|\Q$name3\E|\Q$name4\E|\Q$name5\E)/)
225 $$output->write("$file: $external_name: internal name ($internal_name) mismatch\n");
229 } elsif(/^(\d+|@)\s+stub\s+(\S+)$/) {
230 my $external_name = $2;
235 if($type eq "win16") {
236 $internal_name = $external_name . "16";
238 $internal_name = $external_name;
241 # FIXME: Internal name existing more than once not handled properly
242 $$function_stub{$internal_name} = 1;
243 if(!$$function_module{$internal_name}) {
244 $$function_module{$internal_name} = "$module";
245 } elsif($$function_module{$internal_name} !~ /$module/) {
246 $$function_module{$internal_name} .= " & $module";
248 } elsif(/^(\d+|@)\s+(equate|long|word|extern|forward)/) {
251 my $next_line = <IN
>;
252 if($next_line =~ /^\d|@/) {
253 die "$file: $.: syntax error: '$_'\n";
260 if(defined($ordinal)) {
261 if($ordinal ne "@" && $ordinals{$ordinal}) {
262 $$output->write("$file: ordinal redefined: $_\n");
264 $ordinals{$ordinal}++;
272 my $name = \
${$self->{NAME
}};
277 sub is_allowed_kind
{
279 my $allowed_kind = \
%{$self->{ALLOWED_KIND
}};
283 return $$allowed_kind{$kind};
289 sub is_limited_type
{
291 my $allowed_modules_limited = \
%{$self->{ALLOWED_MODULES_LIMITED
}};
295 return $$allowed_modules_limited{$type};
298 sub allowed_type_in_module
{
300 my $allowed_modules = \
%{$self->{ALLOWED_MODULES
}};
301 my $allowed_modules_limited = \
%{$self->{ALLOWED_MODULES_LIMITED
}};
304 my @modules = split(/ \& /, shift);
306 if(!$$allowed_modules_limited{$type}) { return 1; }
308 foreach my $module (@modules) {
309 if($$allowed_modules{$type}{$module}) { return 1; }
315 sub type_used_in_module
{
317 my $used_modules = \
%{$self->{USED_MODULES
}};
320 my @modules = split(/ \& /, shift);
322 foreach my $module (@modules) {
323 $$used_modules{$type}{$module} = 1;
331 my $used_modules = \
%{$self->{USED_MODULES
}};
332 my $allowed_modules = \
%{$self->{ALLOWED_MODULES
}};
335 foreach my $type (sort(keys(%$allowed_modules))) {
336 foreach my $module (sort(keys(%{$$allowed_modules{$type}}))) {
337 if(!$$used_modules{$type}{$module}) {
338 $$not_used{$module}{$type} = 1;
345 sub types_unlimited_used_in_modules
{
348 my $output = \
${$self->{OUTPUT
}};
349 my $used_modules = \
%{$self->{USED_MODULES
}};
350 my $allowed_modules = \
%{$self->{ALLOWED_MODULES
}};
351 my $allowed_modules_unlimited = \
%{$self->{ALLOWED_MODULES_UNLIMITED
}};
354 foreach my $type (sort(keys(%$allowed_modules_unlimited))) {
357 foreach my $module (sort(keys(%{$$used_modules{$type}}))) {
359 push @modules, $module;
362 foreach my $module (@modules) {
363 $$used_types{$type}{$module} = 1;
370 sub translate_argument
{
372 my $translate_argument = \
%{$self->{TRANSLATE_ARGUMENT
}};
374 my $argument = shift;
376 return $$translate_argument{$argument};
379 sub all_declared_types
{
381 my $translate_argument = \
%{$self->{TRANSLATE_ARGUMENT
}};
383 return sort(keys(%$translate_argument));
388 my $type_found = \
%{$self->{TYPE_FOUND
}};
392 $$type_found{$name}++;
397 my $type_found= \
%{$self->{TYPE_FOUND
}};
401 return $$type_found{$name};
406 my $function_calling_convention = \
%{$self->{FUNCTION_CALLING_CONVENTION
}};
408 return sort(keys(%$function_calling_convention));
411 sub all_functions_stub
{
413 my $function_stub = \
%{$self->{FUNCTION_STUB
}};
415 return sort(keys(%$function_stub));
418 sub all_functions_found
{
420 my $function_found = \
%{$self->{FUNCTION_FOUND
}};
422 return sort(keys(%$function_found));
425 sub function_calling_convention
{
427 my $function_calling_convention = \
%{$self->{FUNCTION_CALLING_CONVENTION
}};
431 return $$function_calling_convention{$name};
436 my $function_calling_convention = \
%{$self->{FUNCTION_CALLING_CONVENTION
}};
440 return $$function_calling_convention{$name};
443 sub is_shared_function
{
445 my $function_shared = \
%{$self->{FUNCTION_SHARED
}};
449 return $$function_shared{$name};
452 sub found_shared_function
{
454 my $function_shared = \
%{$self->{FUNCTION_SHARED
}};
458 $$function_shared{$name} = 1;
461 sub function_arguments
{
463 my $function_arguments = \
%{$self->{FUNCTION_ARGUMENTS
}};
467 return $$function_arguments{$name};
470 sub function_module
{
472 my $function_module = \
%{$self->{FUNCTION_MODULE
}};
476 return $$function_module{$name};
481 my $function_stub = \
%{$self->{FUNCTION_STUB
}};
485 return $$function_stub{$name};
490 my $function_found = \
%{$self->{FUNCTION_FOUND
}};
494 $$function_found{$name}++;
499 my $function_found = \
%{$self->{FUNCTION_FOUND
}};
503 return $$function_found{$name};