- Made the new C parser handle the current Wine source.
- Added a compabillity layer between the old and the new C parser.
- Added parsing of data structures.
diff --git a/tools/winapi/winapi_extract b/tools/winapi/winapi_extract
index ccf3bec..c66b2c9 100755
--- a/tools/winapi/winapi_extract
+++ b/tools/winapi/winapi_extract
@@ -37,11 +37,13 @@
$output->disable_progress;
}
+use c_parser;
use function;
use type;
-use winapi_function;
-use winapi_parser;
+
use winapi qw($win16api $win32api @winapis);
+use winapi_c_parser;
+use winapi_function;
my %module2entries;
my %module2spec_file;
@@ -174,8 +176,15 @@
}
}
+my @h_files = ();
+if($options->headers) {
+ @h_files = $options->h_files;
+ @h_files = files_skip(@h_files);
+ @h_files = files_filter("winelib", @h_files);
+}
+
my @c_files = ();
-if($options->spec_files || $options->pseudo_stub_statistics) {
+if(1 || $options->spec_files || $options->pseudo_stub_statistics) {
@c_files = $options->c_files;
@c_files = files_skip(@c_files);
@c_files = files_filter("winelib", @c_files);
@@ -183,77 +192,148 @@
my $progress_output;
my $progress_current = 0;
-my $progress_max = scalar(@c_files);
+my $progress_max = scalar(@h_files) + scalar(@c_files);
-foreach my $file (@c_files) {
+foreach my $file (@h_files, @c_files) {
my %functions;
$progress_current++;
- $output->progress("$file (file $progress_current of $progress_max)");
- my $create_function = sub {
- if($options->stub_statistics) {
- return 'winapi_function'->new;
+ {
+ open(IN, "< $file");
+ local $/ = undef;
+ $_ = <IN>;
+ close(IN);
+ }
+
+ my $max_line = 0;
+ {
+ local $_ = $_;
+ while(s/^.*?\n//) { $max_line++; }
+ if($_) { $max_line++; }
+ }
+
+ my $parser;
+ if (!$options->old) {
+ $parser = new c_parser($file);
+ } else {
+ $parser = new winapi_c_parser($file);
+ }
+
+ my $function;
+ my $line;
+
+ my $update_output = sub {
+ my $progress = "";
+ my $prefix = "";
+
+ $progress .= "$file (file $progress_current of $progress_max)";
+ $prefix .= "$file:";
+
+ if(defined($function)) {
+ my $name = $function->name;
+ my $begin_line = $function->begin_line;
+ my $begin_column = $function->begin_column;
+
+ $progress .= ": function $name";
+ $prefix .= "$begin_line.$begin_column: function $name: ";
} else {
- return 'function'->new;
+ $prefix .= " ";
}
+
+ if(defined($line)) {
+ $progress .= ": line $line of $max_line";
+ }
+
+ $output->progress($progress);
+ $output->prefix($prefix);
};
+ &$update_output();
+
my $found_function = sub {
- my $function = shift;
+ $function = shift;
- my $internal_name = $function->internal_name;
- $functions{$internal_name} = $function;
+ my $name = $function->name;
+ $functions{$name} = $function;
- $output->progress("$file (file $progress_current of $progress_max): $internal_name");
- $output->prefix_callback(sub { return $function->prefix; });
+ &$update_output();
- my $documentation_line = $function->documentation_line;
- my $documentation = $function->documentation;
- my $function_line = $function->function_line;
- my $linkage = $function->linkage;
- my $return_type = $function->return_type;
- my $calling_convention = $function->calling_convention;
- my $statements = $function->statements;
+ my $old_function;
+ if($options->stub_statistics) {
+ $old_function = 'winapi_function'->new;
+ } else {
+ $old_function = 'function'->new;
+ }
+
+ $function->file($file);
+ $old_function->debug_channels([]); # FIXME: Not complete
+
+ $old_function->documentation_line(0); # FIXME: Not complete
+ $old_function->documentation(""); # FIXME: Not complete
+
+ $old_function->function_line($function->begin_line());
+ $old_function->linkage($function->linkage);
+ $old_function->return_type($function->return_type);
+ $old_function->calling_convention($function->calling_convention);
+ $old_function->internal_name($function->name);
+ if (defined($function->argument_types)) {
+ $old_function->argument_types([@{$function->argument_types}]);
+ }
+ if (defined($function->argument_names)) {
+ $old_function->argument_names([@{$function->argument_names}]);
+ }
+ $old_function->argument_documentations([]); # FIXME: Not complete
+ $old_function->statements_line($function->statements_line);
+ $old_function->statements($function->statements);
if($options->spec_files || $options->winetest) {
- documentation_specifications($function);
+ documentation_specifications($old_function);
}
if($options->stub_statistics) {
- statements_stub($function);
+ statements_stub($old_function);
}
- $output->prefix("");
+ $function = undef;
+ &$update_output();
};
-
- my $create_type = sub {
- return 'type'->new;
- };
+ $parser->set_found_function_callback($found_function);
my $found_type = sub {
my $type = shift;
+
+ &$update_output();
+
+ my $kind = $type->kind;
+ my $_name = $type->_name;
+ my $name = $type->name;
+
+ foreach my $field ($type->fields) {
+ (my $field_type, my $field_name) = @$field;
+
+ if ($options->struct) {
+ if ($name) {
+ $output->write("$name:$field_type:$field_name\n");
+ } else {
+ $output->write("$kind $_name:$field_type:$field_name\n");
+ }
+ }
+ }
+
+ return 1;
};
+ $parser->set_found_type_callback($found_type);
- my $found_preprocessor = sub {
- my $directive = shift;
- my $argument = shift;
- };
-
- &winapi_parser::parse_c_file($file, {
- # c_comment_found => $found_c_comment,
- # cplusplus_comment_found => $found_cplusplus_comment,
- function_create => $create_function,
- function_found => $found_function,
- type_create => $create_type,
- type_found => $found_type,
- preprocessor_found => $found_preprocessor
- });
-
- my @internal_names = keys(%functions);
- if($#internal_names < 0) {
- $output->write("$file: doesn't contain any functions\n");
+ {
+ my $line = 1;
+ my $column = 0;
+ if(!$parser->parse_c_file(\$_, \$line, \$column)) {
+ $output->write("can't parse file\n");
+ }
}
+
+ $output->prefix("");
}
sub output_function {