Support for elements of config.xml
authorJosé Bollo <jose.bollo@iot.bzh>
Tue, 8 Dec 2015 12:16:11 +0000 (13:16 +0100)
committerJosé Bollo <jose.bollo@iot.bzh>
Tue, 8 Dec 2015 12:16:11 +0000 (13:16 +0100)
This add some elements intended to be used later when handling
data coming from config.xml of widgets.

Change-Id: I1df9eb158d5c37578c9c7a8caa9eb8f85527ca4b

Makefile.am
wgt-config-xml.c [new file with mode: 0644]
wgt-locales.c [new file with mode: 0644]
wgt-strings.c [new file with mode: 0644]
wgt.h [new file with mode: 0644]

index 02a724c..d9ffed5 100644 (file)
@@ -10,6 +10,11 @@ COMMONSRCS = \
        wgtpkg-xmlsec.c \
        wgtpkg-zip.c
 
+WGTSRCS = \
+       wgt-config-xml.c \
+       wgt-locales.c \
+       wgt-strings.c
+
 AM_CFLAGS  = -Wall -Wno-pointer-sign
 AM_CFLAGS += -ffunction-sections -fdata-sections
 AM_CFLAGS += ${ZIP_CFLAGS} ${XML2_CFLAGS} ${OPENSSL_CFLAGS} ${XMLSEC_CFLAGS}
@@ -18,7 +23,7 @@ AM_LDFLAGS = -Wl,--gc-sections
 
 LDADD = ${ZIP_LIBS} ${XML2_LIBS} ${OPENSSL_LIBS} ${XMLSEC_LIBS}
 
-wgtpkg_install_SOURCES = wgtpkg-install.c ${COMMONSRCS}
+wgtpkg_install_SOURCES = wgtpkg-install.c ${WGTSRCS} ${COMMONSRCS}
 
 wgtpkg_sign_SOURCES = wgtpkg-sign.c ${COMMONSRCS}
 
