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

« back to all changes in this revision

Viewing changes to src/keys/listkey.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
 *  listkey.cpp - code for base class 'ListKey'.  ListKey is the basis for all
 
3
 *                types of keys that have lists of specified indexes
 
4
 *                (e.g. a list of verses, place, etc.)
 
5
 *
 
6
 *
 
7
 * Copyright 2009 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
 
 
24
#include <utilstr.h>
 
25
#include <stdlib.h>
 
26
#include <swkey.h>
 
27
#include <listkey.h>
 
28
#include <string.h>
 
29
 
 
30
SWORD_NAMESPACE_START
 
31
 
 
32
static const char *classes[] = {"ListKey", "SWKey", "SWObject", 0};
 
33
SWClass ListKey::classdef(classes);
 
34
 
 
35
/******************************************************************************
 
36
 * ListKey Constructor - initializes instance of ListKey
 
37
 *
 
38
 * ENT: ikey - text key
 
39
 */
 
40
 
 
41
ListKey::ListKey(const char *ikey): SWKey(ikey) {
 
42
        arraymax = 0;
 
43
        ClearList();
 
44
        init();
 
45
}
 
46
 
 
47
 
 
48
ListKey::ListKey(ListKey const &k) : SWKey(k.keytext) {
 
49
        arraymax = k.arraymax;
 
50
        arraypos = k.arraypos;
 
51
        arraycnt = k.arraycnt;
 
52
        array = (arraymax)?(SWKey **)malloc(k.arraymax * sizeof(SWKey *)):0;
 
53
        for (int i = 0; i < arraycnt; i++)
 
54
                array[i] = k.array[i]->clone();
 
55
        init();
 
56
}
 
57
 
 
58
 
 
59
void ListKey::init() {
 
60
        myclass = &classdef;
 
61
        // this is a listkey, bound is always set
 
62
        boundSet = true;
 
63
}
 
64
 
 
65
 
 
66
SWKey *ListKey::clone() const
 
67
{
 
68
        return new ListKey(*this);
 
69
}
 
70
 
 
71
/******************************************************************************
 
72
 * ListKey Destructor - cleans up instance of ListKey
 
73
 */
 
74
 
 
75
ListKey::~ListKey()
 
76
{
 
77
        ClearList();
 
78
}
 
79
 
 
80
 
 
81
/******************************************************************************
 
82
 * ListKey::ClearList   - Clears out elements of list
 
83
 */
 
84
 
 
85
void ListKey::clear()
 
86
{
 
87
        int loop;
 
88
 
 
89
        if (arraymax) {
 
90
                for (loop = 0; loop < arraycnt; loop++)
 
91
                        delete array[loop];
 
92
 
 
93
                free(array);
 
94
                arraymax  = 0;
 
95
        }
 
96
        arraycnt  = 0;
 
97
        arraypos  = 0;
 
98
        array     = 0;
 
99
}
 
100
 
 
101
 
 
102
/******************************************************************************
 
103
 * ListKey::copyFrom Equates this ListKey to another ListKey object
 
104
 *
 
105
 * ENT: ikey - other ListKey object
 
106
 */
 
107
 
 
108
void ListKey::copyFrom(const ListKey &ikey) {
 
109
        ClearList();
 
110
 
 
111
        arraymax = ikey.arraymax;
 
112
        arraypos = ikey.arraypos;
 
113
        arraycnt = ikey.arraycnt;
 
114
        array = (arraymax)?(SWKey **)malloc(ikey.arraymax * sizeof(SWKey *)):0;
 
115
        for (int i = 0; i < arraycnt; i++)
 
116
                array[i] = ikey.array[i]->clone();
 
117
 
 
118
        SetToElement(0);
 
119
}
 
120
 
 
121
 
 
122
/******************************************************************************
 
123
 * ListKey::add - Adds an element to the list
 
124
 */
 
125
 
 
126
void ListKey::add(const SWKey &ikey) {
 
127
        if (++arraycnt > arraymax) {
 
128
                array = (SWKey **) ((array) ? realloc(array, (arraycnt + 32) * sizeof(SWKey *)) : calloc(arraycnt + 32, sizeof(SWKey *)));
 
129
                arraymax = arraycnt + 32;
 
130
        }
 
131
        array[arraycnt-1] = ikey.clone();
 
132
        SetToElement(arraycnt-1);
 
133
}
 
