diff options
author | Alexandru Ardelean <ardeleanalex@gmail.com> | 2016-11-16 11:55:41 +0200 |
---|---|---|
committer | Alexandru Ardelean <ardeleanalex@gmail.com> | 2016-11-22 16:33:49 +0200 |
commit | 742e059da1f5bd3c458f38bfbeb6e46ea1145f7b (patch) | |
tree | 38804736cfd606d3fd53feed05f78c6a03e16f7b /json_pointer.c | |
parent | 97dd7d5103f4038f3333b54615f5d233852acdb4 (diff) | |
download | json-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.c | 85 |
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; +} + |