~ubuntu-branches/ubuntu/trusty/lifelines/trusty

« back to all changes in this revision

Viewing changes to src/gedlib/xreffile.c

  • Committer: Bazaar Package Importer
  • Author(s): Felipe Augusto van de Wiel (faw)
  • Date: 2007-05-23 23:49:53 UTC
  • mfrom: (3.1.3 edgy)
  • Revision ID: james.westby@ubuntu.com-20070523234953-ogno9rnbmth61i7p
Tags: 3.0.50-2etch1
* Changing docs/ll-reportmanual.xml and docs/ll-userguide.xml to fix
  documentation build problems (Closes: #418347).

* lifelines-reports
  - Adding a dependency to lifelines >= 3.0.50 to prevent file conflict.
    (Closes: #405500).

* Updating French translation. Thanks to Bernard Adrian. (Closes: #356671).

Show diffs side-by-side

added added

removed removed

Lines of Context:
23
23
*/
24
24
/*=============================================================
25
25
 * xreffile.c -- Handle the xref file
 
26
 * This module manages the lists of free record numbers
 
27
 * For example, if I1, I2, I4, and I6 are in use
 
28
 *  then irecs contains I3 and I5 (free record numbers)
26
29
 * Copyright(c) 1991-94 by T.T. Wetmore IV; all rights reserved
27
30
 * pre-SourceForge version information:
28
31
 *   2.3.4 - 24 Jun 93    2.3.5 - 02 Sep 93
32
35
#include "sys_inc.h"
33
36
#include "llstdlib.h"
34
37
#include "btree.h"
 
38
#include "gedcom.h"
 
39
#include "gedcomi.h"
35
40
#include "table.h"
36
41
#include "translat.h"
37
 
#include "gedcom.h"
38
42
 
39
43
extern BTREE BTR;
40
44
 
41
 
 
42
45
/*===================================================================
43
46
 * First five words in xrefs file are number of INDI, FAM, EVEN, SOUR
44
47
 *   and other keys in file; remaining words are keys, in respective
48
51
 * nixrefs==2 means there is one deleted INDI key (ixrefs[1])
49
52
 *=================================================================*/
50
53
 
51
 
/*==================================== 
 
54
/*********************************************
 
55
 * local types
 
56
 *********************************************/
 
57
 
 
58
typedef enum { DUPSOK, NODUPS } DUPS;
 
59
 
 
60
 /*==================================== 
52
61
 * deleteset -- set of deleted records
53
62
 *  NB: storage order is IFESX
54
63
 *  whereas canonical order is IFSEX
63
72
typedef struct deleteset_s *DELETESET;
64
73
 
65
74
 
66
 
static BOOLEAN readxrefs(void);
67
 
static void readrecs(DELETESET set);
 
75
/*********************************************
 
76
 * local function prototypes
 
77
 *********************************************/
 
78
 
 
79
/* alphabetical */
 
80
static BOOLEAN addxref_impl(CNSTRING key, DUPS dups);
 
81
static INT find_slot(INT keynum, DELETESET set);
 
82
static void freexref(DELETESET set);
 
83
static DELETESET get_deleteset_from_type(char ctype);
68
84
static STRING getxref(DELETESET set);
69
 
static void addxref(INT key, DELETESET set);
70
85
static void growxrefs(DELETESET set);
 
86
static STRING newxref(STRING xrefp, BOOLEAN flag, DELETESET set);
71
87
static INT num_set(DELETESET set);
72
 
static STRING newxref(STRING xrefp, BOOLEAN flag, DELETESET set);
 
88
static void readrecs(DELETESET set);
 
89
static BOOLEAN readxrefs(void);
73
90
static INT xref_last(DELETESET set);
 
91
static BOOLEAN addixref_impl(INT key, DUPS dups);
 
92
static BOOLEAN addfxref_impl(INT key, DUPS dups);
 
93
static BOOLEAN addsxref_impl(INT key, DUPS dups);
 
94
static BOOLEAN addexref_impl(INT key, DUPS dups);
 
95
static BOOLEAN addxxref_impl(INT key, DUPS dups);
 
96
 
 
97
/*********************************************
 
98
 * local variables
 
99
 *********************************************/
74
100
 
75
101
/* INDI, FAM, EVEN, SOUR, other sets */
76
102
static struct deleteset_s irecs, frecs, srecs, erecs, xrecs;
80
106
 
81
107
static INT maxkeynum=-1; /* cache value of largest key extant (-1 means not sure) */
82
108
 
 
109
/*********************************************
 
110
 * local & exported function definitions
 
111
 * body of module
 
112
 *********************************************/
 
113
 
83
114
/*==================================== 
84
115
 * initdset -- Initialize a delete set
85
116
 *==================================*/
150
181
        if (xreffp) {
151
182
                fclose(xreffp); xreffp = 0;
152
183
        }
 
184
        freexref(&irecs);
 
185
        freexref(&frecs);
 
186
        freexref(&srecs);
 
187
        freexref(&erecs);
 
188
        freexref(&xrecs);
153
189
}
154
190
/*=========================================
155
191
 * getxrefnum -- Return new keynum for type
222
258
                                set->recs[j] = set->recs[i];
223
259
                                set->recs[i] = temp;
224
260
                        }
225
 
                        if (i==1 && !ct) return; /* already sorted */
226
261
                }
 
262
                if (i==1 && !ct) return; /* already sorted */
227
263
        }
