changeset 356:599ad98aee00

update gearsTools/lib
author anatofuz <anatofuz@cr.ie.u-ryukyu.ac.jp>
date Mon, 15 Jun 2020 18:29:09 +0900
parents 045299ad7e97
children e194c940c664
files src/gearsTools/lib/Gears/Context.pm src/gearsTools/lib/Gears/Util.pm
diffstat 2 files changed, 76 insertions(+), 14 deletions(-) [+]
line wrap: on
line diff
--- a/src/gearsTools/lib/Gears/Context.pm	Mon Jun 15 18:27:09 2020 +0900
+++ b/src/gearsTools/lib/Gears/Context.pm	Mon Jun 15 18:29:09 2020 +0900
@@ -4,7 +4,9 @@
 use warnings;
 
 use Gears::Util;
-use Gears::Context::Template::XV6;
+
+use Module::Load qw/load/;
+
 use Carp qw/croak carp/;
 
 sub new {
@@ -12,7 +14,8 @@
   my $self = {
     data_gears_with_count => {},
     find_root => $args{find_root} // ".",
-    output   => $args{output},
+    output    => $args{output},
+    template  => $args{template}  // "Gears::Context::Template",
   };
 
   if ($args{compile_sources}) {
@@ -63,12 +66,24 @@
 sub tree2create_context_h {
   my ($self, $dg2path) = @_;
 
-  my $data_struct_str = $dg2path ? $self->tree2data_struct_str($dg2path) : "\n";
+
+  unless ($dg2path) {
+    croak "require ast at tree2create_context_h";
+  }
+
+  my $template = $self->{template};
+  load $template;
+
+  my ($data_struct_str, $from_header_to_caller) = $self->tree2data_struct_str($dg2path);
 
   my $output = $self->_select_output();
-  Gears::Context::Template::XV6->emit_top_header($output);
-  Gears::Context::Template::XV6->emit_data_gears($output,$data_struct_str);
-  Gears::Context::Template::XV6->emit_last_header($output);
+  $template->emit_top_header($output);
+  if (%{$from_header_to_caller}) {
+    $template->emit_include_header($output,$from_header_to_caller);
+  }
+  $template->emit_start_context($output);
+  $template->emit_data_gears($output,$data_struct_str);
+  $template->emit_last_header($output);
   close $output;
 }
 
@@ -82,17 +97,41 @@
   return $fh;
 }
 
+
+# Generate a header with include file list from a structure's tree structure
 sub tree2data_struct_str {
   my ($self, $dg_str) = @_;
+  my %from_header_to_caller;
+
   my $data_struct_str  = "";
   for my $interface (sort keys %$dg_str) {
-    $data_struct_str .= $self->h2context_str_w_macro($dg_str->{$interface}->{elem});
-    next unless ($dg_str->{$interface}->{impl});
-    for my $impl (sort keys %{$dg_str->{$interface}->{impl}}) {
-       $data_struct_str .= $self->h2context_str_w_macro($dg_str->{$interface}->{impl}->{$impl});
+    my $elem = $dg_str->{$interface}->{elem};
+    $data_struct_str .= $self->h2context_str_w_macro($elem);
+
+    for my $header (_find_include_header_each_cbc($elem)) {
+      push(@{$from_header_to_caller{$header}},$elem->{file_name});
+    }
+
+    my $root_impl = $dg_str->{$interface}->{impl};
+
+    next unless ($root_impl);
+    for my $impl_name (sort keys %{$root_impl}) {
+      my $impl = $root_impl->{$impl_name};
+      $data_struct_str .= $self->h2context_str_w_macro($impl);
+      for my $header (_find_include_header_each_cbc($impl)) {
+        push(@{$from_header_to_caller{$header}},$impl->{file_name});
+      }
     }
   }
-  return $data_struct_str;
+  return $data_struct_str, \%from_header_to_caller;
+}
+
+sub _find_include_header_each_cbc {
+  my $ir = shift;
+  unless (exists $ir->{cbc_context_include_headers}) {
+   return ();
+  }
+   return @{$ir->{cbc_context_include_headers}};
 }
 
 sub createImplTree_from_header {
@@ -118,6 +157,7 @@
       }
     }
   } keys %$impls;
+
   return \%dg_str;
 }
 
--- a/src/gearsTools/lib/Gears/Util.pm	Mon Jun 15 18:27:09 2020 +0900
+++ b/src/gearsTools/lib/Gears/Util.pm	Mon Jun 15 18:29:09 2020 +0900
@@ -16,7 +16,7 @@
   my $ir = _parse_base($file_name);
   
   unless ($ir->{name}) {
-    croak 'invalid struct name';
+    croak "invalid struct name $file_name";
   }
   return $ir;
 }
@@ -32,6 +32,28 @@
   my $line = <$fh>;
   my $static_data_gear_write_mode = 0;
 
+  my $directory_containing_file = "";
+
+  if ($file  =~ m<([\.\w/]+)/\w+\.(?:cbc|h|c)>) {
+     $directory_containing_file = $1;
+  }
+
+
+  while ($line =~ /#include\s+"([\w\/\.]+)"/) {
+    my $header_file = $1;
+    if ($header_file =~ m|\./context\.h|) {
+      next;
+     }
+    push(@{$ir->{cbc_context_include_headers}}, "$directory_containing_file/$header_file");
+    $line = <$fh>;
+  }
+
+  # skip space
+
+  while ($line =~ /^\s*$/) {
+    $line = <$fh>;
+  }
+
   if ($line =~ /typedef struct (\w+)\s?<.*>([\s\w{]+)/) {
     die "invalied struct name $1" unless $1;
     $ir->{name} = $1;
@@ -63,12 +85,12 @@
       next if $static_data_gear_write_mode;
       my $args = $';
       #$args eq  (Impl* vm, pde_t* pgdir, char* init, uint sz, __code next(...));
-      while ($args =~ /\s*(struct|union|const)?\s*([\w*\[\]_]+)\s*(\w+),?/g) {
+      while ($args =~ /\s*(struct|union|const|enum)?\s*([\w*\[\]_]+)\s*(\w+),?/g) {
         my $const_type = $1;
         my $type = $2;
         my $vname = $3;
         next if ($type eq '__code');
-        $type =~ s/(?:Impl|Type|Isa)\s*(\*)?/union Data$1/;
+        $type =~ s/^(?:Impl|Type|Isa)\s*(\*)?/union Data$1/;
         my $val = "$type $vname;\n";
         push(@tmp_args, $const_type ?  "$const_type $val" : $val);
       }