[glibmm/gmmproc-refactor: 18/23] Some rework of Gir::Parser and Gir::State.
- From: Krzesimir Nowak <krnowak src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [glibmm/gmmproc-refactor: 18/23] Some rework of Gir::Parser and Gir::State.
- Date: Mon, 26 Sep 2011 13:16:34 +0000 (UTC)
commit 8952c461ee9624d9f23d7bfc1a3e8d5b4431d563
Author: Krzesimir Nowak <qdlacz gmail com>
Date: Mon Sep 26 14:54:14 2011 +0200
Some rework of Gir::Parser and Gir::State.
tools/pm/Gir/Parser.pm | 170 ++++++++++++++++++++++++++++++++++++++----------
tools/pm/Gir/State.pm | 56 +++++++++++++++-
2 files changed, 187 insertions(+), 39 deletions(-)
---
diff --git a/tools/pm/Gir/Parser.pm b/tools/pm/Gir/Parser.pm
index 289ceac..89f5fca 100644
--- a/tools/pm/Gir/Parser.pm
+++ b/tools/pm/Gir/Parser.pm
@@ -1,62 +1,147 @@
-package GirParser;
+## Copyright 2011 Krzesimir Nowak
+##
+## This program is free software; you can redistribute it and/or modify
+## it under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 2 of the License, or
+## (at your option) any later version.
+##
+## This program is distributed in the hope that it will be useful,
+## but WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+## GNU General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with this program; if not, write to the Free Software
+## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
+##
+
+package Gir::Parser;
use strict;
use warnings;
-use Gir::Handlers::Store;
+use Encode;
+
+use Gir::Config;
+use Gir::Handlers::Generated::Common::Store;
use Gir::State;
-use XML::Parser;
+use IO::File;
-sub _init ($)
-{
- my $self = shift;
- my $new_state = Gir::State->new ();
- my $state_stack = $self->{'states_stack'};
+use XML::Parser::Expat;
- push (@{$state_stack}, $new_state);
- $self->{'state'} = $new_state;
+sub _print_error ($$$)
+{
+ my ($state, $error, $elem) = @_;
+ my $xml_parser = $state->get_xml_parser ();
+ my $msg = $state->get_parsed_file ()
+ . ':'
+ . $xml_parser->current_line ()
+ . ': '
+ . $error
+ . "\nTags stack:\n";
+ my @context = $xml_parser->context ();
+
+ foreach my $tag (@context)
+ {
+ $msg .= ' ' . $tag . "\n";
+ }
+ if (defined ($elem))
+ {
+ $msg .= ' ' . $elem . "\n";
+ }
+ print STDERR $msg;
}
-sub _final ($)
+sub _get_file_contents_as_utf8 ($)
{
- my $self = shift;
- my $state_stack = $self->{'states_stack'};
+ my $real_filename = shift;
+ my $xml = IO::File->new ($real_filename, 'r');
- pop (@{$state_stack});
- $self->{'state'} = $state_stack->[-1];
+ unless (defined ($xml))
+ {
+ #TODO: error;
+ print STDERR 'Could not open file: ' . $real_filename . ".\n";
+ exit (1);
+ }
+
+ my $file_size = ($xml->stat ())[7];
+ my $contents = undef;
+
+ unless ($xml->binmode (':raw'))
+ {
+ #TODO: error;
+ print STDERR "Calling binmode on " . $real_filename . " failed.\n";
+ exit (1);
+ }
+
+ my $bytes_read = $xml->read ($contents, $file_size);
+
+ if ($bytes_read != $file_size)
+ {
+ #TODO: error;
+ if (defined ($bytes_read))
+ {
+ print STDERR 'Read ' . $bytes_read . ' bytes from ' . $real_filename . ', wanted: ' . $file_size . " bytes.\n";
+ }
+ else
+ {
+ print STDERR 'Read error from ' . $real_filename . ".\n";
+ }
+ exit (1);
+ }
+ unless ($xml->close ())
+ {
+ print STDERR 'Closing ' . $real_filename . " failed.\n";
+ exit (1);
+ }
+ return decode ('utf-8', $contents);
}
sub _start ($$$@)
{
- my ($self, undef, $elem, @attval) = @_;
- my $state = $self->{'current_state'};
+ my ($self, undef, $elem, @atts_vals) = @_;
+ my $state = $self->get_current_state ();
my $handlers = $state->get_current_handlers ();
my $start_handlers = $handlers->get_start_handlers ();
- if ($start_handlers->has_method_for ($elem))
+ if (defined ($start_handlers))
{
- my $method = $start_handlers->get_method_for ($elem);
- my $subhandlers = $handlers->get_subhandlers_for ($elem);
-
- if (defined ($subhandlers))
+ if ($start_handlers->has_method_for ($elem))
{
- $state->push_handlers ($subhandlers);
- return $handlers->$method ($self, @attval);
+ my $method = $start_handlers->get_method_for ($elem);
+ my $subhandlers = $handlers->get_subhandlers_for ($elem);
+
+ if (defined ($subhandlers))
+ {
+ $state->push_handlers ($subhandlers);
+ return $handlers->$method ($self, @atts_vals);
+ }
+ # TODO: internal error - wrong implementation of get_subhandlers_for?
+ _print_error ($state, 'Internal error - wrong implementation of get_subhandlers_for?', $elem);
+ exit (1);
}
- # TODO: internal error - wrong implementation of get_subhandlers_for?
+ # TODO: unknown elem?
+ _print_error ($state, 'Unknown tag: ' . $elem . '.', $elem);
+ exit (1);
}
- # TODO: unknown elem?
+ _print_error ($state, 'No start handlers: ' . $elem . '.', $elem);
+ exit (1);
}
sub _end ($$$)
{
my ($self, undef, $elem) = @_;
- my $state = $self->{'current_state'};
+ my $state = $self->get_current_state ();
$state->pop_handlers ();
my $handlers = $state->get_current_handlers ();
+ unless (defined $handlers)
+ {
+ _print_error ($state, 'No handlers for tag: ' . $elem . '.', $elem);
+ exit (1);
+ }
my $end_handlers = $handlers->get_end_handlers ();
if ($end_handlers->has_method_for ($elem))
@@ -65,7 +150,8 @@ sub _end ($$$)
return $handlers->$method ($self);
}
- # TODO: unknown elem?
+ _print_error ($state, 'Unknown tag: ' . $elem . '.', $elem);
+ exit (1);
}
#
@@ -80,8 +166,7 @@ sub new($)
{
'states_stack' => [],
'parsed_girs' => {},
- 'state' => undef,
- 'api' => {} # TODO: replace with Gir::Api->new () or something like that.
+ 'api' => {}, # TODO: replace with Gir::Api->new () or something like that.
};
return bless ($self, $class);
@@ -90,7 +175,7 @@ sub new($)
sub _create_xml_parser ($)
{
my $self = shift;
- my $xml_parser = XML::Parser->new ();
+ my $xml_parser = XML::Parser::Expat->new ();
#TODO: implement commented methods.
$xml_parser->setHandlers
@@ -99,8 +184,6 @@ sub _create_xml_parser ($)
# 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 (@_); }
);
@@ -115,11 +198,20 @@ sub parse_file ($$)
unless (exists ($parsed_girs->{$filename}))
{
- my $real_filename = File::Spec->catfile (GirConfig::get_girdir(), $filename);
+ my $real_filename = File::Spec->catfile (Gir::Config::get_girdir(), $filename);
my $xml_parser = $self->_create_xml_parser ();
+ my $new_state = Gir::State->new ($real_filename, $xml_parser);
+ my $states_stack = $self->{'states_stack'};
$parsed_girs->{$filename} = undef;
- $xml_parser->parsefile ($real_filename);
+ push (@{$states_stack}, $new_state);
+
+ my $contents = _get_file_contents_as_utf8 ($real_filename);
+
+ $xml_parser->parse ($contents);
+ $xml_parser->release ();
+ pop (@{$states_stack});
+ #print STDOUT 'Parsed ' . $real_filename . "\n";
}
}
@@ -130,4 +222,12 @@ sub get_api ($)
return $self->{'api'};
}
+sub get_current_state ($)
+{
+ my $self = shift;
+ my $states_stack = $self->{'states_stack'};
+
+ return $states_stack->[-1];
+}
+
1;
diff --git a/tools/pm/Gir/State.pm b/tools/pm/Gir/State.pm
index 18cfd01..d266c5f 100644
--- a/tools/pm/Gir/State.pm
+++ b/tools/pm/Gir/State.pm
@@ -1,3 +1,20 @@
+## Copyright 2011 Krzesimir Nowak
+##
+## This program is free software; you can redistribute it and/or modify
+## it under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 2 of the License, or
+## (at your option) any later version.
+##
+## This program is distributed in the hope that it will be useful,
+## but WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+## GNU General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with this program; if not, write to the Free Software
+## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
+##
+
package Gir::State;
use strict;
@@ -7,13 +24,16 @@ use Gir::Handlers::TopLevel;
##
## public:
##
-sub new ($)
+sub new ($$$)
{
- my $type = shift;
+ my ($type, $parsed_file, $xml_parser) = @_;
my $class = (ref ($type) or $type or 'Gir::State');
my $self =
{
- 'handlers_stack' => [Gir::Handlers::TopLevel->new ()]
+ 'handlers_stack' => [Gir::Handlers::TopLevel->new ()],
+ 'current_namespace' => undef,
+ 'parsed_file' => $parsed_file,
+ 'xml_parser' => $xml_parser
};
return bless ($self, $class);
@@ -43,4 +63,32 @@ sub get_current_handlers ($)
return ${handlers_stack}->[-1];
}
-1;
+sub get_current_namespace ($)
+{
+ my $self = shift;
+
+ return $self->{'current_namespace'};
+}
+
+sub set_current_namespace ($$)
+{
+ my ($self, $namespace) = @_;
+
+ $self->{'current_namespace'} = $namespace;
+}
+
+sub get_parsed_file ($)
+{
+ my $self = shift;
+
+ return $self->{'parsed_file'};
+}
+
+sub get_xml_parser ($)
+{
+ my $self = shift;
+
+ return $self->{'xml_parser'};
+}
+
+1; # indicate proper module load.
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]