228
264
}
229
265
/*======================================
258
294
        ASSERT(xrecs.n > 0);
259
295
        if (irecs.n > irecs.max) growxrefs(&irecs);
260
296
        if (frecs.n > frecs.max) growxrefs(&frecs);
 
297
        if (srecs.n > srecs.max) growxrefs(&srecs);
261
298
        if (erecs.n > erecs.max) growxrefs(&erecs);
262
 
        if (srecs.n > srecs.max) growxrefs(&srecs);
263
299
        if (xrecs.n > xrecs.max) growxrefs(&xrecs);
264
300
        readrecs(&irecs);
265
301
        readrecs(&frecs);
301
337
        return TRUE;
302
338
}
303
339
/*=====================================
304
 
 * addxref -- Add deleted key to xrefs.
 
340
 * find_slot -- Find slot at which to add key
 
341
 *===================================*/
 
342
static INT
 
343
find_slot (INT keynum, DELETESET set)
 
344
{
 
345
        INT lo=1;
 
346
        INT hi=(set->n)-1;
 
347
        /* binary search to find where to insert key */
 
348
        while (lo<=hi) {
 
349
                INT md = (lo + hi)/2;
 
350
                if (keynum > (set->recs)[md])
 
351
                        hi=--md;
 
352
                else if (keynum < (set->recs)[md])
 
353
                        lo=++md;
 
354
                else {
 
355
                        return md;
 
356
                }
 
357
        }
 
358
        return lo;
 
359
}
 
360
/*=====================================
 
361
 * add_xref_to_set_impl -- Add deleted key to xrefs.
305
362
 *  generic for all types
306
363
 *===================================*/
307
 
static void
308
 
addxref (INT key, DELETESET set)
 
364
static BOOLEAN
 
