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