You are viewing a plain text version of this content. The canonical link for it is here.
Posted to p-dev@xerces.apache.org by John Utz <ut...@singingfish.com> on 2002/03/14 00:54:25 UTC

But Wait, There's More!! Re: moron, yet again. Re: creating actual_cast for XML::Xerces::Grammar Re: more problems on porting SEnumval.pl

I think that i have created the correct actual_cast and reinterpret_class,
but i just realized that this doesnt get propogated to the methods,

i see there is some code that has some 'transmogrification' regexp work
and does this work on the lsit @dom_node_methods.

do i need to do something with this? do i need to create a
@grammar_methods? what goes into this list and what doesnt go into this
list, or am i barking up the wrong tree?


On Wed, 13 Mar 2002, John Utz wrote:

> i figured it out, i think, based on getGrammarType and bless $self
> 
> On Wed, 13 Mar 2002, John Utz wrote:
> 
> > ok
> > 
> > On 13 Mar 2002, (Jason E. Stewart) wrote:
> > > 
> > > Ok. You're getting bitten by the SWIG-casts-things-to-the-base-class
> > > problem. Look at the class of the object your code printed out:
> > > XML::Xerces::Grammar into the bless command.
> > > 
> > > The way we get around this for the other class hierarchies is to use a
> > > method called actual_cast() to re-bless the object into the
> > > appropriate subclass:
> > > 
> > >   package XML::Xerces::DOM_Node;
> > > 
> > >   sub actual_cast {
> > >     return undef unless _isa( ref($_[0]), 'XML::Xerces::DOM_Node' );
> > >     return $_[0] if $_[0]->isNull;
> > >   
> > >     my $node_type = $_[0]->getNodeType;
> > >     return _reinterpret_cast('XML::Xerces::DOM_Text', $_[0])
> > 
> > this is a great idea, but how the heck do i resolve the type of Grammar
> > Class?
> > 
> > note that in the example that you provide, you are blessed with the
> > function getNodeType, because you are working with a DOM.
> > 
> > suggestions? wild ass guesses?
> > 
> > here's the 2 implementations sucked outta my Xerces.pm
> > 
> > ############# Class : XML::Xerces::Grammar ##############
> > 
> > package XML::Xerces::Grammar;
> > @ISA = qw( XML::Xerces );
> > %OWNER = ();
> > %ITERATORS = ();
> > *DTDGrammarType = *XML::Xercesc::Grammar_DTDGrammarType;
> > *SchemaGrammarType = *XML::Xercesc::Grammar_SchemaGrammarType;
> > *UNKNOWN_SCOPE = *XML::Xercesc::Grammar_UNKNOWN_SCOPE;
> > *TOP_LEVEL_SCOPE = *XML::Xercesc::Grammar_TOP_LEVEL_SCOPE;
> > 
> > *getGrammarType = *XML::Xercesc::Grammar_getGrammarType;
> > *getTargetNamespace = *XML::Xercesc::Grammar_getTargetNamespace;
> > sub findOrAddElemDecl {
> >     my @args = @_;
> >     my $result = XML::Xercesc::Grammar_findOrAddElemDecl(@args);
> >     return $result unless ref($result) =~ m[XML::Xerces];
> >     my %resulthash;
> >     tie %resulthash, ref($result), $result;
> >     return bless \%resulthash, ref($result);
> > }
> > *getElemId = *XML::Xercesc::Grammar_getElemId;
> > sub getElemDecl {
> >     my @args = @_;
> >     my $result = XML::Xercesc::Grammar_getElemDecl(@args);
> >     return $result unless ref($result) =~ m[XML::Xerces];
> >     my %resulthash;
> >     tie %resulthash, ref($result), $result;
> >     return bless \%resulthash, ref($result);
> > }
> > *getNotationDecl = *XML::Xercesc::Grammar_getNotationDecl;
> > sub putElemDecl {
> >     my @args = @_;
> >     my $result = XML::Xercesc::Grammar_putElemDecl(@args);
> >     return $result unless ref($result) =~ m[XML::Xerces];
> >     my %resulthash;
> >     tie %resulthash, ref($result), $result;
> >     return bless \%resulthash, ref($result);
> > }
> > *putNotationDecl = *XML::Xercesc::Grammar_putNotationDecl;
> > *reset = *XML::Xercesc::Grammar_reset;
> > 
> > 
> > ############# Class : XML::Xerces::SchemaGrammar ##############
> > 
> > package XML::Xerces::SchemaGrammar;
> > @ISA = qw( XML::Xerces XML::Xerces::Grammar );
> > %OWNER = ();
> > %ITERATORS = ();
> > sub new {
> >     my $pkg = shift;
> >     my @args = @_;
> >     my $self = XML::Xercesc::new_SchemaGrammar(@args);
> >     return undef if (!defined($self));
> >     bless $self, "XML::Xerces::SchemaGrammar";
> >     $OWNER{$self} = 1;
> >     my %retval;
> >     tie %retval, "XML::Xerces::SchemaGrammar", $self;
> >     return bless \%retval, $pkg;
> > }
> > 
> > 
> > *getGrammarType = *XML::Xercesc::SchemaGrammar_getGrammarType;
> > *getTargetNamespace = *XML::Xercesc::SchemaGrammar_getTargetNamespace;
> > sub findOrAddElemDecl {
> >     my @args = @_;
> >     my $result = XML::Xercesc::SchemaGrammar_findOrAddElemDecl(@args);
> >     return $result unless ref($result) =~ m[XML::Xerces];
> >     my %resulthash;
> >     tie %resulthash, ref($result), $result;
> >     return bless \%resulthash, ref($result);
> > }
> > *getElemId = *XML::Xercesc::SchemaGrammar_getElemId;
> > sub getElemDecl {
> >     my @args = @_;
> >     my $result = XML::Xercesc::SchemaGrammar_getElemDecl(@args);
> >     return $result unless ref($result) =~ m[XML::Xerces];
> >     my %resulthash;
> >     tie %resulthash, ref($result), $result;
> >     return bless \%resulthash, ref($result);
> > }
> > *getNotationDecl = *XML::Xercesc::SchemaGrammar_getNotationDecl;
> > sub putElemDecl {
> >     my @args = @_;
> >     my $result = XML::Xercesc::SchemaGrammar_putElemDecl(@args);
> >     return $result unless ref($result) =~ m[XML::Xerces];
> >     my %resulthash;
> >     tie %resulthash, ref($result), $result;
> >     return bless \%resulthash, ref($result);
> > }
> > *putNotationDecl = *XML::Xercesc::SchemaGrammar_putNotationDecl;
> > *reset = *XML::Xercesc::SchemaGrammar_reset;
> > *getElemEnumerator = *XML::Xercesc::SchemaGrammar_getElemEnumerator;
> > *getAttributeDeclRegistry =
> > *XML::Xercesc::SchemaGrammar_getAttributeDeclRegistry;
> > *getComplexTypeRegistry =
> > *XML::Xercesc::SchemaGrammar_getComplexTypeRegistry;
> > *getGroupInfoRegistry = *XML::Xercesc::SchemaGrammar_getGroupInfoRegistry;
> > *getAttGroupInfoRegistry =
> > *XML::Xercesc::SchemaGrammar_getAttGroupInfoRegistry;
> > sub getDatatypeRegistry {
> >     my @args = @_;
> >     my $result = XML::Xercesc::SchemaGrammar_getDatatypeRegistry(@args);
> >     return $result unless ref($result) =~ m[XML::Xerces];
> >     my %resulthash;
> >     tie %resulthash, ref($result), $result;
> >     return bless \%resulthash, ref($result);
> > }
> > sub getNamespaceScope {
> >     my @args = @_;
> >     my $result = XML::Xercesc::SchemaGrammar_getNamespaceScope(@args);
> >     return $result unless ref($result) =~ m[XML::Xerces];
> >     my %resulthash;
> >     tie %resulthash, ref($result), $result;
> >     return bless \%resulthash, ref($result);
> > }
> > *getValidSubstitutionGroups =
> > *XML::Xercesc::SchemaGrammar_getValidSubstitutionGroups;
> > *getIDRefList = *XML::Xercesc::SchemaGrammar_getIDRefList;
> > *getUPAChecked = *XML::Xercesc::SchemaGrammar_getUPAChecked;
> > *setTargetNamespace = *XML::Xercesc::SchemaGrammar_setTargetNamespace;
> > *setAttributeDeclRegistry =
> > *XML::Xercesc::SchemaGrammar_setAttributeDeclRegistry;
> > *setComplexTypeRegistry =
> > *XML::Xercesc::SchemaGrammar_setComplexTypeRegistry;
> > *setGroupInfoRegistry = *XML::Xercesc::SchemaGrammar_setGroupInfoRegistry;
> > *setAttGroupInfoRegistry =
> > *XML::Xercesc::SchemaGrammar_setAttGroupInfoRegistry;
> > *setDatatypeRegistry = *XML::Xercesc::SchemaGrammar_setDatatypeRegistry;
> > *setNamespaceScope = *XML::Xercesc::SchemaGrammar_setNamespaceScope;
> > *setValidSubstitutionGroups =
> > *XML::Xercesc::SchemaGrammar_setValidSubstitutionGroups;
> > *setUPAChecked = *XML::Xercesc::SchemaGrammar_setUPAChecked;
> > *putGroupElemDecl = *XML::Xercesc::SchemaGrammar_putGroupElemDecl;
> > 
> >  
> > > jas.
> > > 
> > 
> > 
> > ---------------------------------------------------------------------
> > To unsubscribe, e-mail: xerces-p-dev-unsubscribe@xml.apache.org
> > For additional commands, e-mail: xerces-p-dev-help@xml.apache.org
> > 
> > 
> 
> 


---------------------------------------------------------------------
To unsubscribe, e-mail: xerces-p-dev-unsubscribe@xml.apache.org
For additional commands, e-mail: xerces-p-dev-help@xml.apache.org


Re: But Wait, There's More!! Re: moron, yet again. Re: creating actual_cast for XML::Xerces::Grammar Re: more problems on porting SEnumval.pl

Posted by "Jason E. Stewart" <ja...@openinformatics.com>.
"John Utz" <ut...@singingfish.com> writes:

> really? i am working from the example of the DOM stuff, and the methods
> that are listed in the @dom_node_methods all end up in Xerces.pm with
> the following line added:
> 
>     # automatically convert to base class
>     $result = $result->actual_cast();

My mistake. You are correct, you have to go through the code, and find
all functions that return a XML::Xerces::Grammar instance and add in
the actual_cast() call.

> sub actual_cast {
>   return undef unless _isa( ref($_[0]), 'XML::Xerces::Grammar' );
>   return $_[0] if $_[0]->isNull;

Like I mentioned yesterday, get rid of the isNull() line, there is no
such method for Grammar, and get rid of _isa() and just use the
following:

  sub actual_cast {
    my ($self) = @_
    return undef unless $self->isa('XML::Xerces::Grammar' );

> but i dont think this is sufficient, because it appears to me that the
> call to actual_cast has to be inserted in the methods in the pm
> file.

correct.

> thats what i assume this code is doing:
> 
>     #   I?DOM_Node: automatically convert to base class
>     if (grep {/$CURR_CLASS/} @dom_node_methods) {
>       if (my ($sub) = /^sub\s+([\w_]+)/) {
> 	$sub = "$ {CURR_CLASS}::$sub";
> 	if (grep {/$sub$/} @dom_node_methods) {
> 	  my $fix = <<'EOT';
>     # automatically convert to base class
>     $result = $result->actual_cast();
> EOT
> 	  fix_method(\*FILE,
> 		     \*TEMP,
> 		     qr/return undef/,
> 		     $fix,
> 		     1);
> 	  next;
> 	}
>       }
>     }
> 
> so, am i still wrong? i am content to be wrong. :-) 

You are most definately correct, I wasn't taking time to read your
email. 

You'll need to have a @grammar_methods array that you populate with
the names of methods that return grammars. and then use:

    #   Grammar: automatically convert to base class
    if (grep {/$CURR_CLASS/} @dom_node_methods) {
      if (my ($sub) = /^sub\s+([\w_]+)/) {
	$sub = "$ {CURR_CLASS}::$sub";
	if (grep {/$sub$/} @grammar_methods) {
	  my $fix = <<'EOT';
    # automatically convert to base class
    $result = $result->actual_cast();
EOT
	  fix_method(\*FILE,
		     \*TEMP,
		     qr/return undef/,
		     $fix,
		     1);
	  next;
	}
      }

The fix_method() call goes through the text of the method and
substitutes your code (in $fix) for the code inside the regular
expression (qr/return undef/).

> 10 days ago i knew zip about SWIG, and this was probably not the project i
> would have picked for getting my tootsies wet :-)
> 
> but the help you've provided has more than made up for the steepness of
> the learning curve...

Glad I've helped. Getting other people to help with the development of
XML::Xerces has been a dream of mine for quite a while.

Keep up the good work,
jas.

---------------------------------------------------------------------
To unsubscribe, e-mail: xerces-p-dev-unsubscribe@xml.apache.org
For additional commands, e-mail: xerces-p-dev-help@xml.apache.org


Re: But Wait, There's More!! Re: moron, yet again. Re: creating actual_cast for XML::Xerces::Grammar Re: more problems on porting SEnumval.pl

Posted by John Utz <ut...@singingfish.com>.
hmmmm

On 13 Mar 2002, (Jason E. Stewart) wrote:

> "John Utz" <ut...@singingfish.com> writes:
> 
> > I think that i have created the correct actual_cast and reinterpret_class,
> > but i just realized that this doesnt get propogated to the methods,
> > 
> > i see there is some code that has some 'transmogrification' regexp work
> > and does this work on the lsit @dom_node_methods.
> > 
> > do i need to do something with this? do i need to create a
> > @grammar_methods? what goes into this list and what doesnt go into this
> > list, or am i barking up the wrong tree?
> 
> You're barking pretty loud. Chances are it's the wrong tree ;-)

really? i am working from the example of the DOM stuff, and the methods
that are listed in the @dom_node_methods all end up in Xerces.pm with
the following line added:

    # automatically convert to base class
    $result = $result->actual_cast();


> At about line 609 in postModule.pl, there's the begining of a HERE
> doc:
> 
>   my $extra = <<'EXTRA';
> 
> which goes until almost the end of the file at line 1234. The last few
> lines of the script print out $extra to the TEMP filehandle, and then
> the temp file gets renamed to Xerces.pm. 
> 
> The moral of this story is that anything that you insert between the
> start of the HERE doc and the end will get printed out verbatim into
> Xerces.pm.
> 
> The only thing you have to watch out for is the 'package'
> declarations, like:
> 
>    package XML::Xerces::DOM_Node;
> 
> every method defined after that line will be in the
> XML::Xerces::DOM_Node package, until a new package declaration occurs.
> 
> So if you want stuff to appear in the XML::Xerces::Grammar package,
> you'll need to stick it right before one of my package defs like so:
> 
>    package XML::Xerces::Grammar;
> 
>    # insert you methods here
> 
>    package XML::Xerces::DOM_Node;
> 
>    # define methods for DOM_Node...
> 
> Also, for actual_cast() you don't need the following:
> 
>   sub actual_cast {
>     return undef unless _isa( ref($_[0]), 'XML::Xerces::DOM_Node' );
>     return $_[0] if $_[0]->isNull;
> 
> This should work:
> 
>   sub actual_cast {
>     my ($self) = @_;
>     return undef unless $self->isa('XML::Xerces::Grammar');
> 
> The isNull() stuff is only for DOM_Node subclasses, and I have no idea
> why the _isa() method exists. As far as I can tell, it is just a very
> inefficient reimplementation of UNIVERSAL::isa(). If Harmon or
> Frederick Paul are listening maybe they can enlighten me.

well, i thing that i actually had all those parts sorted out yesterday,
before i sent the mail:

package XML::Xerces::Grammar;

sub _isa {
  return 0 unless defined $_[0];

  my %package_hash = ($_[0] => 1);
  my @package_array = ($_[0]);
  my $base = $_[1];

  while(my $class = shift @package_array) {
    return 1 if "$class" eq "$base";
    foreach my $inherit (eval "\@$class\::ISA;") {
      unless ($package_hash{$inherit}) {
        $package_hash{$inherit} = 1;
        push @package_array, $inherit;
      }
    }
  }
  return 0;
};


sub _reinterpret_cast {
  return undef unless ref $_[1];

  bless $_[1], $_[0];

  my($raw_ref, $tied) = ($_[1] =~ m[=(.*)\(]);

  if ($raw_ref eq 'SCALAR')   { $tied = tied ${$_[1]}; }
  elsif ($raw_ref eq 'ARRAY') { $tied = tied @{$_[1]}; }
  elsif ($raw_ref eq 'HASH')  { $tied = tied %{$_[1]}; }

  return $_[1] unless $tied;

  bless $tied, $_[0];
  return $_[1];
};

sub actual_cast {
  return undef unless _isa( ref($_[0]), 'XML::Xerces::Grammar' );
  return $_[0] if $_[0]->isNull;

  my $grammar_type = $_[0]->getGrammarType;
  return _reinterpret_cast('XML::Xerces::SchemaGrammar', $_[0])
      if $grammar_type == $XML::Xerces::SchemaGrammar;
  return _reinterpret_cast('XML::Xerces::Grammar', $_[0])
      if $grammar_type == $XML::Xerces::Grammar;

  return $_[0];
}


but i dont think this is sufficient, because it appears to me that the
call to actual_cast has to be inserted in the methods in the pm file.

thats what i assume this code is doing:

    #   I?DOM_Node: automatically convert to base class
    if (grep {/$CURR_CLASS/} @dom_node_methods) {
      if (my ($sub) = /^sub\s+([\w_]+)/) {
	$sub = "$ {CURR_CLASS}::$sub";
	if (grep {/$sub$/} @dom_node_methods) {
	  my $fix = <<'EOT';
    # automatically convert to base class
    $result = $result->actual_cast();
EOT
	  fix_method(\*FILE,
		     \*TEMP,
		     qr/return undef/,
		     $fix,
		     1);
	  next;
	}
      }
    }


so, am i still wrong? i am content to be wrong. :-) 

10 days ago i knew zip about SWIG, and this was probably not the project i
would have picked for getting my tootsies wet :-)

but the help you've provided has more than made up for the steepness of
the learning curve...

> HTH,
> jas.
> 
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: xerces-p-dev-unsubscribe@xml.apache.org
> For additional commands, e-mail: xerces-p-dev-help@xml.apache.org
> 
> 


---------------------------------------------------------------------
To unsubscribe, e-mail: xerces-p-dev-unsubscribe@xml.apache.org
For additional commands, e-mail: xerces-p-dev-help@xml.apache.org


Re: But Wait, There's More!! Re: moron, yet again. Re: creating actual_cast for XML::Xerces::Grammar Re: more problems on porting SEnumval.pl

Posted by "Jason E. Stewart" <ja...@openinformatics.com>.
"John Utz" <ut...@singingfish.com> writes:

> I think that i have created the correct actual_cast and reinterpret_class,
> but i just realized that this doesnt get propogated to the methods,
> 
> i see there is some code that has some 'transmogrification' regexp work
> and does this work on the lsit @dom_node_methods.
> 
> do i need to do something with this? do i need to create a
> @grammar_methods? what goes into this list and what doesnt go into this
> list, or am i barking up the wrong tree?

You're barking pretty loud. Chances are it's the wrong tree ;-)

At about line 609 in postModule.pl, there's the begining of a HERE
doc:

  my $extra = <<'EXTRA';

which goes until almost the end of the file at line 1234. The last few
lines of the script print out $extra to the TEMP filehandle, and then
the temp file gets renamed to Xerces.pm. 

The moral of this story is that anything that you insert between the
start of the HERE doc and the end will get printed out verbatim into
Xerces.pm.

The only thing you have to watch out for is the 'package'
declarations, like:

   package XML::Xerces::DOM_Node;

every method defined after that line will be in the
XML::Xerces::DOM_Node package, until a new package declaration occurs.

So if you want stuff to appear in the XML::Xerces::Grammar package,
you'll need to stick it right before one of my package defs like so:

   package XML::Xerces::Grammar;

   # insert you methods here

   package XML::Xerces::DOM_Node;

   # define methods for DOM_Node...

Also, for actual_cast() you don't need the following:

  sub actual_cast {
    return undef unless _isa( ref($_[0]), 'XML::Xerces::DOM_Node' );
    return $_[0] if $_[0]->isNull;

This should work:

  sub actual_cast {
    my ($self) = @_;
    return undef unless $self->isa('XML::Xerces::Grammar');

The isNull() stuff is only for DOM_Node subclasses, and I have no idea
why the _isa() method exists. As far as I can tell, it is just a very
inefficient reimplementation of UNIVERSAL::isa(). If Harmon or
Frederick Paul are listening maybe they can enlighten me.

HTH,
jas.

---------------------------------------------------------------------
To unsubscribe, e-mail: xerces-p-dev-unsubscribe@xml.apache.org
For additional commands, e-mail: xerces-p-dev-help@xml.apache.org