365
add_xref_to_set_impl (INT keynum, DELETESET set, DUPS dups)
309
366
{
310
 
        INT lo,hi,md, i;
311
 
        if (key <= 0 || !xreffp || (set->n) < 1) FATAL();
 
367
        INT lo, i;
 
368
        if (keynum <= 0 || !xreffp || (set->n) < 1) FATAL();
312
369
        if (set->n >= set->max)
313
370
                growxrefs(set);
314
371
        ASSERT(set->n < set->max);
315
 
        lo=1;
316
 
        hi=(set->n)-1;
317
 
        /* binary search to find where to insert key */
318
 
        while (lo<=hi) {
319
 
                md = (lo + hi)/2;
320
 
                if (key>(set->recs)[md])
321
 
                        hi=--md;
322
 
                else if (key<(set->recs)[md])
323
 
                        lo=++md;
324
 
                else {
325
 
                        char msg[64];
326
 
                        sprintf(msg, "Tried to add already-deleted record (%d) to xref (%c)!"
327
 
                                , key, set->ctype);
328
 
                        FATAL2(msg); /* deleting a deleted record! */
329
 
                }
 
372
 
 
373
        lo = find_slot(keynum, set);
 
374
        if ((set->recs)[lo] == keynum) {
 
375
                /* key is already free */
 
376
                char msg[96];
 
377
                if (dups==DUPSOK) 
 
378
                        return FALSE;
 
379
                sprintf(msg, "Tried to add already-deleted record (%d) to xref (%c)!"
 
380
                        , keynum, set->ctype);
 
381
                FATAL2(msg); /* deleting a deleted record! */
330
382
        }
331
383
        /* key replaces xrefs[lo] - push lo+ up */
332
384
        for (i=set->n-1; i>=lo; --i)
333
385
                (set->recs)[i+1] = (set->recs)[i];
334
 
        (set->recs)[lo] = key;
 
386
        (set->recs)[lo] = keynum;
335
387
        (set->n)++;
336
388
        ASSERT(writexrefs());
337
389
        maxkeynum=-1;
338
 
}
339
 
/*===================================================
340
 
 * add?xref -- Wrappers for each type to addxref (qv)
341
 
 *  5 symmetric versions
342
 
 *=================================================*/
343
 
void addixref (INT key) { addxref(key, &irecs); }
344
 
void addfxref (INT key) { addxref(key, &frecs); }
345
 
void addsxref (INT key) { addxref(key, &srecs); }
346
 
void addexref (INT key) { addxref(key, &erecs); }
347
 
void addxxref (INT key) { addxref(key, &xrecs); }
 
390
        return TRUE;
 
391
}
 
392
/*===================================================
 
393
 * add?xref_impl -- Wrappers for each type to add_xref_to_set (qv)
 
394
 *  5 symmetric versions
 
395
 *=================================================*/
 
396
static BOOLEAN addixref_impl (INT key, DUPS dups) { return add_xref_to_set_impl(key, &irecs, dups); }
 
397
static BOOLEAN addfxref_impl (INT key, DUPS dups) { return add_xref_to_set_impl(key, &frecs, dups); }
 
398
static BOOLEAN addsxref_impl (INT key, DUPS dups) { return add_xref_to_set_impl(key, &srecs, dups); }
 
399
static BOOLEAN addexref_impl (INT key, DUPS dups) { return add_xref_to_set_impl(key, &erecs, dups); }
 
400
static BOOLEAN addxxref_impl (INT key, DUPS dups) { return add_xref_to_set_impl(key, &xrecs, dups); }
 
401
/*===================================================
 
402
 * add?xref -- Wrappers for each type to add_xref_to_set (qv)
 
403
 *  5 symmetric versions
 
404
 *=================================================*/
 
405
void addixref (INT key) { addixref_impl(key, NODUPS); }
 
406
void addfxref (INT key) { addfxref_impl(key, NODUPS); }
 
407
void addsxref (INT key) { addsxref_impl(key, NODUPS); }
 
408
void addexref (INT key) { addexref_impl(key, NODUPS); }
 
409
void addxxref (INT key) { addxxref_impl(key, NODUPS); }
 
410
/*===================================================
 
411
 * addxref_impl -- Mark key free (accepts string key, any type)
 
412
 *  key:    [IN]  key to delete (add to free set)
 
413
 *  silent: [IN]  if FALSE, ASSERT if record is already free
 
414
 *=================================================*/
 
415
static BOOLEAN
 
416
addxref_impl (CNSTRING key, DUPS dups)
 
417
{
 
418
        INT keyint = atoi(key + 1);
 
419
        switch(key[0]) {
 
420
        case 'I': return addixref_impl(keyint, dups);
 
421
        case 'F': return addfxref_impl(keyint, dups);
 
422
        case 'S': return addsxref_impl(keyint, dups);
 
423
        case 'E': return addexref_impl(keyint, dups);
 
424
        case 'X': return addxxref_impl(keyint, dups);
 
425
        default: ASSERT(0); return FALSE;
 
426
        }
 
427
}
 
