diff --git a/configure b/configure index 56db59a6..4993b4e7 100755 --- a/configure +++ b/configure @@ -622,8 +622,10 @@ ac_includes_default="\ # include #endif" +enable_option_checking=no ac_subst_vars='LTLIBOBJS LIBOBJS +subdirs EGREP GREP CPP @@ -685,7 +687,7 @@ LDFLAGS LIBS CPPFLAGS CPP' - +ac_subdirs_all='src/ src/common/ src/test/' # Initialize some variables set by options. ac_init_help= @@ -3628,7 +3630,40 @@ _ACEOF esac -ac_config_files="$ac_config_files Makefile src/common/Makefile src/test/Makefile" +ac_config_files="$ac_config_files Makefile src/Makefile src/common/Makefile src/test/Makefile" + +ac_aux_dir= +for ac_dir in "$srcdir" "$srcdir/.." "$srcdir/../.."; do + if test -f "$ac_dir/install-sh"; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/install-sh -c" + break + elif test -f "$ac_dir/install.sh"; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/install.sh -c" + break + elif test -f "$ac_dir/shtool"; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/shtool install -c" + break + fi +done +if test -z "$ac_aux_dir"; then + as_fn_error $? "cannot find install-sh, install.sh, or shtool in \"$srcdir\" \"$srcdir/..\" \"$srcdir/../..\"" "$LINENO" 5 +fi + +# These three variables are undocumented and unsupported, +# and are intended to be withdrawn in a future Autoconf release. +# They can cause serious problems if a builder's source tree is in a directory +# whose full name contains unusual characters. +ac_config_guess="$SHELL $ac_aux_dir/config.guess" # Please don't use this var. +ac_config_sub="$SHELL $ac_aux_dir/config.sub" # Please don't use this var. +ac_configure="$SHELL $ac_aux_dir/configure" # Please don't use this var. + + + + +subdirs="$subdirs src/ src/common/ src/test/" cat >confcache <<\_ACEOF # This file is a shell script that caches the results of configure @@ -4336,6 +4371,7 @@ for ac_config_target in $ac_config_targets do case $ac_config_target in "Makefile") CONFIG_FILES="$CONFIG_FILES Makefile" ;; + "src/Makefile") CONFIG_FILES="$CONFIG_FILES src/Makefile" ;; "src/common/Makefile") CONFIG_FILES="$CONFIG_FILES src/common/Makefile" ;; "src/test/Makefile") CONFIG_FILES="$CONFIG_FILES src/test/Makefile" ;; @@ -4782,6 +4818,151 @@ if test "$no_create" != yes; then # would make configure fail if this is the last instruction. $ac_cs_success || as_fn_exit 1 fi + +# +# CONFIG_SUBDIRS section. +# +if test "$no_recursion" != yes; then + + # Remove --cache-file, --srcdir, and --disable-option-checking arguments + # so they do not pile up. + ac_sub_configure_args= + ac_prev= + eval "set x $ac_configure_args" + shift + for ac_arg + do + if test -n "$ac_prev"; then + ac_prev= + continue + fi + case $ac_arg in + -cache-file | --cache-file | --cache-fil | --cache-fi \ + | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c) + ac_prev=cache_file ;; + -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \ + | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* \ + | --c=*) + ;; + --config-cache | -C) + ;; + -srcdir | --srcdir | --srcdi | --srcd | --src | --sr) + ac_prev=srcdir ;; + -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*) + ;; + -prefix | --prefix | --prefi | --pref | --pre | --pr | --p) + ac_prev=prefix ;; + -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*) + ;; + --disable-option-checking) + ;; + *) + case $ac_arg in + *\'*) ac_arg=`$as_echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;; + esac + as_fn_append ac_sub_configure_args " '$ac_arg'" ;; + esac + done + + # Always prepend --prefix to ensure using the same prefix + # in subdir configurations. + ac_arg="--prefix=$prefix" + case $ac_arg in + *\'*) ac_arg=`$as_echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;; + esac + ac_sub_configure_args="'$ac_arg' $ac_sub_configure_args" + + # Pass --silent + if test "$silent" = yes; then + ac_sub_configure_args="--silent $ac_sub_configure_args" + fi + + # Always prepend --disable-option-checking to silence warnings, since + # different subdirs can have different --enable and --with options. + ac_sub_configure_args="--disable-option-checking $ac_sub_configure_args" + + ac_popdir=`pwd` + for ac_dir in : $subdirs; do test "x$ac_dir" = x: && continue + + # Do not complain, so a configure script can configure whichever + # parts of a large source tree are present. + test -d "$srcdir/$ac_dir" || continue + + ac_msg="=== configuring in $ac_dir (`pwd`/$ac_dir)" + $as_echo "$as_me:${as_lineno-$LINENO}: $ac_msg" >&5 + $as_echo "$ac_msg" >&6 + as_dir="$ac_dir"; as_fn_mkdir_p + ac_builddir=. + +case "$ac_dir" in +.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; +*) + ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'` + # A ".." for each directory in $ac_dir_suffix. + ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` + case $ac_top_builddir_sub in + "") ac_top_builddir_sub=. ac_top_build_prefix= ;; + *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; + esac ;; +esac +ac_abs_top_builddir=$ac_pwd +ac_abs_builddir=$ac_pwd$ac_dir_suffix +# for backward compatibility: +ac_top_builddir=$ac_top_build_prefix + +case $srcdir in + .) # We are building in place. + ac_srcdir=. + ac_top_srcdir=$ac_top_builddir_sub + ac_abs_top_srcdir=$ac_pwd ;; + [\\/]* | ?:[\\/]* ) # Absolute name. + ac_srcdir=$srcdir$ac_dir_suffix; + ac_top_srcdir=$srcdir + ac_abs_top_srcdir=$srcdir ;; + *) # Relative name. + ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix + ac_top_srcdir=$ac_top_build_prefix$srcdir + ac_abs_top_srcdir=$ac_pwd/$srcdir ;; +esac +ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix + + + cd "$ac_dir" + + # Check for guested configure; otherwise get Cygnus style configure. + if test -f "$ac_srcdir/configure.gnu"; then + ac_sub_configure=$ac_srcdir/configure.gnu + elif test -f "$ac_srcdir/configure"; then + ac_sub_configure=$ac_srcdir/configure + elif test -f "$ac_srcdir/configure.in"; then + # This should be Cygnus configure. + ac_sub_configure=$ac_aux_dir/configure + else + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: no configuration information is in $ac_dir" >&5 +$as_echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2;} + ac_sub_configure= + fi + + # The recursion is here. + if test -n "$ac_sub_configure"; then + # Make the cache file name correct relative to the subdirectory. + case $cache_file in + [\\/]* | ?:[\\/]* ) ac_sub_cache_file=$cache_file ;; + *) # Relative name. + ac_sub_cache_file=$ac_top_build_prefix$cache_file ;; + esac + + { $as_echo "$as_me:${as_lineno-$LINENO}: running $SHELL $ac_sub_configure $ac_sub_configure_args --cache-file=$ac_sub_cache_file --srcdir=$ac_srcdir" >&5 +$as_echo "$as_me: running $SHELL $ac_sub_configure $ac_sub_configure_args --cache-file=$ac_sub_cache_file --srcdir=$ac_srcdir" >&6;} + # The eval makes quoting arguments work. + eval "\$SHELL \"\$ac_sub_configure\" $ac_sub_configure_args \ + --cache-file=\"\$ac_sub_cache_file\" --srcdir=\"\$ac_srcdir\"" || + as_fn_error $? "$ac_sub_configure failed for $ac_dir" "$LINENO" 5 + fi + + cd "$ac_popdir" + done +fi if test -n "$ac_unrecognized_opts" && test "$enable_option_checking" != no; then { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: unrecognized options: $ac_unrecognized_opts" >&5 $as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2;} diff --git a/configure.ac b/configure.ac index 253b1f6f..348aee04 100644 --- a/configure.ac +++ b/configure.ac @@ -27,5 +27,6 @@ AC_TYPE_UINT32_T AC_TYPE_UINT64_T AC_TYPE_UINT8_T -AC_CONFIG_FILES([Makefile src/common/Makefile src/test/Makefile]) +AC_CONFIG_FILES([Makefile src/Makefile src/common/Makefile src/test/Makefile]) +AC_CONFIG_SUBDIRS([src/ src/common/ src/test/]) AC_OUTPUT diff --git a/src/Makefile.in b/src/Makefile.in index a9d1352e..7785aee0 100644 --- a/src/Makefile.in +++ b/src/Makefile.in @@ -16,7 +16,7 @@ srcdir = @srcdir@ VPATH = @srcdir@ default: - cd common && $(MAKE) + cd common && $(MAKE) $@ all : default test @@ -57,10 +57,10 @@ distcheck: $(distdir).tar.gz rm -rf $(distdir) @echo "*** Package $(distdir).tar.gz is ready for distribution" -Makefile: Makefile.in config.status - ./config.status $@ +#Makefile: Makefile.in config.status +# ./config.status $@ -configure.status: configure - ./config.status --recheck +#configure.status: configure +# ./config.status --recheck -.PHONY: all distclean clean default +.PHONY: all distclean clean default test diff --git a/src/common/getdns_core_only.h b/src/common/getdns_core_only.h index e43d8e4a..9d699172 100644 --- a/src/common/getdns_core_only.h +++ b/src/common/getdns_core_only.h @@ -402,6 +402,18 @@ struct getdns_list_item { * @return GETDNS_RETURN_NO_SUCH_LIST_ITEM if list is not valid or params are NULL */ getdns_return_t getdns_list_get_length(struct getdns_list *list, size_t *answer); +/** + * private function (API users should not be calling this), this uses library + * routines to make a copy of the list - would be faster to make the copy directly + * caller must ensure that dstlist points to unallocated storage - the address will + * be overwritten by a new list via a call to getdns_list_create() + * @param srclist pointer to list to copy + * @param srclist pointer to pointer to list to receive the copy (will be allocated) + * @return GETDNS_RETURN_GOOD on success + * @return GETDNS_RETURN_NO_SUCH_LIST_ITEM if list is invalid + * @return GETDNS_RETURN_GENERIC_ERROR if out of memory + */ +getdns_return_t getdns_list_copy(struct getdns_list *srclist, struct getdns_list **dstlist); /** * get the enumerated data type of the indexed list item * @param list the list from which to fetch the data type @@ -410,8 +422,20 @@ getdns_return_t getdns_list_get_length(struct getdns_list *list, size_t *answer) * @return GETDNS_RETURN_GOOD on success * @return GETDNS_RETURN_NO_SUCH_LIST_ITEM if the index is out of range or the list is NULL */ -getdns_return_t getdns_list_get_data_type(struct getdns_list *this_list, size_t index, getdns_data_type *answer); -getdns_return_t getdns_list_get_dict(struct getdns_list *this_list, size_t index, struct getdns_dict **answer); +getdns_return_t getdns_list_get_data_type(struct getdns_list *list, size_t index, getdns_data_type *answer); +/** + * retrieve the dictionary value of the specified list item, the caller must not free + * storage associated with the return value. When the list is destroyed this + * dict data is also free()'d - keep this in mind when using this function. + * @param list the list from which to fetch the value + * @param index the item in the list from which to fetch the value + * @param **answer assigned a pointer to the dict value of the indexed element + * @return GETDNS_RETURN_GOOD on success + * @return GETDNS_RETURN_NO_SUCH_LIST_ITEM if the index is out of range or the list is NULL + * @return GETDNS_RETURN_WRONG_TYPE_REQUESTED if the data type does not match the contents of the indexed item + */ +getdns_return_t getdns_list_get_dict(struct getdns_list *list, size_t index, struct getdns_dict **answer); + /** * retrieve the list value of the specified list item, the caller must not free * storage associated with the return value. When the list is destroyed any @@ -423,7 +447,7 @@ getdns_return_t getdns_list_get_dict(struct getdns_list *this_list, size_t index * @return GETDNS_RETURN_NO_SUCH_LIST_ITEM if the index is out of range or the list is NULL * @return GETDNS_RETURN_WRONG_TYPE_REQUESTED if the data type does not match the contents of the indexed item */ -getdns_return_t getdns_list_get_list(struct getdns_list *this_list, size_t index, struct getdns_list **answer); +getdns_return_t getdns_list_get_list(struct getdns_list *list, size_t index, struct getdns_list **answer); /** * retrieve the binary data value of the specified list item, the caller must not * free storage associated with the return value. When the list is destroyed any @@ -435,7 +459,7 @@ getdns_return_t getdns_list_get_list(struct getdns_list *this_list, size_t index * @return GETDNS_RETURN_NO_SUCH_LIST_ITEM if the index is out of range or the list is NULL * @return GETDNS_RETURN_WRONG_TYPE_REQUESTED if the data type does not match the contents of the indexed item */ -getdns_return_t getdns_list_get_bindata(struct getdns_list *this_list, size_t index, struct getdns_bindata **answer); +getdns_return_t getdns_list_get_bindata(struct getdns_list *list, size_t index, struct getdns_bindata **answer); /** * retrieve the integer value of the specified list item * @param list the list from which to fetch the item @@ -453,7 +477,7 @@ getdns_return_t getdns_list_get_int(struct getdns_list *list, size_t index, uint * @param dict dictionary from which to produce the list of names * @param **answer a pointer to the new list will be assigned to *answer * @return GETDNS_RETURN_GOOD on success - * @return GETDNS_RETURN_NO_SUCH_DICT_NAME if dict is invalid + * @return GETDNS_RETURN_NO_SUCH_DICT_NAME if dict is invalid or empty */ getdns_return_t getdns_dict_get_names(struct getdns_dict *dict, struct getdns_list **answer); /** @@ -467,7 +491,8 @@ getdns_return_t getdns_dict_get_names(struct getdns_dict *dict, struct getdns_li getdns_return_t getdns_dict_get_data_type(struct getdns_dict *this_dict, char *name, getdns_data_type *answer); /** * fetch the dictionary associated with the specified name, the dictionary should - * be free()'d by the caller via getdns_dict_destroy() + * not be free()'d by the caller, it will be freed when the parent dictionary is + * free()'d * @param dict dictionary from which to fetch the dictionary * @param name a name/key value to look up in the dictionary * @param **answer a copy of the dictionary will be stored at this address @@ -476,8 +501,9 @@ getdns_return_t getdns_dict_get_data_type(struct getdns_dict *this_dict, char *n */ getdns_return_t getdns_dict_get_dict(struct getdns_dict *this_dict, char *name, struct getdns_dict **answer); /** - * fetch the list associated with the specified name, the list should be free()'d - * by the caller via getdns_list_destroy() + * fetch the list associated with the specified name + * the list should not be free()'d by the caller, when the dictionary is destroyed + * the list will also be destroyed * @param dict dictionary from which to fetch the list * @param name a name/key value to look up in the dictionary * @param **answer a copy of the list will be stored at this address @@ -486,7 +512,7 @@ getdns_return_t getdns_dict_get_dict(struct getdns_dict *this_dict, char *name, */ getdns_return_t getdns_dict_get_list(struct getdns_dict *this_dict, char *name, struct getdns_list **answer); /** - * fetch the bindata associated with the specified name, the bindata should be + * fetch the bindata associated with the specified name, the bindata should not be * free()'d by the caller * @param dict dictionary from which to fetch the bindata * @param name a name/key value to look up in the dictionary @@ -517,7 +543,7 @@ struct getdns_list * getdns_list_create(); * you MUST copy those instances BEFORE you destroy the list else * unpleasant things will happen at run-time */ -void getdns_list_destroy(struct getdns_list *this_list); +void getdns_list_destroy(struct getdns_list *list); /** * add an item to the tail of a list - note that this was not in the getdns API * description but the list_set functions seem to be designed to modify an existing @@ -549,7 +575,7 @@ getdns_return_t getdns_list_set_list(struct getdns_list *list, size_t index, str */ getdns_return_t getdns_list_set_bindata(struct getdns_list *list, size_t index, struct getdns_bindata *child_bindata); /** - * set the integrer value of the indexed item (zero based index) + * set the integer value of the indexed item (zero based index) * @return GETDNS_RETURN_GOOD on success * @return GETDNS_RETURN_NO_SUCH_LIST_ITEM if index is out of range, or list is NULL */ @@ -561,18 +587,51 @@ getdns_return_t getdns_list_set_int(struct getdns_list *list, size_t index, uint */ struct getdns_dict *getdns_dict_create(); +/** + * private function used to make a copy of a dict structure, the caller is responsible + * for freeing storage allocated to returned value + * NOTE: not thread safe - this needs to be fixed to be thread safe + * @param srcdict the dictionary structure to copy + * @param dstdict pointer to the location to write pointer to new dictionary + * @return GETDNS_RETURN_GOOD on success + */ +getdns_return_t +getdns_dict_copy(struct getdns_dict *srcdict, struct getdns_dict **dstdict); + /** * destroy a dictionary and all items within that dictionary * be aware that if you have fetched any data from the dictionary it will * no longer be available (you are likely to experience bad things if you try) - * @return pointer to an allocated dictionary, NULL if insufficient memory */ -void getdns_dict_destroy(struct getdns_dict *this_dict); +void getdns_dict_destroy(struct getdns_dict *dict); -getdns_return_t getdns_dict_set_dict(struct getdns_dict *this_dict, char *name, struct getdns_dict *child_dict); -getdns_return_t getdns_dict_set_list(struct getdns_dict *this_dict, char *name, struct getdns_list *child_list); -getdns_return_t getdns_dict_set_bindata(struct getdns_dict *this_dict, char *name, struct getdns_bindata *child_bindata); -getdns_return_t getdns_dict_set_int(struct getdns_dict *this_dict, char *name, uint32_t child_uint32); +getdns_return_t getdns_dict_set_dict(struct getdns_dict *dict, char *name, struct getdns_dict *child_dict); +/** + * create a new entry in the dictionary, or replace the value of an existing entry + * this routine makes a copy of the child_list + * @param dict dictionary in which to add or change the value + * @param name key that identifies which item in the dictionary to add/change + * @param child_list value to assign to the node identified by name + * @return GETDNS_RETURN_GOOD on success + */ +getdns_return_t getdns_dict_set_list(struct getdns_dict *dict, char *name, struct getdns_list *child_list); +/** + * create a new entry in the dictionary, or replace the value of an existing entry + * this routine makes a copy of the child_bindata + * @param dict dictionary in which to add or change the value + * @param name key that identifies which item in the dictionary to add/change + * @param child_bindata value to assign to the node identified by name + * @return GETDNS_RETURN_GOOD on success + */ +getdns_return_t getdns_dict_set_bindata(struct getdns_dict *dict, char *name, struct getdns_bindata *child_bindata); +/** + * create a new entry in the dictionary, or replace the value of an existing entry + * @param dict dictionary in which to add or change the value + * @param name key that identifies which item in the dictionary to add/change + * @param child_uint32 value to assign to the node identified by name + * @return GETDNS_RETURN_GOOD on success + */ +getdns_return_t getdns_dict_set_int(struct getdns_dict *dict, char *name, uint32_t child_uint32); /* Callback arguments */ typedef void (*getdns_callback_t)( @@ -757,10 +816,15 @@ getdns_validate_dnssec( struct getdns_list *trust_anchor_rdatas ); +/** + * creates a string that describes the dictionary in a human readable form + * one line per item in the dictionary + * TODO: maybe this should be json or something machine readable too + * @param dict dictionary to pretty print + * @return character array (caller must free this) containing pretty string + */ char * -getdns_pretty_print_dict( - struct getdns_dict *some_dict -); +getdns_pretty_print_dict(struct getdns_dict *dict); char * getdns_display_ip_address( diff --git a/src/common/getdns_dict.c b/src/common/getdns_dict.c index 0b477525..518af737 100644 --- a/src/common/getdns_dict.c +++ b/src/common/getdns_dict.c @@ -33,8 +33,11 @@ #include #include -/* stuff to make it compile pedantically */ -#define UNUSED_PARAM(x) ((void)(x)) +/* TODO: change this to make the walk safe for reentrant/multi-thread calls */ +struct getdns_list *walkresultlist; +struct getdns_dict *walkresultdict; +char *walkresultchar; +int walkresultcharlen; /*---------------------------------------- getdns_dict_cmp */ /** @@ -104,27 +107,91 @@ getdns_dict_find(struct getdns_dict *dict, char *key, bool addifnotfnd) ret = *item; } - return *item; -} /* getdns_dict_set_int */ + return ret; +} /* getdns_dict_find */ -getdns_return_t getdns_dict_get_names(struct getdns_dict *this_dict, struct getdns_list **answer) -{ UNUSED_PARAM(this_dict); UNUSED_PARAM(answer); return GETDNS_RETURN_GOOD; } +/*---------------------------------------- getdns_dict_visit */ +/** + * private function called by the tree walk function invoked by getdns_dict_get_names + * it is called as each node is visited. twalk() calls 3x for each node and passes order + * to tell us whether it is a pre/in/post order + */ +void +getdns_dict_visit(const void *node, VISIT order, int level) +{ + struct getdns_dict_item *item; + size_t index; + + item = *(struct getdns_dict_item **) node; + /* postorder is mis-named - it results in in-order traversal */ + if(order == postorder || order == leaf) + { + if(getdns_list_add_item(walkresultlist, &index) == GETDNS_RETURN_GOOD) + { + switch(item->dtype) + { + case t_bindata: + getdns_list_set_bindata(walkresultlist, index, item->data.bindata); + break; + + case t_dict: + getdns_list_set_dict(walkresultlist, index, item->data.dict); + break; + + case t_int: + getdns_list_set_int(walkresultlist, index, item->data.n); + break; + + case t_list: + getdns_list_set_list(walkresultlist, index, item->data.list); + break; + + case t_invalid: + default: + // TODO: this is a fault of some kind, for now ignore it + break; + } + } + } + + return; +} /* getdns_dict_visit */ + +/*---------------------------------------- getdns_dict_get_names + TODO: this needs to be made thread safe by creating a thread specific list + the binary search tree implementation in the +*/ +getdns_return_t +getdns_dict_get_names(struct getdns_dict *dict, struct getdns_list **answer) +{ + getdns_return_t retval = GETDNS_RETURN_NO_SUCH_DICT_NAME; + + if(dict != NULL && answer != NULL) + { + *answer = getdns_list_create(); + walkresultlist = *answer; + + twalk(dict->rootp, getdns_dict_visit); + + retval = GETDNS_RETURN_GOOD; + } + + return retval; +} /* getdns_dict_get_names */ /*---------------------------------------- getdns_dict_get_data_type */ getdns_return_t getdns_dict_get_data_type(struct getdns_dict *dict, char *name, getdns_data_type *answer) { - struct getdns_dict_item keyitem; - struct getdns_dict_item **item; + struct getdns_dict_item *item; getdns_return_t retval = GETDNS_RETURN_NO_SUCH_DICT_NAME; if(dict != NULL && name != NULL && answer != NULL) { - keyitem.key = name; - item = tfind(&keyitem, &(dict->rootp), getdns_dict_cmp); - if(item != NULL && *item != NULL) + item = getdns_dict_find(dict, name, false); + if(item != NULL) { - *answer = (*item)->dtype; + *answer = item->dtype; retval = GETDNS_RETURN_GOOD; } } @@ -136,21 +203,19 @@ getdns_dict_get_data_type(struct getdns_dict *dict, char *name, getdns_data_type getdns_return_t getdns_dict_get_dict(struct getdns_dict *dict, char *name, struct getdns_dict **answer) { - struct getdns_dict_item keyitem; - struct getdns_dict_item **item; + struct getdns_dict_item *item; getdns_return_t retval = GETDNS_RETURN_NO_SUCH_DICT_NAME; if(dict != NULL && name != NULL && answer != NULL) { - keyitem.key = name; - item = tfind(&keyitem, &(dict->rootp), getdns_dict_cmp); - if(item != NULL && *item != NULL) + item = getdns_dict_find(dict, name, false); + if(item != NULL) { - if((*item)->dtype != t_dict) + if(item->dtype != t_dict) retval = GETDNS_RETURN_WRONG_TYPE_REQUESTED; else { - *answer = (*item)->data.dict; + *answer = item->data.dict; retval = GETDNS_RETURN_GOOD; } } @@ -163,21 +228,19 @@ getdns_dict_get_dict(struct getdns_dict *dict, char *name, struct getdns_dict ** getdns_return_t getdns_dict_get_list(struct getdns_dict *dict, char *name, struct getdns_list **answer) { - struct getdns_dict_item keyitem; - struct getdns_dict_item **item; + struct getdns_dict_item *item; getdns_return_t retval = GETDNS_RETURN_NO_SUCH_DICT_NAME; if(dict != NULL && name != NULL && answer != NULL) { - keyitem.key = name; - item = tfind(&keyitem, &(dict->rootp), getdns_dict_cmp); - if(item != NULL && *item != NULL) + item = getdns_dict_find(dict, name, false); + if(item != NULL) { - if((*item)->dtype != t_list) + if(item->dtype != t_list) retval = GETDNS_RETURN_WRONG_TYPE_REQUESTED; else { - *answer = (*item)->data.list; + *answer = item->data.list; retval = GETDNS_RETURN_GOOD; } } @@ -190,21 +253,19 @@ getdns_dict_get_list(struct getdns_dict *dict, char *name, struct getdns_list ** getdns_return_t getdns_dict_get_bindata(struct getdns_dict *dict, char *name, struct getdns_bindata **answer) { - struct getdns_dict_item keyitem; - struct getdns_dict_item **item; + struct getdns_dict_item *item; getdns_return_t retval = GETDNS_RETURN_NO_SUCH_DICT_NAME; if(dict != NULL && name != NULL && answer != NULL) { - keyitem.key = name; - item = tfind(&keyitem, &(dict->rootp), getdns_dict_cmp); - if(item != NULL && *item != NULL) + item = getdns_dict_find(dict, name, false); + if(item != NULL) { - if((*item)->dtype != t_bindata) + if(item->dtype != t_bindata) retval = GETDNS_RETURN_WRONG_TYPE_REQUESTED; else { - *answer = (*item)->data.bindata; + *answer = item->data.bindata; retval = GETDNS_RETURN_GOOD; } } @@ -217,21 +278,19 @@ getdns_dict_get_bindata(struct getdns_dict *dict, char *name, struct getdns_bind getdns_return_t getdns_dict_get_int(struct getdns_dict *dict, char *name, uint32_t *answer) { - struct getdns_dict_item keyitem; - struct getdns_dict_item **item; + struct getdns_dict_item *item; getdns_return_t retval = GETDNS_RETURN_NO_SUCH_DICT_NAME; if(dict != NULL && name != NULL && answer != NULL) { - keyitem.key = name; - item = tfind(&keyitem, &(dict->rootp), getdns_dict_cmp); - if(item != NULL && *item != NULL) + item = getdns_dict_find(dict, name, false); + if(item != NULL) { - if((*item)->dtype != t_int) + if(item->dtype != t_int) retval = GETDNS_RETURN_WRONG_TYPE_REQUESTED; else { - *answer = (*item)->data.n; + *answer = item->data.n; retval = GETDNS_RETURN_GOOD; } } @@ -252,24 +311,75 @@ getdns_dict_create() return dict; } /* getdns_dict_create */ +/*---------------------------------------- getdns_dict_visit_copyitem */ +/** + * private function called by getdns_dict_copy() through the tree walk function + * is called as each node is visited. twalk() calls 3x for each node and passes order + * to tell us whether it is a pre/in/post order. We use this to copy the dictionary one item at + * a time - this could be sped up + */ +void +getdns_dict_visit_copyitem(const void *node, VISIT order, int level) +{ + struct getdns_dict_item *item; + + item = *(struct getdns_dict_item **) node; + /* postorder is mis-named - it results in in-order traversal */ + if(order == postorder || order == leaf) + { + switch(item->dtype) + { + case t_bindata: + getdns_dict_set_bindata(walkresultdict, item->key, item->data.bindata); + break; + + case t_dict: + getdns_dict_set_dict(walkresultdict, item->key, item->data.dict); + break; + + case t_int: + getdns_dict_set_int(walkresultdict, item->key, item->data.n); + break; + + case t_list: + getdns_dict_set_list(walkresultdict, item->key, item->data.list); + break; + + case t_invalid: + default: + // TODO: this is a fault of some kind, for now ignore it + break; + } + } + + return; +} /* getdns_dict_visit_copyitem */ + /*---------------------------------------- getdns_dict_copy */ /** - * private function used to make a copy of a dict structure + * private function used to make a copy of a dict structure, the caller is responsible + * for freeing storage allocated to returned value + * NOTE: not thread safe - this needs to be fixed to be thread safe * @param srcdict the dictionary structure to copy * @return the address of the copy of the dictionary structure on success * @return NULL on error (out of memory, invalid srcdict) */ -struct getdns_dict * -getdns_dict_copy(struct getdns_dict *srcdict) +getdns_return_t +getdns_dict_copy(struct getdns_dict *srcdict, struct getdns_dict **dstdict) { - struct getdns_dict *newdict = NULL; + getdns_return_t retval = GETDNS_RETURN_NO_SUCH_DICT_NAME; - if(srcdict != NULL) + if(srcdict != NULL && dstdict != NULL) { - + *dstdict = getdns_dict_create(); + walkresultdict = *dstdict; + + twalk(srcdict->rootp, getdns_dict_visit_copyitem); + + retval = GETDNS_RETURN_GOOD; } - return newdict; + return retval; } /* getdns_dict_copy */ /*---------------------------------------- getdns_dict_item_free */ @@ -331,37 +441,85 @@ getdns_dict_destroy(struct getdns_dict *dict) getdns_return_t getdns_dict_set_dict(struct getdns_dict *dict, char *name, struct getdns_dict *child_dict) { - struct getdns_dict_item keyitem; - struct getdns_dict_item **item; + struct getdns_dict_item *item; + struct getdns_dict *newdict; getdns_return_t retval = GETDNS_RETURN_NO_SUCH_DICT_NAME; - if(dict != NULL && name != NULL && child_dict != NULL) + if(dict != NULL && name != NULL) { - /* we try to find it first, if we do then clear the existing data */ - keyitem.key = name; - item = tfind(&keyitem, &(dict->rootp), getdns_dict_cmp); - if(item != NULL && *item != NULL) + item = getdns_dict_find(dict, name, true); + if(item != NULL) { - getdns_dict_item_free(*item); - } - else - { - /* tsearch will add a node automatically for us */ - item = tsearch(&keyitem, &(dict->rootp), getdns_dict_cmp); - (*item)->key = strdup(keyitem.key); - (*item)->dtype = t_dict; - (*item)->data.dict = getdns_dict_copy(child_dict); + retval = getdns_dict_copy(child_dict, &newdict); + if(retval == GETDNS_RETURN_GOOD) + { + item->dtype = t_dict; + item->data.dict = newdict; + } + else + item->dtype = t_invalid; } } return retval; } /* getdns_dict_set_dict */ -getdns_return_t getdns_dict_set_list(struct getdns_dict *this_dict, char *name, struct getdns_list *child_list) -{ UNUSED_PARAM(this_dict); UNUSED_PARAM(name); UNUSED_PARAM(child_list); return GETDNS_RETURN_GOOD; } +/*---------------------------------------- getdns_dict_set_list */ +getdns_return_t +getdns_dict_set_list(struct getdns_dict *dict, char *name, struct getdns_list *child_list) +{ + struct getdns_dict_item *item; + struct getdns_list *newlist; + getdns_return_t retval = GETDNS_RETURN_NO_SUCH_DICT_NAME; -getdns_return_t getdns_dict_set_bindata(struct getdns_dict *this_dict, char *name, struct getdns_bindata *child_bindata) -{ UNUSED_PARAM(this_dict); UNUSED_PARAM(name); UNUSED_PARAM(child_bindata); return GETDNS_RETURN_GOOD; } + if(dict != NULL && name != NULL) + { + item = getdns_dict_find(dict, name, true); + if(item != NULL) + { + retval = getdns_list_copy(child_list, &newlist); + if(retval == GETDNS_RETURN_GOOD) + { + item->dtype = t_list; + item->data.list = newlist; + } + else + item->dtype = t_invalid; + } + } + + return retval; +} /* getdns_dict_set_list */ + +/*---------------------------------------- getdns_dict_set_bindata */ +getdns_return_t +getdns_dict_set_bindata(struct getdns_dict *dict, char *name, struct getdns_bindata *child_bindata) +{ + struct getdns_dict_item *item; + getdns_return_t retval = GETDNS_RETURN_NO_SUCH_DICT_NAME; + + if(dict != NULL && name != NULL && child_bindata != NULL) + { + item = getdns_dict_find(dict, name, true); + if(item != NULL) + { + item->dtype = t_bindata; + item->data.bindata = (struct getdns_bindata *) malloc(sizeof(struct getdns_bindata)); + if(item->data.bindata != NULL) + { + item->data.bindata->data = (void *) malloc(item->data.bindata->size); + if(item->data.bindata->data != NULL) + { + item->data.bindata->size = child_bindata->size; + memcpy(item->data.bindata->data, child_bindata->data, child_bindata->size); + retval = GETDNS_RETURN_GOOD; + } + } + } + } + + return retval; +} /* getdns_dict_set_bindata */ /*---------------------------------------- getdns_dict_set_int */ getdns_return_t @@ -370,21 +528,106 @@ getdns_dict_set_int(struct getdns_dict *dict, char *name, uint32_t child_uint32) struct getdns_dict_item *item; getdns_return_t retval = GETDNS_RETURN_NO_SUCH_DICT_NAME; - item = getdns_dict_find(dict, name, true); if(dict != NULL && name != NULL) { - item->dtype = t_int; - item->data.n = child_uint32; - retval = GETDNS_RETURN_GOOD; + item = getdns_dict_find(dict, name, true); + if(item != NULL) + { + item->dtype = t_int; + item->data.n = child_uint32; + retval = GETDNS_RETURN_GOOD; + } } return retval; } /* getdns_dict_set_int */ +/*---------------------------------------- getdns_dict_visit_print */ +/** + * private function called by the tree walk function invoked by getdns_pretty_print_dict + * it is called as each node is visited. twalk() calls 3x for each node and passes order + * to tell us whether it is a pre/in/post order + * TODO: need to handle nested non-trivial data types + */ +void +getdns_dict_visit_print(const void *node, VISIT order, int level) +{ + struct getdns_dict_item *item; + int newlen; + char *dtypestr = NULL; + char *valstr = NULL; + char *itemstr = NULL; + + item = *(struct getdns_dict_item **) node; + /* postorder is mis-named - it results in in-order traversal */ + if(order == postorder || order == leaf) + { + switch(item->dtype) + { + case t_bindata: + dtypestr = "bindata"; + valstr = strdup("NOT IMPLEMENTED"); + break; + + case t_dict: + dtypestr = "dict"; + valstr = strdup("NOT IMPLEMENTED"); + break; + + case t_int: + dtypestr = "int"; + asprintf(&valstr, "%d", item->data.n); + break; + + case t_list: + dtypestr = "list"; + valstr = strdup("NOT IMPLEMENTED"); + break; + + case t_invalid: + default: + dtypestr = "invalid"; + valstr = strdup(""); + break; + } + + newlen = asprintf(&itemstr, "key=\"%s\", type=\"%s\", value=\"%s\"\n", item->key, dtypestr, valstr); + if(newlen != -1) + { + walkresultchar = (char *) realloc(walkresultchar, walkresultcharlen + newlen + 1); + memcpy(walkresultchar + walkresultcharlen, itemstr, newlen); + walkresultcharlen += newlen; + walkresultchar[walkresultcharlen] = '\0'; + } + // else + // TODO: this is a fault - do something + + free(valstr); + } + + return; +} /* getdns_dict_visit_print */ + +/*---------------------------------------- getdns_pretty_print_dict */ char * -getdns_pretty_print_dict( - struct getdns_dict *some_dict -) -{ UNUSED_PARAM(some_dict); return NULL; } +getdns_pretty_print_dict(struct getdns_dict *dict) +{ + char *retval = NULL; + + walkresultcharlen = 0; + walkresultchar = NULL; + + if(dict != NULL && dict->rootp != NULL) + { + twalk(dict->rootp, getdns_dict_visit_print); + if(walkresultcharlen > 0) + { + retval = strdup(walkresultchar); + free(walkresultchar); + } + } + + return retval; +} /* getdns_pretty_print_dict */ /* getdns_dict.c */ diff --git a/src/common/getdns_list.c b/src/common/getdns_list.c index e6849f32..4921303c 100644 --- a/src/common/getdns_list.c +++ b/src/common/getdns_list.c @@ -32,10 +32,7 @@ #include #include "getdns_core_only.h" -/* stuff to make it compile pedantically */ -#define UNUSED_PARAM(x) ((void)(x)) - - +/*---------------------------------------- getdns_list_get_length */ getdns_return_t getdns_list_get_length(struct getdns_list *list, size_t *answer) { @@ -64,8 +61,25 @@ getdns_list_get_data_type(struct getdns_list *list, size_t index, getdns_data_ty return retval; } /* getdns_list_get_data_type */ -getdns_return_t getdns_list_get_dict(struct getdns_list *this_list, size_t index, struct getdns_dict **answer) -{ UNUSED_PARAM(this_list); UNUSED_PARAM(index); UNUSED_PARAM(answer); return GETDNS_RETURN_GOOD; } +/*---------------------------------------- getdns_list_get_dict */ +getdns_return_t +getdns_list_get_dict(struct getdns_list *list, size_t index, struct getdns_dict **answer) +{ + getdns_return_t retval = GETDNS_RETURN_NO_SUCH_LIST_ITEM; + + if(list != NULL && index < list->numinuse) + { + if(list->items[index].dtype != t_dict) + retval = GETDNS_RETURN_WRONG_TYPE_REQUESTED; + else + { + *answer = list->items[index].data.dict; + retval = GETDNS_RETURN_GOOD; + } + } + + return retval; +} /* getdns_list_get_dict */ /*---------------------------------------- getdns_list_get_list */ getdns_return_t @@ -162,15 +176,6 @@ getdns_list_realloc(struct getdns_list *list) } /* getdns_list_realloc */ /*---------------------------------------- getdns_list_copy */ -/** - * private function (API users should not be calling this), this uses library - * routines to make a copy of the list - would be faster to make the copy directly - * @param list pointer to list to copy - * @param newlist pointer to pointer to list to receive the copy (will be allocated) - * @return GETDNS_RETURN_GOOD on success - * @return GETDNS_RETURN_NO_SUCH_LIST_ITEM if list is invalid - * @return GETDNS_RETURN_GENERIC_ERROR if out of memory - */ getdns_return_t getdns_list_copy(struct getdns_list *srclist, struct getdns_list **dstlist) { @@ -178,7 +183,7 @@ getdns_list_copy(struct getdns_list *srclist, struct getdns_list **dstlist) size_t index; getdns_return_t retval = GETDNS_RETURN_NO_SUCH_LIST_ITEM; - if(srclist != NULL && *dstlist != NULL) + if(srclist != NULL && dstlist != NULL) { *dstlist = getdns_list_create(); if(*dstlist != NULL) @@ -296,8 +301,23 @@ getdns_list_add_item(struct getdns_list *list, size_t *index) return retval; } /* getdns_list_add_item */ -getdns_return_t getdns_list_set_dict(struct getdns_list *this_list, size_t index, struct getdns_dict *child_dict) -{ UNUSED_PARAM(this_list); UNUSED_PARAM(index); UNUSED_PARAM(child_dict); return GETDNS_RETURN_GOOD; } +/*---------------------------------------- getdns_list_set_dict */ +getdns_return_t +getdns_list_set_dict(struct getdns_list *list, size_t index, struct getdns_dict *child_dict) +{ + getdns_return_t retval = GETDNS_RETURN_NO_SUCH_LIST_ITEM; + + if(list != NULL && child_dict != NULL) + { + if(list->numinuse > index) + { + list->items[index].dtype = t_dict; + retval = getdns_dict_copy(child_dict, &(list->items[index].data.dict)); + } + } + + return retval; +} /* getdns_list_set_dict */ /*---------------------------------------- getdns_set_list */ getdns_return_t diff --git a/src/test/testmessages.h b/src/test/testmessages.h index 88f4c35e..206eaa1a 100644 --- a/src/test/testmessages.h +++ b/src/test/testmessages.h @@ -50,6 +50,7 @@ void tstmsg_case_end(); /** * call to display message regarding the current test case * to display case end message + * TODO: add macro to automatically output source file line */ void tstmsg_case_msg(char *msg); diff --git a/src/test/tests_dict.c b/src/test/tests_dict.c index 5516ae78..4161f87a 100644 --- a/src/test/tests_dict.c +++ b/src/test/tests_dict.c @@ -34,6 +34,319 @@ #define TSTMSGBUF 80 +/*---------------------------------------- tst_bindatasetget */ +/** + * test the bindata get and set routines + */ +void +tst_bindatasetget(void) +{ + char msg[TSTMSGBUF]; + char key[20]; + getdns_return_t retval; + struct getdns_dict *dict = NULL; + struct getdns_bindata *ans_bdata; + struct getdns_bindata *bindata; + + tstmsg_case_begin("tst_bindatasetget"); + + dict = getdns_dict_create(); + + /* test int get function against empty dict and with bogus params */ + + strcpy(key, "foo"); + + tstmsg_case_msg("getdns_dict_get_bindata() empty dict"); + retval = getdns_dict_get_bindata(NULL, key, &ans_bdata); + sprintf(msg, "line %d: getdns_dict_get_bindata(NULL, key, &ans_bdata),retval = %d", __LINE__, retval); + tstmsg_case_msg(msg); + + retval = getdns_dict_get_bindata(dict, key, NULL); + sprintf(msg, "line %d: getdns_dict_get_bindata(dict, key, NULL),retval = %d", __LINE__, retval); + tstmsg_case_msg(msg); + + tstmsg_case_msg("getdns_dict_get_bindata(dict, NULL, &ans_bindata)"); + retval = getdns_dict_get_bindata(dict, NULL, &ans_bdata); + sprintf(msg, "line %d: getdns_dict_get_bindata,retval = %d", __LINE__, retval); + tstmsg_case_msg(msg); + + tstmsg_case_msg("getdns_dict_get_bindata(dict, key, &ans_bdata)"); + retval = getdns_dict_get_bindata(dict, key, &ans_bdata); + sprintf(msg, "line %d: getdns_list_get_bindata,retval = %d", __LINE__, retval); + tstmsg_case_msg(msg); + + getdns_dict_destroy(dict); + + /* TODO: test getdns_dict_set functions with bogus params */ + + /* test set and get legitimate use case */ + + dict = getdns_dict_create(); + + strcpy(key, "foo"); + bindata = (struct getdns_bindata *) malloc(sizeof(struct getdns_bindata)); + bindata->size = strlen("foobar") + 1; + bindata->data = (void *) strdup("foobar"); + + tstmsg_case_msg("getdns_dict_set_bindata(dict, key, bindata)"); + retval = getdns_dict_set_bindata(dict, key, bindata); + sprintf(msg, "line %d: getdns_dict_set_bindata,retval=%d,key=%s", __LINE__, retval, key); + tstmsg_case_msg(msg); + + tstmsg_case_msg("getdns_dict_get_bindata(dict, key, &ans_bdata)"); + retval = getdns_dict_get_bindata(dict, key, &ans_bdata); + sprintf(msg, "line %d: getdns_dict_get_bindata,retval=%d,key=%s,data=%s", __LINE__, retval, key, ans_bdata->data); + tstmsg_case_msg(msg); + + getdns_dict_destroy(dict); + free(bindata->data); + free(bindata); + + tstmsg_case_end(); + + return; +} /* tst_bindatasetget */ + +/*---------------------------------------- tst_dictsetget */ +/** + * test the dict get and set routines + */ +void +tst_dictsetget(void) +{ + char msg[TSTMSGBUF]; + char key[20]; + uint32_t int1; + uint32_t int2; + getdns_return_t retval; + struct getdns_dict *newdict; + struct getdns_dict *ansdict; + struct getdns_dict *dict = NULL; + + tstmsg_case_begin("tst_dictsetget"); + + dict = getdns_dict_create(); + + /* test get function against empty list and with bogus params */ + + strcpy(key, "foo"); + + tstmsg_case_msg("getdns_dict_get_dict() empty dict"); + retval = getdns_dict_get_dict(NULL, key, &ansdict); + sprintf(msg, "line %d: getdns_dict_get_dict(NULL, key, &ansdict),retval = %d", __LINE__, retval); + tstmsg_case_msg(msg); + + retval = getdns_dict_get_dict(dict, key, NULL); + sprintf(msg, "line %d: getdns_dict_get_dict(dict, key, NULL),retval = %d", __LINE__, retval); + tstmsg_case_msg(msg); + + tstmsg_case_msg("getdns_dict_get_dict(dict, NULL, &ansdict)"); + retval = getdns_dict_get_dict(dict, NULL, &ansdict); + sprintf(msg, "line %d: getdns_dict_get_dict,retval = %d", __LINE__, retval); + tstmsg_case_msg(msg); + + tstmsg_case_msg("getdns_dict_get_dict(dict, key, &ansdict)"); + retval = getdns_dict_get_dict(dict, key, &ansdict); + sprintf(msg, "line %d: getdns_list_get_dict,retval = %d", __LINE__, retval); + tstmsg_case_msg(msg); + + getdns_dict_destroy(dict); + + /* TODO: test getdns_dict_set functions with bogus params */ + + /* test set and get legitimate use case */ + + dict = getdns_dict_create(); + + strcpy(key, "foo"); + newdict = getdns_dict_create(); + getdns_dict_set_int(newdict, "foo", 42); + getdns_dict_set_int(newdict, "bar", 52); + + tstmsg_case_msg("getdns_dict_set_dict(dict, key, newdict)"); + retval = getdns_dict_set_dict(dict, key, newdict); + sprintf(msg, "line %d: getdns_dict_set_dict,retval=%d,key=%s", __LINE__, retval, key); + tstmsg_case_msg(msg); + getdns_dict_destroy(newdict); + + tstmsg_case_msg("getdns_dict_get_dict(dict, key, &ansdict)"); + retval = getdns_dict_get_dict(dict, key, &ansdict); + getdns_dict_get_int(ansdict, "foo", &int1); + getdns_dict_get_int(ansdict, "bar", &int2); + sprintf(msg, "line %d: getdns_dict_get_dict,retval=%d,key=%s,int1=%d,int2=%d" + , __LINE__, retval, key, int1, int2); + tstmsg_case_msg(msg); + + getdns_dict_destroy(dict); + + tstmsg_case_end(); + + return; +} /* tst_dictsetget */ + +/*---------------------------------------- tst_getnames */ +/** + * exercise the getdns_dict_get_names function + */ +void +tst_getnames(void) +{ + size_t index; + size_t llen; + uint32_t ansint; + int i; + getdns_return_t result; + getdns_data_type dtype; + struct getdns_dict *dict = NULL; + struct getdns_list *list = NULL; + + tstmsg_case_begin("tst_getnames"); + + dict = getdns_dict_create(); + + /* degenerative use cases */ + + tstmsg_case_msg("getdns_dict_get_names(NULL, &list)"); + getdns_dict_get_names(NULL, &list); + + tstmsg_case_msg("getdns_dict_get_names(dict, NULL)"); + getdns_dict_get_names(dict, NULL); + + tstmsg_case_msg("getdns_dict_get_names(dict, &list), empty dictionary"); + getdns_dict_get_names(dict, &list); + + /* legit use case, add items out of order to exercise tree */ + /* TODO: add elements of type dict, bindata, list to the dict */ + + i = 0; + getdns_dict_set_int(dict, "foo", i++); + getdns_dict_set_int(dict, "bar", i++); + getdns_dict_set_int(dict, "quz", i++); + getdns_dict_set_int(dict, "alpha", i++); + + getdns_dict_get_names(dict, &list); + + result = getdns_list_get_length(list, &llen); + if(llen != i) + { + tstmsg_case_msg("getdns_list_get_length returned unreasonable length, exiting"); + return; + } + + for(index=0; indexdata = 7,foobar +TESTCASE tests_list:tst_bindatasetget END +TESTCASE tests_list:tst_dictsetget BEGIN + tests_list:tst_dictsetget: getdns_list_get_dict() empty list + tests_list:tst_dictsetget: getdns_list_get_dict(NULL, index, &dict),retval = 304 + tests_list:tst_dictsetget: getdns_list_get_dict(list, index, NULL),retval = 304 + tests_list:tst_dictsetget: getdns_list_get_dict(list, 0, &dict) + tests_list:tst_dictsetget: getdns_list_get_dict,retval = 304 + tests_list:tst_dictsetget: getdns_list_get_dict(list, 1, &dict) + tests_list:tst_dictsetget: getdns_list_get_dict,retval = 304 + tests_list:tst_dictsetget: getdns_list_set_dict() empty list + tests_list:tst_dictsetget: getdns_list_set_dict(NULL, index, dict),retval = 304 + tests_list:tst_dictsetget: getdns_list_set_dict(list, 0, dict) + tests_list:tst_dictsetget: getdns_list_set_dict,retval = 304 + tests_list:tst_dictsetget: getdns_list_set_dict(list, 1, dict) + tests_list:tst_dictsetget: getdns_list_set_dict,retval = 304 + tests_list:tst_dictsetget: getdns_list_set/get_dict,retval=0, ans=42 +TESTCASE tests_list:tst_dictsetget END TESTCASE tests_list:tst_intsetget BEGIN tests_list:tst_intsetget: getdns_list_get_int() empty list tests_list:tst_intsetget: getdns_list_get_int(NULL, index, &ans_int),retval = 304 @@ -33,7 +65,7 @@ TESTCASE tests_list:tst_listsetget BEGIN tests_list:tst_listsetget: getdns_list_get_list(list, index, NULL),retval = 304 tests_list:tst_listsetget: getdns_list_get_list(list, 0, &ans_list) tests_list:tst_listsetget: getdns_list_get_list,retval = 304 - tests_list:tst_listsetget: getdns_list_get_int(list, 1, &ans_list) + tests_list:tst_listsetget: getdns_list_get_list(list, 1, &ans_list) tests_list:tst_listsetget: getdns_list_get_list,retval = 304 tests_list:tst_listsetget: getdns_list_set_list() empty list tests_list:tst_listsetget: getdns_list_set_list(NULL, index, ans_list),retval = 304