diff --git a/wgt-config-xml.c b/wgt-config-xml.c
new file mode 100644 (file)
index 0000000..41c2085
--- /dev/null
@@ -0,0 +1,215 @@
+/*
+ Copyright 2015 IoT.bzh
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+     http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+*/
+
+#include <string.h>
+#include <syslog.h>
+#include <assert.h>
+#include <errno.h>
+
+#include <libxml/parser.h>
+#include <libxml/tree.h>
+#include <libxml/uri.h>
+
+
+#include "wgt.h"
+
+static xmlDocPtr configxml = NULL;
+
+static xmlNodePtr next(xmlNodePtr node, const char *type)
+{
+       while (node && node->type != XML_ELEMENT_NODE && strcmp(type, node->name))
+               node = node->next;
+       return node;
+}
+
+static xmlNodePtr first(const char *type)
+{
+       xmlNodePtr root;
+       if (configxml) {
+               root = xmlDocGetRootElement(configxml);
+               if (root)
+                       return next(root->children, type);
+       }
+       return NULL;
+}
+
+static xmlNodePtr element_based_localisation(const char *type)
+{
+       xmlNodePtr resu;
+       char *lang;
+
+       resu = first(type);
+       while (resu) {
+               lang = xmlNodeGetLang(resu);
+               if (lang) {
+                       xmlFree(lang);
+               }
+               resu = next(resu->next, type);
+       }
+       return resu;
+}
+
+void confixml_close()
+{
+       if (configxml) {
+               xmlFreeDoc(configxml);
+               configxml = NULL;
+       }
+}
+
+int confixml_open()
+{
+       assert(!configxml);
+       configxml = xmlReadFile(_config_xml_, NULL, 0);
+       if (configxml == NULL) {
+               syslog(LOG_ERR, "xml parse of config file %s failed", _config_xml_);
+               return -1;
+       }
+       return 0;
+}
+
+/* elements based on localisation */
+xmlNodePtr confixml_name()
+{
+       return element_based_localisation(_name_);
+}
+
+xmlNodePtr confixml_description()
+{
+       return element_based_localisation(_description_);
+}
+
+xmlNodePtr confixml_license()
+{
+       return element_based_localisation(_license_);
+}
+
+/* elements based on path localisation */
+xmlNodePtr confixml_author()
+{
+       return first(_author_);
+}
+
+xmlNodePtr confixml_content()
+{
+       return first(_content_);
+}
+
+/* element multiple */
+
+xmlNodePtr confixml_first_feature()
+{
+       return first(_feature_);
+}
+
+xmlNodePtr confixml_next_feature(xmlNodePtr node)
+{
+       return next(node->next, _feature_);
+}
+
+xmlNodePtr confixml_first_preference()
+{
+       return first(_preference_);
+}
+
+xmlNodePtr confixml_next_preference(xmlNodePtr node)
+{
+       return next(node->next, _preference_);
+}
+
+xmlNodePtr confixml_first_icon()
+{
+       return first(_icon_);
+}
+
+xmlNodePtr confixml_next_icon(xmlNodePtr node)
+{
+       return next(node->next, _icon_);
+}
+
+/* best sized icon */
+
+static int score_dim(xmlNodePtr ref, xmlNodePtr x, const char *dim, int request)
+{
+       int r, iref, ix;
+       char *sref, *sx;
+
+       sref = xmlGetProp(ref, dim);
+       if (sref) {
+               iref = atoi(sref);
+               xmlFree(sref);
+               sx = xmlGetProp(x, dim);
+               if (sx) {
+                       /* sref && sx */
+                       ix = atoi(sx);
+                       xmlFree(sx);
+                       if (ix >= request) {
+                               if (iref >= request)
+                                       r = ix - iref;
+                               else
+                                       r = request - ix;
+                       } else {
+                               if (iref >= request)
+                                       r = iref - request;
+                               else
+                                       r = iref - ix;
+                       }
+               } else {
+                       /* sref && !sx */
+                       if (iref >= request)
+                               r = iref - request;
+                       else
+                               r = 0;
+               }
+       } else {
+               sx = xmlGetProp(x, dim);
+               if (sx) {
+                       /* !sref && sx */
+                       ix = atoi(sx);
+                       xmlFree(sx);
+                       if (ix >= request)
+                               r = request - ix;
+                       else
+                               r = 0;
+               } else {
+                       /* !sref && !sx */
+                       r = 0;
+               }
+       }
+       return r;
+}
+
+static int better_icon(xmlNodePtr ref, xmlNodePtr x, int width, int height)
+{
+       int sw = score_dim(ref, x, _width_, width);
+       int sh = score_dim(ref, x, _height_, height);
+       return sw+sh < 0;
+}
+
+xmlNodePtr confixml_icon(int width, int height)
+{
+       xmlNodePtr resu, icon;
+
+       resu = confixml_first_icon();
+       icon = confixml_next_icon(resu);
+       while (icon) {
+               if (better_icon(resu, icon, width, height))
+                       resu = icon;
+               icon = confixml_next_icon(icon);
+       }
+       return resu;
+}
+
diff --git a/wgt-locales.c b/wgt-locales.c
new file mode 100644 (file)
index 0000000..d985b64
--- /dev/null
@@ -0,0 +1,105 @@
+
+#define _GNU_SOURCE
+#include <string.h>
+#include <errno.h>
+#include <unistd.h>
+#include <ctype.h>
+
+#include "wgt.h"
+
+struct locarr {
+       int count;
+       char **arr;
+};
+
+static struct locarr locarr = { 0, NULL };
+
+static int add(const char *locstr, int length)
+{
+       int i;
+       char *item, **ptr;
+
+       item = strndup(locstr, length);
+       if (item != NULL) {
+               for (i = 0 ; item[i] ; i++)
+                       item[i] = tolower(item[i]);
+               for (i = 0 ; i < locarr.count ; i++)
+                       if (!strcmp(item, locarr.arr[i])) {
+                               free(item);
+                               return 0;
+                       }
+
+               ptr = realloc(locarr.arr, (1 + locarr.count) * sizeof(locarr.arr[0]));
+               if (ptr) {
+                       locarr.arr = ptr;
+                       locarr.arr[locarr.count++] = item;
+                       return 0;
+               }
+               free(item);
+       }
+       errno = ENOMEM;
+       return -1;
+}
+
+void locales_reset()
+{
+       while (locarr.count)
+               free(locarr.arr[--locarr.count]);
+}
+
+int locales_add(const char *locstr)
+{
+       const char *stop, *next;
+       while (*locstr) {
+               stop = strchrnul(locstr, ',');
+               next = stop + !!*stop;
+               while (locstr != stop) {
+                       if (add(locstr, stop - locstr))
+                               return -1;
+                       do { stop--; } while(stop > locstr && *stop != '-');
+               }
+               locstr = next;
+       }
+       return 0;
+}
+
+int locales_score(const char *lang)
+{
+       int i;
+
+       if (lang)
+               for (i = 0 ; i < locarr.count ; i++)
+                       if (!strcasecmp(lang, locarr.arr[i]))
+                               return i;
+
+       return INT_MAX;
+}
+
+char *locales_locate_file(const char *filename)
+{
+       int i;
+       char path[PATH_MAX];
+       char * result;
+
+       for (i = 0 ; i < locarr.count ; i++) {
+               if (snprintf(path, sizeof path, "locales/%s/%s", locarr.arr[i], filename) >= (int)(sizeof path)) {
+                       errno = EINVAL;
+                       return NULL;
+               }
+               if (!access(path, F_OK)) {
+                       result = strdup(path);
+                       if (!result)
+                               errno = ENOMEM;
+                       return result;
+               }
+       }
+       if (access(filename, F_OK)) {
+               result = strdup(filename);
+               if (!result)
+                       errno = ENOMEM;
+               return result;
+       }
+       errno = ENOENT;
+       return NULL;
+}
+
diff --git a/wgt-strings.c b/wgt-strings.c
new file mode 100644 (file)
index 0000000..b11bbaf
--- /dev/null
@@ -0,0 +1,14 @@
+
+const char _config_xml_[] = "config.xml";
+const char _name_[] = "name";
+const char _description_[] = "description";
+const char _author_[] = "author";
+const char _license_[] = "license";
+const char _icon_[] = "icon";
+const char _content_[] = "content";
+const char _feature_[] = "feature";
+const char _preference_[] = "preference";
+const char _width_[] = "width";
+const char _height_[] = "height";
+
+
diff --git a/wgt.h b/wgt.h
new file mode 100644 (file)
index 0000000..63c4bcd
--- /dev/null
+++ b/wgt.h
@@ -0,0 +1,62 @@
+/*
+ Copyright 2015 IoT.bzh
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+     http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+*/
+
+
+#include <libxml/tree.h>
+#include "config.h"
+
+
+/**************************************************************/
+/* from wgt-config-xml */
+
+extern int confixml_open();
+extern void confixml_close();
+extern xmlNodePtr confixml_name();
+extern xmlNodePtr confixml_description();
+extern xmlNodePtr confixml_license();
+extern xmlNodePtr confixml_author();
+extern xmlNodePtr confixml_content();
+extern xmlNodePtr confixml_icon(int width, int height);
+extern xmlNodePtr confixml_first_feature();
+extern xmlNodePtr confixml_next_feature(xmlNodePtr node);
+extern xmlNodePtr confixml_first_preference();
+extern xmlNodePtr confixml_next_preference(xmlNodePtr node);
+extern xmlNodePtr confixml_first_icon();
+extern xmlNodePtr confixml_next_icon(xmlNodePtr node);
+
+/**************************************************************/
+/* from wgt-locales */
+
+extern void locales_reset();
+extern int locales_add(const char *locstr);
+extern int locales_score(const char *lang);
+extern char *locales_locate_file(const char *filename);
+
+/**************************************************************/
+/* from wgt-strings */
+
+extern const char _config_xml_[];
+extern const char _name_[];
+extern const char _description_[];
+extern const char _author_[];
+extern const char _license_[];
+extern const char _icon_[];
+extern const char _content_[];
+extern const char _feature_[];
+extern const char _preference_[];
+extern const char _width_[];
+extern const char _height_[];
+