428
/*===================================================
 
429
 * addxref -- Mark key free (accepts string key, any type)
 
430
 * ASSERT if key is already free
 
431
 *=================================================*/
 
432
void addxref (CNSTRING key)
 
433
{
 
434
        addxref_impl(key, NODUPS);
 
435
}
 
436
/*===================================================
 
437
 * addxref_if_missing -- Mark key free (accepts string key, any type)
 
438
 * Does nothing if key already free
 
439
 *=================================================*/
 
440
BOOLEAN addxref_if_missing (CNSTRING key)
 
441
{
 
442
        return addxref_impl(key, DUPSOK);
 
443
}
348
444
/*==========================================
349
445
 * growxrefs -- Grow memory for xrefs array.
350
446
 *  generic for all types
353
449
growxrefs (DELETESET set)
354
450
{
355
451
        INT i, m = set->max, *newp;
356
 
        if (set->n < 500)
357
 
                set->max = set->n + 10;
358
 
        else
359
 
                set->max = set->n + 100;
 
452
        if (set->max == 0)
 
453
                set->max = 64;
 
454
        while (set->max <= set->n)
 
455
                set->max = set->max << 1;
360
456
        newp = (INT *) stdalloc((set->max)*sizeof(INT));
361
457
        if (m) {
362
458
                for (i = 0; i < set->n; i++)
365
461
        }
366
462
        set->recs = newp;
367
463
}
 
464
/*==========================================
 
465
 * get_deleteset_from_type -- Return deleteset
 
466
 *  of type specified
 
467
 *========================================*/
 
468
static DELETESET
 
469
get_deleteset_from_type (char ctype)
 
470
{
 
471
        switch(ctype) {
 
472
        case 'I': return &irecs;
 
473
        case 'F': return &frecs;
 
474
        case 'S': return &srecs;
 
475
        case 'E': return &erecs;
 
476
        case 'X': return &xrecs;
 
477
        }
 
478
        ASSERT(0); return 0;
 
479
}
 
480
/*==========================================
 
481
 * delete_xref_if_present -- If record is listed
 
482
 *  as free, remove it from the free list
 
483
 *========================================*/
 
484
BOOLEAN
 
485
delete_xref_if_present (CNSTRING key)
 
486
{
 
487
        DELETESET set=0;
 
488
        INT keynum=0;
 
489
        INT lo=0;
 
490
        INT i=0;
 
491
 
 
492
        ASSERT(key && key[0] && key[1]);
 
493
        set = get_deleteset_from_type(key[0]);
 
494
        keynum = atoi(key + 1);
 
495
        ASSERT(keynum>0);
 
496
        lo = find_slot(keynum, set);
 
497
        if ((set->recs)[lo] != keynum)
 
498
                return FALSE;
 
499
        /* removing xrefs[lo] -- move lo+ down */
 
500
        for (i=lo; i+1<set->n-1; ++i)
 
501
                (set->recs)[i] = (set->recs)[i+1];
 
502
        --(set->n);
 
503
        ASSERT(writexrefs());
 
504
        maxkeynum=-1;
 
505
        return TRUE;
 
506
 
 
507
}
 
508
/*==========================================
 
509
 * freexref -- Free memory & clear xrefs array
 
510
 *  Called when database is closed
 
511
 *========================================*/
 
512
static void
 
513
freexref (DELETESET set)
 
514
{
 
515
        ASSERT(set);
 
516
        if (set->recs) {
 
517
                stdfree(set->recs);
 
518
                set->recs = 0;
 
519
                set->max = 0;
 
520
                set->n = 0;
 
521
        } else {
 
522
                ASSERT(set->max == 0);
 
523
                ASSERT(set->n == 0);
 
524
        }
 
525
}
368
526
/*==========================================================
369
527
 * num_????s -- Return number of type of things in database.
370
528
 *  5 symmetric versions
371
529
 *========================================================*/
372
530
static INT num_set (DELETESET set)
373
531
{
 
532
        ASSERT(set);
374
533
        return set->recs[0] - set->n;
375
534
}
376
535
INT num_indis (void) { return num_set(&irecs); }
417
576
 * flag = use the current key
