afm-unit: Fix http port multi allocation
[src/app-framework-main.git] / src / wgtpkg-mustach.c
index cc79505..5e4348a 100644 (file)
 
 #include <stdio.h>
 #include <string.h>
+#include <errno.h>
 
 #include <json-c/json.h>
 
 #include "mustach.h"
+#include "verbose.h"
 
 #define MAX_DEPTH 256
 
-
+/*
+ * exploration state when instantiating mustache
+ */
 struct expl {
        struct json_object *root;
        int depth;
@@ -58,8 +62,8 @@ static char *keyval(char *read, int isptr)
                } else {
                        if (c == '\\') {
                                switch (read[1]) {
-                               case '\\': *write++ = c;
-                               case '=': c = *++read;
+                               case '\\': *write++ = c; /*@fallthrough@*/
+                               case '=': c = *++read; /*@fallthrough@*/
                                default: break;
                                }
                        }
@@ -88,8 +92,8 @@ static char *first(char **name, int isptr)
                        while (c && c != '/') {
                                if (c == '~') {
                                        switch(read[1]) {
-                                       case '1': c = '/';
-                                       case '0': read++;
+                                       case '1': c = '/'; /*@fallthrough@*/
+                                       case '0': read++; /*@fallthrough@*/
                                        default: break;
                                        }
                                }
@@ -110,6 +114,31 @@ static char *first(char **name, int isptr)
        return r;
 }
 
+/*
+ * Returns the unescaped version of the first value
+ * and update 'val' to point the next value if any.
+ */
+static char *value(char **val)
+{
+       char *r, *read, *write, c;
+
+       c = *(read = *val);
+       if (!c)
+               r = NULL;
+       else {
+               r = write = read;
+               while (c && c != '|') {
+                       if (c == '\\' && (read[1] == '|' || read[1] == '\\'))
+                               c = *++read;
+                       *write++ = c;
+                       c = *++read;
+               }
+               *write = 0;
+               *val = read + !!c;
+       }
+       return r;
+}
+
 /*
  * Replace the last occurence of ':' followed by
  * any character not being '*' by ':*', the
@@ -179,7 +208,11 @@ static struct json_object *find(struct expl *e, const char *name)
                        /* check the value if requested */
                        if (v) {
                                i = v[0] == '!';
-                               if (i == !strcmp(&v[i], json_object_get_string(o)))
+                               v += i;
+                               do {
+                                       c = value(&v);
+                               } while (c && strcmp(c, json_object_get_string(o)));
+                               if (i != !c)
                                        o = NULL;
                        }
                        return o;
@@ -290,8 +323,29 @@ static struct mustach_itf itf = {
  */
 int apply_mustach(const char *template, struct json_object *root, char **result, size_t *size)
 {
+       int rc;
        struct expl e;
+
        e.root = root;
-       return mustach(template, &itf, &e, result, size);
+       rc = mustach(template, &itf, &e, result, size);
+       if (rc < 0) {
+               static const char *msgs[] = {
+                       "SYSTEM",
+                       "UNEXPECTED_END",
+                       "EMPTY_TAG",
+                       "TAG_TOO_LONG",
+                       "BAD_SEPARATORS",
+                       "TOO_DEPTH",
+                       "CLOSING",
+                       "BAD_UNESCAPE_TAG"
+               };
+
+               rc = -(rc + 1);
+               ERROR("mustach error found: MUSTACH_ERROR_%s",
+                       rc < 0 || rc >= (int)(sizeof msgs / sizeof * msgs) ? "???" : msgs[rc]);
+               rc = -1;
+               errno = EINVAL;
+       }
+       return rc;
 }