[glibmm] generate_wrap_init.pl: Improve it for deprecated files and sub-namespaces.



commit 9f8e635198013af8c630db74cb45c1e5951092e1
Author: Kjell Ahlstedt <kjell ahlstedt bredband net>
Date:   Tue Feb 28 15:24:29 2012 +0100

    generate_wrap_init.pl: Improve it for deprecated files and sub-namespaces.
    
    * tools/generate_wrap_init.pl.in: Note that _IS_DEPRECATED deprecates a
    whole file. Keep track of sub-namespaces for _CLASS_GOBJECT and
    _CLASS_GTKOBJECT (not just for _WRAP_GERROR). Ignore macros in comments.
    Bug #640029.

 ChangeLog                      |    9 +
 tools/generate_wrap_init.pl.in |  315 +++++++++++++++++++---------------------
 2 files changed, 155 insertions(+), 169 deletions(-)
---
diff --git a/ChangeLog b/ChangeLog
index 5284331..3c0c3d8 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,12 @@
+2012-02-28  Kjell Ahlstedt  <kjell ahlstedt bredband net>
+
+	generate_wrap_init.pl: Improve it for deprecated files and sub-namespaces.
+
+	* tools/generate_wrap_init.pl.in: Note that _IS_DEPRECATED deprecates a
+	whole file. Keep track of sub-namespaces for _CLASS_GOBJECT and
+	_CLASS_GTKOBJECT (not just for _WRAP_GERROR). Ignore macros in comments.
+	Bug #640029.
+
 2.31.18.1:
 
 2012-02-26  Josà Alburquerque  <jaalburquerque gmail com>
diff --git a/tools/generate_wrap_init.pl.in b/tools/generate_wrap_init.pl.in
index 89f9165..4f96408 100644
--- a/tools/generate_wrap_init.pl.in
+++ b/tools/generate_wrap_init.pl.in
@@ -8,46 +8,47 @@ use strict;
 my @namespace_whole = (); # list of strings.
 my $function_prefix = "";
 my $parent_dir = ""; # e.g. gtkmm
-my $path = "gtk--";
 my $debug = 0;
-my %filenames_headers = ();
-my %objects = ();
-my %exceptions = ();
-my %namespaces = (); # hashmap of lists of strings.
-my %basenames = ();
+my %objects = ();    # Hashmap of arrays of objects (classes) in each file
+my %exceptions = (); # Hashmap of arrays of exception classes in each file
 my %win32_nowrap = ();
 my %deprecated = ();
 
+# $objects{$filename_header} is a reference to an array. That array contains
+# references to arrays with two or more elements, ($cppname, $basename, @extra_namespace),
+# one reference per object defined in file $filename_header.
+# %exceptions has the same structure as %objects.
+
 sub print_with_guards
 {
-  my $object = $_[0];
+  my $file = $_[0];
   my $message = $_[1];
-  if( $deprecated{$object} eq 1 )
+  if ($deprecated{$file})
   {
     # The uc(parent_dir) is a bit of a hack. One day it will get it wrong.
     print "#ifndef " . uc($parent_dir) ."_DISABLE_DEPRECATED\n"
   }
 
-  #On Win32, these classes are not compiled:
-  if( $win32_nowrap{$object} eq 1 )
+  #On Win32, these files are not compiled:
+  if ($win32_nowrap{$file})
   {
     print "#ifndef G_OS_WIN32\n"
   }
 
   print "$message";
 
-  if( $win32_nowrap{$object} eq 1 )
+  if ($win32_nowrap{$file})
   {
     print "#endif //G_OS_WIN32\n"
   }
 
-  if( $deprecated{$object} eq 1 )
+  if ($deprecated{$file})
   {
     print "#endif // *_DISABLE_DEPRECATED\n"
   }
 }
 
