7 my $class = ref($proto) || $proto;
11 my $output = \${$self->{OUTPUT}};
12 my $name = \${$self->{NAME}};
19 $file =~ s/^.\/(.*)$/$1/;
20 $self->parse_api_file($file);
25 } split(/\n/, `find $path -name \\*.api`);
27 foreach my $file (@files) {
29 $module =~ s/.*?\/([^\/]*?)\.api$/$1/;
30 $self->parse_api_file($file,$module);
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}};
51 $$output->progress("$file");
53 open(IN, "< $file") || die "$file: $!\n";
56 s/^\s*?(.*?)\s*$/$1/; # remove whitespace at begin and end of line
57 s/^(.*?)\s*#.*$/$1/; # remove comments
58 /^$/ && next; # skip empty lines
64 $$allowed_kind{$kind} = 1;
68 } elsif(defined($kind)) {
71 if(defined($module)) {
72 if($$allowed_modules_unlimited{$type}) {
73 $$output->write("$file: type ($type) already specificed as an unlimited type\n");
74 } elsif(!$$allowed_modules{$type}{$module}) {
75 $$allowed_modules{$type}{$module} = 1;
76 $$allowed_modules_limited{$type} = 1;
78 $$output->write("$file: type ($type) already specificed\n");
81 $$allowed_modules_unlimited{$type} = 1;
84 $$allowed_modules_limited{$type} = 1;
86 if(defined($$translate_argument{$type}) && $$translate_argument{$type} ne $kind) {
87 $$output->write("$file: type ($type) respecified as different kind ($kind != $$translate_argument{$type})\n");
89 $$translate_argument{$type} = $kind;
92 $$output->write("$file: file must begin with %<type> statement\n");
99 sub get_spec_file_type {
101 my $class = ref($proto) || $proto;
107 open(IN, "< $file") || die "$file: $!\n";
110 if(/^type\s*(\w+)/) {
120 sub read_spec_files {
122 my $class = ref($proto) || $proto;
125 my $win16api = shift;
126 my $win32api = shift;
131 } split(/\n/, `find $path -name \\*.spec`);
133 foreach my $file (@files) {
134 my $type = 'winapi'->get_spec_file_type($file);
135 if($type eq "win16") {
136 $win16api->parse_spec_file($file);
137 } elsif($type eq "win32") {
138 $win32api->parse_spec_file($file);
143 sub parse_spec_file {
146 my $output = \${$self->{OUTPUT}};
147 my $function_arguments = \%{$self->{FUNCTION_ARGUMENTS}};
148 my $function_calling_convention = \%{$self->{FUNCTION_CALLING_CONVENTION}};
149 my $function_stub = \%{$self->{FUNCTION_STUB}};
150 my $function_module = \%{$self->{FUNCTION_MODULE}};
159 $$output->progress("$file");
161 open(IN, "< $file") || die "$file: $!\n";
165 while($lookahead || defined($_ = <IN>)) {
172 if(/^name\s*(\S*)/) { $module = $1; }
173 if(/^\d+/) { $header = 0 };
178 if(/^(\d+)\s+(pascal|pascal16|stdcall|cdecl|register|interrupt|varargs)\s+(\S+)\s*\(\s*(.*?)\s*\)\s*(\S+)$/) {
179 my $calling_convention = $2;
180 my $external_name = $3;
182 my $internal_name = $5;
186 # FIXME: Internal name existing more than once not handled properly
187 $$function_arguments{$internal_name} = $arguments;
188 $$function_calling_convention{$internal_name} = $calling_convention;
189 $$function_module{$internal_name} = "$module";
190 } elsif(/^(\d+)\s+stub\s+(\S+)$/) {
191 my $external_name = $2;
195 $$function_stub{$external_name} = 1;
196 $$function_module{$external_name} = $module;
197 } elsif(/^\d+\s+(equate|long|word|extern|forward)/) {
200 my $next_line = <IN>;
201 if($next_line =~ /^\d/) {
202 die "$file: $.: syntax error: '$_'\n";
209 if(defined($ordinal)) {
210 if($ordinals{$ordinal}) {
211 $$output->write("$file: ordinal redefined: $_\n");
213 $ordinals{$ordinal}++;
221 my $name = \${$self->{NAME}};
226 sub is_allowed_kind {
228 my $allowed_kind = \%{$self->{ALLOWED_KIND}};
232 return $$allowed_kind{$kind};
238 sub is_limited_type {
240 my $allowed_modules_limited = \%{$self->{ALLOWED_MODULES_LIMITED}};
244 return $$allowed_modules_limited{$type};
247 sub allowed_type_in_module {
249 my $allowed_modules = \%{$self->{ALLOWED_MODULES}};
250 my $allowed_modules_limited = \%{$self->{ALLOWED_MODULES_LIMITED}};
255 return !$$allowed_modules_limited{$type} || $$allowed_modules{$type}{$module};
258 sub type_used_in_module {
260 my $used_modules = \%{$self->{USED_MODULES}};
265 $$used_modules{$type}{$module} = 1;
272 my $used_modules = \%{$self->{USED_MODULES}};
273 my $allowed_modules = \%{$self->{ALLOWED_MODULES}};
276 foreach my $type (sort(keys(%$allowed_modules))) {
277 foreach my $module (sort(keys(%{$$allowed_modules{$type}}))) {
278 if(!$$used_modules{$type}{$module}) {
279 $$not_used{$module}{$type} = 1;
286 sub translate_argument {
288 my $translate_argument = \%{$self->{TRANSLATE_ARGUMENT}};
290 my $argument = shift;
292 return $$translate_argument{$argument};
295 sub all_declared_types {
297 my $translate_argument = \%{$self->{TRANSLATE_ARGUMENT}};
299 return sort(keys(%$translate_argument));
304 my $type_found = \%{$self->{TYPE_FOUND}};
308 $$type_found{$name}++;
313 my $type_found= \%{$self->{TYPE_FOUND}};
317 return $$type_found{$name};
322 my $function_calling_convention = \%{$self->{FUNCTION_CALLING_CONVENTION}};
324 return sort(keys(%$function_calling_convention));
327 sub all_functions_found {
329 my $function_found = \%{$self->{FUNCTION_FOUND}};
331 return sort(keys(%$function_found));
334 sub function_calling_convention {
336 my $function_calling_convention = \%{$self->{FUNCTION_CALLING_CONVENTION}};
340 return $$function_calling_convention{$name};
345 my $function_calling_convention = \%{$self->{FUNCTION_CALLING_CONVENTION}};
349 return $$function_calling_convention{$name};
352 sub is_shared_function {
354 my $function_shared = \%{$self->{FUNCTION_SHARED}};
358 return $$function_shared{$name};
361 sub found_shared_function {
363 my $function_shared = \%{$self->{FUNCTION_SHARED}};
367 $$function_shared{$name} = 1;
370 sub function_arguments {
372 my $function_arguments = \%{$self->{FUNCTION_ARGUMENTS}};
376 return $$function_arguments{$name};
379 sub function_module {
381 my $function_module = \%{$self->{FUNCTION_MODULE}};
385 return $$function_module{$name};
390 my $function_stub = \%{$self->{FUNCTION_STUB}};
394 return $$function_stub{$name};
399 my $function_found = \%{$self->{FUNCTION_FOUND}};
403 $$function_found{$name}++;
408 my $function_found = \%{$self->{FUNCTION_FOUND}};
412 return $$function_found{$name};