summaryrefslogtreecommitdiff
path: root/json_pointer.c
diff options
context:
space:
mode:
authorAlexandru Ardelean <ardeleanalex@gmail.com>2016-11-16 11:55:41 +0200
committerAlexandru Ardelean <ardeleanalex@gmail.com>2016-11-22 16:33:49 +0200
commit742e059da1f5bd3c458f38bfbeb6e46ea1145f7b (patch)
tree38804736cfd606d3fd53feed05f78c6a03e16f7b /json_pointer.c
parent97dd7d5103f4038f3333b54615f5d233852acdb4 (diff)
downloadjson-c-742e059da1f5bd3c458f38bfbeb6e46ea1145f7b.tar.gz
json_pointer: add json_pointer_getf/setf() function variants
These include support for printf() style args for path. Adds support for calling with 'json_pointer_getf(obj, &res, "/foo/%d/%s", 0, bar)' style args. Makes it easier for doing more dynamic stuff/magic, without needing to use vasprintf() externally. Signed-off-by: Alexandru Ardelean <ardeleanalex@gmail.com>
Diffstat (limited to 'json_pointer.c')
-rw-r--r--json_pointer.c85
1 files changed, 85 insertions, 0 deletions
diff --git a/json_pointer.c b/json_pointer.c
index a445e3b..582ca28 100644
--- a/json_pointer.c
+++ b/json_pointer.c
@@ -8,6 +8,7 @@
#include "config.h"
+#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
@@ -192,6 +193,37 @@ int json_pointer_get(struct json_object *obj, const char *path, struct json_obje
return rc;
}
+int json_pointer_getf(struct json_object *obj, struct json_object **res, const char *path_fmt, ...)
+{
+ char *path_copy = NULL;
+ int rc = 0;
+ va_list args;
+
+ if (!obj || !path_fmt) {
+ errno = EINVAL;
+ return -1;
+ }
+
+ va_start(args, path_fmt);
+ rc = vasprintf(&path_copy, path_fmt, args);
+ va_end(args);
+
+ if (rc < 0)
+ return rc;
+
+ if (path_copy[0] == '\0') {
+ if (res)
+ *res = obj;
+ goto out;
+ }
+
+ rc = json_pointer_get_recursive(obj, path_copy, res);
+out:
+ free(path_copy);
+
+ return rc;
+}
+
int json_pointer_set(struct json_object **obj, const char *path, struct json_object *value)
{
const char *endp;
@@ -237,3 +269,56 @@ int json_pointer_set(struct json_object **obj, const char *path, struct json_obj
return json_pointer_set_single_path(set, endp, value);
}
+int json_pointer_setf(struct json_object **obj, struct json_object *value, const char *path_fmt, ...)
+{
+ char *endp;
+ char *path_copy = NULL;
+ struct json_object *set = NULL;
+ va_list args;
+ int rc = 0;
+
+ if (!obj || !path_fmt) {
+ errno = EINVAL;
+ return -1;
+ }
+
+ /* pass a working copy to the recursive call */
+ va_start(args, path_fmt);
+ rc = vasprintf(&path_copy, path_fmt, args);
+ va_end(args);
+
+ if (rc < 0)
+ return rc;
+
+ if (path_copy[0] == '\0') {
+ json_object_put(*obj);
+ *obj = value;
+ goto out;
+ }
+
+ if (path_copy[0] != '/') {
+ errno = EINVAL;
+ rc = -1;
+ goto out;
+ }
+
+ /* If there's only 1 level to set, stop here */
+ if ((endp = strrchr(path_copy, '/')) == path_copy) {
+ set = *obj;
+ goto set_single_path;
+ }
+
+ *endp = '\0';
+ rc = json_pointer_get_recursive(*obj, path_copy, &set);
+
+ if (rc)
+ goto out;
+
+set_single_path:
+ endp++;
+ rc = json_pointer_set_single_path(set, endp, value);
+out:
+ free(path_copy);
+ return rc;
+}
+