[glibmm] generate_wrap_init.pl: Improve reg. of exception classes in sub-namespaces.



commit ea9678603eb8a0284885a54e8c2e7d306b2ef4b2
Author: Kjell Ahlstedt <kjell ahlstedt bredband net>
Date:   Tue Feb 28 15:31:17 2012 +0100

    generate_wrap_init.pl: Improve reg. of exception classes in sub-namespaces.
    
    * tools/generate_wrap_init.pl.in: When there are exception classes in sub-
    namespaces, create extra wrap_init() functions in those namespaces, and
    register the exception classes from there. wrap_init() is a friend that makes
    a pointer to the private throw_func(), and that's easier if wrap_init() is
    declared in the same namespace as the exception class. Bug #640029.

 ChangeLog                      |   10 +++++
 tools/generate_wrap_init.pl.in |   84 ++++++++++++++++++++++++++++++++++++++-
 2 files changed, 91 insertions(+), 3 deletions(-)
---
diff --git a/ChangeLog b/ChangeLog
index 3c0c3d8..4eb9ffe 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,4 +1,14 @@
 2012-02-28  Kjell Ahlstedt  <kjell ahlstedt bredband net>
+ 
+	generate_wrap_init.pl: Improve reg. of exception classes in sub-namespaces.
+
+	* tools/generate_wrap_init.pl.in: When there are exception classes in sub-
+	namespaces, create extra wrap_init() functions in those namespaces, and
+	register the exception classes from there. wrap_init() is a friend that makes
+	a pointer to the private throw_func(), and that's easier if wrap_init() is
+	declared in the same namespace as the exception class. Bug #640029.
+
+2012-02-28  Kjell Ahlstedt  <kjell ahlstedt bredband net>
 
 	generate_wrap_init.pl: Improve it for deprecated files and sub-namespaces.
 
diff --git a/tools/generate_wrap_init.pl.in b/tools/generate_wrap_init.pl.in
index 4f96408..fa2eea7 100644
--- a/tools/generate_wrap_init.pl.in
+++ b/tools/generate_wrap_init.pl.in
@@ -261,6 +261,70 @@ foreach my $filename_header (sort keys %objects)
   print_with_guards($filename_header, $message);
 }
 
+# wrap_init() calls throw_func() in each exception class. throw_func() is a
+# private method. wrap_init() is declared as a friend of the exception class.
+# The friends will find each other easily only if the calling wrap_init()
+# function is declared in the same namespace as the exception class.
+# If there are extra namespaces, we define extra wrap_init() functions, which
+# are called from the wrap_init() function in @namespace_whole.
+
+my %extra_namespaces = ();
+foreach my $filename_header (keys %exceptions)
+{
+  my @exceptions_in_file = @{$exceptions{$filename_header}};
+  foreach my $i (@exceptions_in_file)
+  {
+    if (@{$i} > 2)
+    {
+      my (undef, undef, @extra_namespace) = @{$i};
+      $extra_namespaces{join("::", @extra_namespace)} = 1;
+    }
+  }
+}
+
+# Generate the extra wrap_init() functions in sub-namespaces, if any.
+
+# If you suspect that code with three levels of foreach is inefficient, you are
+# probably right, but it's not important here. The exception classes are few in
+# most modules (hardly more than about 10), and the sub-namespaces are even
+# fewer (usually 0 or 1).
+
+print "\n// Register Error domains in sub-namespaces:\n" if keys %extra_namespaces > 0;
+
+foreach my $sub_namespace (sort keys %extra_namespaces)
+{
+  my @extra_namespace = split("::", $sub_namespace);
+  my $namespace_declarations = "";
+  my $namespace_close = "";
+  foreach (@extra_namespace)
+  {
+    $namespace_declarations .= "namespace $_ {\n";
+    $namespace_close = "} // $_\n$namespace_close";
+  }
+
+  print "\n$namespace_declarations";
+  print "\nvoid wrap_init()\n{\n";
+
+  foreach my $filename_header (sort keys %exceptions)
+  {
+    my @exceptions_in_file = @{$exceptions{$filename_header}};
+    my $message = "";
+    foreach my $i (@exceptions_in_file)
+    {
+      my ($cppname, $basename, @extra_namespace) = @{$i};
+      if (@extra_namespace > 0 && $sub_namespace eq join("::", @extra_namespace))
+      {
+        $message .= "  Glib::Error::register_domain(${basename}_quark(), &" .
+                    "${sub_namespace}::${cppname}::throw_func);\n";
+      }
+    }
+    print_with_guards($filename_header, $message) if $message;
+  }
+
+  print "\n} // wrap_init()\n";
+  print "\n$namespace_close";
+}
+
 # Generate namespace::wrap_init() body
 
 print "\nvoid ${function_prefix}wrap_init()\n{\n";
@@ -274,13 +338,27 @@ foreach my $filename_header (sort keys %exceptions)
   foreach my $i (@exceptions_in_file)
   {
     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";
+    if (@extra_namespace == 0)
+    {
+      $message .= "  Glib::Error::register_domain(${basename}_quark(), &" .
+                  "${cppname}::throw_func);\n";
+    }
   }
   print_with_guards($filename_header, $message) if $message;
 }
 
+# Exception classes in sub-namespaces are registered after the ones in the main
+# namespace. If you ever change this order, check that it's ok with Glib::ThreadError
+# and Glib::Threads::ThreadError. Both these classes wrap GThreadError, and
+# Glib::ThreadError is deprecated (2012-02-27).
+
+print "\n  // Call the wrap_init() functions in sub-namespaces:\n" if keys %extra_namespaces > 0;
+
+foreach my $sub_namespace (sort keys %extra_namespaces)
+{
+  print "  ${sub_namespace}::wrap_init();\n";
+}
+
 print "\n";
 print "  // Map gtypes to gtkmm wrapper-creation functions:\n";
 



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