418
577
 *  returns static buffer
419
578
 *==============================================*/
420
 
STRING
 
579
static STRING
421
580
newxref (STRING xrefp, BOOLEAN flag, DELETESET set)
422
581
{
423
582
        INT keynum;
438
597
        return(getxref(set));
439
598
}
440
599
/*================================================
441
 
 * newixref -- Return original or next ixref value
442
 
 * xrefp = key of the individual
 
600
 * new?xref -- Return original or next ?xref value
 
601
 * xrefp = key of the record
443
602
 * flag = use the current key
444
603
 *==============================================*/
445
604
STRING
447
606
{
448
607
        return newxref(xrefp, flag, &irecs);
449
608
}
450
 
/*================================================
451
 
 * newfxref -- Return original or next fxref value
452
 
 * xrefp = key of the individual
453
 
 * flag = use the current key
454
 
 *==============================================*/
455
609
STRING
456
610
newfxref (STRING xrefp, BOOLEAN flag)
457
611
{
458
612
        return newxref(xrefp, flag, &frecs);
459
613
}
460
 
/*================================================
461
 
 * newsxref -- Return original or next sxref value
462
 
 * xrefp = key of the individual
463
 
 * flag = use the current key
464
 
 *==============================================*/
465
614
STRING
466
615
newsxref (STRING xrefp, BOOLEAN flag)
467
616
{
468
617
        return newxref(xrefp, flag, &srecs);
469
618
}
470
 
/*================================================
471
 
 * newexref -- Return original or next exref value
472
 
 * xrefp = key of the individual
473
 
 * flag = use the current key
474
 
 *==============================================*/
475
619
STRING
476
620
newexref (STRING xrefp, BOOLEAN flag)
477
621
{
478
622
        return newxref(xrefp, flag, &erecs);
479
623
}
480
 
/*================================================
481
 
 * newxxref -- Return original or next xxref value
482
 
 * xrefp = key of the individual
483
 
 * flag = use the current key
484
 
 *==============================================*/
485
624
STRING
486
625
newxxref (STRING xrefp, BOOLEAN flag)
487
626
{
610
749
INT xref_lasts (void) { return xref_last(&srecs); }
611
750
INT xref_laste (void) { return xref_last(&erecs); }
612
751
INT xref_lastx (void) { return xref_last(&xrecs); }
 
752
/*=======================================
 
753
 * xrefs_get_counts_from_unopened_db --
 
754
 *  read record counts out of file on disk
 
755
 * returns FALSE if specified path is not the root of a traditional lifelines database
 
756
 *=====================================*/
 
757
BOOLEAN
 
758
xrefs_get_counts_from_unopened_db (CNSTRING path, INT *nindis, INT *nfams
 
759
        , INT *nsours, INT *nevens, INT *nothrs)
 
760
{
 
761
        char scratch[100];
 
762
        FILE * fp = 0;
 
763
        INT i;
 
764
        INT ndels[5], nmax[5];
 
765
 
 
766
        ASSERT(!xreffp);
 
767
        sprintf(scratch, "%s/xrefs", path);
 
768
        if (!(fp = fopen(scratch, LLREADBINARY))) {
 
769
                return FALSE;
 
770
        }
 
771
        for (i=0; i<5; ++i) {
 
772
                ASSERT(fread(&ndels[i], sizeof(INT), 1, fp) == 1);
 
773
        }
 
774
        for (i=0; i<5; ++i) {
 
775
                INT j;
 
776
                for (j=0; j<ndels[i]; ++j) {
 
777
                        INT k;
 
778
                        ASSERT(fread(&k, sizeof(INT), 1, fp) == 1);
 
779
                        if (!j)
 
780
                                nmax[i] = k;
 
781
                }
 
782
        }
 
783
        *nindis = nmax[0] - ndels[0];
 
784
        *nfams = nmax[1] - ndels[1];
 
785
        *nevens = nmax[2] - ndels[2];
 
786
        *nsours = nmax[3] - ndels[3];
 
787
        *nothrs = nmax[4] - ndels[4];
 
788
        fclose(fp);
 
789
        return TRUE;
 
790
}