1 //
2 //      aegis - project change supervisor
3 //      Copyright (C) 2004-2008, 2012 Peter Miller
4 //      Copyright (C) 2006 Walter Franzini
5 //
6 //      This program is free software; you can redistribute it and/or modify
7 //      it under the terms of the GNU General Public License as published by
8 //      the Free Software Foundation; either version 3 of the License, or
9 //      (at your option) any later version.
10 //
11 //      This program is distributed in the hope that it will be useful,
12 //      but WITHOUT ANY WARRANTY; without even the implied warranty of
13 //      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 //      GNU General Public License for more details.
15 //
16 //      You should have received a copy of the GNU General Public License
17 //      along with this program. If not, see
18 //      <http://www.gnu.org/licenses/>.
19 //
20 
21 #include <common/ac/assert.h>
22 #include <common/ac/string.h>
23 #include <common/ac/stdlib.h>
24 
25 #include <common/boolean.h>
26 
27 #include <libaegis/attribute.h>
28 
29 
30 attributes_ty *
attributes_list_find(attributes_list_ty * alp,const char * name)31 attributes_list_find(attributes_list_ty *alp, const char *name)
32 {
33     if (!alp)
34         return 0;
35     for (size_t j = 0; j < alp->length; ++j)
36     {
37         attributes_ty *ap = alp->list[j];
38         assert(ap);
39         assert(ap->name);
40         assert(ap->value);
41         if (ap->name && ap->value && 0 == strcasecmp(ap->name->str_text, name))
42             return ap;
43     }
44     return 0;
45 }
46 
47 
48 bool
attributes_list_find_boolean(attributes_list_ty * alp,const char * name,bool default_value)49 attributes_list_find_boolean(attributes_list_ty *alp, const char *name,
50     bool default_value)
51 {
52     attributes_ty *ap = attributes_list_find(alp, name);
53     if (!ap || !ap->value)
54         return default_value;
55     return string_to_bool(nstring(ap->value), default_value);
56 }
57 
58 
59 double
attributes_list_find_real(attributes_list_ty * alp,const char * name,double default_value)60 attributes_list_find_real(attributes_list_ty *alp, const char *name,
61     double default_value)
62 {
63     attributes_ty *ap = attributes_list_find(alp, name);
64     if (!ap || !ap->value)
65         return default_value;
66     char *ep = 0;
67     double result = strtod(ap->value->str_text, &ep);
68     if (ep == ap->value->str_text || *ep)
69         return default_value;
70     return result;
71 }
72 
73 
74 long
attributes_list_find_integer(attributes_list_ty * alp,const char * name,long default_value)75 attributes_list_find_integer(attributes_list_ty *alp, const char *name,
76     long default_value)
77 {
78     attributes_ty *ap = attributes_list_find(alp, name);
79     if (!ap || !ap->value)
80         return default_value;
81     char *ep = 0;
82     long result = strtol(ap->value->str_text, &ep, 0);
83     if (ep == ap->value->str_text || *ep)
84         return default_value;
85     return result;
86 }
87 
88 
89 void
attributes_list_remove(attributes_list_ty * alp,const char * name)90 attributes_list_remove(attributes_list_ty *alp, const char *name)
91 {
92     attributes_ty *ap = attributes_list_extract(alp, name);
93     if (ap)
94         attributes_type.free(ap);
95 }
96 
97 
98 attributes_ty *
attributes_list_extract(attributes_list_ty * alp,const char * name)99 attributes_list_extract(attributes_list_ty *alp, const char *name)
100 {
101     if (!alp)
102         return 0;
103     for (size_t j = 0; j < alp->length; ++j)
104     {
105         attributes_ty *ap = alp->list[j];
106         assert(ap);
107         assert(ap->name);
108         if (ap->name && 0 == strcasecmp(ap->name->str_text, name))
109         {
110             for (size_t k = j + 1; k < alp->length; ++k)
111                 alp->list[k - 1] = alp->list[k];
112             alp->length--;
113             return ap;
114         }
115     }
116     return 0;
117 }
118 
119 
120 void
attributes_list_insert(attributes_list_ty * alp,const char * name,const char * value)121 attributes_list_insert(attributes_list_ty *alp, const char *name,
122     const char *value)
123 {
124     attributes_ty *ap = attributes_list_find(alp, name);
125     if (ap)
126     {
127         assert(ap->value);
128         if (ap->value)
129             str_free(ap->value);
130         ap->value = str_from_c(value);
131         return;
132     }
133     attributes_list_append(alp, name, value);
134 }
135 
136 
137 void
attributes_list_append(attributes_list_ty * alp,const char * name,const char * value)138 attributes_list_append(attributes_list_ty *alp, const char *name,
139     const char *value)
140 {
141     assert(alp);
142     if (!alp)
143         return;
144     meta_type *type;
145     attributes_ty **app =
146         (attributes_ty **)attributes_list_type.list_parse(alp, &type);
147     assert(type == &attributes_type);
148     assert(app);
149     attributes_ty *ap = (attributes_ty *)attributes_type.alloc();
150     ap->name = str_from_c(name);
151     ap->value = str_from_c(value);
152     *app = ap;
153 }
154 
155 
156 void
attributes_list_append_unique(attributes_list_ty * alp,const char * name,string_ty * value)157 attributes_list_append_unique(attributes_list_ty *alp, const char *name,
158     string_ty *value)
159 {
160     assert(alp);
161     if (!alp)
162         return;
163 
164     //
165     // If this exact name and value is already present,
166     // return without doing anything.
167     //
168     for (size_t j = 0; j < alp->length; ++j)
169     {
170         attributes_ty *ap = alp->list[j];
171         assert(ap);
172         assert(ap->name);
173         assert(ap->value);
174         if
175         (
176             0 == strcasecmp(ap->name->str_text, name)
177         &&
178             str_equal(ap->value, value)
179         )
180         {
181             return;
182         }
183     }
184 
185     //
186     // Now that we know it is a unique pair,
187     // append it to the end of the list.
188     //
189     attributes_list_append(alp, name, value->str_text);
190 }
191 
192 void
attributes_list_append_unique(attributes_list_ty * alp,const char * name,const char * value)193 attributes_list_append_unique(attributes_list_ty *alp, const char *name,
194     const char *value)
195 {
196     assert(alp);
197     if (!alp)
198         return;
199 
200     //
201     // If this exact name and value is already present,
202     // return without doing anything.
203     //
204     for (size_t j = 0; j < alp->length; ++j)
205     {
206         attributes_ty *ap = alp->list[j];
207         assert(ap);
208         assert(ap->name);
209         assert(ap->value);
210         if
211         (
212             0 == strcasecmp(ap->name->str_text, name)
213         &&
214             0 == strcmp(ap->value->str_text, value)
215         )
216         {
217             return;
218         }
219     }
220 
221     //
222     // Now that we know it is a unique pair,
223     // append it to the end of the list.
224     //
225     attributes_list_append(alp, name, value);
226 }
227 
228 
229 // vim: set ts=8 sw=4 et :
230