gnunet-svn
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[taler-merchant] branch master updated: jansson adapter for mustache tem


From: gnunet
Subject: [taler-merchant] branch master updated: jansson adapter for mustache templates
Date: Thu, 20 Aug 2020 19:38:19 +0200

This is an automated email from the git hooks/post-receive script.

dold pushed a commit to branch master
in repository merchant.

The following commit(s) were added to refs/heads/master by this push:
     new 0a5308e  jansson adapter for mustache templates
0a5308e is described below

commit 0a5308e71e7f65a9921d74e8d55b389654defca6
Author: Florian Dold <florian.dold@gmail.com>
AuthorDate: Thu Aug 20 23:08:13 2020 +0530

    jansson adapter for mustache templates
---
 src/mustach/.gitignore                             |   1 +
 src/mustach/Makefile.am                            |  12 +-
 src/mustach/mustach-jansson.c                      | 308 ++++++++++++
 .../{mustach-json-c.h => mustach-jansson.h}        |  28 +-
 src/mustach/mustach-json-c.c                       | 526 ---------------------
 src/mustach/test_mustach_jansson.c                 |  80 ++++
 6 files changed, 416 insertions(+), 539 deletions(-)

diff --git a/src/mustach/.gitignore b/src/mustach/.gitignore
new file mode 100644
index 0000000..b2bf6ef
--- /dev/null
+++ b/src/mustach/.gitignore
@@ -0,0 +1 @@
+test_mustach_jansson
diff --git a/src/mustach/Makefile.am b/src/mustach/Makefile.am
index a39a28d..ac9f284 100644
--- a/src/mustach/Makefile.am
+++ b/src/mustach/Makefile.am
@@ -11,7 +11,17 @@ lib_LIBRARIES = \
   libmustach.a
 
 libmustach_a_SOURCES = \
-  mustach.c mustach.h
+  mustach.c mustach.h \
+  mustach-jansson.c mustach-jansson.h
+
+test_mustach_jansson_SOURCES = \
+  test_mustach_jansson.c
+test_mustach_jansson_LDADD = \
+  -lgnunetutil \
+  libmustach.a
+
+check_PROGRAMS = \
+  test_mustach_jansson
 
 check_SCRIPTS = \
   run-original-tests.sh