-# Loop through command line arguments, setting variables:
+# Loop through command line flags, setting variables:
 while ($ARGV[0] =~ /^-/)
 {
   if ($ARGV[0] =~ /--namespace=(\S+)/)
@@ -65,13 +66,13 @@ while ($ARGV[0] =~ /^-/)
   {
     $parent_dir = "$1";
   }
-  elsif
-  (
-    $ARGV[0] =~ /--debug/) {$debug = 1;
+  elsif ($ARGV[0] =~ /--debug/)
+  {
+    $debug = 1;
   }
   elsif ($ARGV[0] =~ /--path=(\S+)/)
   {
-    $path = "$1";
+    # Do nothing. Just for backwards compatibility.
   }
   else
   {
@@ -82,118 +83,92 @@ while ($ARGV[0] =~ /^-/)
   shift @ARGV;
 }
 
-
-
+# Loop through remaining command line arguments, names of .hg files.
 while ($ARGV[0])
 {
   if ($debug) {warn "Processing file : $ARGV[0]\n";}
 
   my $filename = $ARGV[0];
-  open FILE, $filename or die "Couldn't open file $ARGV[0] : $!\n";
-
-  # my $file = $ARGV[0];
-  # $file =~ s/.*\/([^\/]+)$/$1/;
-  # $file =~ s/\.hg//;
-  my @tmpnamespace = @namespace_whole;
-  my $cppname = "";
-  my $cname = "";
-  my $ccast = "";
+  open FILE, $filename or die "Couldn't open file $filename : $!\n";
+
+  # Store header filename, so we can #include it later:
+  my $filename_header = $filename;
+  $filename_header =~ s#.*/([^/]+)\.hg#$1.h#;
+  $win32_nowrap{$filename_header} = 0;
+  $deprecated{$filename_header} = 0;
+
+  # Keep track of sub-namespaces, if any.
+  # Otherwise we can't tell the difference between Gio::Error and Gio::DBus::Error.
+  my @extra_namespace = ();
+
   while (<FILE>)
   {
+    # Skip comments.
+    # This is far from foolproof. It only skips one-line comments, and it does
+    # not try to skip quoted strings.
+    s#//.*##;
+    s#/\*.*?\*/##g;
+
     # This is useful when only some classes use a sub-namespace.
     # Alternatively, we could parse the namespace start and end parentheses,
     # but this hack is easier.
-    if (/_GMMPROC_EXTRA_NAMESPACE\((\w+)\)/)
+    if (/\b_GMMPROC_EXTRA_NAMESPACE\((\w+)\)/)
     {
       # debug: print "generate_wrap_init: namespace found: $1\n";
-      push(@tmpnamespace, $1);
+      push(@extra_namespace, $1);
     }
-    elsif (/_CLASS_GOBJECT\s*\(/) #TODO: There is duplication of code here.
+    elsif (/\b(_CLASS_GOBJECT|_CLASS_GTKOBJECT|_WRAP_GERROR)\s*\(/)
     {
+      my $type_of_class = $1;
       my $line = $_;
       while ($line !~ /\)/ && ($_ = <FILE>))
       {
         $line .= $_;
       }
-
-      $line =~ s/^.*_CLASS_GOBJECT\s*\(//;
-      $line =~ s/\s+//g;
-      ($cppname, $cname, $ccast) = split(/,/, $line);
-
-      $objects{$cppname} = $cname;
-      @{$namespaces{$cppname}} = ( @tmpnamespace ); #both are lists of strings
-      $basenames{$cppname} = lc($ccast);
-    }
-    elsif (/_CLASS_GTKOBJECT\s*\(/)
-    {
-      my $line = $_;
-      while ($line !~ /\)/ && ($_ = <FILE>))
+      if (!$_)
       {
-        $line .= $_;
+        die "Reached end of file $filename in $type_of_class macro. " .
+            "(No right parenthesis.)\n";
       }
 
-      $line =~ s/^.*_CLASS_GTKOBJECT\s*\(//;
+      $line =~ s/^.*$type_of_class\s*\(//;
       $line =~ s/\s+//g;
-      ($cppname, $cname, $ccast) = split(/,/, $line);
-
-      #TODO: Remove this hack eventually.
-      if( ($cname ne "GtkTree") && ($cname ne "GtkTreeItem") && ($cname ne "GtkText") )
-      {
-        $objects{$cppname} = $cname;
-        @{$namespaces{$cppname}} = ( @tmpnamespace ); #both are lists of strings
-        $basenames{$cppname} = lc($ccast);
-      }
-    }
-    elsif (/_WRAP_GERROR\s*\(/) #TODO: There is duplication of code here.
-    {
-      my $line = $_;
-      while ($line !~ /\)/ && ($_ = <FILE>))
+      $line =~ s/\).*//;
+      my ($cppname, $cname, $ccast) = split(/,/, $line);
+      my $basename = lc($ccast);
+      my @names = ($cppname, $basename, @extra_namespace);
+
+      if ($type_of_class eq "_CLASS_GOBJECT" or
+         ($type_of_class eq "_CLASS_GTKOBJECT" and
+         #TODO: Remove this hack eventually.
+         ($cname ne "GtkTree" && $cname ne "GtkTreeItem" && $cname ne "GtkText")))
       {
-        $line .= $_;
+        push(@{$objects{$filename_header}}, \ names);
       }
-
-      $line =~ s/^.*_WRAP_GERROR\s*\(//;
-      $line =~ s/\s+//g;
-      $line =~ s/\)//;
-      ($cppname, $cname, $ccast) = split(/,/, $line);
-
-      # Generate a unique ID for the GError.
-      # Otherwise we will overwrite Gio::Error with Gio::DBus::Error.
-      # TODO: Isn't this necessary for other classes (not just Errors)?
-      my $qualification = "";
-      foreach ( @tmpnamespace )
+      elsif ($type_of_class eq "_WRAP_GERROR")
       {
-         $qualification .= "::$_";
+        push(@{$exceptions{$filename_header}}, \ names);
       }
-
-      my $qualified_cppname = $qualification . "::" . $cppname;
-      # print "debug: " . $qualified_cppname . "\n";
-      $exceptions{$qualified_cppname} = $cname;
-      @{$namespaces{$cppname}} = ( @tmpnamespace ); #both are lists of strings
-      $basenames{$qualified_cppname} = lc($ccast);
     }
-    elsif (/_GTKMMPROC_WIN32_NO_WRAP/)
+    elsif (/\b_GTKMMPROC_WIN32_NO_WRAP\b/)
     {
-      $win32_nowrap{$cppname} = 1;
+      $win32_nowrap{$filename_header} = 1; # This file will not be compiled on Win32
     }
-    elsif (/_IS_DEPRECATED/)
+    elsif (/\b_IS_DEPRECATED\b/)
     {
-      $deprecated{$cppname} = 1;
+      $deprecated{$filename_header} = 1; # This file is deprecated
     }
   }
 
-  # Store header filename so that we can #include it later:
-  my $filename_header = $filename;
-  $filename_header =~ s/.*\/([^\/]+)\.hg/$1.h/;
-  $filenames_headers{$filename_header} = $cppname;
-
   shift @ARGV;
   close(FILE);
 }
 
-# my $namespace_whole_lower = lc($namespace_whole);
+
+# Print the wrap_init.cc file.
 
 print << "EOF";
+// Generated by generate_wrap_init.pl -- DO NOT MODIFY!
 
 #include <glibmm.h>
 
@@ -207,133 +182,136 @@ print << "EOF";
 #include <glibmm/object.h>
 
 // #include the widget headers so that we can call the get_type() static methods:
-
 EOF
 
-my $i = 0;
-foreach $i (sort keys %filenames_headers)
+# keys %deprecated contains all filenames, not just the names of deprecated files.
+foreach my $filename_header (sort keys %deprecated)
 {
-  print_with_guards( $filenames_headers{$i}, "#include \"" . $i . "\"\n" );
+  print_with_guards($filename_header, "#include \"$filename_header\"\n");
 }
 
-print "\n";
-
-# Here we have to be subtle. The gtkmm objects are easy, they all go
-# into the Gtk namespace. But in gnomemm, some go into the Gnome
-# namespace (most of them), and some into the Gtk one (because the
-# corresponding widget is Gtk-prefixed, e.g. GtkTed, GtkDial, etc...
-
-# First, the Gtk namespace
+# Declarations of glib functions.
 
-print "extern \"C\"\n";
+print "\nextern \"C\"\n";
 print "{\n";
-print "\n//Declarations of the *_get_type() functions:\n\n";
+print "//Declarations of the *_get_type() functions:\n\n";
 
-my $i = 0;
-foreach $i (sort keys %objects)
+foreach my $filename_header (sort keys %objects)
 {
-  print_with_guards( $i, "GType $basenames{$i}_get_type(void);\n" );
+  my @objects_in_file = @{$objects{$filename_header}};
+  my $message = "";
+  foreach my $i (@objects_in_file)
+  {
+    # $i is a reference to an array with info on one object, declared in file $filename_header.
+    my $basename = ${$i}[1];
+    $message .= "GType ${basename}_get_type(void);\n";
+  }
+  print_with_guards($filename_header, $message);
 }
 
 print "\n//Declarations of the *_error_quark() functions:\n\n";
 
-my $i = 0;
-foreach $i (sort keys %exceptions)
+foreach my $filename_header (sort keys %exceptions)
 {
-  print "GQuark $basenames{$i}_quark(void);\n";
+  my @exceptions_in_file = @{$exceptions{$filename_header}};
+  my $message = "";
+  foreach my $i (@exceptions_in_file)
+  {
+    # $i is a reference to an array with info on one exception, declared in file $filename_header.
+    my $basename = ${$i}[1];
+    $message .= "GQuark ${basename}_quark(void);\n";
+  }
+  print_with_guards($filename_header, $message);
 }
 
 print "} // extern \"C\"\n";
 print "\n";
 
-print "\n//Declarations of the *_Class::wrap_new() methods, instead of including all the private headers:\n\n";
-
-my $i = 0;
-foreach $i (sort keys %objects)
+my $namespace_whole_declarations = "";
+my $namespace_whole_close = "";
+foreach (@namespace_whole)
 {
-  my $namespace_declarations = "";
-  my $namespace_close = "";
-  foreach ( @{$namespaces{$i}} )
-  {
-    $namespace_declarations .= "namespace $_ { ";
-    $namespace_close .= " }";
-  }
-
-  print_with_guards( $i, "${namespace_declarations} class ${i}_Class { public: static Glib::ObjectBase* wrap_new(GObject*); }; ${namespace_close}\n" );
+  $namespace_whole_declarations .= "namespace $_ {\n";
+  $namespace_whole_close = "} // $_\n$namespace_whole_close";
 }
 
-# print "\n//Declarations of the *Error::throw_func() methods:\n\n";
-#
-# my $i = 0;
-# foreach $i (sort keys %exceptions)
-# {
-#   my $namespace_declarations = "";
-#   my $namespace_close = "";
-#   foreach ( @{$namespaces{$i}} )
-#   {
-#     $namespace_declarations .= "namespace $_ { ";
-#     $namespace_close .= " }";
-#   }
-#
-#   print "${namespace_declarations} class ${i} { public: static void throw_func(GError*); }; ${namespace_close}\n";
-# }
+print "$namespace_whole_declarations";
 
-my $namespace_whole_declarations = "";
-my $namespace_whole_close = "";
-foreach( @namespace_whole )
+print "\n//Declarations of the *_Class::wrap_new() methods, instead of including all the private headers:\n\n";
+
+foreach my $filename_header (sort keys %objects)
 {
-  $namespace_whole_declarations .= "namespace " . $_ ." { ";
-  $namespace_whole_close = "} //" . $_ . "\n" . $namespace_whole_close;
-}
+  my @objects_in_file = @{$objects{$filename_header}};
+  my $message = "";
+  foreach my $i (@objects_in_file)
+  {
+    my ($cppname, undef, @extra_namespace) = @{$i};
 
-print "\n";
-print "$namespace_whole_declarations\n";
-print "\n";
-print "void " .$function_prefix . "wrap_init()\n{\n";
+    my $namespace_declarations = "";
+    my $namespace_close = "";
+    foreach (@extra_namespace)
+    {
+      $namespace_declarations .= "namespace $_ { ";
+      $namespace_close .= " }";
+    }
 
+    $message .= "${namespace_declarations}class ${cppname}_Class " .
+                "{ public: static Glib::ObjectBase* wrap_new(GObject*); };$namespace_close\n";
+  }
+  print_with_guards($filename_header, $message);
+}
 
 # Generate namespace::wrap_init() body
-#
 
-print "  // Register Error domains:\n";
+print "\nvoid ${function_prefix}wrap_init()\n{\n";
+
+print "  // Register Error domains in the main namespace:\n";
 
-foreach $i (sort keys %exceptions)
+foreach my $filename_header (sort keys %exceptions)
 {
-  my $namespace_prefix = "";
-  foreach( @{$namespaces{$i}} )
+  my @exceptions_in_file = @{$exceptions{$filename_header}};
+  my $message = "";
+  foreach my $i (@exceptions_in_file)
   {
-    $namespace_prefix .= $_ ."::";
+    my ($cppname, $basename, @extra_namespace) = @{$i};
+    my $qualified_cppname = join("::", (@extra_namespace, $cppname));
+    $message .= "  Glib::Error::register_domain(${basename}_quark(), &" .
+                "${qualified_cppname}::throw_func);\n";
   }
-
-  print "  Glib::Error::register_domain($basenames{$i}_quark(), &", "${namespace_prefix}${i}::throw_func);\n";
+  print_with_guards($filename_header, $message) if $message;
 }
 
 print "\n";
-print "// Map gtypes to gtkmm wrapper-creation functions:\n";
+print "  // Map gtypes to gtkmm wrapper-creation functions:\n";
 
-foreach $i (sort keys %objects)
+foreach my $filename_header (sort keys %objects)
 {
-  my $namespace_prefix = "";
-  foreach( @{$namespaces{$i}} )
+  my @objects_in_file = @{$objects{$filename_header}};
+  my $message = "";
+  foreach my $i (@objects_in_file)
   {
-    $namespace_prefix .= $_ ."::";
+    my ($cppname, $basename, @extra_namespace) = @{$i};
+    my $qualified_cppname = join("::", (@extra_namespace, $cppname));
+    $message .= "  Glib::wrap_register(${basename}_get_type(), &" .
+                "${qualified_cppname}_Class::wrap_new);\n";
   }
-
-  print_with_guards( $i, "  Glib::wrap_register($basenames{$i}_get_type(), &" . "${namespace_prefix}${i}_Class::wrap_new);\n" );
+  print_with_guards($filename_header, $message);
 }
 
 print "\n";
 print "  // Register the gtkmm gtypes:\n";
 
-foreach $i (sort keys %objects)
+foreach my $filename_header (sort keys %objects)
 {
-  my $namespace_prefix = "";
-  foreach( @{$namespaces{$i}} )
+  my @objects_in_file = @{$objects{$filename_header}};
+  my $message = "";
+  foreach my $i (@objects_in_file)
   {
-    $namespace_prefix .= $_ ."::";
+    my ($cppname, $basename, @extra_namespace) = @{$i};
+    my $qualified_cppname = join("::", (@extra_namespace, $cppname));
+    $message .= "  ${qualified_cppname}::get_type();\n"
   }
-
-  print_with_guards( $i, "  ${namespace_prefix}${i}::get_type();\n" );
+  print_with_guards($filename_header, $message);
 }
 
 print << "EOF";
@@ -341,7 +319,6 @@ print << "EOF";
 } // wrap_init()
 
 $namespace_whole_close
-
 EOF
 
 exit 0;



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]