134
 
 
135
 
 
136
 
 
137
/******************************************************************************
 
138
 * ListKey::setPosition(SW_POSITION)    - Positions this key
 
139
 *
 
140
 * ENT: p       - position
 
141
 *
 
142
 * RET: *this
 
143
 */
 
144
 
 
145
void ListKey::setPosition(SW_POSITION p) {
 
146
        switch (p) {
 
147
        case 1: // GCC won't compile P_TOP
 
148
                SetToElement(0, p);
 
149
                break;
 
150
        case 2: // GCC won't compile P_BOTTOM
 
151
                SetToElement(arraycnt-1, p);
 
152
                break;
 
153
        }
 
154
}
 
155
 
 
156
 
 
157
/******************************************************************************
 
158
 * ListKey::increment - Increments a number of elements
 
159
 */
 
160
 
 
161
void ListKey::increment(int step) {
 
162
        if (step < 0) {
 
163
                decrement(step*-1);
 
164
                return;
 
165
        }
 
166
        Error();                // clear error
 
167
        for(; step && !Error(); step--) {
 
168
                if (arraypos < arraycnt) {
 
169
                        if (array[arraypos]->isBoundSet())
 
170
                                (*(array[arraypos]))++;
 
171
                        if ((array[arraypos]->Error()) || (!array[arraypos]->isBoundSet())) {
 
172
                                SetToElement(arraypos+1);
 
173
                        }
 
174
                        else SWKey::setText((const char *)(*array[arraypos]));
 
175
                }
 
176
                else error = KEYERR_OUTOFBOUNDS;
 
177
        }
 
178
}
 
179
 
 
180
 
 
181
/******************************************************************************
 
182
 * ListKey::decrement - Decrements a number of elements
 
183
 */
 
184
 
 
185
void ListKey::decrement(int step) {
 
186
        if (step < 0) {
 
187
                increment(step*-1);
 
188
                return;
 
189
        }
 
190
        Error();                // clear error
 
191
        for(; step && !Error(); step--) {
 
192
                if (arraypos > -1) {
 
193
                        if (array[arraypos]->isBoundSet())
 
194
                                (*(array[arraypos]))--;
 
195
                        if ((array[arraypos]->Error()) || (!array[arraypos]->isBoundSet())) {
 
196
                                SetToElement(arraypos-1, BOTTOM);
 
197
                        }
 
198
                        else SWKey::setText((const char *)(*array[arraypos]));
 
199
                }
 
200
                else error = KEYERR_OUTOFBOUNDS;
 
201
        }
 
202
}
 
203
 
 
204
 
 
205
/******************************************************************************
 
206
 * ListKey::Count       - Returns number of elements in list
 
207
 */
 
208
 
 
209
int ListKey::Count() {
 
210
        return arraycnt;
 
211
}
 
212
 
 
213
 
 
214
/******************************************************************************
 
215
 * ListKey::SetToElement        - Sets key to element number
 
216
 *
 
217
 * ENT: ielement        - element number to set to
 
218
 *
 
219
 * RET: error status
 
220
 */
 
221
 
 
222
char ListKey::SetToElement(int ielement, SW_POSITION pos) {
 
223
        arraypos = ielement;
 
224
        if (arraypos >= arraycnt) {
 
225
                arraypos = (arraycnt>0)?arraycnt - 1:0;
 
226
                error = KEYERR_OUTOFBOUNDS;
 
227
        }
 
228
        else {
 
229
                if (arraypos < 0) {
 
230
                        arraypos = 0;
 
231
                        error = KEYERR_OUTOFBOUNDS;
 
232
                }
 
233
                else {
 
234
                        error = 0;
 
235
                }
 
236
        }
 
237
        
 
238
        if (arraycnt) {
 
239
                if (array[arraypos]->isBoundSet())
 
240
                        (*array[arraypos]) = pos;
 
241
                SWKey::setText((const char *)(*array[arraypos]));
 
242
        }
 
243
        else SWKey::setText("");
 
244
        
 
245
        return error;
 
246
}
 
247
 
 
248
 
 
249
/******************************************************************************
 
250
 * ListKey::GetElement  - Gets a key element number
 
251
 *
 
252
 * ENT: pos     - element number to get (or default current)
 
253
 *
 
254
 * RET: Key or null on error
 
255
 */
 
