the dict and list data types with helper functions work, unit tests

are mostly done as well
This commit is contained in:
Glen Wiley 2013-07-31 16:21:42 -04:00
parent 68ae437210
commit 6280a1b7b6
11 changed files with 1209 additions and 131 deletions

185
configure vendored
View File

@ -622,8 +622,10 @@ ac_includes_default="\
# include <unistd.h>
#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;}

View File

@ -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

View File

@ -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

View File

@ -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(

View File

@ -33,8 +33,11 @@
#include <string.h>
#include <getdns_libevent.h>
/* 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 */

View File

@ -32,10 +32,7 @@
#include <getdns_libevent.h>
#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

View File

@ -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);

View File

@ -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; index<llen; index++)
{
getdns_list_get_data_type(list, index, &dtype);
printf(" list item %d: ", (int) index);
switch(dtype)
{
case t_bindata:
printf("NOTIMPLEMENTED");
break;
case t_dict:
printf("NOTIMPLEMENTED");
break;
case t_int:
getdns_list_get_int(list, index, &ansint);
printf("t_int, value=%d\n", ansint);
break;
case t_invalid:
printf("data type invalid");
break;
case t_list:
printf("NOTIMPLEMENTED");
break;
}
}
getdns_dict_destroy(dict);
tstmsg_case_end();
} /* tst_getnames */
/*---------------------------------------- tst_listsetget */
/**
* test the list get and set routines
*/
void
tst_listsetget(void)
{
char msg[TSTMSGBUF];
char key[20];
size_t index;
uint32_t int1;
uint32_t int2;
getdns_return_t retval;
struct getdns_list *newlist;
struct getdns_list *anslist;
struct getdns_dict *dict = NULL;
tstmsg_case_begin("tst_listsetget");
dict = getdns_dict_create();
/* test get function against empty list and with bogus params */
strcpy(key, "foo");
tstmsg_case_msg("getdns_dict_get_list() empty dict");
retval = getdns_dict_get_list(NULL, key, &anslist);
sprintf(msg, "line %d: getdns_dict_get_list(NULL, key, &anslist),retval = %d", __LINE__, retval);
tstmsg_case_msg(msg);
retval = getdns_dict_get_list(dict, key, NULL);
sprintf(msg, "line %d: getdns_dict_get_list(dict, key, NULL),retval = %d", __LINE__, retval);
tstmsg_case_msg(msg);
tstmsg_case_msg("getdns_dict_get_list(dict, NULL, &anslist)");
retval = getdns_dict_get_list(dict, NULL, &anslist);
sprintf(msg, "line %d: getdns_dict_get_list,retval = %d", __LINE__, retval);
tstmsg_case_msg(msg);
tstmsg_case_msg("getdns_dict_get_list(dict, key, &anslist)");
retval = getdns_dict_get_list(dict, key, &anslist);
sprintf(msg, "line %d: getdns_list_get_list,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");
newlist = getdns_list_create();
getdns_list_add_item(newlist, &index);
getdns_list_set_int(newlist, index, 42);
getdns_list_add_item(newlist, &index);
getdns_list_set_int(newlist, index, 52);
tstmsg_case_msg("getdns_dict_set_list(dict, key, newlist)");
retval = getdns_dict_set_list(dict, key, newlist);
sprintf(msg, "line %d: getdns_dict_set_list,retval=%d,key=%s", __LINE__, retval, key);
tstmsg_case_msg(msg);
getdns_list_destroy(newlist);
tstmsg_case_msg("getdns_dict_get_list(dict, key, &anslist)");
retval = getdns_dict_get_list(dict, key, &anslist);
getdns_list_get_int(anslist, 0, &int1);
getdns_list_get_int(anslist, 1, &int2);
sprintf(msg, "line %d: getdns_dict_get_list,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_listsetget */
/*---------------------------------------- tst_intsetget */
/**
* test the int get and set routines
@ -47,6 +360,7 @@ tst_intsetget(void)
uint32_t newint;
getdns_return_t retval;
struct getdns_dict *dict = NULL;
getdns_data_type dtype;
tstmsg_case_begin("tst_intsetget");
@ -108,6 +422,11 @@ tst_intsetget(void)
sprintf(msg, "line %d: getdns_dict_get_int,retval=%d,key=%s,int=%d", __LINE__, retval, key, ans_int);
tstmsg_case_msg(msg);
tstmsg_case_msg("getdns_dict_get_data_type(dict, key, &dtype)");
retval = getdns_dict_get_data_type(dict, key, &dtype);
sprintf(msg, "line %d: getdns_dict_get_data_type,retval=%d,key=%s,dtype=%d", __LINE__, retval, key, dtype);
tstmsg_case_msg(msg);
getdns_dict_destroy(dict);
tstmsg_case_end();
@ -115,6 +434,52 @@ tst_intsetget(void)
return;
} /* tst_intsetget */
/*---------------------------------------- tst_copy */
/**
* test the copy and pretty print functions
*/
void
tst_copy(void)
{
char *dictstr = NULL;
struct getdns_dict *dict1 = NULL;
struct getdns_dict *dict2 = NULL;
tstmsg_case_begin("tst_copy");
tstmsg_case_msg("empty list cases");
getdns_dict_copy(NULL, NULL);
dict1 = getdns_dict_create();
getdns_dict_copy(dict1, &dict2);
getdns_dict_copy(NULL, &dict1);
tstmsg_case_msg("dict1 populate");
getdns_dict_set_int(dict1, "foo", 42);
getdns_dict_set_int(dict1, "bar", 52);
getdns_dict_set_int(dict1, "quz", 62);
dictstr = getdns_pretty_print_dict(dict1);
printf("%s", dictstr);
free(dictstr);
tstmsg_case_msg("getdns_dict_copy(dict1, &dict2)");
getdns_dict_copy(dict1, &dict2);
dictstr = getdns_pretty_print_dict(dict2);
printf("%s", dictstr);
free(dictstr);
getdns_dict_destroy(dict1);
getdns_dict_destroy(dict2);
tstmsg_case_end();
return;
} /* tst_copy */
/*---------------------------------------- tst_create */
/**
* test the create, destroy and allocation functions
@ -156,15 +521,20 @@ main(int argc, char *argv[])
tst_create();
tst_intsetget();
/*
tst_listsetget();
tst_bindatasetget();
tst_dictsetget();
tst_intsetget();
tst_listsetget();
tst_getnames();
tst_copy();
tstmsg_prog_end();
*/
return 0;
} /* main */

85
src/test/tests_dict.can Normal file
View File

@ -0,0 +1,85 @@
TESTPROG tests_dict START
TESTCASE tests_dict:tst_create BEGIN
tests_dict:tst_create: getdns_dict_create
tests_dict:tst_create: getdns_dict_destroy(dict)
tests_dict:tst_create: getdns_dict_destroy(NULL)
TESTCASE tests_dict:tst_create END
TESTCASE tests_dict:tst_bindatasetget BEGIN
tests_dict:tst_bindatasetget: getdns_dict_get_bindata() empty dict
tests_dict:tst_bindatasetget: line 61: getdns_dict_get_bindata(NULL, key, &ans_bdata),retval = 305
tests_dict:tst_bindatasetget: line 65: getdns_dict_get_bindata(dict, key, NULL),retval = 305
tests_dict:tst_bindatasetget: getdns_dict_get_bindata(dict, NULL, &ans_bindata)
tests_dict:tst_bindatasetget: line 70: getdns_dict_get_bindata,retval = 305
tests_dict:tst_bindatasetget: getdns_dict_get_bindata(dict, key, &ans_bdata)
tests_dict:tst_bindatasetget: line 75: getdns_list_get_bindata,retval = 305
tests_dict:tst_bindatasetget: getdns_dict_set_bindata(dict, key, bindata)
tests_dict:tst_bindatasetget: line 93: getdns_dict_set_bindata,retval=0,key=foo
tests_dict:tst_bindatasetget: getdns_dict_get_bindata(dict, key, &ans_bdata)
tests_dict:tst_bindatasetget: line 98: getdns_dict_get_bindata,retval=0,key=foo,data=foobar
TESTCASE tests_dict:tst_bindatasetget END
TESTCASE tests_dict:tst_dictsetget BEGIN
tests_dict:tst_dictsetget: getdns_dict_get_dict() empty dict
tests_dict:tst_dictsetget: line 136: getdns_dict_get_dict(NULL, key, &ansdict),retval = 305
tests_dict:tst_dictsetget: line 140: getdns_dict_get_dict(dict, key, NULL),retval = 305
tests_dict:tst_dictsetget: getdns_dict_get_dict(dict, NULL, &ansdict)
tests_dict:tst_dictsetget: line 145: getdns_dict_get_dict,retval = 305
tests_dict:tst_dictsetget: getdns_dict_get_dict(dict, key, &ansdict)
tests_dict:tst_dictsetget: line 150: getdns_list_get_dict,retval = 305
tests_dict:tst_dictsetget: getdns_dict_set_dict(dict, key, newdict)
tests_dict:tst_dictsetget: line 168: getdns_dict_set_dict,retval=0,key=foo
tests_dict:tst_dictsetget: getdns_dict_get_dict(dict, key, &ansdict)
tests_dict:tst_dictsetget: line 177: getdns_dict_get_dict,retval=0,key=foo,int1=42,int2=52
TESTCASE tests_dict:tst_dictsetget END
TESTCASE tests_dict:tst_intsetget BEGIN
tests_dict:tst_intsetget: getdns_dict_get_int() empty dict
tests_dict:tst_intsetget: line 375: getdns_dict_get_int(NULL, key, &ans_int),retval = 305
tests_dict:tst_intsetget: line 379: getdns_dict_get_int(dict, key, NULL),retval = 305
tests_dict:tst_intsetget: getdns_dict_get_int(dict, NULL, &ans_int)
tests_dict:tst_intsetget: line 384: getdns_dict_get_int,retval = 305
tests_dict:tst_intsetget: getdns_dict_get_int(dict, key, &ans_int)
tests_dict:tst_intsetget: line 389: getdns_list_get_int,retval = 305
tests_dict:tst_intsetget: getdns_dict_set_int(dict, key, newint)
tests_dict:tst_intsetget: line 405: getdns_dict_set_int,retval=0,key=foo,int=42
tests_dict:tst_intsetget: getdns_dict_get_int(dict, key, &ans_int)
tests_dict:tst_intsetget: line 410: getdns_dict_get_int,retval=0,key=foo,int=42
tests_dict:tst_intsetget: getdns_dict_set_int(dict, key, newint)
tests_dict:tst_intsetget: line 417: getdns_dict_set_int,retval=0,key=bar,int=52
tests_dict:tst_intsetget: getdns_dict_get_int(dict, key, &ans_int)
tests_dict:tst_intsetget: line 422: getdns_dict_get_int,retval=0,key=bar,int=52
tests_dict:tst_intsetget: getdns_dict_get_data_type(dict, key, &dtype)
tests_dict:tst_intsetget: line 427: getdns_dict_get_data_type,retval=0,key=bar,dtype=2
TESTCASE tests_dict:tst_intsetget END
TESTCASE tests_dict:tst_listsetget BEGIN
tests_dict:tst_listsetget: getdns_dict_get_list() empty dict
tests_dict:tst_listsetget: line 297: getdns_dict_get_list(NULL, key, &anslist),retval = 305
tests_dict:tst_listsetget: line 301: getdns_dict_get_list(dict, key, NULL),retval = 305
tests_dict:tst_listsetget: getdns_dict_get_list(dict, NULL, &anslist)
tests_dict:tst_listsetget: line 306: getdns_dict_get_list,retval = 305
tests_dict:tst_listsetget: getdns_dict_get_list(dict, key, &anslist)
tests_dict:tst_listsetget: line 311: getdns_list_get_list,retval = 305
tests_dict:tst_listsetget: getdns_dict_set_list(dict, key, newlist)
tests_dict:tst_listsetget: line 331: getdns_dict_set_list,retval=0,key=foo
tests_dict:tst_listsetget: getdns_dict_get_list(dict, key, &anslist)
tests_dict:tst_listsetget: line 340: getdns_dict_get_list,retval=0,key=foo,int1=42,int2=52
TESTCASE tests_dict:tst_listsetget END
TESTCASE tests_dict:tst_getnames BEGIN
tests_dict:tst_getnames: getdns_dict_get_names(NULL, &list)
tests_dict:tst_getnames: getdns_dict_get_names(dict, NULL)
tests_dict:tst_getnames: getdns_dict_get_names(dict, &list), empty dictionary
list item 0: t_int, value=3
list item 1: t_int, value=1
list item 2: t_int, value=0
list item 3: t_int, value=2
TESTCASE tests_dict:tst_getnames END
TESTCASE tests_dict:tst_copy BEGIN
tests_dict:tst_copy: empty list cases
tests_dict:tst_copy: dict1 populate
key="bar", type="int", value="52"
key="foo", type="int", value="42"
key="quz", type="int", value="62"
tests_dict:tst_copy: getdns_dict_copy(dict1, &dict2)
key="bar", type="int", value="52"
key="foo", type="int", value="42"
key="quz", type="int", value="62"
TESTCASE tests_dict:tst_copy END
TESTPROG tests_dict END

View File

@ -34,6 +34,9 @@
#define TSTMSGBUF 80
/* TODO: might want a separate unit test for getdns_list_copy() - right now the code gets
covered as a result of other tests */
/*---------------------------------------- tst_bindatasetget */
/**
* test the list get and set routines
@ -112,6 +115,82 @@ tst_bindatasetget(void)
return;
} /* tst_bindatasetget */
/*---------------------------------------- tst_dictsetget */
/**
* test the dict get and set routines
*/
void
tst_dictsetget(void)
{
char msg[TSTMSGBUF];
size_t index;
uint32_t ans_int;
getdns_return_t retval;
struct getdns_list *list = NULL;
struct getdns_dict *dict = NULL;
struct getdns_dict *ansdict = NULL;
tstmsg_case_begin("tst_dictsetget");
list = getdns_list_create();
dict = getdns_dict_create();
/* test dict get function against empty list and with bogus params */
tstmsg_case_msg("getdns_list_get_dict() empty list");
retval = getdns_list_get_dict(NULL, index, &dict);
sprintf(msg, "getdns_list_get_dict(NULL, index, &dict),retval = %d", retval);
tstmsg_case_msg(msg);
retval = getdns_list_get_dict(list, index, NULL);
sprintf(msg, "getdns_list_get_dict(list, index, NULL),retval = %d", retval);
tstmsg_case_msg(msg);
tstmsg_case_msg("getdns_list_get_dict(list, 0, &dict)");
retval = getdns_list_get_dict(list, 0, &dict);
sprintf(msg, "getdns_list_get_dict,retval = %d", retval);
tstmsg_case_msg(msg);
tstmsg_case_msg("getdns_list_get_dict(list, 1, &dict)");
retval = getdns_list_get_dict(list, 1, &dict);
sprintf(msg, "getdns_list_get_dict,retval = %d", retval);
tstmsg_case_msg(msg);
/* test int set function against empty list with bogus params */
tstmsg_case_msg("getdns_list_set_dict() empty list");
retval = getdns_list_set_dict(NULL, index, dict);
sprintf(msg, "getdns_list_set_dict(NULL, index, dict),retval = %d", retval);
tstmsg_case_msg(msg);
tstmsg_case_msg("getdns_list_set_dict(list, 0, dict)");
retval = getdns_list_set_dict(list, 0, dict);
sprintf(msg, "getdns_list_set_dict,retval = %d", retval);
tstmsg_case_msg(msg);
tstmsg_case_msg("getdns_list_set_dict(list, 1, dict)");
retval = getdns_list_set_dict(list, 1, dict);
sprintf(msg, "getdns_list_set_dict,retval = %d", retval);
tstmsg_case_msg(msg);
/* test set and get legitimate use case */
getdns_dict_set_int(dict, "foo", 42);
getdns_list_add_item(list, &index);
getdns_list_set_dict(list, index, dict);
retval = getdns_list_get_dict(list, index, &ansdict);
getdns_dict_get_int(ansdict, "foo", &ans_int);
sprintf(msg, "getdns_list_set/get_dict,retval=%d, ans=%d", retval, ans_int);
tstmsg_case_msg(msg);
getdns_dict_destroy(dict);
getdns_list_destroy(list);
tstmsg_case_end();
return;
} /* tst_dictsetget */
/*---------------------------------------- tst_listsetget */
/**
* test the list get and set routines
@ -347,12 +426,14 @@ main(int argc, char *argv[])
tst_create();
tst_bindatasetget();
tst_dictsetget();
tst_intsetget();
tst_listsetget();
tst_bindatasetget();
tstmsg_prog_end();
return 0;

View File

@ -11,6 +11,38 @@ TESTCASE tests_list:tst_create BEGIN
tests_list:tst_create: NUll, NULL, retval = 304
tests_list:tst_create: list, NULL, retval = 304
TESTCASE tests_list:tst_create END
TESTCASE tests_list:tst_bindatasetget BEGIN
tests_list:tst_bindatasetget: getdns_list_get_bindata() empty list
tests_list:tst_bindatasetget: getdns_list_get_bindata(NULL, index, &ans_bindata),retval = 304
tests_list:tst_bindatasetget: getdns_list_get_bindata(list, index, NULL),retval = 304
tests_list:tst_bindatasetget: getdns_list_get_bindata(list, 0, &ans_bindata)
tests_list:tst_bindatasetget: getdns_list_get_bindata,retval = 304
tests_list:tst_bindatasetget: getdns_list_get_bindata(list, 1, &ans_bindata)
tests_list:tst_bindatasetget: getdns_list_get_bindata,retval = 304
tests_list:tst_bindatasetget: getdns_list_set_bindata() empty list
tests_list:tst_bindatasetget: getdns_list_set_bindata(NULL, index, ans_bindata),retval = 304
tests_list:tst_bindatasetget: getdns_list_set_bindata(list, 0, ans_bindata)
tests_list:tst_bindatasetget: getdns_list_set_bindata,retval = 304
tests_list:tst_bindatasetget: getdns_list_set_bindata(list, 1, ans_bindata)
tests_list:tst_bindatasetget: getdns_list_set_bindata,retval = 304
tests_list:tst_bindatasetget: getdns_list_set/get_bindata,retval = 0, bindata->data = 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