diff --git a/Makefile.in b/Makefile.in index b73de965..85e9e386 100644 --- a/Makefile.in +++ b/Makefile.in @@ -5,6 +5,8 @@ prefix = @prefix@ includedir = $(DESTDIR)@includedir@ libdir = $(DESTDIR)@libdir@ +AR = @AR@ +CC = @CC@ CFLAGS = @CFLAGS@ LDFLAGS = @LDFLAGS@ SRCS = $(wildcard *.c) diff --git a/README.md b/README.md index 169d25e6..95b6b4a1 100644 --- a/README.md +++ b/README.md @@ -36,3 +36,8 @@ The `type` field of `json_value` is one of: * `json_string` (see `u.string.ptr`, `u.string.length`) * `json_boolean` (see `u.boolean`) * `json_null` + +Some higher-level accessors are available, e.g.: + +* `json_object_get (obj, key)` can be used to retrieve the value of the specified key. +* `json_array_for_each (array, idx, elem)` iterates over all items in an array. diff --git a/configure b/configure index ad6e9115..3d88d35e 100755 --- a/configure +++ b/configure @@ -584,6 +584,7 @@ PACKAGE_URL='' ac_subst_vars='LTLIBOBJS LIBOBJS VERSION_MAJOR +AR OBJEXT EXEEXT ac_ct_CC @@ -2525,6 +2526,98 @@ ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}ar", so it can be a program name with args. +set dummy ${ac_tool_prefix}ar; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_AR+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$AR"; then + ac_cv_prog_AR="$AR" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_AR="${ac_tool_prefix}ar" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +AR=$ac_cv_prog_AR +if test -n "$AR"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AR" >&5 +$as_echo "$AR" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_AR"; then + ac_ct_AR=$AR + # Extract the first word of "ar", so it can be a program name with args. +set dummy ar; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_AR+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_AR"; then + ac_cv_prog_ac_ct_AR="$ac_ct_AR" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_AR="ar" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_AR=$ac_cv_prog_ac_ct_AR +if test -n "$ac_ct_AR"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_AR" >&5 +$as_echo "$ac_ct_AR" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_AR" = x; then + AR=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + AR=$ac_ct_AR + fi +else + AR="$ac_cv_prog_AR" +fi + # Check whether --enable-debug was given. if test "${enable_debug+set}" = set; then : diff --git a/configure.ac b/configure.ac index 19c03118..6de09ef4 100644 --- a/configure.ac +++ b/configure.ac @@ -7,6 +7,7 @@ VERSION_MAJOR="1.0" AC_CONFIG_MACRO_DIR([m4]) AC_PROG_CC +AC_CHECK_TOOL(AR, ar, :) AC_ARG_ENABLE([debug], [AS_HELP_STRING([--enable-debug], diff --git a/json.c b/json.c index afc1a728..66404a16 100644 --- a/json.c +++ b/json.c @@ -881,3 +881,31 @@ void json_value_free (json_value * value) json_value_free_ex (&settings, value); } +char *json_string_get (json_value *str) +{ + if (!str || str->type != json_string) + return NULL; + + return str->u.string.ptr; +} + +json_value *json_object_get (json_value *obj, char *key) +{ + int i; + + if (!obj || obj->type != json_object) + return NULL; + + for (i = 0; i < obj->u.object.length; i++) { + if (!strcmp (obj->u.object.values[i].name, key)) + return obj->u.object.values[i].value; + } + + return NULL; +} + +char *json_object_get_string (json_value *obj, char *key) +{ + json_value *str = json_object_get (obj, key); + return json_string_get (str); +} diff --git a/json.h b/json.h index 1a85d184..c41f0c5a 100644 --- a/json.h +++ b/json.h @@ -258,6 +258,30 @@ void json_value_free (json_value *); void json_value_free_ex (json_settings * settings, json_value *); +/* Retrieve the underlying string of str, returns NULL if str is NULL + * or not a string + */ +char *json_string_get (json_value *str); + +/* Retrieve a value by its key, returns NULL if obj is NULL or not an + * object, or key is not in obj. + */ +json_value *json_object_get (json_value *obj, char *key); + +/* Retrieve s string attribute from an object by its key, returns NULL + * if obj is NULL or not an object, or if the key is not in obj or not + * a string. + */ +char *json_object_get_string (json_value *obj, char *key); + +/* Iterate over all elements in the array _arr, binding _idx and _elm + * to the corresponding index and value. + */ +#define json_array_for_each(_arr, _idx, _elm) \ + if ((_arr) && (_arr)->type == json_array) \ + for (*(_idx) = 0, *(_elm) = (_arr)->u.array.values[0]; \ + *(_idx) < (_arr)->u.array.length; \ + *(_elm) = (_arr)->u.array.values[++(*(_idx))]) #ifdef __cplusplus } /* extern "C" */