2 Copyright 2015, 2016, 2017 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)
110 r = malloc(2 + lid + lver);
114 memcpy(r + lid + 1, ver, lver);
115 r[lid + lver + 1] = 0;
122 static void make_lowercase(char *s)
126 *s = (char)tolower(*s);
132 static int fill_desc(struct wgt_desc *desc, int want_icons, int want_features, int want_preferences)
134 xmlNodePtr node, pnode;
135 struct wgt_desc_icon *icon, **icontail;
136 struct wgt_desc_feature *feature, **featuretail;
137 struct wgt_desc_preference *preference, **preferencetail;
138 struct wgt_desc_param *param, **paramtail;
140 node = wgt_config_widget();
142 WARNING("no widget");
146 desc->id = xmlGetProp(node, string_id);
147 make_lowercase(desc->id);
148 desc->version = xmlGetProp(node, string_version);
149 desc->ver = mkver(desc->version);
150 make_lowercase(desc->ver);
151 desc->idaver = mkidaver(desc->id, desc->ver);
152 desc->width = getpropnum(node, string_width, 0);
153 desc->height = getpropnum(node, string_height, 0);
154 desc->viewmodes = xmlGetProp(node, string_viewmodes);
155 desc->defaultlocale = xmlGetProp(node, string_defaultlocale);
157 node = wgt_config_name();
158 desc->name = optcontent(node);
159 desc->name_short = optprop(node, string_short);
161 node = wgt_config_description();
162 desc->description = optcontent(node);
164 node = wgt_config_author();
165 desc->author = optcontent(node);
166 desc->author_href = optprop(node, string_href);
167 desc->author_email = optprop(node, string_email);
169 node = wgt_config_license();
170 desc->license = optcontent(node);
171 desc->license_href = optprop(node, string_href);
173 node = wgt_config_content();
174 desc->content_src = optprop(node, string_src);
175 if (node && desc->content_src == NULL) {
176 WARNING("content without src");
180 desc->content_type = optprop(node, string_type);
181 desc->content_encoding = optprop(node, string_encoding);
184 icontail = &desc->icons;
185 node = wgt_config_first_icon();
187 icon = malloc(sizeof * icon);
192 icon->src = xmlGetProp(node, string_src);
193 icon->width = getpropnum(node, string_width, 0);
194 icon->height = getpropnum(node, string_height, 0);
199 if (icon->src == NULL) {
200 WARNING("icon without src");
204 icontail = &icon->next;
205 node = wgt_config_next_icon(node);
210 featuretail = &desc->features;
211 node = wgt_config_first_feature();
213 feature = malloc(sizeof * feature);
214 if (feature == NULL) {
218 feature->name = xmlGetProp(node, string_name);
219 feature->required = getpropbool(node, string_required, 1);
220 feature->params = NULL;
222 feature->next = NULL;
223 *featuretail = feature;
225 if (feature->name == NULL) {
226 WARNING("feature without name");
231 paramtail = &feature->params;
232 pnode = wgt_config_first_param(node);
234 param = malloc(sizeof * param);
239 param->name = xmlGetProp(pnode, string_name);
240 param->value = xmlGetProp(pnode, string_value);
245 if (param->name == NULL || param->value == NULL) {
246 WARNING("param without name or value");
251 paramtail = ¶m->next;
252 pnode = wgt_config_next_param(pnode);
255 featuretail = &feature->next;
256 node = wgt_config_next_feature(node);
260 if (want_preferences) {
261 preferencetail = &desc->preferences;
262 node = wgt_config_first_preference();
264 preference = malloc(sizeof * preference);
265 if (preference == NULL) {
269 preference->name = xmlGetProp(node, string_name);
270 preference->value = xmlGetProp(node, string_value);
271 preference->readonly = getpropbool(node, string_readonly, 0);
273 *preferencetail = preference;
274 preference->next = NULL;
276 if (preference->name == NULL) {
277 WARNING("preference without name");
282 preferencetail = &preference->next;
283 node = wgt_config_next_preference(node);
289 static void free_desc(struct wgt_desc *desc)
291 struct wgt_desc_icon *icon;
292 struct wgt_desc_feature *feature;
293 struct wgt_desc_preference *preference;
294 struct wgt_desc_param *param;
297 xmlFree(desc->version);
300 xmlFree(desc->viewmodes);
301 xmlFree(desc->defaultlocale);
303 xmlFree(desc->name_short);
304 xmlFree(desc->description);
305 xmlFree(desc->author);
306 xmlFree(desc->author_href);
307 xmlFree(desc->author_email);
308 xmlFree(desc->license);
309 xmlFree(desc->license_href);
310 xmlFree(desc->content_src);
311 xmlFree(desc->content_type);
312 xmlFree(desc->content_encoding);
316 desc->icons = icon->next;
321 while(desc->features) {
322 feature = desc->features;
323 desc->features = feature->next;
324 xmlFree(feature->name);
325 while(feature->params) {
326 param = feature->params;
327 feature->params = param->next;
328 xmlFree(param->name);
329 xmlFree(param->value);
335 while(desc->preferences) {
336 preference = desc->preferences;
337 desc->preferences = preference->next;
338 xmlFree(preference->name);
339 xmlFree(preference->value);
344 static void dump_desc(struct wgt_desc *desc, FILE *f, const char *prefix)
346 struct wgt_desc_icon *icon;
347 struct wgt_desc_feature *feature;
348 struct wgt_desc_preference *preference;
349 struct wgt_desc_param *param;
351 if (desc->id) fprintf(f, "%sid: %s\n", prefix, desc->id);
352 if (desc->version) fprintf(f, "%sversion: %s\n", prefix, desc->version);
353 if (desc->ver) fprintf(f, "%sver: %s\n", prefix, desc->ver);
354 if (desc->idaver) fprintf(f, "%sidaver: %s\n", prefix, desc->idaver);
355 if (desc->width) fprintf(f, "%swidth: %d\n", prefix, desc->width);
356 if (desc->height) fprintf(f, "%sheight: %d\n", prefix, desc->height);
357 if (desc->viewmodes) fprintf(f, "%sviewmodes: %s\n", prefix, desc->viewmodes);
358 if (desc->defaultlocale) fprintf(f, "%sdefaultlocale: %s\n", prefix, desc->defaultlocale);
359 if (desc->name) fprintf(f, "%sname: %s\n", prefix, desc->name);
360 if (desc->name_short) fprintf(f, "%sname_short: %s\n", prefix, desc->name_short);
361 if (desc->description) fprintf(f, "%sdescription: %s\n", prefix, desc->description);
362 if (desc->author) fprintf(f, "%sauthor: %s\n", prefix, desc->author);
363 if (desc->author_href) fprintf(f, "%sauthor_href: %s\n", prefix, desc->author_href);
364 if (desc->author_email) fprintf(f, "%sauthor_email: %s\n", prefix, desc->author_email);
365 if (desc->license) fprintf(f, "%slicense: %s\n", prefix, desc->license);
366 if (desc->license_href) fprintf(f, "%slicense_href: %s\n", prefix, desc->license_href);
367 if (desc->content_src) fprintf(f, "%scontent_src: %s\n", prefix, desc->content_src);
368 if (desc->content_type) fprintf(f, "%scontent_type: %s\n", prefix, desc->content_type);
369 if (desc->content_encoding) fprintf(f, "%scontent_encoding: %s\n", prefix, desc->content_encoding);
373 fprintf(f, "%s+ icon src: %s\n", prefix, icon->src);
374 if (icon->width) fprintf(f, "%s width: %d\n", prefix, icon->width);
375 if (icon->height) fprintf(f, "%s height: %d\n", prefix, icon->height);
379 feature = desc->features;
381 fprintf(f, "%s+ feature name: %s\n", prefix, feature->name);
382 fprintf(f, "%s required: %s\n", prefix, feature->required ? "true" : "false");
383 param = feature->params;
385 fprintf(f, "%s + param name: %s\n", prefix, param->name);
386 fprintf(f, "%s value: %s\n", prefix, param->value);
389 feature = feature->next;
392 preference = desc->preferences;
394 fprintf(f, "%s+ preference name: %s\n", prefix, preference->name);
395 if (preference->value) fprintf(f, "%s value: %s\n", prefix, preference->value);
396 fprintf(f, "%s readonly: %s\n", prefix, preference->readonly ? "true" : "false");
397 preference = preference->next;
401 struct wgt_info *wgt_info_create(struct wgt *wgt, int icons, int features, int preferences)
404 struct wgt_info *result;
407 assert(wgt_is_connected(wgt));
408 rc = wgt_config_open(wgt);
414 result = calloc(sizeof * result, 1);
420 result->refcount = 1;
424 rc = fill_desc(&result->desc, icons, features, preferences);
427 wgt_info_unref(result);
433 struct wgt_info *wgt_info_createat(int dirfd, const char *pathname, int icons, int features, int preferences)
435 struct wgt_info *result = NULL;
436 struct wgt *wgt = wgt_createat(dirfd, pathname);
438 result = wgt_info_create(wgt, icons, features, preferences);
444 const struct wgt_desc *wgt_info_desc(struct wgt_info *ifo)
450 struct wgt *wgt_info_wgt(struct wgt_info *ifo)
457 void wgt_info_addref(struct wgt_info *ifo)
460 assert(ifo->refcount > 0);
464 void wgt_info_unref(struct wgt_info *ifo)
467 assert(ifo->refcount > 0);
471 free_desc(&ifo->desc);
476 void wgt_info_dump(struct wgt_info *ifo, int fd, const char *prefix)
483 WARNING("can't fdopen in wgt_info_dump");
485 dump_desc(&ifo->desc, f, prefix);
490 const struct wgt_desc_feature *wgt_info_feature(struct wgt_info *ifo, const char *name)
492 const struct wgt_desc_feature *result = ifo->desc.features;
493 while(result && strcmp(result->name, name))
494 result = result->next;
498 const char *wgt_info_param(const struct wgt_desc_feature *feature, const char *name)
500 const struct wgt_desc_param *param = feature->params;
502 if (0 == strcmp(name, param->name))