~ubuntu-branches/debian/squeeze/sword/squeeze

« back to all changes in this revision

Viewing changes to src/mgr/versemgr.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Jonathan Marsden, Jonathan Marsden, Dmitrijs Ledkovs, Closed Bugs
  • Date: 2009-05-30 11:55:55 UTC
  • mfrom: (1.3.1 upstream) (6.1.1 experimental)
  • Revision ID: james.westby@ubuntu.com-20090530115555-r427zsn3amivdpfu
Tags: 1.6.0+dfsg-1
[ Jonathan Marsden ]
* New upstream release. (Closes: #507960) (LP: #320558)
* debian/patches/02_libver.diff:
  - Bump SONAME to 8 -- SWORD 1.6 is not backward compatible with 1.5.11.
* debian/patches/series:
  - Remove 10_diatheke.diff -- included in upstream source.
* debian/patches/:
  - Remove several old unused .diff files.
  - Add 11_regex_only_when_needed.diff to conditionally include regex lib.
  - Add 12_fix_compiler_warnings.diff to remove all compiler warnings.
  - Add 13_fix_osis2mod_compression_default.diff from upstream svn.
  - Add 14_closing_section_not_chapter.diff from upstream svn.
* debian/libsword7.*: 
  - Rename to libsword8.*
  - Change libsword7 to libsword8 within files.
* debian/rules: 
  - SONAME bump to 8.
  - Set library version check to >= 1.6
* debian/control:
  - Change libsword7 to libsword8.
  - Add libsword7 to Conflicts.
  - Fix case of sword to SWORD in package descriptions.
  - Bump Standards-Version to 3.8.1 (no changes needed).
  - Fix section for libsword-dbg to avoid lintian warning.
* debian/rules:
  - Add DFSG get-orig-source target.
* debian/copyright:
  - Fix various mistakes in initial attempt to document copyrights.

[ Dmitrijs Ledkovs ]
* debian/rules: Added utils.mk to use missing-files target and call it on
  each build.
* debian/libsword-dev.install: Added libsword.la, previously missing.
* debian/libsword7.install: Added missing libicu translit files.
* debian/control:
  - Updated all uses of SWORD version to 1.6
  - Added libsword-dbg package
* debian/watch: Fixed a small mistake which was resulting in extra "."
  in final version name.
* debian/rules: simplified manpage processing.
* debian/libsword8.lintian-overrides: added override for module
  installation directory.
* debian/copyright: Updated with information about everyfile.
  Closes: #513448 LP: #322638
* debian/diatheke.examples: moved examples here from the diatheke.install
* debian/rules:
  - enabled shell script based testsuite
  - added commented out cppunit testsuite
* debian/patches/40_missing_includes.diff: 
  - added several missing stdio.h includes to prevent FTBFS of testsuite.

[ Closed Bugs ]
* FTBFS on intrepid (LP: #305172)

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/******************************************************************************
 
2
 *  versemgr.cpp        - implementation of class VerseMgr used for managing
 
3
 *                                      versification systems
 
4
 *
 
5
 * $Id: versemgr.cpp 2108 2007-10-13 20:35:02Z scribe $
 
6
 *
 
7
 * Copyright 1998 CrossWire Bible Society (http://www.crosswire.org)
 
8
 *      CrossWire Bible Society
 
9
 *      P. O. Box 2528
 
10
 *      Tempe, AZ  85280-2528
 
11
 *
 
12
 * This program is free software; you can redistribute it and/or modify it
 
13
 * under the terms of the GNU General Public License as published by the
 
14
 * Free Software Foundation version 2.
 
15
 *
 
16
 * This program is distributed in the hope that it will be useful, but
 
17
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 
18
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 
19
 * General Public License for more details.
 
20
 *
 
21
 */
 
22
 
 
23
#include <versemgr.h>
 
24
#include <vector>
 
25
#include <map>
 
26
#include <treekey.h>
 
27
#include <canon.h>              // KJV internal versification system
 
28
#include <swlog.h>
 
29
#include <algorithm>
 
30
 
 
31
#include <canon_null.h>         // null v11n system
 
32
 
 
33
#include <canon_leningrad.h>    // Leningrad Codex (WLC) v11n system
 
34
#include <canon_mt.h>           // Masoretic Text (MT) v11n system
 
35
#include <canon_kjva.h>         // KJV + Apocrypha v11n system
 
36
#include <canon_nrsv.h>         // NRSV v11n system
 
37
#include <canon_nrsva.h>        // NRSVA + Apocrypha v11n system
 
38
 
 
39
using std::vector;
 
40
using std::map;
 
41
using std::distance;
 
42
using std::lower_bound;
 
43
 
 
44
SWORD_NAMESPACE_START
 
45
 
 
46
 
 
47
VerseMgr *VerseMgr::getSystemVerseMgr() {
 
48
        if (!systemVerseMgr) {
 
49
                systemVerseMgr = new VerseMgr();
 
50
                systemVerseMgr->registerVersificationSystem("KJV", otbooks, ntbooks, vm);
 
51
                systemVerseMgr->registerVersificationSystem("Leningrad", otbooks_leningrad, ntbooks_null, vm_leningrad);
 
52
                systemVerseMgr->registerVersificationSystem("MT", otbooks_mt, ntbooks_null, vm_mt);
 
53
                systemVerseMgr->registerVersificationSystem("KJVA", otbooks_kjva, ntbooks, vm_kjva);
 
54
                systemVerseMgr->registerVersificationSystem("NRSV", otbooks, ntbooks, vm_nrsv);
 
55
                systemVerseMgr->registerVersificationSystem("NRSVA", otbooks_nrsva, ntbooks, vm_nrsva);
 
56
        }
 
57
        return systemVerseMgr;
 
58
}
 
59
 
 
60
 
 
61
class VerseMgr::System::Private {
 
62
public:
 
63
        /** Array[chapmax] of maximum verses in chapters */
 
64
        vector<Book> books;
 
65
        map<SWBuf, int> osisLookup;
 
66
 
 
67
        Private() {
 
68
        }
 
69
        Private(const VerseMgr::System::Private &other) {
 
70
                books = other.books;
 
71
                osisLookup = other.osisLookup;
 
72
        }
 
73
        VerseMgr::System::Private &operator =(const VerseMgr::System::Private &other) {
 
74
                books = other.books;
 
75
                osisLookup = other.osisLookup;
 
76
                return *this;
 
77
        }
 
78
};
 
79
 
 
80
 
 
81
class VerseMgr::Book::Private {
 
82
friend struct BookOffsetLess;
 
83
public:
 
84
        /** Array[chapmax] of maximum verses in chapters */
 
85
        vector<int> verseMax;
 
86
        vector<long> offsetPrecomputed;
 
87
 
 
88
        Private() {
 
89
                verseMax.clear();
 
90
        }
 
91
        Private(const VerseMgr::Book::Private &other) {
 
92
                verseMax.clear();
 
93
                verseMax = other.verseMax;
 
94
                offsetPrecomputed = other.offsetPrecomputed;
 
95
        }
 
96
        VerseMgr::Book::Private &operator =(const VerseMgr::Book::Private &other) {
 
97
                verseMax.clear();
 
98
                verseMax = other.verseMax;
 
99
                offsetPrecomputed = other.offsetPrecomputed;
 
100
                return *this;
 
101
        }
 
102
};
 
103
 
 
104
struct BookOffsetLess {
 
105
        bool operator() (const VerseMgr::Book &o1, const VerseMgr::Book &o2) const { return o1.p->offsetPrecomputed[0] < o2.p->offsetPrecomputed[0]; }
 
106
        bool operator() (const long &o1, const VerseMgr::Book &o2) const { return o1 < o2.p->offsetPrecomputed[0]; }
 
107
        bool operator() (const VerseMgr::Book &o1, const long &o2) const { return o1.p->offsetPrecomputed[0] < o2; }
 
108
        bool operator() (const long &o1, const long &o2) const { return o1 < o2; }
 
109
};
 
110
 
 
111
void VerseMgr::Book::init() {
 
112
        p = new Private();
 
113
}
 
114
 
 
115
void VerseMgr::System::init() {
 
116
        p = new Private();
 
117
        BMAX[0] = 0;
 
118
        BMAX[1] = 0;
 
119
        ntStartOffset = 0;
 
120
}
 
121
 
 
122
 
 
123
VerseMgr::System::System(const System &other) {
 
124
        init();
 
125
        name = other.name;
 
126
        BMAX[0] = other.BMAX[0];
 
127
        BMAX[1] = other.BMAX[1];
 
128
        (*p) = *(other.p);
 
129
        ntStartOffset = other.ntStartOffset;
 
130
}
 
131
 
 
132
VerseMgr::System &VerseMgr::System::operator =(const System &other) {
 
133
        name = other.name;
 
134
        BMAX[0] = other.BMAX[0];
 
135
        BMAX[1] = other.BMAX[1];
 
136
        (*p) = *(other.p);
 
137
        ntStartOffset = other.ntStartOffset;
 
138
        return *this;
 
139
}
 
140
 
 
141
 
 
142
VerseMgr::System::~System() {
 
143
        delete p;
 
144
}
 
145
 
 
146
const VerseMgr::Book *VerseMgr::System::getBook(int number) const {
 
147
        return (number < (signed int)p->books.size()) ? &(p->books[number]) : 0;
 
148
}
 
149
 
 
150
 
 
151
int VerseMgr::System::getBookNumberByOSISName(const char *bookName) const {
 
152
        map<SWBuf, int>::const_iterator it = p->osisLookup.find(bookName);
 
153
        return (it != p->osisLookup.end()) ? it->second : -1;
 
154
}
 
155
 
 
156
 
 
157
void VerseMgr::System::loadFromSBook(const sbook *ot, const sbook *nt, int *chMax) {
 
158
        int chap = 0;
 
159
        int book = 0;
 
160
        long offset = 0;        // module heading
 
161
        offset++;                       // testament heading
 
162
        while (ot->chapmax) {
 
163
                p->books.push_back(Book(ot->name, ot->osis, ot->prefAbbrev, ot->chapmax));
 
164
                offset++;               // book heading
 
165
                Book &b = p->books[p->books.size()-1];
 
166
                p->osisLookup[b.getOSISName()] = p->books.size();
 
167
                for (int i = 0; i < ot->chapmax; i++) {
 
168
                        b.p->verseMax.push_back(chMax[chap]);
 
169
                        offset++;               // chapter heading
 
170
                        b.p->offsetPrecomputed.push_back(offset);
 
171
                        offset += chMax[chap++];
 
172
                }
 
173
                ot++;
 
174
                book++;
 
175
        }
 
176
        BMAX[0] = book;
 
177
        book = 0;
 
178
        ntStartOffset = offset;
 
179
        offset++;                       // testament heading
 
180
        while (nt->chapmax) {
 
181
                p->books.push_back(Book(nt->name, nt->osis, nt->prefAbbrev, nt->chapmax));
 
182
                offset++;               // book heading
 
183
                Book &b = p->books[p->books.size()-1];
 
184
                p->osisLookup[b.getOSISName()] = p->books.size();
 
185
                for (int i = 0; i < nt->chapmax; i++) {
 
186
                        b.p->verseMax.push_back(chMax[chap]);
 
187
                        offset++;               // chapter heading
 
188
                        b.p->offsetPrecomputed.push_back(offset);
 
189
                        offset += chMax[chap++];
 
190
                }
 
191
                nt++;
 
192
                book++;
 
193
        }
 
194
        BMAX[1] = book;
 
195
 
 
196
        // TODO: build offset speed array
 
197
}
 
198
 
 
199
 
 
200
VerseMgr::Book::Book(const Book &other) {
 
201
        longName = other.longName;
 
202
        osisName = other.osisName;
 
203
        prefAbbrev = other.prefAbbrev;
 
204
        chapMax = other.chapMax;
 
205
        init();
 
206
        (*p) = *(other.p);
 
207
}
 
208
 
 
209
VerseMgr::Book& VerseMgr::Book::operator =(const Book &other) {
 
210
        longName = other.longName;
 
211
        osisName = other.osisName;
 
212
        prefAbbrev = other.prefAbbrev;
 
213
        chapMax = other.chapMax;
 
214
        init();
 
215
        (*p) = *(other.p);
 
216
        return *this;
 
217
}
 
218
 
 
219
 
 
220
VerseMgr::Book::~Book() {
 
221
        delete p;
 
222
}
 
223
 
 
224
 
 
225
int VerseMgr::Book::getVerseMax(int chapter) const {
 
226
        chapter--;
 
227
        return (p && (chapter < (signed int)p->verseMax.size()) && (chapter > -1)) ? p->verseMax[chapter] : -1;
 
228
}
 
229
 
 
230
 
 
231
int VerseMgr::System::getBookCount() const {
 
232
        return (p ? p->books.size() : 0);
 
233
}
 
234
 
 
235
 
 
236
long VerseMgr::System::getOffsetFromVerse(int book, int chapter, int verse) const {
 
237
        long  offset = -1;
 
238
        chapter--;
 
239
 
 
240
        const Book *b = getBook(book);
 
241
 
 
242
        if (!b)                                        return -1;       // assert we have a valid book
 
243
        if ((chapter > -1) && (chapter >= (signed int)b->p->offsetPrecomputed.size())) return -1;       // assert we have a valid chapter
 
244
 
 
245
        offset = b->p->offsetPrecomputed[(chapter > -1)?chapter:0];
 
246
        if (chapter < 0) offset--;
 
247
 
 
248
/* old code
 
249
 *
 
250
        offset = offsets[testament-1][0][book];
 
251
        offset = offsets[testament-1][1][(int)offset + chapter];
 
252
        if (!(offset|verse)) // if we have a testament but nothing else.
 
253
                offset = 1;
 
254
 
 
255
*/
 
256
 
 
257
        return (offset + verse);
 
258
}
 
259
 
 
260
 
 
261
char VerseMgr::System::getVerseFromOffset(long offset, int *book, int *chapter, int *verse) const {
 
262
 
 
263
        if (offset < 1) {       // just handle the module heading corner case up front (and error case)
 
264
                (*book) = -1;
 
265
                (*chapter) = 0;
 
266
                (*verse) = 0;
 
267
                return offset;  // < 0 = error
 
268
        }
 
269
 
 
270
        // binary search for book
 
271
        vector<Book>::iterator b = lower_bound(p->books.begin(), p->books.end(), offset, BookOffsetLess());
 
272
        if (b == p->books.end()) b--;
 
273
        (*book)    = distance(p->books.begin(), b)+1;
 
274
        if (offset < (*(b->p->offsetPrecomputed.begin()))-((((!(*book)) || (*book)==BMAX[0]+1))?2:1)) { // -1 for chapter headings
 
275
                (*book)--;
 
276
                if (b != p->books.begin()) {
 
277
                        b--;    
 
278
                }
 
279
        }
 
280
        vector<long>::iterator c = lower_bound(b->p->offsetPrecomputed.begin(), b->p->offsetPrecomputed.end(), offset);
 
281
 
 
282
        // if we're a book heading, we are lessthan chapter precomputes, but greater book.  This catches corner case.
 
283
        if (c == b->p->offsetPrecomputed.end()) {
 
284
                c--;
 
285
        }
 
286
        if ((offset < *c) && (c == b->p->offsetPrecomputed.begin())) {
 
287
                (*chapter) = (offset - *c)+1;   // should be 0 or -1 (for testament heading)
 
288
                (*verse) = 0;
 
289
        }
 
290
        else {
 
291
                if (offset < *c) c--;
 
292
                (*chapter) = distance(b->p->offsetPrecomputed.begin(), c)+1;
 
293
                (*verse)   = (offset - *c);
 
294
        }
 
295
        return ((*chapter > 0) && (*verse > b->getVerseMax(*chapter))) ? KEYERR_OUTOFBOUNDS : 0;
 
296
}
 
297
 
 
298
 
 
299
/***************************************************
 
300
 * VerseMgr
 
301
 */
 
302
 
 
303
class VerseMgr::Private {
 
304
public:
 
305
        Private() {
 
306
        }
 
307
        Private(const VerseMgr::Private &other) {
 
308
                systems = other.systems;
 
309
        }
 
310
        VerseMgr::Private &operator =(const VerseMgr::Private &other) {
 
311
                systems = other.systems;
 
312
                return *this;
 
313
        }
 
314
        map<SWBuf, System> systems;
 
315
};
 
316
// ---------------- statics -----------------
 
317
VerseMgr *VerseMgr::systemVerseMgr = 0;
 
318
 
 
319
class __staticsystemVerseMgr {
 
320
public:
 
321
        __staticsystemVerseMgr() { }
 
322
        ~__staticsystemVerseMgr() { delete VerseMgr::systemVerseMgr; }
 
323
} _staticsystemVerseMgr;
 
324
 
 
325
 
 
326
void VerseMgr::init() {
 
327
        p = new Private();
 
328
}
 
329
 
 
330
 
 
331
VerseMgr::~VerseMgr() {
 
332
        delete p;
 
333
}
 
334
 
 
335
 
 
336
void VerseMgr::setSystemVerseMgr(VerseMgr *newVerseMgr) {
 
337
        if (systemVerseMgr)
 
338
                delete systemVerseMgr;
 
339
        systemVerseMgr = newVerseMgr;
 
340
}
 
341
 
 
342
 
 
343
const VerseMgr::System *VerseMgr::getVersificationSystem(const char *name) const {
 
344
        map<SWBuf, System>::const_iterator it = p->systems.find(name);
 
345
        return (it != p->systems.end()) ? &(it->second) : 0;
 
346
}
 
347
 
 
348
 
 
349
void VerseMgr::registerVersificationSystem(const char *name, const sbook *ot, const sbook *nt, int *chMax) {
 
350
        p->systems[name] = name;
 
351
        System &s = p->systems[name];
 
352
        s.loadFromSBook(ot, nt, chMax);
 
353
}
 
354
 
 
355
 
 
356
void VerseMgr::registerVersificationSystem(const char *name, const TreeKey *tk) {
 
357
}
 
358
 
 
359
 
 
360
const StringList VerseMgr::getVersificationSystems() const {
 
361
        StringList retVal;
 
362
        for (map<SWBuf, System>::const_iterator it = p->systems.begin(); it != p->systems.end(); it++) {
 
363
                retVal.push_back(it->first);
 
364
        }
 
365
        return retVal;
 
366
}
 
367
 
 
368
 
 
369
SWORD_NAMESPACE_END