[glibmm/gmmproc-refactor] Added several handlers.



commit c8e0ebd838ff4a796d117bb1ec70344b1cbed380
Author: Krzesimir Nowak <qdlacz gmail com>
Date:   Fri Sep 2 16:00:59 2011 +0200

    Added several handlers.

 tools/pm/Gir/Handlers/Base.pm             |   60 ++++++++++
 tools/pm/Gir/Handlers/Common.pm           |  100 ++++++++++++++++
 tools/pm/Gir/Handlers/Ignore.pm           |   34 ++++++
 tools/pm/Gir/Handlers/IgnoreEndStore.pm   |   32 +++++
 tools/pm/Gir/Handlers/IgnoreStartStore.pm |   32 +++++
 tools/pm/Gir/Handlers/Repository.pm       |   83 +++++++++++++
 tools/pm/Gir/Handlers/Store.pm            |   42 +++++++
 tools/pm/Gir/Handlers/TopLevel.pm         |   37 +++++--
 tools/pm/Gir/Parser.pm                    |  181 ++++-------------------------
 tools/pm/Gir/State.pm                     |   34 ++++--
 10 files changed, 455 insertions(+), 180 deletions(-)
---
diff --git a/tools/pm/Gir/Handlers/Base.pm b/tools/pm/Gir/Handlers/Base.pm
new file mode 100644
index 0000000..c5a52ad
--- /dev/null
+++ b/tools/pm/Gir/Handlers/Base.pm
@@ -0,0 +1,60 @@
+package Gir::Handlers::Base;
+
+use strict;
+use warnings;
+
+##
+## private:
+##
+sub _new_impl_ ($)
+{
+  my $type = shift;
+  my $class = (ref ($type) or $type or 'Gir::Handlers::Base');
+  my $self =
+  {
+    'start_handlers' => {},
+    'end_handlers' => {}
+  };
+
+  return bless ($self, $class);
+}
+
+##
+## protected:
+##
+sub _set_handlers ($$$)
+{
+  my ($self, $start_handlers, $end_handlers) = @_;
+
+  $self->{'start_handlers'} = $start_handlers;
+  $self->{'end_handlers'} = $end_handlers;
+}
+
+##
+## public:
+##
+sub new ($)
+{
+  return _new_impl_ (shift);
+}
+
+sub get_start_handlers ($)
+{
+  my $self = shift;
+
+  return $self->{'start_handlers'};
+}
+
+sub get_end_handlers ($)
+{
+  my $self = shift;
+
+  return $self->{'end_handlers'};
+}
+
+sub get_subhandlers_for ($$)
+{
+  #TODO: error - not implemented.
+}
+
+1;
diff --git a/tools/pm/Gir/Handlers/Common.pm b/tools/pm/Gir/Handlers/Common.pm
new file mode 100644
index 0000000..16ab33f
--- /dev/null
+++ b/tools/pm/Gir/Handlers/Common.pm
@@ -0,0 +1,100 @@
+package Gir::Handlers::Common;
+
+use strict;
+use warnings;
+
+##
+## public:
+##
+sub start_ignore ($$@)
+{}
+
+sub end_ignore ($$)
+{}
+
+sub extract_values($$$$)
+{
+  my ($keys, $optional_keys, $atts_vals, $tag) = @_;
+  my $params = {};
+  my $check = {};
+  my $leftovers = {};
+  my $leftover = undef;
+  my $att = undef;
+
+  foreach my $key (@keys)
+  {
+    $params->{$key} = undef;
+    $check->{$key} = undef;
+  }
+  foreach my $key in (@optional_keys)
+  {
+    $params->{$key} = undef;
+  }
+
+  foreach my $entry (@{$atts_vals})
+  {
+    if (defined ($leftover))
+    {
+      $leftovers->{$leftover} = $entry;
+      $leftover = undef;
+    }
+    elsif (not defined ($att))
+    {
+      if (exists ($params->{$entry}))
+      {
+        $att = $entry;
+        delete ($check->{$att});
+      }
+      else
+      {
+        $leftover = $entry;
+      }
+    }
+    else
+    {
+      $params{$att} = $entry;
+      $att = undef;
+    }
+  }
+
+  my @check_keys = keys (%{$check})
+
+  if (@check_keys > 0)
+  {
+    my $message = "Missing attributes in tag '" . $tag . "':\n";
+
+    foreach my $key (@check_keys)
+    {
+      $message .= "  " . $key . "\n";
+    }
+    # TODO: change this later maybe to exception and remove $tag parameter.
+    print STDERR $message;
+    exit (1);
+  }
+
+  return ($params, $leftovers);
+}
+
+sub extract_values_warn ($$$$)
+{
+  my ($keys, $optional_keys, $atts_vals, $tag) = @_;
+  my ($params, $leftovers) = extract_values ($keys, $optional_keys, $atts_vals);
+  my @leftover_keys = keys (%{$leftovers});
+
+  if (@leftover_keys > 0)
+  {
+    my $message = "Leftover attributes in tag '" . $tag . "':\n";
+
+    foreach my $leftover (@leftover_keys)
+    {
+      $message .= "  " . $leftover . " => " . $leftovers->{$leftover} . "\n";
+    }
+    # TODO: change this later maybe to exception and remove $tag parameter.
+    print STDERR $message;
+    exit (1);
+  }
+
+  return $params;
+}
+
+1;
diff --git a/tools/pm/Gir/Handlers/Ignore.pm b/tools/pm/Gir/Handlers/Ignore.pm
new file mode 100644
index 0000000..5b77b98
--- /dev/null
+++ b/tools/pm/Gir/Handlers/Ignore.pm
@@ -0,0 +1,34 @@
+package Gir::Handlers::Ignore;
+
+use strict;
+use warnings;
+
+use parent qw(Gir::Handlers::Base);
+
+use Gir::Handlers::IgnoreEndStore;
+use Gir::Handlers::IgnoreStartStore;
+
+##
+## public:
+##
+sub new ($)
+{
+  my $type = shift;
+  my $class = (ref ($type) or $type or 'Gir::Handlers::Ignore');
+  my $self = $class->SUPER->new ();
+
+  $self->_set_handlers
+  (
+    Gir::Handlers::IgnoreStartStore->new (),
+    Gir::Handlers::IgnoreEndStore->new ()
+  );
+
+  return bless ($self, $class);
+}
+
+sub get_subhandlers_for ($$)
+{
+  return Gir::Handlers::Ignore->new ();
+}
+
+1;
diff --git a/tools/pm/Gir/Handlers/IgnoreEndStore.pm b/tools/pm/Gir/Handlers/IgnoreEndStore.pm
new file mode 100644
index 0000000..40ed88a
--- /dev/null
+++ b/tools/pm/Gir/Handlers/IgnoreEndStore.pm
@@ -0,0 +1,32 @@
+package Gir::Handlers::IgnoreEndStore;
+
+use strict;
+use warnings;
+
+use parent qw(Gir::Handlers::Store);
+
+use Gir::Handlers::Common;
+
+##
+## public:
+##
+sub new ($)
+{
+  my $type = shift;
+  my $class = (ref ($type) or $type or 'Gir::Handlers::IgnoreEndStore');
+  my $self = $class->SUPER->new ({});
+
+  return bless ($self, $class);
+}
+
+sub has_method_for ($$)
+{
+  return 1;
+}
+
+sub get_method_for ($$)
+{
+  return \&Gir::Handlers::Common::end_ignore;
+}
+
+1;
diff --git a/tools/pm/Gir/Handlers/IgnoreStartStore.pm b/tools/pm/Gir/Handlers/IgnoreStartStore.pm
new file mode 100644
index 0000000..1b5d3f5
--- /dev/null
+++ b/tools/pm/Gir/Handlers/IgnoreStartStore.pm
@@ -0,0 +1,32 @@
+package Gir::Handlers::IgnoreStartStore;
+
+use strict;
+use warnings;
+
+use parent qw(Gir::Handlers::Store);
+
+use Gir::Handlers::Common;
+
+##
+## public:
+##
+sub new ($)
+{
+  my $type = shift;
+  my $class = (ref ($type) or $type or 'Gir::Handlers::IgnoreStartStore');
+  my $self = $class->SUPER->new ({});
+
+  return bless ($self, $class);
+}
+
+sub has_method_for ($$)
+{
+  return 1;
+}
+
+sub get_method_for ($$)
+{
+  return \&Gir::Handlers::Common::start_ignore;
+}
+
+1;
diff --git a/tools/pm/Gir/Handlers/Repository.pm b/tools/pm/Gir/Handlers/Repository.pm
new file mode 100644
index 0000000..baf34b7
--- /dev/null
+++ b/tools/pm/Gir/Handlers/Repository.pm
@@ -0,0 +1,83 @@
+package Gir::Handlers::Repository;
+
+use strict;
+use warnings;
+
+use parent qw(Gir::Handlers::Base);
+
+use Gir::Handlers::Common;
+use Gir::Handlers::Ignore;
+use Gir::Handlers::Namespace;
+use Gir::Handlers::Store;
+use Gir::Parser;
+
+##
+## private:
+##
+sub _namespace_start ($$@)
+{
+  my ($self, $parser, @atts_vals) = @_;
+  my $params = Gir::Handlers::Common::extract_values (['name', 'version', 'shared-library', 'c:identifier-prefixes', 'c:symbol-prefixes'], [], \ atts_vals, 'namespace');
+  my $api = $parser->get_api ();
+  my $name = $params->{'name'};
+
+  if ($api->has_namespace ($name))
+  {
+    # TODO: error? every gir probably should have different namespace, right?
+  }
+  $api->add_namespace ($name);
+}
+
+sub _include_start ($$@)
+{
+  my ($self, $parser, @atts_vals) = @_;
+  my $params = extract_values_warn (['name', 'version'], [], \ atts_vals, 'include');
+
+  $parser->parse_file ($params->{'name'} . '-' . $params->{'version'});
+}
+
+##
+## public:
+##
+sub new ($)
+{
+  my $type = shift;
+  my $class = (ref ($type) or $type or 'Gir::Handlers::Repository');
+  my $self = $class->SUPER->new ();
+
+  $self->_set_handlers
+  (
+    Gir::Handlers::Store->new
+    ({
+      'c:include' => \&Gir::Handlers::Common::start_ignore,
+      'implementation' => \&Gir::Handlers::Common::start_ignore,
+      'include' => \&_include_start,
+      'namespace' => \&_namespace_start,
+      'package' => \&Gir::Handlers::Common::start_ignore
+    }),
+    Gir::Handlers::Store->new
+    ({
+      'c:include' => \&Gir::Handlers::Common::end_ignore,
+      'implementation' => \&Gir::Handlers::Common::end_ignore,
+      'include' => \&Gir::Handlers::Common::end_ignore,
+      'namespace' => \&Gir::Handlers::Common::end_ignore,
+      'package' => \&Gir::Handlers::Common::end_ignore
+    })
+  );
+
+  return bless ($self, $class);
+}
+
+sub get_subhandlers_for ($$)
+{
+  my ($self, $elem) = @_;
+
+  if ($elem eq 'namespace')
+  {
+    return Gir::Handlers::Namespace->new ();
+  }
+  # rest is either ignored or has no children
+  return Gir::Handlers::Ignore->new ();
+}
+
+1;
diff --git a/tools/pm/Gir/Handlers/Store.pm b/tools/pm/Gir/Handlers/Store.pm
new file mode 100644
index 0000000..1fbcf9d
--- /dev/null
+++ b/tools/pm/Gir/Handlers/Store.pm
@@ -0,0 +1,42 @@
+package Gir::Handlers::Store;
+
+use strict;
+use warnings;
+
+##
+## public:
+##
+sub new ($$)
+{
+  my ($type, $methods) = @_;
+  my $class = (ref ($type) or $type or 'Gir::Handlers::Store');
+  my $self =
+  {
+    'methods' => $methods
+  };
+
+  return bless ($self, $class);
+}
+
+sub has_method_for ($$)
+{
+  my ($self, $elem) = @_;
+  my $methods = $self->{'methods'};
+
+  return exists ($methods->{$elem});
+}
+
+sub get_method_for ($$)
+{
+  my ($self, $elem) = @_;
+
+  if ($self->has_method_for ($elem))
+  {
+    my $methods = $self->{'methods'};
+
+    return $methods->{$elem};
+  }
+  # TODO: error.
+}
+
+1;
diff --git a/tools/pm/Gir/Handlers/TopLevel.pm b/tools/pm/Gir/Handlers/TopLevel.pm
index 7d984b2..59fd9f6 100644
--- a/tools/pm/Gir/Handlers/TopLevel.pm
+++ b/tools/pm/Gir/Handlers/TopLevel.pm
@@ -1,18 +1,37 @@
-package GirTopLevelHandlers;
+package Gir::Handlers::TopLevel;
 
 use strict;
 use warnings;
