2 Copyright 2015, 2016 IoT.bzh
4 author: José Bollo <jose.bollo@iot.bzh>
6 Licensed under the Apache License, Version 2.0 (the "License");
7 you may not use this file except in compliance with the License.
8 You may obtain a copy of the License at
10 http://www.apache.org/licenses/LICENSE-2.0
12 Unless required by applicable law or agreed to in writing, software
13 distributed under the License is distributed on an "AS IS" BASIS,
14 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 See the License for the specific language governing permissions and
16 limitations under the License.
25 #include <libxml/tree.h>
29 #include "wgt-config.h"
38 static int getpropbool(xmlNodePtr node, const char *prop, int def)
41 char *val = xmlGetProp(node, prop);
45 if (!strcmp(val, "true"))
47 else if (!strcmp(val, "false"))
56 static int getpropnum(xmlNodePtr node, const char *prop, int def)
59 char *val = xmlGetProp(node, prop);
69 static xmlChar *optprop(xmlNodePtr node, const char *prop)
71 return node ? xmlGetProp(node, prop) : NULL;
74 static xmlChar *optcontent(xmlNodePtr node)
76 return node ? xmlNodeGetContent(node) : NULL;
79 static char *mkver(char *version)
84 c = version[lver = 0];
85 while(c && c != ' ' && c != '.')
89 while(c && c != ' ' && c != '.')
94 memcpy(r, version, lver);
102 static char *mkidaver(char *id, char *ver)
109 r = malloc(2 + lid + lver);
113 memcpy(r + lid + 1, ver, lver);
114 r[lid + lver + 1] = 0;
121 static void make_lowercase(char *s)
125 *s = (char)tolower(*s);
131 static int fill_desc(struct wgt_desc *desc, int want_icons, int want_features, int want_preferences)
133 xmlNodePtr node, pnode;
134 struct wgt_desc_icon *icon, **icontail;
135 struct wgt_desc_feature *feature, **featuretail;
136 struct wgt_desc_preference *preference, **preferencetail;
137 struct wgt_desc_param *param, **paramtail;
139 node = wgt_config_widget();
141 WARNING("no widget");
145 desc->id = xmlGetProp(node, wgt_config_string_id);
146 make_lowercase(desc->id);
147 desc->version = xmlGetProp(node, wgt_config_string_version);
148 desc->ver = mkver(desc->version);
149 make_lowercase(desc->ver);
150 desc->idaver = mkidaver(desc->id, desc->ver);
151 desc->width = getpropnum(node, wgt_config_string_width, 0);
152 desc->height = getpropnum(node, wgt_config_string_height, 0);
153 desc->viewmodes = xmlGetProp(node, wgt_config_string_viewmodes);
154 desc->defaultlocale = xmlGetProp(node, wgt_config_string_defaultlocale);
156 node = wgt_config_name();
157 desc->name = optcontent(node);
158 desc->name_short = optprop(node, wgt_config_string_short);
160 node = wgt_config_description();
161 desc->description = optcontent(node);
163 node = wgt_config_author();
164 desc->author = optcontent(node);
165 desc->author_href = optprop(node, wgt_config_string_href);
166 desc->author_email = optprop(node, wgt_config_string_email);
168 node = wgt_config_license();
169 desc->license = optcontent(node);
170 desc->license_href = optprop(node, wgt_config_string_href);
172 node = wgt_config_content();
173 desc->content_src = optprop(node, wgt_config_string_src);
174 if (node && desc->content_src == NULL) {
175 WARNING("content without src");
179 desc->content_type = optprop(node, wgt_config_string_type);
180 desc->content_encoding = optprop(node, wgt_config_string_encoding);
183 icontail = &desc->icons;
184 node = wgt_config_first_icon();
186 icon = malloc(sizeof * icon);
191 icon->src = xmlGetProp(node, wgt_config_string_src);
192 icon->width = getpropnum(node, wgt_config_string_width, 0);
193 icon->height = getpropnum(node, wgt_config_string_height, 0);
198 if (icon->src == NULL) {
199 WARNING("icon without src");
203 icontail = &icon->next;
204 node = wgt_config_next_icon(node);
209 featuretail = &desc->features;
210 node = wgt_config_first_feature();
212 feature = malloc(sizeof * feature);
213 if (feature == NULL) {
217 feature->name = xmlGetProp(node, wgt_config_string_name);
218 feature->required = getpropbool(node, wgt_config_string_required, 1);
219 feature->params = NULL;
221 feature->next = NULL;
222 *featuretail = feature;
224 if (feature->name == NULL) {
225 WARNING("feature without name");
230 paramtail = &feature->params;
231 pnode = wgt_config_first_param(node);
233 param = malloc(sizeof * param);
238 param->name = xmlGetProp(pnode, wgt_config_string_name);
239 param->value = xmlGetProp(pnode, wgt_config_string_value);
244 if (param->name == NULL || param->value == NULL) {
245 WARNING("param without name or value");
250 paramtail = ¶m->next;
251 pnode = wgt_config_next_param(pnode);
254 featuretail = &feature->next;
255 node = wgt_config_next_feature(node);
259 if (want_preferences) {
260 preferencetail = &desc->preferences;
261 node = wgt_config_first_preference();
263 preference = malloc(sizeof * preference);
264 if (preference == NULL) {
268 preference->name = xmlGetProp(node, wgt_config_string_name);
269 preference->value = xmlGetProp(node, wgt_config_string_value);
270 preference->readonly = getpropbool(node, wgt_config_string_readonly, 0);
272 *preferencetail = preference;
273 preference->next = NULL;
275 if (preference->name == NULL) {
276 WARNING("preference without name");
281 preferencetail = &preference->next;
282 node = wgt_config_next_preference(node);
288 static void free_desc(struct wgt_desc *desc)
290 struct wgt_desc_icon *icon;
291 struct wgt_desc_feature *feature;
292 struct wgt_desc_preference *preference;
293 struct wgt_desc_param *param;
296 xmlFree(desc->version);
299 xmlFree(desc->viewmodes);
300 xmlFree(desc->defaultlocale);
302 xmlFree(desc->name_short);
303 xmlFree(desc->description);
304 xmlFree(desc->author);
305 xmlFree(desc->author_href);
306 xmlFree(desc->author_email);
307 xmlFree(desc->license);
308 xmlFree(desc->license_href);
309 xmlFree(desc->content_src);
310 xmlFree(desc->content_type);
311 xmlFree(desc->content_encoding);
315 desc->icons = icon->next;
320 while(desc->features) {
321 feature = desc->features;
322 desc->features = feature->next;
323 xmlFree(feature->name);
324 while(feature->params) {
325 param = feature->params;
326 feature->params = param->next;
327 xmlFree(param->name);
328 xmlFree(param->value);
334 while(desc->preferences) {
335 preference = desc->preferences;
336 desc->preferences = preference->next;
337 xmlFree(preference->name);
338 xmlFree(preference->value);
343 static void dump_desc(struct wgt_desc *desc, FILE *f, const char *prefix)
345 struct wgt_desc_icon *icon;
346 struct wgt_desc_feature *feature;
347 struct wgt_desc_preference *preference;
348 struct wgt_desc_param *param;
350 if (desc->id) fprintf(f, "%sid: %s\n", prefix, desc->id);
351 if (desc->version) fprintf(f, "%sversion: %s\n", prefix, desc->version);
352 if (desc->ver) fprintf(f, "%sver: %s\n", prefix, desc->ver);
353 if (desc->idaver) fprintf(f, "%sidaver: %s\n", prefix, desc->idaver);
354 if (desc->width) fprintf(f, "%swidth: %d\n", prefix, desc->width);
355 if (desc->height) fprintf(f, "%sheight: %d\n", prefix, desc->height);
356 if (desc->viewmodes) fprintf(f, "%sviewmodes: %s\n", prefix, desc->viewmodes);
357 if (desc->defaultlocale) fprintf(f, "%sdefaultlocale: %s\n", prefix, desc->defaultlocale);
358 if (desc->name) fprintf(f, "%sname: %s\n", prefix, desc->name);
359 if (desc->name_short) fprintf(f, "%sname_short: %s\n", prefix, desc->name_short);
360 if (desc->description) fprintf(f, "%sdescription: %s\n", prefix, desc->description);
361 if (desc->author) fprintf(f, "%sauthor: %s\n", prefix, desc->author);
362 if (desc->author_href) fprintf(f, "%sauthor_href: %s\n", prefix, desc->author_href);
363 if (desc->author_email) fprintf(f, "%sauthor_email: %s\n", prefix, desc->author_email);
364 if (desc->license) fprintf(f, "%slicense: %s\n", prefix, desc->license);
365 if (desc->license_href) fprintf(f, "%slicense_href: %s\n", prefix, desc->license_href);
366 if (desc->content_src) fprintf(f, "%scontent_src: %s\n", prefix, desc->content_src);
367 if (desc->content_type) fprintf(f, "%scontent_type: %s\n", prefix, desc->content_type);
368 if (desc->content_encoding) fprintf(f, "%scontent_encoding: %s\n", prefix, desc->content_encoding);
372 fprintf(f, "%s+ icon src: %s\n", prefix, icon->src);
373 if (icon->width) fprintf(f, "%s width: %d\n", prefix, icon->width);
374 if (icon->height) fprintf(f, "%s height: %d\n", prefix, icon->height);
378 feature = desc->features;
380 fprintf(f, "%s+ feature name: %s\n", prefix, feature->name);
381 fprintf(f, "%s required: %s\n", prefix, feature->required ? "true" : "false");
382 param = feature->params;
384 fprintf(f, "%s + param name: %s\n", prefix, param->name);
385 fprintf(f, "%s value: %s\n", prefix, param->value);
388 feature = feature->next;
391 preference = desc->preferences;
393 fprintf(f, "%s+ preference name: %s\n", prefix, preference->name);
394 if (preference->value) fprintf(f, "%s value: %s\n", prefix, preference->value);
395 fprintf(f, "%s readonly: %s\n", prefix, preference->readonly ? "true" : "false");
396 preference = preference->next;
400 struct wgt_info *wgt_info_create(struct wgt *wgt, int icons, int features, int preferences)
403 struct wgt_info *result;
406 assert(wgt_is_connected(wgt));
407 rc = wgt_config_open(wgt);
413 result = calloc(sizeof * result, 1);
419 result->refcount = 1;
423 rc = fill_desc(&result->desc, icons, features, preferences);
426 wgt_info_unref(result);
432 struct wgt_info *wgt_info_createat(int dirfd, const char *pathname, int icons, int features, int preferences)
434 struct wgt_info *result = NULL;
435 struct wgt *wgt = wgt_createat(dirfd, pathname);
437 result = wgt_info_create(wgt, icons, features, preferences);
443 const struct wgt_desc *wgt_info_desc(struct wgt_info *ifo)
449 struct wgt *wgt_info_wgt(struct wgt_info *ifo)
456 void wgt_info_addref(struct wgt_info *ifo)
459 assert(ifo->refcount > 0);
463 void wgt_info_unref(struct wgt_info *ifo)
466 assert(ifo->refcount > 0);
470 free_desc(&ifo->desc);
475 void wgt_info_dump(struct wgt_info *ifo, int fd, const char *prefix)
482 WARNING("can't fdopen in wgt_info_dump");
484 dump_desc(&ifo->desc, f, prefix);
489 const struct wgt_desc_feature *wgt_info_feature(struct wgt_info *ifo, const char *name)
491 const struct wgt_desc_feature *result = ifo->desc.features;
492 while(result && strcmp(result->name, name))
493 result = result->next;
497 const char *wgt_info_param(const struct wgt_desc_feature *feature, const char *name)
499 const struct wgt_desc_param *param = feature->params;
501 if (0 == strcmp(name, param->name))