diff --git a/src/mustach/mustach-jansson.c b/src/mustach/mustach-jansson.c
new file mode 100644
index 0000000..afb8f82
--- /dev/null
+++ b/src/mustach/mustach-jansson.c
@@ -0,0 +1,308 @@
+/*
+ Copyright (C) 2020 Taler Systems SA
+
+ Original license:
+ Author: José Bollo <jobol@nonadev.net>
+ Author: José Bollo <jose.bollo@iot.bzh>
+
+ https://gitlab.com/jobol/mustach
+
+ 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 "platform.h"
+#include "mustach-jansson.h"
+
+struct Context
+{
+  /**
+   * Context object.
+   */
+  json_t *cont;
+
+  /**
+   * Current object.
+   */
+  json_t *obj;
+
+  /**
+   * Opaque object iterator.
+   */
+  void *iter;
+
+  /**
+   * Current index when iterating over an array.
+   */
+  unsigned int index;
+
+  /**
+   * Count when iterating over an array.
+   */
+  unsigned int count;
+
+  bool is_objiter;
+};
+
+struct JanssonClosure
+{
+  json_t *root;
+  mustach_jansson_write_cb writecb;
+  int depth;
+
+  /**
+   * Did the last find(..) call result in an iterable?
+   */
+  struct Context stack[MUSTACH_MAX_DEPTH];
+
+  /**
+   * The last object we found should be iterated over.
+   */
+  bool found_iter;
+};
+
+static json_t *
+find (struct JanssonClosure *e, const char *name)
+{
+  json_t *obj = e->stack[e->depth].obj;
+  char *nd = GNUNET_strdup (name);
+  char *p = nd;
+  char *saveptr = NULL;
+
+  while (true)
+  {
+    char *tok = strtok_r (p, ".", &saveptr);
+    if (tok == NULL)
+      break;
+    obj = json_object_get (obj, tok);
+    if (obj == NULL)
+      break;
+    p = NULL;
+  }
+
+  GNUNET_free (nd);
+
+  return obj;
+}
+
+
+static int
+start(void *closure)
+{
+  struct JanssonClosure *e = closure;
+  e->depth = 0;
+  e->stack[0].cont = NULL;
+  e->stack[0].obj = e->root;
+  e->stack[0].index = 0;
+  e->stack[0].count = 1;
+  return MUSTACH_OK;
+}
+
+
+static int
+emituw (void *closure, const char *buffer, size_t size, int escape, FILE *file)
+{
+  struct JanssonClosure *e = closure;
+  if (!escape)
+    e->writecb (file, buffer, size);
+  else
+    do
+    {
+      switch (*buffer)
+      {
+        case '<':
+          e->writecb (file, "&lt;", 4);
+          break;
+        case '>':
+          e->writecb (file, "&gt;", 4);
+          break;
+        case '&':
+          e->writecb (file, "&amp;", 5);
+          break;
+        default:
+          e->writecb (file, buffer, 1);
+          break;
+      }
+      buffer++;
+    }
+    while(--size);
+  return MUSTACH_OK;
+}
+
+
+static const char *
+item (struct JanssonClosure *e, const char *name)
+{
+  json_t *obj;
+
+  if ( (0 == strcmp (name, "*") ) &&
+       (e->stack[e->depth].is_objiter ) )
+    return json_object_iter_key (e->stack[e->depth].iter);
+  obj = find (e, name);
+  if (NULL != obj)
+    return json_string_value (obj);
+  return NULL;
+}
+
+
+static int
+enter(void *closure, const char *name)
+{
+  struct JanssonClosure *e = closure;
+  json_t *o = find(e, name);
+  if (++e->depth >= MUSTACH_MAX_DEPTH)
+    return MUSTACH_ERROR_TOO_DEEP;
+
+  if (json_is_object (o))
+  {
+    if (e->found_iter)
+    {
+      void *iter = json_object_iter (o);
+      if (NULL == iter)
+      {
+        e->depth--;
+        return 0;
+      }
+      e->stack[e->depth].is_objiter = 1;
+      e->stack[e->depth].iter = iter;
+      e->stack[e->depth].obj = json_object_iter_value (iter);
+      e->stack[e->depth].cont = o;
+    }
+    else
+    {
+      e->stack[e->depth].is_objiter = 0;
+      e->stack[e->depth].obj = o;
+      e->stack[e->depth].cont = o;
+    }
+    return 1;
+  }
+
+  if (json_is_array (o))
+  {
+    unsigned int size = json_array_size (o);
+    if (size == 0)
+    {
+      e->depth--;
+      return 0;
+    }
+    e->stack[e->depth].count = size;
+    e->stack[e->depth].cont = o;
+    e->stack[e->depth].obj = json_array_get (o, 0);
+    e->stack[e->depth].index = 0;
+    e->stack[e->depth].is_objiter = 0;
+    return 1;
+  }
+
+  e->depth--;
+  return 0;
+}
+
+
+static int
+next (void *closure)
+{
+  struct JanssonClosure *e = closure;
+  struct Context *ctx;
+  if (e->depth <= 0)
+    return MUSTACH_ERROR_CLOSING;
+  ctx = &e->stack[e->depth];
+  if (ctx->is_objiter)
+  {
+    ctx->iter = json_object_iter_next (ctx->obj, ctx->iter);
+    if (NULL == ctx->iter)
+      return 0;
+    ctx->obj = json_object_iter_value (ctx->iter);
+    return 1;
+  }
+  ctx->index++;
+  if (ctx->index >= ctx->count)
+    return 0;
+  ctx->obj = json_array_get (ctx->cont, ctx->index);
+  return 1;
+}
+
+static int leave (void *closure)
+{
+  struct JanssonClosure *e = closure;
+  if (e->depth <= 0)
+    return MUSTACH_ERROR_CLOSING;
+  e->depth--;
+  return 0;
+}
+
+static int get (void *closure, const char *name, struct mustach_sbuf *sbuf)
+{
+  struct JanssonClosure *e = closure;
+  const char *s;
+
+  s = item (e, name);
+  if (s)
+    sbuf->value = s;
+  else
+    sbuf->value = "";
+  return MUSTACH_OK;
+}
+
+static struct mustach_itf itf = {
+  .start = start,
+  .put = NULL,
+  .enter = enter,
+  .next = next,
+  .leave = leave,
+  .partial =NULL,
+  .get = get,
+  .emit = NULL,
+  .stop = NULL
+};
+
+static struct mustach_itf itfuw = {
+  .start = start,
+  .put = NULL,
+  .enter = enter,
+  .next = next,
+  .leave = leave,
+  .partial = NULL,
+  .get = get,
+  .emit = emituw,
+  .stop = NULL
+};
+
+int fmustach_jansson (const char *template, json_t *root, FILE *file)
+{
+  struct JanssonClosure e = { 0 };
+  e.root = root;
+  return fmustach(template, &itf, &e, file);
+}
+
+int fdmustach_jansson (const char *template, json_t *root, int fd)
+{
+  struct JanssonClosure e = { 0 };
+  e.root = root;
+  return fdmustach(template, &itf, &e, fd);
+}
+
+int mustach_jansson (const char *template, json_t *root, char **result, size_t 
*size)
+{
+  struct JanssonClosure e = { 0 };
+  e.root = root;
+  e.writecb = NULL;
+  return mustach(template, &itf, &e, result, size);
+}
+
+int umustach_jansson (const char *template, json_t *root, 
mustach_jansson_write_cb writecb, void *closure)
+{
+  struct JanssonClosure e = { 0 };
+  e.root = root;
+  e.writecb = writecb;
+  return fmustach(template, &itfuw, &e, closure);
+}
+
diff --git a/src/mustach/mustach-json-c.h b/src/mustach/mustach-jansson.h
similarity index 66%
rename from src/mustach/mustach-json-c.h
rename to src/mustach/mustach-jansson.h
index 3dfa228..f1a1b76 100644
--- a/src/mustach/mustach-json-c.h
+++ b/src/mustach/mustach-jansson.h
@@ -1,4 +1,7 @@
 /*
+ Copyright (C) 2020 Taler Systems SA
+
+ Original license:
  Author: José Bollo <jose.bollo@iot.bzh>
  Author: José Bollo <jobol@nonadev.net>
 
@@ -17,13 +20,14 @@
  limitations under the License.
 */
 
