[sword-devel] Feature Complete Perl Interface

John Keiser sword-devel@crosswire.org
21 Jul 2001 17:43:10 -0400

On 21 Jul 2001 10:57:23 -0700, Chris Little wrote:
> > I'll take a look ... right now I'm implementing a new 
> > parse_verse_list() in Perl (the Sword one doesn't seem to 
> > actually support ranges, even though there's an option for it).
> It does parse verse lists.  Just use VerseKey::ParseVerseList and it
> will return a listkey, containing a number of VerseKeys and SWKeys.  The
> VerseKeys have UpperBound and LowerBound indicating the first and last
> verse of the range.  The SWKeys are a single verse.  Check one of the
> front ends for examples of implementation.  I believe the addvs utility
> may have the simples to read implementation.

Oh!  I didn't realize the UpperBound and LowerBound were set.  I've
already implemented it in Perl (and it's pretty nice IMHO) but I'll look
into it.

Oh, while we're at it, I think I've found a bug (though I could be just
doing something wrong.  The software does not seem to be able to compare
verses from books 32 and above (Jonah and above in the Old Testament).
Specifically, given the following code:

int VerseIterator::_verse_greater(char * verse1, char * verse2) {
        if(module->SetKey(verse1)) {
                return -1;
        SWKey key1 = module->Key();
        if(module->SetKey(verse2)) {
                return -1;
        SWKey key2 = module->Key();
        return key1 > key2;

The following results occur:

_verse_greater("James 3:4", "Malachi 4:5"); FALSE
_verse_greater("James 3:4", "Obadiah 12:21"); TRUE
_verse_greater("James 3:4", "Jonah 1:1"); FALSE

I have reimplemented it myself using the testament and book # direct
from Sword, and it works.  Looking at the compare() function in VerseKey
(and tests confirm that it is called) I cannot figure out why this is.

> > How does language stuff work?  Can you just say
> > systemLocaleMgr.setDefaultLocaleName(...) and then book names 
> > and verses and everything will automagically come back in the 
> > new language? Specifically, will the book[] array in VerseKey 
> > work correctly?
> In short, you need to do
>               LocaleMgr::systemLocaleMgr.setDefaultLocaleName(locale);
>               vk.setLocale(locale);
> where locale is string containing the name of a locale and vk is a
> VerseKey you're using.  (Repeat for all VerseKeys whose keys you
> output.)
> You can use 
>               LocaleMgr lm = LocaleMgr::systemLocaleMgr;
>               list<string> loclist =  lm.getAvailableLocales();
>               list<string>::iterator li = loclist.begin();
>               for (;li != loclist.end(); li++) {
>                 cout << li->c_str();
>                 cout << "\n";
>               }
> to output a list of locales installed on the system to your users.

Yahoo!  Thanks.  I'll get that into 0.3 (to be released shortly--I've
included a bunch of functions to play with and merge verse lists and

> I'm looking forward to trying this module out myself.  I have a feeling
> it's not going to be much faster if I rig the diatheke CGI to use it,
> though, since the biggest performance hit still comes with instantiating
> SWMgr.

I agree to a degree on the performance issue; starting up a shell is a
definite hit, though.  The thing I wanted most to gain with a Perl
interface was an easier, more flexible interface than shelling can

> Do you (or anyone else) have any ideas for keeping SWMgr running
> between CGI queries, aside from the idea I mentioned before of making a
> Sword daemon to communicate using sockets?

To keep SWMgr running, all you have to do is use a lib and run your CGI
against mod_perl.  mod_perl allows CGIs to keep static data around
between invocations.  I have not determined how safe this lib is under 
mod_perl; I am working on features still.  But in theory it should
oughta work fine.  I'm not keeping SWMgr around right now, I'll put that
in the next release.