I’ve released XML::Genx 0.22. There are no functional changes, just a couple of minor bugfixes in order to ensure that it works on Windows correctly.
For some time now, I’d been trying to get XS modules compiling on Windows correctly under ActiveState Perl, all to no avail. But now, thanks to the wonder of Strawberry Perl, I’ve actually been able to build and test the module all on my own. I am hugely grateful to the authors for putting together Strawberry Perl. It’s a huge boon for developing Perl on Windows (Not that I diss ActiveState; they’ve also done a good job, but they’ve gone in different directions).
I pushed out a new release of XML::Genx last night. Nothing worth upgrading for, it just fixes a few compiler warnings under gcc 4.0. Thankfully, after some sage advice from Daniel Jalkut, I managed to get rid of the warnings I was complaining about. Unfortunately, there’s still one warning coming out. But it’s in code that is entirely generated by xsubpp, so there’s not a lot that I can do about it. Ah well.
XML::Genx Compiler Warnings
Naturally, one of the first things I did when I got the new mac was to try compiling my software, XML::Genx, on it. Sadly, it throws up a number of errors.
Genx.xs: In function 'string_sender_write': Genx.xs:209: warning: pointer targets in passing argument 3 of 'Perl_sv_catpv' differ in signedness Genx.xs: In function 'string_sender_write_bounded': Genx.xs:223: warning: pointer targets in passing argument 3 of 'Perl_sv_catpvn_flags' differ in signedness Genx.xs: In function 'XS_XML__Genx_ScrubText': Genx.xs:606: warning: pointer targets in passing argument 2 of 'genxScrubText' differ in signedness Genx.xs:606: warning: pointer targets in passing argument 3 of 'genxScrubText' differ in signedness Genx.c: In function 'XS_XML__Genx__Namespace_GetNamespacePrefix': Genx.c:1068: warning: pointer targets in passing argument 3 of 'Perl_sv_setpv' differ in signedness
Looking around the web, it appears that this is a new warning in gcc 4.0. It also baffles me that that apple would have considered using signed characters for anything by default. However, the obvious fix doesn’t work.
- sv_catpv( *svp, s ); + sv_catpv( *svp, (signed char *)s );
At this point, I suspect that my knowledge of C is fundamentally lacking. Does anybody out there have any ideas what I need to do to fix this warning? The source is
string_sender_write() in Genx.xs, although you’ll probably also want genx.h to look for the typedefs.
Sadly, the gcc manual doesn’t have much to say, except to note the existence of -Wno-pointer-sign to disable the warning. But I’d rather fix it if I can.
XML::Genx 0.19 is now out. Changes include:
- Allow namespace objects to be passed in to StartElementLiteral() and AddAttributeLiteral(). This makes it much easier to put things into the default namespace.
- Add a missing “static” declaration to some XS helper functions.
- Allow multiple different default namespaces inside XML::Genx::SAXWriter. Previously you would get a “Duplicate Prefix” error. Bug spotted by Aristotle Pagaltzis.
- Make the tests work in perl 5.6.1. Not sure when I broke this.
I deliberately left out the SAX changes that Aristotle was talking about on the list, as I wanted some more feedback. I’ll do another new release in a few days if nobody has said anything.
Aristotle Pagaltzis has mentioned XML::Genx. Yay, it needs all the publicity that it can get. He highlighted some issues in XML::Genx::SAXWriter, which I need to address, although getting some consensus from the list first would be good.
He also mentions a problem with default namespaces a little further on. I’ll have to look into that one. I’m not sure if it’s a bug or Genx is supposed to work that way.
But it has made me realise that I need to upgrade the documentation that comes with Genx. The API usage is not always as clear as it could be, particularly when it comes to namespaces and optional function arguments. So a very good EXAMPLES section would do well I think.
Not only that, it’s also made realise that there’s some bad behaviour in there.
- Passing in a namespace object to
StartElementLiteral()doesn’t work properly. It assumes that the stringification of the namespace object is the URL.
- The manner for using
StartElementLiteral()to declare a default namespace sucks, badly. You have to declare the namespace object with the default prefix (ie: ””). Then, you have to call
StartElementLiteral()passing in the URI yourself. And then you have to call
AddNamespace()on the namespace object to switch from the genx created prefix back to the default. Very weird, but fixing the bug above would render this much simpler.
It’s really important to get this sort of thing fixed up so that the API is easy to use and works as expected.
Finally, I’ve also noticed that the last release had an unexpected failure (the Win32 stuff is at least expected failure). What’s irritating is that it’s nothing to do with my code. For some reason, version.xs is being picked up and mingled into my module. I blame the person submitting the CPAN tester report (for now, anyway). I’m sure I saw something about this on a use.perl.org journal recently…
Recently, in yet another fit of distraction from my existing projects, I’ve started working on jenx. It’s an XML writer for Java along similiar lines to GenX. At the moment, I’m just at the stage of banning invalid characters that go through it. So it’s extremely fortuitous that I’ve just seen a link to HOWTO Avoid Being Called a Bozo When Producing XML.
I’ve mostly been basing it on the GenX source code and it’s certainly made me realise quite how complicated a job it is to produce well-formed XML reliably. In particular, namespaces add a very large amount of complexity.
This just underlines how important it is to have good libraries to produce this sort of thing.
Hmmm, looking through that HOWTO makes me realise that I need to check that XML::Genx correctly supports astral characters. I’m sure it does, but I’d better double check in a test… For that matter, does Perl support them?
I came across an interesting situation today. The exception thrown by XML::Genx showed up in completely the wrong place. I suspect that this is due to the fact that I’ve made it a dual valued scalar and Perl doesn’t want to overwrite by appending “at Foo.pm line 23” to the end of it. More investigation required.
Further investigation shows that it’s because I was using the “object” form of
croak(), so Perl didn’t dare touch what I was doing. Doh. So I’ve now simplified things so that it works correctly. XML::Genx 0.12 is now up.
After months of neglect, I’ve picked up on XML::Genx again. One “A. Pagaltzis” wrote to me and made two suggestions. Firstly, why didn’t I wrap
genxScrubText() and secondly why didn’t have a method for automatically creating XML output as a string since that’s such a common use case.
Well, I tried the first one and got very frustrated by XS and its little foibles. So I left the whole project alone for a while.
But last night, I started working on the string appender. And it was actually much easier than I thought. Not only that, it gave me the idea for making the internals much better and cleaner. At the moment I have an internal global hash, because I can’t store things in
$self like normal Perl OO code (because
$self is a blessed scalar point at a genxWriter instead. But genxWriter takes a user pointer, so I can just stick the hash in there. I shoulda thought of that ages ago.
So, one new release today and a cleanup release RSN to rework the internals around user data a bit better. And then I’ll get back to