-#ifndef _mustach_json_c_h_included_
-#define _mustach_json_c_h_included_
+#ifndef _mustach_jansson_h_included_
+#define _mustach_jansson_h_included_
 
-#include <json-c/json.h>
+#include <taler/taler_json_lib.h>
+#include "mustach.h"
 
 /**
- * fmustach_json_c - Renders the mustache 'template' in 'file' for 'root'.
+ * fmustach_jansson - Renders the mustache 'template' in 'file' for 'root'.
  *
  * @template: the template string to instanciate
  * @root:     the root json object to render
@@ -32,10 +36,10 @@
  * Returns 0 in case of success, -1 with errno set in case of system error
  * a other negative value in case of error.
  */
-extern int fmustach_json_c(const char *template, struct json_object *root, 
FILE *file);
+extern int fmustach_jansson(const char *template, json_t *root, FILE *file);
 
 /**
- * fmustach_json_c - Renders the mustache 'template' in 'fd' for 'root'.
+ * fmustach_jansson - Renders the mustache 'template' in 'fd' for 'root'.
  *
  * @template: the template string to instanciate
  * @root:     the root json object to render
@@ -44,11 +48,11 @@ extern int fmustach_json_c(const char *template, struct 
json_object *root, FILE
  * Returns 0 in case of success, -1 with errno set in case of system error
  * a other negative value in case of error.
  */
-extern int fdmustach_json_c(const char *template, struct json_object *root, 
int fd);
+extern int fdmustach_jansson(const char *template, json_t *root, int fd);
 
 
 /**
- * fmustach_json_c - Renders the mustache 'template' in 'result' for 'root'.
+ * fmustach_jansson - Renders the mustache 'template' in 'result' for 'root'.
  *
  * @template: the template string to instanciate
  * @root:     the root json object to render
@@ -58,10 +62,10 @@ extern int fdmustach_json_c(const char *template, struct 
json_object *root, int
  * Returns 0 in case of success, -1 with errno set in case of system error
  * a other negative value in case of error.
  */
