42cc577449528ae63a3406151ddec793ca5cdb44
[yaz-moved-to-github.git] / src / zoom-opt.c
1 /*
2  * Copyright (C) 1995-2007, Index Data ApS
3  * See the file LICENSE for details.
4  *
5  * $Id: zoom-opt.c,v 1.9 2008-01-07 17:32:49 adam Exp $
6  */
7 /**
8  * \file zoom-opt.c
9  * \brief Implements ZOOM options handling
10  */
11 #include <assert.h>
12 #include "zoom-p.h"
13
14 #include <yaz/xmalloc.h>
15
16 static void set_value(struct ZOOM_options_entry **e,
17                       const char *value, int len)
18 {
19     (*e)->value = 0;
20     (*e)->len = 0;
21     if (value)
22     {
23         (*e)->value = (char *) xmalloc(len+1);
24         memcpy((*e)->value, value, len);
25         (*e)->value[len] = '\0';
26         (*e)->len = len;
27     }
28 }
29
30 static void append_entry(struct ZOOM_options_entry **e,
31                          const char *name, const char *value, int len)
32 {
33     *e = (struct ZOOM_options_entry *) xmalloc(sizeof(**e));
34     (*e)->name = xstrdup(name);
35     set_value(e, value, len);
36     (*e)->next = 0;
37 }
38
39 ZOOM_API(ZOOM_options)
40     ZOOM_options_dup(ZOOM_options src)
41 {
42     if (!src)
43         return 0;
44     else
45     {
46         ZOOM_options dst = ZOOM_options_create();
47         struct ZOOM_options_entry *src_e = src->entries;
48         struct ZOOM_options_entry **dst_e = &dst->entries;
49         
50         while(src_e)
51         {
52             append_entry(dst_e, src_e->name, src_e->value, src_e->len);
53             dst_e = &(*dst_e)->next;
54             src_e = src_e->next;
55         }
56         dst->parent1 = ZOOM_options_dup(src->parent1);
57         dst->parent2 = ZOOM_options_dup(src->parent2);
58         return dst;
59     }
60 }
61
62 ZOOM_API(ZOOM_options)
63     ZOOM_options_create_with_parent(ZOOM_options parent)
64 {
65     return ZOOM_options_create_with_parent2(parent, 0);
66 }
67
68 ZOOM_API(ZOOM_options)
69     ZOOM_options_create(void)
70 {
71     return ZOOM_options_create_with_parent(0);
72 }
73
74
75 ZOOM_API(ZOOM_options)
76     ZOOM_options_create_with_parent2(ZOOM_options parent1,
77                                      ZOOM_options parent2)
78 {
79     ZOOM_options opt = (ZOOM_options) xmalloc(sizeof(*opt));
80
81     opt->refcount = 1;
82     opt->callback_func = 0;
83     opt->callback_handle = 0;
84     opt->entries = 0;
85     opt->parent1= parent1;
86     if (parent1)
87         (parent1->refcount)++;
88     opt->parent2= parent2;
89     if (parent2)
90         (parent2->refcount)++;
91     return opt;
92 }
93
94
95 void ZOOM_options_addref(ZOOM_options opt)
96 {
97     (opt->refcount)++;
98 }
99
100 ZOOM_API(ZOOM_options_callback)
101     ZOOM_options_set_callback (
102     ZOOM_options opt,
103     ZOOM_options_callback callback_func,
104     void *callback_handle)
105 {
106     ZOOM_options_callback callback_old;
107     
108     assert(opt);
109     callback_old = opt->callback_func;
110     opt->callback_func = callback_func;
111     opt->callback_handle = callback_handle;
112     return callback_old;
113 }
114
115 ZOOM_API(void)
116     ZOOM_options_destroy(ZOOM_options opt)
117 {
118     if (!opt)
119         return;
120     (opt->refcount)--;
121     if (opt->refcount == 0)
122     {
123         struct ZOOM_options_entry *e;
124         
125         ZOOM_options_destroy(opt->parent1);
126         ZOOM_options_destroy(opt->parent2);
127         e = opt->entries;
128         while (e)
129         {
130             struct ZOOM_options_entry *e0 = e;
131             xfree(e->name);
132             xfree(e->value);
133             e = e->next;
134             xfree(e0);
135         }
136         xfree(opt);
137     }
138 }
139
140
141 ZOOM_API(void)
142     ZOOM_options_setl(ZOOM_options opt, const char *name, const char *value,
143                       int len)
144 {
145     struct ZOOM_options_entry **e;
146
147     e = &opt->entries;
148     while (*e)
149     {
150         if (!strcmp((*e)->name, name))
151         {
152             xfree((*e)->value);
153             set_value(e, value, len);
154             return;
155         }
156         e = &(*e)->next;
157     }
158     append_entry(e, name, value, len);
159 }
160
161 ZOOM_API(void)
162     ZOOM_options_set(ZOOM_options opt, const char *name, const char *value)
163 {
164     ZOOM_options_setl(opt, name, value, value ? strlen(value): 0);
165 }
166
167 ZOOM_API(const char *)
168     ZOOM_options_getl(ZOOM_options opt, const char *name, int *lenp)
169 {
170     const char *v = 0;
171     if (!opt)
172         return 0;
173     if (opt->callback_func)
174     {
175         v = (*opt->callback_func)(opt->callback_handle, name);
176         if (v)
177             *lenp = strlen(v);
178     }
179     if (!v)
180     {
181         struct ZOOM_options_entry *e;
182         for (e = opt->entries; e; e = e->next)
183             if (!strcmp(e->name, name))
184             {
185                 v = e->value;
186                 *lenp = e->len;
187                 break;
188             }
189     }
190     if (!v)
191         v = ZOOM_options_getl(opt->parent1, name, lenp);
192     if (!v)
193         v = ZOOM_options_getl(opt->parent2, name, lenp);
194     return v;
195 }
196
197 ZOOM_API(const char *)
198     ZOOM_options_get(ZOOM_options opt, const char *name)
199 {
200     int dummy;
201     return ZOOM_options_getl(opt, name, &dummy);
202 }
203
204 ZOOM_API(int)
205     ZOOM_options_get_bool(ZOOM_options opt, const char *name, int defa)
206 {
207     const char *v = ZOOM_options_get(opt, name);
208     
209     if (!v)
210         return defa;
211     if (!strcmp(v, "1") || !strcmp(v, "T"))
212         return 1;
213     return 0;
214 }
215
216 ZOOM_API(int)
217     ZOOM_options_get_int(ZOOM_options opt, const char *name, int defa)
218 {
219     const char *v = ZOOM_options_get(opt, name);
220
221     if (!v || !*v)
222         return defa;
223     return atoi(v);
224 }
225
226 ZOOM_API(void)
227 ZOOM_options_set_int(ZOOM_options opt, const char *name, int value)
228 {
229     char s[40];
230
231     sprintf(s, "%d", value);
232     ZOOM_options_set(opt, name, s);
233 }
234 /*
235  * Local variables:
236  * c-basic-offset: 4
237  * indent-tabs-mode: nil
238  * End:
239  * vim: shiftwidth=4 tabstop=8 expandtab
240  */
241