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