-extern int mustach_json_c(const char *template, struct json_object *root, char 
**result, size_t *size);
+extern int mustach_jansson(const char *template, json_t *root, char **result, 
size_t *size);
 
 /**
- * umustach_json_c - Renders the mustache 'template' for 'root' to custom 
writer 'writecb' with 'closure'.
+ * umustach_jansson - Renders the mustache 'template' for 'root' to custom 
writer 'writecb' with 'closure'.
  *
  * @template: the template string to instanciate
  * @root:     the root json object to render
@@ -71,8 +75,8 @@ extern int mustach_json_c(const char *template, struct 
json_object *root, char *
  * Returns 0 in case of success, -1 with errno set in case of system error
  * a other negative value in case of error.
  */
-typedef int (*mustach_json_c_write_cb)(void*closure, const char*buffer, size_t 
size);
-extern int umustach_json_c(const char *template, struct json_object *root, 
mustach_json_c_write_cb writecb, void *closure);
+typedef int (*mustach_jansson_write_cb)(void *closure, const char *buffer, 
size_t size);
+extern int umustach_jansson(const char *template, json_t *root, 
mustach_jansson_write_cb writecb, void *closure);
 
 #endif
 
diff --git a/src/mustach/mustach-json-c.c b/src/mustach/mustach-json-c.c
deleted file mode 100644
index df901dc..0000000
--- a/src/mustach/mustach-json-c.c
+++ /dev/null
@@ -1,526 +0,0 @@
-/*
- Author: José Bollo <jobol@nonadev.net>
- Author: José Bollo <jose.bollo@iot.bzh>
-
- https://gitlab.com/jobol/mustach
-
- 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.
-*/
-
-#define _GNU_SOURCE
-
-#include <stdio.h>
-#include <string.h>
-#ifdef _WIN32
-#include <malloc.h>
-#endif
-#ifdef __sun
-# include <alloca.h>
-#endif
-
-#include "mustach.h"
-#include "mustach-json-c.h"
-
-#if defined(NO_EXTENSION_FOR_MUSTACH)
-# undef  NO_SINGLE_DOT_EXTENSION_FOR_MUSTACH
-# define NO_SINGLE_DOT_EXTENSION_FOR_MUSTACH
-# undef  NO_EQUAL_VALUE_EXTENSION_FOR_MUSTACH
-# define NO_EQUAL_VALUE_EXTENSION_FOR_MUSTACH
-# undef  NO_COMPARE_VALUE_EXTENSION_FOR_MUSTACH
-# define NO_COMPARE_VALUE_EXTENSION_FOR_MUSTACH
-# undef  NO_JSON_POINTER_EXTENSION_FOR_MUSTACH
-# define NO_JSON_POINTER_EXTENSION_FOR_MUSTACH
-# undef  NO_OBJECT_ITERATION_FOR_MUSTACH
-# define NO_OBJECT_ITERATION_FOR_MUSTACH
-# undef  NO_INCLUDE_PARTIAL_FALLBACK
-# define NO_INCLUDE_PARTIAL_FALLBACK
-#endif
-
-#if !defined(NO_INCLUDE_PARTIAL_FALLBACK) \
-  &&  !defined(INCLUDE_PARTIAL_EXTENSION)
-# define INCLUDE_PARTIAL_EXTENSION ".mustache"
-#endif
-
-#if !defined(NO_COMPARE_VALUE_EXTENSION_FOR_MUSTACH)
-# undef NO_EQUAL_VALUE_EXTENSION_FOR_MUSTACH
-#endif
-
-struct expl {
-       struct json_object *root;
-       mustach_json_c_write_cb writecb;
-       int depth;
-#if !defined(NO_OBJECT_ITERATION_FOR_MUSTACH)
-       int found_objiter;
-#endif
-       struct {
-               struct json_object *cont;
-               struct json_object *obj;
-#if !defined(NO_OBJECT_ITERATION_FOR_MUSTACH)
-               struct json_object_iterator biter, eiter;
-               int is_objiter;
-#endif
-               int index, count;
-       } stack[MUSTACH_MAX_DEPTH];
-};
-
-enum comp {
-       C_no = 0,
-       C_eq = 1,
-       C_lt = 5,
-       C_le = 6,
-       C_gt = 9,
-       C_ge = 10
-};
-
-#if !defined(NO_EQUAL_VALUE_EXTENSION_FOR_MUSTACH)
-static enum comp getcomp(char *head)
-{
-       return head[0] == '=' ? C_eq
-#if !defined(NO_COMPARE_VALUE_EXTENSION_FOR_MUSTACH)
-               : head[0] == '<' ? (head[1] == '=' ? C_le : C_lt)
-               : head[0] == '>' ? (head[1] == '=' ? C_ge : C_gt)
-#endif
-               : C_no;
-}
-
-static char *keyval(char *head, int isptr, enum comp *comp)
-{
-       char *w, c, s;
-       enum comp k;
-
-       k = C_no;
-#if !defined(NO_USE_VALUE_ESCAPE_FIRST_EXTENSION_FOR_MUSTACH)
-       s = getcomp(head) != C_no;
-#else
-       s = 0;
-#endif
-       c = *(w = head);
-       while (c && (s || (k = getcomp(head)) == C_no)) {
-               if (s)
-                       s = 0;
-               else
-                       s = (isptr ? c == '~' : c == '\\')
-                           && (getcomp(head + 1) != C_no);
-               if (!s)
-                       *w++ = c;
-               c = *++head;
-       }
-       *w = 0;
-       *comp = k;
-       return k == C_no ? NULL : &head[k & 3];
-}
-
-static int compare(struct json_object *o, const char *value)
-{
-       switch (json_object_get_type(o)) {
-       case json_type_double:
-               return json_object_get_double(o) - atof(value);
-       case json_type_int:
-               return json_object_get_int64(o) - (int64_t)atoll(value);
-       default:
-               return strcmp(json_object_get_string(o), value);
-       }
-}
-
-static int evalcomp(struct json_object *o, char *value, enum comp k)
-{
-       int r, c;
-
-       c = compare(o, value);
-       switch (k) {
-       case C_eq: r = c == 0; break;
-#if !defined(NO_COMPARE_VALUE_EXTENSION_FOR_MUSTACH)
-       case C_lt: r = c < 0; break;
-       case C_le: r = c <= 0; break;
-       case C_gt: r = c > 0; break;
-       case C_ge: r = c >= 0; break;
-#endif
-       default: r = 0; break;
-       }
-       return r;
-}
-#else
-static inline char *keyval(char *head, int isptr, enum comp *comp)
-{
-       *comp = C_no;
-       return NULL;
-}
-static inline int compare(struct json_object *o, char *value, enum comp k)
-{
-       return 0;
-}
-#endif
-
-static char *key(char **head, int isptr)
-{
-       char *r, *i, *w, c;
-
-       c = *(i = *head);
-       if (!c)
-               r = NULL;
-       else {
-               r = w = i;
-#if !defined(NO_JSON_POINTER_EXTENSION_FOR_MUSTACH)
-               if (isptr)
-                       while (c && c != '/') {
-                               if (c == '~')
-                                       switch (i[1]) {
-                                       case '1': c = '/'; /*@fallthrough@*/
-                                       case '0': i++;
-                                       }
-                               *w++ = c;
-                               c = *++i;
-                       }
-               else
-#endif
-               while (c && c != '.') {
-                       if (c == '\\' && (i[1] == '.' || i[1] == '\\'))
-                               c = *++i;
-                       *w++ = c;
-                       c = *++i;
-               }
-               *w = 0;
-               *head = i + !!c;
-       }
-       return r;
-}
-
-static struct json_object *find(struct expl *e, const char *name)
-{
-       int i, isptr;
-       struct json_object *o, *no;
-       char *n, *c, *v;
-       enum comp k;
-
-       n = alloca(1 + strlen(name));
-       strcpy(n, name);
-       isptr = 0;
-#if !defined(NO_JSON_POINTER_EXTENSION_FOR_MUSTACH)
-       isptr = n[0] == '/';
-       n += isptr;
-#endif
-
-       v = keyval(n, isptr, &k);
-#if !defined(NO_OBJECT_ITERATION_FOR_MUSTACH)
-       e->found_objiter = 0;
-#endif
-#if !defined(NO_SINGLE_DOT_EXTENSION_FOR_MUSTACH)
-       if (n[0] == '.' && !n[1]) {
-               /* case of . alone */
-               o = e->stack[e->depth].obj;
-       } else
-#endif
-       {
-               c = key(&n, isptr);
-               if (c == NULL)
-                       return NULL;
-               o = NULL;
-               i = e->depth;
-               while (i >= 0 && !json_object_object_get_ex(e->stack[i].obj, c, 
&o))
-                       i--;
-               if (i < 0) {
-#if !defined(NO_OBJECT_ITERATION_FOR_MUSTACH)
-                       o = e->stack[e->depth].obj;
-                       if (c[0] == '*' && !c[1] && !v && !key(&n, isptr) && 
json_object_is_type(o, json_type_object)) {
-                               e->found_objiter = 1;
-                               return o;
-                       }
-#endif
-                       return NULL;
-               }
-               c = key(&n, isptr);
-               while(c) {
-                       if (!json_object_object_get_ex(o, c, &no)) {
-#if !defined(NO_OBJECT_ITERATION_FOR_MUSTACH)
-                               if (c[0] == '*' && !c[1] && !v && !key(&n, 
isptr) && json_object_is_type(o, json_type_object)) {
-                                       e->found_objiter = 1;
-                                       return o;
-                               }
-#endif
-                               return NULL;
-                       }
-                       o = no;
-                       c = key(&n, isptr);
-               }
-       }
-       if (v) {
-               i = v[0] == '!';
-               if (i == evalcomp(o, &v[i], k))
-                       o = NULL;
-       }
-       return o;
-}
-
-static int start(void *closure)
-{
-       struct expl *e = closure;
-       e->depth = 0;
-       e->stack[0].cont = NULL;
-       e->stack[0].obj = e->root;
-       e->stack[0].index = 0;
-       e->stack[0].count = 1;
-       return MUSTACH_OK;
-}
-
-static int write(struct expl *e, const char *buffer, size_t size, FILE *file)
-{
-       return e->writecb(file, buffer, size);
-}
-
-static int emituw(void *closure, const char *buffer, size_t size, int escape, 
FILE *file)
-{
-       struct expl *e = closure;
-       if (!escape)
-               write(e, buffer, size, file);
-       else
-               do {
-                       switch(*buffer) {
-                       case '<': write(e, "&lt;", 4, file); break;
-                       case '>': write(e, "&gt;", 4, file); break;
-                       case '&': write(e, "&amp;", 5, file); break;
-                       default: write(e, buffer, 1, file); break;
-                       }
-                       buffer++;
-               } while(--size);
-       return MUSTACH_OK;
-}
-
-static const char *item(struct expl *e, const char *name)
-{
-       struct json_object *o;
-       const char *s;
-
-#if !defined(NO_OBJECT_ITERATION_FOR_MUSTACH)
-       if (name[0] == '*' && !name[1] && e->stack[e->depth].is_objiter)
-               s = json_object_iter_peek_name(&e->stack[e->depth].biter);
-       else
-               s = (o = find(e, name)) && !e->found_objiter ? 
json_object_get_string(o) : NULL;
-#else
-       s = (o = find(e, name)) ? json_object_get_string(o) : NULL;
-#endif
-       return s;
-}
-
-static int enter(void *closure, const char *name)
-{
-       struct expl *e = closure;
-       struct json_object *o = find(e, name);
-       if (++e->depth >= MUSTACH_MAX_DEPTH)
-               return MUSTACH_ERROR_TOO_DEEP;
-       if (json_object_is_type(o, json_type_array)) {
-               e->stack[e->depth].count = json_object_array_length(o);
-               if (e->stack[e->depth].count == 0) {
-                       e->depth--;
-                       return 0;
-               }
-               e->stack[e->depth].cont = o;
-               e->stack[e->depth].obj = json_object_array_get_idx(o, 0);
-               e->stack[e->depth].index = 0;
-#if !defined(NO_OBJECT_ITERATION_FOR_MUSTACH)
-               e->stack[e->depth].is_objiter = 0;
-       } else if (json_object_is_type(o, json_type_object) && 
e->found_objiter) {
-               e->stack[e->depth].biter = json_object_iter_begin(o);
-               e->stack[e->depth].eiter = json_object_iter_end(o);
-               if (json_object_iter_equal(&e->stack[e->depth].biter, 
&e->stack[e->depth].eiter)) {
-                       e->depth--;
-                       return 0;
-               }
-               e->stack[e->depth].obj = 
json_object_iter_peek_value(&e->stack[e->depth].biter);
-               e->stack[e->depth].cont = o;
-               e->stack[e->depth].is_objiter = 1;
-#endif
-       } else if (json_object_is_type(o, json_type_object) || 
json_object_get_boolean(o)) {
-               e->stack[e->depth].count = 1;
-               e->stack[e->depth].cont = NULL;
-               e->stack[e->depth].obj = o;
-               e->stack[e->depth].index = 0;
-#if !defined(NO_OBJECT_ITERATION_FOR_MUSTACH)
-               e->stack[e->depth].is_objiter = 0;
-#endif
-       } else {
-               e->depth--;
-               return 0;
-       }
-       return 1;
-}
-
-static int next(void *closure)
-{
-       struct expl *e = closure;
-       if (e->depth <= 0)
-               return MUSTACH_ERROR_CLOSING;
-#if !defined(NO_OBJECT_ITERATION_FOR_MUSTACH)
-       if (e->stack[e->depth].is_objiter) {
-               json_object_iter_next(&e->stack[e->depth].biter);
-               if (json_object_iter_equal(&e->stack[e->depth].biter, 
&e->stack[e->depth].eiter))
-                       return 0;
-               e->stack[e->depth].obj = 
json_object_iter_peek_value(&e->stack[e->depth].biter);
-               return 1;
-       }
-#endif
-       e->stack[e->depth].index++;
-       if (e->stack[e->depth].index >= e->stack[e->depth].count)
-               return 0;
-       e->stack[e->depth].obj = 
json_object_array_get_idx(e->stack[e->depth].cont, e->stack[e->depth].index);
-       return 1;
-}
-
-static int leave(void *closure)
-{
-       struct expl *e = closure;
-       if (e->depth <= 0)
-               return MUSTACH_ERROR_CLOSING;
-       e->depth--;
-       return 0;
-}
-
-#if !defined(NO_INCLUDE_PARTIAL_FALLBACK)
-static int get_partial_from_file(const char *name, struct mustach_sbuf *sbuf)
-{
-       static char extension[] = INCLUDE_PARTIAL_EXTENSION;
-       size_t s;
-       long pos;
-       FILE *file;
-       char *path, *buffer;
-
-       /* allocate path */
-       s = strlen(name);
-       path = malloc(s + sizeof extension);
-       if (path == NULL)
-               return MUSTACH_ERROR_SYSTEM;
-
-       /* try without extension first */
-       memcpy(path, name, s + 1);
-       file = fopen(path, "r");
-       if (file == NULL) {
-               memcpy(&path[s], extension, sizeof extension);
-               file = fopen(path, "r");
-       }
-       free(path);
-
-       /* if file opened */
-       if (file != NULL) {
-               /* compute file size */
-               if (fseek(file, 0, SEEK_END) >= 0
-                && (pos = ftell(file)) >= 0
-                && fseek(file, 0, SEEK_SET) >= 0) {
-                       /* allocate value */
-                       s = (size_t)pos;
-                       buffer = malloc(s + 1);
-                       if (buffer != NULL) {
-                               /* read value */
-                               if (1 == fread(buffer, s, 1, file)) {
-                                       /* force zero at end */
-                                       sbuf->value = buffer;
-                                       buffer[s] = 0;
-                                       sbuf->freecb = free;
-                                       fclose(file);
-                                       return MUSTACH_OK;
-                               }
-                               free(buffer);
-                       }
-               }
-               fclose(file);
-       }
-       return MUSTACH_ERROR_SYSTEM;
-}
-
-static int partial(void *closure, const char *name, struct mustach_sbuf *sbuf)
-{
-       struct expl *e = closure;
-       const char *s;
-
-       s = item(e, name);
-       if (s)
-               sbuf->value = s;
-       else if (get_partial_from_file(name, sbuf) < 0)
-               sbuf->value = "";
-       return MUSTACH_OK;
-}
-#endif
-
-static int get(void *closure, const char *name, struct mustach_sbuf *sbuf)
-{
-       struct expl *e = closure;
-       const char *s;
-
-       s = item(e, name);
-       if (s)
-               sbuf->value = s;
-       else
-               sbuf->value = "";
-       return MUSTACH_OK;
-}
-
-static struct mustach_itf itf = {
-       .start = start,
-       .put = NULL,
-       .enter = enter,
-       .next = next,
-       .leave = leave,
-#if !defined(NO_INCLUDE_PARTIAL_FALLBACK)
-       .partial = partial,
-#else
-       .partial =NULL,
-#endif
-       .get = get,
-       .emit = NULL,
-       .stop = NULL
-};
-
-static struct mustach_itf itfuw = {
-       .start = start,
-       .put = NULL,
-       .enter = enter,
-       .next = next,
-       .leave = leave,
-#if !defined(NO_INCLUDE_PARTIAL_FALLBACK)
-       .partial = partial,
-#else
-       .partial =NULL,
-#endif
-       .get = get,
-       .emit = emituw,
-       .stop = NULL
-};
-
-int fmustach_json_c(const char *template, struct json_object *root, FILE *file)
-{
-       struct expl e;
-       e.root = root;
-       return fmustach(template, &itf, &e, file);
-}
-
-int fdmustach_json_c(const char *template, struct json_object *root, int fd)
-{
-       struct expl e;
-       e.root = root;
-       return fdmustach(template, &itf, &e, fd);
-}
-
-int mustach_json_c(const char *template, struct json_object *root, char 
**result, size_t *size)
-{
-       struct expl e;
-       e.root = root;
-       e.writecb = NULL;
-       return mustach(template, &itf, &e, result, size);
-}
-
-int umustach_json_c(const char *template, struct json_object *root, 
mustach_json_c_write_cb writecb, void *closure)
-{
-       struct expl e;
-       e.root = root;
-       e.writecb = writecb;
-       return fmustach(template, &itfuw, &e, closure);
-}
-
diff --git a/src/mustach/test_mustach_jansson.c 
b/src/mustach/test_mustach_jansson.c
new file mode 100644
index 0000000..8f1e37b
--- /dev/null
+++ b/src/mustach/test_mustach_jansson.c
@@ -0,0 +1,80 @@
+/*
+  This file is part of TALER
+  Copyright (C) 2014-2020 Taler Systems SA
+
+  TALER is free software; you can redistribute it and/or modify
+  it under the terms of the GNU General Public License as
+  published by the Free Software Foundation; either version 3, or
+  (at your option) any later version.
+
+  TALER is distributed in the hope that it will be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  GNU General Public License for more details.
+
+  You should have received a copy of the GNU General Public
+  License along with TALER; see the file COPYING.  If not, see
+  <http://www.gnu.org/licenses/>
+*/
+
+/**
+ * @file mustac/test_mustach_jansson.c
+ * @brief testcase to test the mustach/jansson integration
+ * @author Florian Dold
+ */
+#include "platform.h"
+#include "mustach-jansson.h"
+
+void
+assert_template (const char *template, json_t *root, const char *expected)
+{
+  char *r;
+  size_t sz;
+
+  GNUNET_assert (0 == mustach_jansson (template, root, &r, &sz));
+  GNUNET_assert (0 == strcmp (r, expected));
+  GNUNET_free (r);
+}
+
+int
+main (int argc,
+      char *const *argv)
+{
+  json_t *root = json_object ();
+  json_t *arr = json_array ();
+  json_t *obj = json_object();
+  /* test 1 */
+  char *t1 = "hello world";
+  char *x1 = "hello world";
+  /* test 2 */
+  char *t2 = "hello {{ v1 }}";
+  char *x2 = "hello world";
+  /* test 3 */
+  char *t3 = "hello {{ v3.x }}";
+  char *x3 = "hello baz";
+  /* test 4 */
+  char *t4 = "hello {{# v2 }}{{ . }}{{/ v2 }}";
+  char *x4 = "hello foobar";
+  /* test 5 */
+  char *t5 = "hello {{# v3 }}{{ y }}/{{ x }}{{ z }}{{/ v3 }}";
+  char *x5 = "hello quux/baz";
+
+  json_object_set_new (root, "v1", json_string ("world"));
+  json_array_append_new (arr, json_string ("foo"));
+  json_array_append_new (arr, json_string ("bar"));
+  json_object_set_new (root, "v2", arr);
+  json_object_set_new (root, "v3", obj);
+  json_object_set_new (obj, "x", json_string ("baz"));
+  json_object_set_new (obj, "y", json_string ("quux"));
+
+  assert_template (t1, root, x1);
+  assert_template (t2, root, x2);
+  assert_template (t3, root, x3);
+  assert_template (t4, root, x4);
+  assert_template (t5, root, x5);
+
+  json_decref (root);
+
+  return 0;
+}
+

-- 
To stop receiving notification emails like this one, please contact
gnunet@gnunet.org.



reply via email to

[Prev in Thread] Current Thread [Next in Thread]