1 /*
2 * bibl.c
3 *
4 * Copyright (c) Chris Putnam 2005-2020
5 *
6 * Source code released under the GPL version 2
7 *
8 */
9 #include <stdio.h>
10 #include <stdlib.h>
11 #include <string.h>
12 #include "bibdefs.h"
13 #include "bibl.h"
14
15 void
bibl_init(bibl * b)16 bibl_init( bibl *b )
17 {
18 b->n = b->max = 0L;
19 b->ref = NULL;
20 }
21
22 static int
bibl_alloc(bibl * b)23 bibl_alloc( bibl * b )
24 {
25 int alloc = 50;
26
27 b->ref = ( fields ** ) malloc( sizeof( fields* ) * alloc );
28 if ( !b->ref ) return BIBL_ERR_MEMERR;
29
30 b->max = alloc;
31
32 return BIBL_OK;
33 }
34
35 static int
bibl_realloc(bibl * b)36 bibl_realloc( bibl * b )
37 {
38 long alloc = b->max * 2;
39 fields **more;
40
41 more = ( fields ** ) realloc( b->ref, sizeof( fields* ) * alloc );
42 if ( !more ) return BIBL_ERR_MEMERR;
43
44 b->ref = more;
45 b->max = alloc;
46
47 return BIBL_OK;
48 }
49
50 int
bibl_addref(bibl * b,fields * ref)51 bibl_addref( bibl *b, fields *ref )
52 {
53 int status = BIBL_OK;
54
55 if ( b->max==0 )
56 status = bibl_alloc( b );
57 else if ( b->n >= b->max )
58 status = bibl_realloc( b );
59
60 if ( status==BIBL_OK ) {
61 b->ref[ b->n ] = ref;
62 b->n++;
63 }
64 return status;
65 }
66
67 void
bibl_free(bibl * b)68 bibl_free( bibl *b )
69 {
70 long i;
71
72 for ( i=0; i<b->n; ++i )
73 fields_delete( b->ref[i] );
74
75 free( b->ref );
76
77 bibl_init( b );
78 }
79
80 /* bibl_copy()
81 *
82 * returns BIBL_OK on success, BIBL_ERR_MEMERR on failure
83 */
84 int
bibl_copy(bibl * bout,bibl * bin)85 bibl_copy( bibl *bout, bibl *bin )
86 {
87 fields *ref;
88 int status;
89 long i;
90
91 for ( i=0; i<bin->n; ++i ) {
92
93 ref = fields_dupl( bin->ref[i] );
94 if ( !ref ) return BIBL_ERR_MEMERR;
95
96 status = bibl_addref( bout, ref );
97 if ( status!=BIBL_OK ) return status;
98
99 }
100
101 return BIBL_OK;
102 }
103
104 /* bibl_findref()
105 *
106 * returns position of reference matching citekey, else -1
107 */
108 long
bibl_findref(bibl * bin,const char * citekey)109 bibl_findref( bibl *bin, const char *citekey )
110 {
111 long i;
112 int n;
113
114 for ( i=0; i<bin->n; ++i ) {
115
116 n = fields_find( bin->ref[i], "refnum", LEVEL_ANY );
117 if ( n==FIELDS_NOTFOUND ) continue;
118
119 if ( !strcmp( fields_value( bin->ref[i], n, FIELDS_CHRP_NOUSE ), citekey ) ) return i;
120
121 }
122
123 return -1;
124 }
125