2 Copyright (C) 2015-2020 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"
30 #include "wgt-strings.h"
39 static int getpropbool(xmlNodePtr node, const char *prop, int def)
42 char *val = xmlGetProp(node, prop);
46 if (!strcmp(val, "true"))
48 else if (!strcmp(val, "false"))
57 static int getpropnum(xmlNodePtr node, const char *prop, int def)
60 char *val = xmlGetProp(node, prop);
70 static xmlChar *optprop(xmlNodePtr node, const char *prop)
72 return node ? xmlGetProp(node, prop) : NULL;
75 static xmlChar *optcontent(xmlNodePtr node)
77 return node ? xmlNodeGetContent(node) : NULL;
80 static char *mkver(char *version)
85 c = version[lver = 0];
86 while(c && c != ' ' && c != '.')
90 while(c && c != ' ' && c != '.')
95 memcpy(r, version, lver);
103 static char *mkidaver(char *id, char *ver)
105 #if DISTINCT_VERSIONS
111 r = malloc(2 + lid + lver);
115 memcpy(r + lid + 1, ver, lver);
116 r[lid + lver + 1] = 0;
126 static void make_lowercase(char *s)
130 *s = (char)tolower(*s);
136 static int fill_desc(struct wgt_desc *desc, int want_icons, int want_features, int want_preferences)
138 xmlNodePtr node, pnode;
139 struct wgt_desc_icon *icon, **icontail;
140 struct wgt_desc_feature *feature, **featuretail;
141 struct wgt_desc_preference *preference, **preferencetail;
142 struct wgt_desc_param *param, **paramtail;
144 node = wgt_config_widget();
146 WARNING("no widget");
150 desc->id = xmlGetProp(node, string_id);
151 make_lowercase(desc->id);
152 desc->version = xmlGetProp(node, string_version);
153 desc->ver = mkver(desc->version);
154 make_lowercase(desc->ver);
155 desc->idaver = mkidaver(desc->id, desc->ver);
156 desc->width = getpropnum(node, string_width, 0);
157 desc->height = getpropnum(node, string_height, 0);
158 desc->viewmodes = xmlGetProp(node, string_viewmodes);
159 desc->defaultlocale = xmlGetProp(node, string_defaultlocale);
161 node = wgt_config_name();
162 desc->name = optcontent(node);
163 desc->name_short = optprop(node, string_short);
165 node = wgt_config_description();
166 desc->description = optcontent(node);
168 node = wgt_config_author();
169 desc->author = optcontent(node);
170 desc->author_href = optprop(node, string_href);
171 desc->author_email = optprop(node, string_email);
173 node = wgt_config_license();
174 desc->license = optcontent(node);
175 desc->license_href = optprop(node, string_href);
177 node = wgt_config_content();
178 desc->content_src = optprop(node, string_src);
179 if (node && desc->content_src == NULL) {
180 WARNING("content without src");
184 desc->content_type = optprop(node, string_type);
185 desc->content_encoding = optprop(node, string_encoding);
188 icontail = &desc->icons;
189 node = wgt_config_first_icon();
191 icon = malloc(sizeof * icon);
196 icon->src = xmlGetProp(node, string_src);
197 icon->width = getpropnum(node, string_width, 0);
198 icon->height = getpropnum(node, string_height, 0);
203 if (icon->src == NULL) {
204 WARNING("icon without src");
208 icontail = &icon->next;
209 node = wgt_config_next_icon(node);
214 featuretail = &desc->features;
215 node = wgt_config_first_feature();
217 feature = malloc(sizeof * feature);
218 if (feature == NULL) {
222 feature->name = xmlGetProp(node, string_name);
223 feature->required = getpropbool(node, string_required, 1);
224 feature->params = NULL;
226 feature->next = NULL;
227 *featuretail = feature;
229 if (feature->name == NULL) {
230 WARNING("feature without name");
235 paramtail = &feature->params;
236 pnode = wgt_config_first_param(node);
238 param = malloc(sizeof * param);
243 param->name = xmlGetProp(pnode, string_name);
244 param->value = xmlGetProp(pnode, string_value);
249 if (param->name == NULL || param->value == NULL) {
250 WARNING("param without name or value");
255 paramtail = ¶m->next;
256 pnode = wgt_config_next_param(pnode);
259 featuretail = &feature->next;
260 node = wgt_config_next_feature(node);
264 if (want_preferences) {
265 preferencetail = &desc->preferences;
266 node = wgt_config_first_preference();
268 preference = malloc(sizeof * preference);
269 if (preference == NULL) {
273 preference->name = xmlGetProp(node, string_name);
274 preference->value = xmlGetProp(node, string_value);
275 preference->readonly = getpropbool(node, string_readonly, 0);
277 *preferencetail = preference;
278 preference->next = NULL;
280 if (preference->name == NULL) {
281 WARNING("preference without name");
286 preferencetail = &preference->next;
287 node = wgt_config_next_preference(node);
293 static void free_desc(struct wgt_desc *desc)
295 struct wgt_desc_icon *icon;
296 struct wgt_desc_feature *feature;
297 struct wgt_desc_preference *preference;
298 struct wgt_desc_param *param;
301 xmlFree(desc->version);
304 xmlFree(desc->viewmodes);
305 xmlFree(desc->defaultlocale);
307 xmlFree(desc->name_short);
308 xmlFree(desc->description);
309 xmlFree(desc->author);
310 xmlFree(desc->author_href);
311 xmlFree(desc->author_email);
312 xmlFree(desc->license);
313 xmlFree(desc->license_href);
314 xmlFree(desc->content_src);
315 xmlFree(desc->content_type);
316 xmlFree(desc->content_encoding);
320 desc->icons = icon->next;
325 while(desc->features) {
326 feature = desc->features;
327 desc->features = feature->next;
328 xmlFree(feature->name);
329 while(feature->params) {
330 param = feature->params;
331 feature->params = param->next;
332 xmlFree(param->name);
333 xmlFree(param->value);
339 while(desc->preferences) {
340 preference = desc->preferences;
341 desc->preferences = preference->next;
342 xmlFree(preference->name);
343 xmlFree(preference->value);
348 static void dump_desc(struct wgt_desc *desc, FILE *f, const char *prefix)
350 struct wgt_desc_icon *icon;
351 struct wgt_desc_feature *feature;
352 struct wgt_desc_preference *preference;
353 struct wgt_desc_param *param;
355 if (desc->id) fprintf(f, "%sid: %s\n", prefix, desc->id);
356 if (desc->version) fprintf(f, "%sversion: %s\n", prefix, desc->version);
357 if (desc->ver) fprintf(f, "%sver: %s\n", prefix, desc->ver);
358 if (desc->idaver) fprintf(f, "%sidaver: %s\n", prefix, desc->idaver);
359 if (desc->width) fprintf(f, "%swidth: %d\n", prefix, desc->width);
360 if (desc->height) fprintf(f, "%sheight: %d\n", prefix, desc->height);
361 if (desc->viewmodes) fprintf(f, "%sviewmodes: %s\n", prefix, desc->viewmodes);
362 if (desc->defaultlocale) fprintf(f, "%sdefaultlocale: %s\n", prefix, desc->defaultlocale);
363 if (desc->name) fprintf(f, "%sname: %s\n", prefix, desc->name);
364 if (desc->name_short) fprintf(f, "%sname_short: %s\n", prefix, desc->name_short);
365 if (desc->description) fprintf(f, "%sdescription: %s\n", prefix, desc->description);
366 if (desc->author) fprintf(f, "%sauthor: %s\n", prefix, desc->author);
367 if (desc->author_href) fprintf(f, "%sauthor_href: %s\n", prefix, desc->author_href);
368 if (desc->author_email) fprintf(f, "%sauthor_email: %s\n", prefix, desc->author_email);
369 if (desc->license) fprintf(f, "%slicense: %s\n", prefix, desc->license);
370 if (desc->license_href) fprintf(f, "%slicense_href: %s\n", prefix, desc->license_href);
371 if (desc->content_src) fprintf(f, "%scontent_src: %s\n", prefix, desc->content_src);
372 if (desc->content_type) fprintf(f, "%scontent_type: %s\n", prefix, desc->content_type);
373 if (desc->content_encoding) fprintf(f, "%scontent_encoding: %s\n", prefix, desc->content_encoding);
377 fprintf(f, "%s+ icon src: %s\n", prefix, icon->src);
378 if (icon->width) fprintf(f, "%s width: %d\n", prefix, icon->width);
379 if (icon->height) fprintf(f, "%s height: %d\n", prefix, icon->height);
383 feature = desc->features;
385 fprintf(f, "%s+ feature name: %s\n", prefix, feature->name);
386 fprintf(f, "%s required: %s\n", prefix, feature->required ? "true" : "false");
387 param = feature->params;
389 fprintf(f, "%s + param name: %s\n", prefix, param->name);
390 fprintf(f, "%s value: %s\n", prefix, param->value);
393 feature = feature->next;
396 preference = desc->preferences;
398 fprintf(f, "%s+ preference name: %s\n", prefix, preference->name);
399 if (preference->value) fprintf(f, "%s value: %s\n", prefix, preference->value);
400 fprintf(f, "%s readonly: %s\n", prefix, preference->readonly ? "true" : "false");
401 preference = preference->next;
405 struct wgt_info *wgt_info_create(struct wgt *wgt, int icons, int features, int preferences)
408 struct wgt_info *result;
411 assert(wgt_is_connected(wgt));
412 rc = wgt_config_open(wgt);
418 result = calloc(sizeof * result, 1);
424 result->refcount = 1;
428 rc = fill_desc(&result->desc, icons, features, preferences);
431 wgt_info_unref(result);
437 struct wgt_info *wgt_info_createat(int dirfd, const char *pathname, int icons, int features, int preferences)
439 struct wgt_info *result = NULL;
440 struct wgt *wgt = wgt_createat(dirfd, pathname);
442 result = wgt_info_create(wgt, icons, features, preferences);
448 const struct wgt_desc *wgt_info_desc(struct wgt_info *ifo)
454 struct wgt *wgt_info_wgt(struct wgt_info *ifo)
461 void wgt_info_addref(struct wgt_info *ifo)
464 assert(ifo->refcount > 0);
468 void wgt_info_unref(struct wgt_info *ifo)
471 assert(ifo->refcount > 0);
475 free_desc(&ifo->desc);
480 void wgt_info_dump(struct wgt_info *ifo, int fd, const char *prefix)
487 WARNING("can't fdopen in wgt_info_dump");
489 dump_desc(&ifo->desc, f, prefix);
494 const struct wgt_desc_feature *wgt_info_feature(struct wgt_info *ifo, const char *name)
496 const struct wgt_desc_feature *result = ifo->desc.features;
497 while(result && strcmp(result->name, name))
498 result = result->next;
502 const char *wgt_info_param(const struct wgt_desc_feature *feature, const char *name)
504 const struct wgt_desc_param *param = feature->params;
506 if (0 == strcmp(name, param->name))