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