256
 
 
257
SWKey *ListKey::getElement(int pos) {
 
258
        if (pos < 0)
 
259
                pos = arraypos;
 
260
                
 
261
        if (pos >=arraycnt)
 
262
                error = KEYERR_OUTOFBOUNDS;
 
263
 
 
264
        return (error) ? 0:array[pos];
 
265
}
 
266
        
 
267
 
 
268
/******************************************************************************
 
269
 * ListKey::Remove      - Removes current element from list
 
270
 */
 
271
 
 
272
void ListKey::Remove() {
 
273
        if ((arraypos > -1) && (arraypos < arraycnt)) {
 
274
                delete array[arraypos];
 
275
                if (arraypos < arraycnt - 1)
 
276
                        memmove(&array[arraypos], &array[arraypos+1], (arraycnt - arraypos - 1) * sizeof(SWKey *));
 
277
                arraycnt--;
 
278
                
 
279
                SetToElement((arraypos)?arraypos-1:0);
 
280
        }
 
281
}
 
282
 
 
283
 
 
284
/******************************************************************************
 
285
 * ListKey::getRangeText - returns parsable range text for this key
 
286
 */
 
287
 
 
288
const char *ListKey::getRangeText() const {
 
289
        char *buf = new char[(arraycnt + 1) * 255];
 
290
        buf[0] = 0;
 
291
        for (int i = 0; i < arraycnt; i++) {
 
292
                strcat(buf, array[i]->getRangeText());
 
293
                if (i < arraycnt-1)
 
294
                        strcat(buf, "; ");
 
295
        }
 
296
        stdstr(&rangeText, buf);
 
297
        delete [] buf;
 
298
        return rangeText;
 
299
}
 
300
 
 
301
 
 
302
/******************************************************************************
 
303
 * ListKey::getOSISRefRangeText - returns parsable range text for this key
 
304
 */
 
305
 
 
306
const char *ListKey::getOSISRefRangeText() const {
 
307
        char *buf = new char[(arraycnt + 1) * 255];
 
308
        buf[0] = 0;
 
309
        for (int i = 0; i < arraycnt; i++) {
 
310
                strcat(buf, array[i]->getOSISRefRangeText());
 
311
                if (i < arraycnt-1)
 
312
                        strcat(buf, ";");
 
313
        }
 
314
        stdstr(&rangeText, buf);
 
315
        delete [] buf;
 
316
        return rangeText;
 
317
}
 
318
 
 
319
 
 
320
/******************************************************************************
 
321
 * ListKey::getText - returns text key if (const char *) cast is requested
 
322
 */
 
323
 
 
324
const char *ListKey::getText() const {
 
325
        int pos = arraypos;
 
326
        SWKey *key = (pos >= arraycnt) ? 0:array[pos];
 
327
        return (key) ? key->getText() : keytext;
 
328
}
 
329
 
 
330
 
 
331
void ListKey::setText(const char *ikey) {
 
332
        // at least try to set the current element to this text
 
333
        for (arraypos = 0; arraypos < arraycnt; arraypos++) {
 
334
                SWKey *key = array[arraypos];
 
335
                if (key) {
 
336
                        if (key->isTraversable() && key->isBoundSet()) {
 
337
                                key->setText(ikey);
 
338
                                if (!key->Error())
 
339
                                        break;
 
340
                        }
 
341
                        else {
 
342
                                if (!strcmp(key->getText(), ikey))
 
343
                                        break;
 
344
                        }
 
345
                }
 
346
        }
 
347
        if (arraypos >= arraycnt) {
 
348
                error = 1;
 
349
                arraypos = arraycnt-1;
 
350
        }
 
351
        
 
352
        SWKey::setText(ikey);
 
353
}
 
354
 
 
355
// This sort impl sucks.  Let's change it to a quicksort or some other efficient algol
 
356
void ListKey::sort() {
 
357
        for (int i = 0; i < arraycnt; i++) {
 
358
                for (int j = i; j < arraycnt; j++) {
 
359
                        if (*array[j] < *array[i]) {
 
360
                                SWKey *tmp = array[i];
 
361
                                array[i] = array[j];
 
362
                                array[j] = tmp;
 
363
                        }
 
364
                }
 
365
        }
 
366
}
 
367
 
 
368
SWORD_NAMESPACE_END
 
369