-use GirParser;
 
-sub _namespace_handler ($@)
+use parent qw(Gir::Handlers::Base);
+
+use Gir::Handlers::Common;
+use Gir::Handlers::Repository;
+use Gir::Handlers::Store;
+
+##
+## public:
+##
+sub new ($)
 {
-  my ($self, $
+  my $type = shift;
+  my $class = (ref ($type) or $type or 'Gir::Handlers::TopLevel');
+  my $self = $class->SUPER->new ();
+
+  $self->_set_handlers
+  (
+    Gir::Handlers::Store->new ({ 'repository' => \&Gir::Handlers::Common::start_ignore }),
+    Gir::Handlers::Store->new ({ 'repository' => \&Gir::Handlers::Common::end_ignore })
+  );
+
+  return bless ($self, $class);
 }
 
-sub get_handlers ()
+sub get_subhandlers_for ($$)
 {
-  return
-  {
-    'namespace' => \&_namespace_handler
-  }
+  my ($self, $elem) = @_;
+
+  return Gir::Handlers::Repository->new ();
 }
+
+1;
diff --git a/tools/pm/Gir/Parser.pm b/tools/pm/Gir/Parser.pm
index fb57200..289ceac 100644
--- a/tools/pm/Gir/Parser.pm
+++ b/tools/pm/Gir/Parser.pm
@@ -2,87 +2,16 @@ package GirParser;
 
 use strict;
 use warnings;
-use XML::Parser;
-
-sub _extract_values($$)
-{
-  my ($keys, $attval) = @_;
-  my %params = ();
-  my %check = ();
-
-  foreach my $key (@keys)
-  {
-    $params{$key} = undef;
-    $check{$key} = undef;
-  }
-
-  my $att = undef;
-
-  foreach my $entry (@{$attval})
-  {
-    unless (defined ($att))
-    {
-      if (exists ($params{$entry}))
-      {
-        $att = $entry;
-        delete ($check{$att});
-      }
-      else
-      {
-        # TODO: unknown attribute, ignored.
-      }
-    }
-    else
-    {
-      $params{$att} = $entry;
-      $att = undef;
-    }
-  }
-
-  if (keys (%check) > 0)
-  {
-    # TODO: missing needed attribute.
-  }
-
-  return \%params;
-}
-
-sub _sub_start_include ($@)
-{
-  my ($self, @attval) = @_;
-  my $params = _extract_values (['name', 'version'], \ attval);
-
-  $self->parse_file ($params->{'name'} . '-' . $params->{'version'});
-}
-
-sub _sub_end_include ($)
-{
-  # NOTHING.
-}
-
-sub _sub_start_namespace ($@)
-{
-  my ($self, @attval) = @_;
-  my $params = _extract_values (['name'], @attval);
-  my $api = $self->{'api'};
-  my $name = $params->{'name'};
 
-  if ($api->has_namespace ($name))
-  {
-    # TODO: error?
-  }
-  $api->add_namespace ($name);
-}
+use Gir::Handlers::Store;
+use Gir::State;
 
-sub _sub_end_namespace ($)
-{
-  # NOTHING
-}
+use XML::Parser;
 
 sub _init ($)
 {
   my $self = shift;
-  my $new_state = GirParserState->new ();
+  my $new_state = Gir::State->new ();
   my $state_stack = $self->{'states_stack'};
 
   push (@{$state_stack}, $new_state);
@@ -98,24 +27,29 @@ sub _final ($)
   $self->{'state'} = $state_stack->[-1];
 }
 
-sub _proof_of_concept_start ($$$@)
+sub _start ($$$@)
 {
   my ($self, undef, $elem, @attval) = @_;
   my $state = $self->{'current_state'};
   my $handlers = $state->get_current_handlers ();
   my $start_handlers = $handlers->get_start_handlers ();
 
-  if (exists ($start_handlers->{$elem}))
+  if ($start_handlers->has_method_for ($elem))
   {
-    my $method = $start_handlers->{$elem};
+    my $method = $start_handlers->get_method_for ($elem);
+    my $subhandlers = $handlers->get_subhandlers_for ($elem);
 
-    $state->push_handlers ($handlers->get_subhandlers_for ($elem));
-    return $handlers->$method ($self, @attval);
+    if (defined ($subhandlers))
+    {
+      $state->push_handlers ($subhandlers);
+      return $handlers->$method ($self, @attval);
+    }
+    # TODO: internal error - wrong implementation of get_subhandlers_for?
   }
   # TODO: unknown elem?
 }
 
-sub _proof_of_concept_end ($$$)
+sub _end ($$$)
 {
   my ($self, undef, $elem) = @_;
   my $state = $self->{'current_state'};
@@ -125,84 +59,18 @@ sub _proof_of_concept_end ($$$)
   my $handlers = $state->get_current_handlers ();
   my $end_handlers = $handlers->get_end_handlers ();
 
-  if (exists ($end_handlers->{$elem}))
+  if ($end_handlers->has_method_for ($elem))
   {
-    my $method = $end_handlers->{$elem};
+    my $method = $end_handlers->get_method_for ($elem);
 
     return $handlers->$method ($self);
   }
   # TODO: unknown elem?
 }
 
-sub _start ($$$@)
-{
-  my ($self, undef, $elem, @attval) = @_;
-  my $subhandlers = $self->{'start_subhandlers'};
-  my $ignored_tags = $self->{'ignored_tags'};
-
-  unless (exists ($ignored_tags->{$elem}))
-  {
-    if (exists ($subhandlers->{$elem}))
-    {
-      my $method = $subhandlers->{$elem};
-      my $state = $self->{'state'};
-
-      $state->push_tag ($elem);
-      return $self->$method (@attval);
-    }
-    # TODO: error - unknown element.
-  }
-}
-
-sub _end ($$$)
-{
-  my ($self, undef, $elem) = @_;
-  my $subhandlers = $self->{'end_subhandlers'};
-
-  if (exists ($subhandlers->{$elem}))
-  {
-    my $method = $subhandlers->{$elem};
-    my $state = $self->{'state'};
-
-    $state->pop_tag ();
-    return $self->$method ();
-  }
-}
-
 #
 ## private functions
 #
-sub _get_ignored_tags ()
-{
-  return
-  {
-    'repository' => 0,
-    'package' => 1,
-    'c:include' => 1,
-    'alias' => 1,
-    'constant' => 1,
-    'doc' => 1 # TODO: docs are ignored temporarily - remove it later.
-    ''
-  }
-}
-
-sub _get_start_subhandlers ()
-{
-  return
-  {
-    'include' => \&_sub_start_include,
-    'namespace' => \&_sub_start_namespace
-  };
-}
-
-sub _get_end_subhandlers ()
-{
-  return
-  {
-    'include' => \&_sub_end_include,
-    'namespace' => \&_sub_end_namespace
-  };
-}
 
 sub new($)
 {
@@ -211,12 +79,6 @@ sub new($)
   my $self =
   {
     'states_stack' => [],
-    'top_level_start_subhandlers' => _get_top_level_start_subhandlers (),
-    'top_level_end_subhandlers' => _get_top_level_end_subhandlers (),
-    'repository_start_subhandlers' => _get_repository_start_subhandlers (),
-    'repository_end_subhandlers' => _get_repository_end_subhandlers (),
-    'namespace_start_subhandlers' => _get_namespace_start_subhandlers (),
-    'namespace_end_subhandlers' => _get_namespace_end_subhandlers (),
     'parsed_girs' => {},
     'state' => undef,
     'api' => {} # TODO: replace with Gir::Api->new () or something like that.
@@ -230,16 +92,17 @@ sub _create_xml_parser ($)
   my $self = shift;
   my $xml_parser = XML::Parser->new ();
 
+  #TODO: implement commented methods.
   $xml_parser->setHandlers
   (
-    Char => sub { $self->_char (@_); },
-    Comment => sub { $self->_comment (@_); },
-    Default => sub { $self->_default (@_); },
+#    Char => sub { $self->_char (@_); },
+#    Comment => sub { $self->_comment (@_); },
+#    Default => sub { $self->_default (@_); },
     End => sub { $self->_end (@_); },
     Final => sub { $self->_final (@_); },
     Init => sub { $self->_init (@_); },
     Start => sub { $self ->_start (@_); },
-    XMLDecl => sub { $self->_xmldecl (@_); }
+#    XMLDecl => sub { $self->_xmldecl (@_); }
   );
 
   return $xml_parser;
diff --git a/tools/pm/Gir/State.pm b/tools/pm/Gir/State.pm
index f65d42d..18cfd01 100644
--- a/tools/pm/Gir/State.pm
+++ b/tools/pm/Gir/State.pm
@@ -1,36 +1,46 @@
-package GirParserState;
+package Gir::State;
 
 use strict;
 use warnings;
-use GirTopLevelHandlers;
+use Gir::Handlers::TopLevel;
 
+##
+## public:
+##
 sub new ($)
 {
   my $type = shift;
-  my $class = (ref ($type) or $type or 'GirParserState');
+  my $class = (ref ($type) or $type or 'Gir::State');
   my $self =
   {
-    'tags_stack' => [],
-    'current_handlers' => GirTopLevelHandlers::get_handlers ()
+    'handlers_stack' => [Gir::Handlers::TopLevel->new ()]
   };
 
   return bless ($self, $class);
 }
 
-sub push_tag ($$)
+sub push_handlers ($$)
 {
-  my ($self, $name) = @_;
-  my $tags_stack = $self->{'tags_stack'};
+  my ($self, $handlers) = @_;
+  my $handlers_stack = $self->{'handlers_stack'};
 
-  push (@{$tags_stack}, $name);
+  push (@{$handlers_stack}, $handlers);
 }
 
-sub pop_tag ($)
+sub pop_handlers ($)
 {
   my $self = shift;
-  my $tags_stack = $self->{'tags_stack'};
+  my $handlers_stack = $self->{'handlers_stack'};
 
-  pop (@{$tags_stack});
+  pop (@{$handlers_stack});
+}
+
+sub get_current_handlers ($)
+{
+  my $self = shift;
+  my $handlers_stack = $self->{'handlers_stack'};
+
+  return ${handlers_stack}->[-1];
 }
 
 1;



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