--- /dev/null
+/* vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
+ *
+ * LibMemcached
+ *
+ * Copyright (C) 2011 Data Differential, http://datadifferential.com/
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * * The names of its contributors may not be used to endorse or
+ * promote products derived from this software without specific prior
+ * written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include <config.h>
+
+#include "libmemcached/common.h"
+
+struct memcached_array_st
+{
+ size_t size;
+ char c_str[];
+};
+
+memcached_array_st *memcached_strcpy(const char *str, size_t str_length)
+{
+ memcached_array_st *array= (struct memcached_array_st *)malloc(sizeof(struct memcached_array_st) +str_length +1);
+
+ array->size= str_length;
+ memcpy(array->c_str, str, str_length);
+ array->c_str[str_length]= 0;
+
+ return array;
+}
+
+void memcached_array_free(memcached_array_st *array)
+{
+ WATCHPOINT_ASSERT(array);
+ if (array)
+ free(array);
+}
--- /dev/null
+/* vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
+ *
+ * LibMemcached
+ *
+ * Copyright (C) 2011 Data Differential, http://datadifferential.com/
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * * The names of its contributors may not be used to endorse or
+ * promote products derived from this software without specific prior
+ * written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#pragma once
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+LIBMEMCACHED_LOCAL
+memcached_array_st *memcached_strcpy(const char *str, size_t str_length);
+
+LIBMEMCACHED_LOCAL
+void memcached_array_free(memcached_array_st *array);
+
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
memcached_server_write_instance_st instance;
bool no_reply= ptr->flags.no_reply;
- unlikely (memcached_server_count(ptr) == 0)
- return MEMCACHED_NO_SERVERS;
+ if (memcached_server_count(ptr) == 0)
+ return memcached_set_error(ptr, MEMCACHED_NO_SERVERS, NULL);
if (ptr->flags.verify_key && (memcached_key_test((const char **)&key, &key_length, 1) == MEMCACHED_BAD_KEY_PROVIDED))
return MEMCACHED_BAD_KEY_PROVIDED;
memcached_server_write_instance_st instance;
bool no_reply= ptr->flags.no_reply;
- unlikely (memcached_server_count(ptr) == 0)
- return MEMCACHED_NO_SERVERS;
+ if (memcached_server_count(ptr) == 0)
+ return memcached_set_error(ptr, MEMCACHED_NO_SERVERS, NULL);
server_key= memcached_generate_hash_with_redistribution(ptr, master_key, master_key_length);
instance= memcached_server_instance_fetch(ptr, server_key);
uint32_t offset,
uint64_t *value)
{
+ uint64_t local_value;
+ if (! value)
+ value= &local_value;
+
return memcached_increment_by_key(ptr, key, key_length, key, key_length, offset, value);
}
uint32_t offset,
uint64_t *value)
{
+ uint64_t local_value;
+ if (! value)
+ value= &local_value;
+
return memcached_decrement_by_key(ptr, key, key_length, key, key_length, offset, value);
}
unlikely (rc != MEMCACHED_SUCCESS)
return rc;
+ uint64_t local_value;
+ if (! value)
+ value= &local_value;
+
LIBMEMCACHED_MEMCACHED_INCREMENT_START();
if (ptr->flags.binary_protocol)
{
unlikely (rc != MEMCACHED_SUCCESS)
return rc;
+ uint64_t local_value;
+ if (! value)
+ value= &local_value;
+
LIBMEMCACHED_MEMCACHED_DECREMENT_START();
if (ptr->flags.binary_protocol)
{
time_t expiration,
uint64_t *value)
{
+ uint64_t local_value;
+ if (! value)
+ value= &local_value;
+
return memcached_increment_with_initial_by_key(ptr, key, key_length,
key, key_length,
offset, initial, expiration, value);
unlikely (rc != MEMCACHED_SUCCESS)
return rc;
+ uint64_t local_value;
+ if (! value)
+ value= &local_value;
+
LIBMEMCACHED_MEMCACHED_INCREMENT_WITH_INITIAL_START();
if (ptr->flags.binary_protocol)
rc= binary_incr_decr(ptr, PROTOCOL_BINARY_CMD_INCREMENT,
time_t expiration,
uint64_t *value)
{
+ uint64_t local_value;
+ if (! value)
+ value= &local_value;
+
return memcached_decrement_with_initial_by_key(ptr, key, key_length,
key, key_length,
offset, initial, expiration, value);
unlikely (rc != MEMCACHED_SUCCESS)
return rc;
+ uint64_t local_value;
+ if (! value)
+ value= &local_value;
+
LIBMEMCACHED_MEMCACHED_INCREMENT_WITH_INITIAL_START();
if (ptr->flags.binary_protocol)
{
#endif
LIBMEMCACHED_API
-memcached_return_t memcached_increment(memcached_st *ptr,
- const char *key, size_t key_length,
- uint32_t offset,
- uint64_t *value);
+ memcached_return_t memcached_increment(memcached_st *ptr,
+ const char *key, size_t key_length,
+ uint32_t offset,
+ uint64_t *value);
LIBMEMCACHED_API
-memcached_return_t memcached_decrement(memcached_st *ptr,
- const char *key, size_t key_length,
- uint32_t offset,
- uint64_t *value);
+ memcached_return_t memcached_decrement(memcached_st *ptr,
+ const char *key, size_t key_length,
+ uint32_t offset,
+ uint64_t *value);
LIBMEMCACHED_API
-memcached_return_t memcached_increment_by_key(memcached_st *ptr,
- const char *master_key, size_t master_key_length,
- const char *key, size_t key_length,
- uint64_t offset,
- uint64_t *value);
+ memcached_return_t memcached_increment_by_key(memcached_st *ptr,
+ const char *master_key, size_t master_key_length,
+ const char *key, size_t key_length,
+ uint64_t offset,
+ uint64_t *value);
LIBMEMCACHED_API
-memcached_return_t memcached_decrement_by_key(memcached_st *ptr,
- const char *master_key, size_t master_key_length,
- const char *key, size_t key_length,
- uint64_t offset,
- uint64_t *value);
+ memcached_return_t memcached_decrement_by_key(memcached_st *ptr,
+ const char *master_key, size_t master_key_length,
+ const char *key, size_t key_length,
+ uint64_t offset,
+ uint64_t *value);
LIBMEMCACHED_API
-memcached_return_t memcached_increment_with_initial(memcached_st *ptr,
- const char *key,
- size_t key_length,
- uint64_t offset,
- uint64_t initial,
- time_t expiration,
- uint64_t *value);
+ memcached_return_t memcached_increment_with_initial(memcached_st *ptr,
+ const char *key,
+ size_t key_length,
+ uint64_t offset,
+ uint64_t initial,
+ time_t expiration,
+ uint64_t *value);
+
LIBMEMCACHED_API
-memcached_return_t memcached_decrement_with_initial(memcached_st *ptr,
- const char *key,
- size_t key_length,
- uint64_t offset,
- uint64_t initial,
- time_t expiration,
- uint64_t *value);
+ memcached_return_t memcached_decrement_with_initial(memcached_st *ptr,
+ const char *key,
+ size_t key_length,
+ uint64_t offset,
+ uint64_t initial,
+ time_t expiration,
+ uint64_t *value);
+
LIBMEMCACHED_API
-memcached_return_t memcached_increment_with_initial_by_key(memcached_st *ptr,
- const char *master_key,
- size_t master_key_length,
- const char *key,
- size_t key_length,
- uint64_t offset,
- uint64_t initial,
- time_t expiration,
- uint64_t *value);
+ memcached_return_t memcached_increment_with_initial_by_key(memcached_st *ptr,
+ const char *master_key,
+ size_t master_key_length,
+ const char *key,
+ size_t key_length,
+ uint64_t offset,
+ uint64_t initial,
+ time_t expiration,
+ uint64_t *value);
+
LIBMEMCACHED_API
-memcached_return_t memcached_decrement_with_initial_by_key(memcached_st *ptr,
- const char *master_key,
- size_t master_key_length,
- const char *key,
- size_t key_length,
- uint64_t offset,
- uint64_t initial,
- time_t expiration,
- uint64_t *value);
+ memcached_return_t memcached_decrement_with_initial_by_key(memcached_st *ptr,
+ const char *master_key,
+ size_t master_key_length,
+ const char *key,
+ size_t key_length,
+ uint64_t offset,
+ uint64_t initial,
+ time_t expiration,
+ uint64_t *value);
#ifdef __cplusplus
}
/* We just try the first host, and if it is down we return zero */
if ((memcached_connect(instance)) != MEMCACHED_SUCCESS)
{
- return EXIT_SUCCESS;
+ return 0;
}
if (memcached_io_wait_for_write(instance) != MEMCACHED_SUCCESS)
{
- return EXIT_SUCCESS;
+ return 0;
}
if (getsockopt(instance->fd, SOL_SOCKET, SO_SNDBUF, &sock_size, &sock_length) < 0)
{
ptr->cached_errno= errno;
- return EXIT_SUCCESS; /* Zero means error */
+ return 0; /* Zero means error */
}
}
/* We just try the first host, and if it is down we return zero */
if ((memcached_connect(instance)) != MEMCACHED_SUCCESS)
{
- return EXIT_SUCCESS;
+ return 0;
}
if (memcached_io_wait_for_write(instance) != MEMCACHED_SUCCESS)
{
- return EXIT_SUCCESS;
+ return 0;
}
if (getsockopt(instance->fd, SOL_SOCKET, SO_RCVBUF, &sock_size, &sock_length) < 0)
{
ptr->cached_errno= errno;
- return EXIT_SUCCESS; /* Zero means error */
+ return 0; /* Zero means error */
}
}
case MEMCACHED_BEHAVIOR_MAX:
default:
WATCHPOINT_ASSERT(0); /* Programming mistake if it gets this far */
- return EXIT_SUCCESS;
+ return 0;
}
/* NOTREACHED */
#ifndef __LIBMEMCACHED_COMMON_H__
#define __LIBMEMCACHED_COMMON_H__
-#include "config.h"
+#include <config.h>
#include <stdio.h>
#include <stdlib.h>
#include "libmemcached/memcached.h"
#include "libmemcached/watchpoint.h"
+#include "libmemcached/is.h"
typedef struct memcached_server_st * memcached_server_write_instance_st;
#define memcached_server_response_decrement(A) (A)->cursor_active--
#define memcached_server_response_reset(A) (A)->cursor_active=0
-// These are private
-#define memcached_is_allocated(__object) ((__object)->options.is_allocated)
-#define memcached_is_initialized(__object) ((__object)->options.is_initialized)
-#define memcached_is_purging(__object) ((__object)->state.is_purging)
-#define memcached_is_processing_input(__object) ((__object)->state.is_processing_input)
-#define memcached_set_purging(__object, __value) ((__object)->state.is_purging= (__value))
-#define memcached_set_processing_input(__object, __value) ((__object)->state.is_processing_input= (__value))
-#define memcached_set_initialized(__object, __value) ((__object)->options.is_initialized(= (__value))
-#define memcached_set_allocated(__object, __value) ((__object)->options.is_allocated(= (__value))
-
LIBMEMCACHED_LOCAL
void set_last_disconnected_host(memcached_server_write_instance_st ptr);
--- /dev/null
+/* vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
+ *
+ * LibMemcached
+ *
+ * Copyright (C) 2011 Data Differential, http://datadifferential.com/
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * * The names of its contributors may not be used to endorse or
+ * promote products derived from this software without specific prior
+ * written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include "libmemcached/common.h"
+
+struct memcached_error_st
+{
+ memcached_st *root;
+ struct memcached_error_st *next;
+ memcached_return_t rc;
+ int local_errno;
+ size_t size;
+ char c_str[];
+};
+
+static memcached_error_st *_set(memcached_st *memc, memcached_string_t *str)
+{
+ if (! memc)
+ return NULL;
+
+ memcached_error_st *error;
+ error= (struct memcached_error_st *)libmemcached_malloc(memc, sizeof(struct memcached_error_st) +(str ? str->size :0) +1);
+
+ if (! error)
+ return NULL;
+
+ error->root= memc;
+
+ if (str)
+ {
+ error->size= str->size;
+ memcpy(error->c_str, str->c_str, str->size);
+ }
+ error->c_str[(str ? str->size :0)]= 0;
+
+ error->next= memc->error_messages;
+ memc->error_messages= error;
+
+ return error;
+}
+
+memcached_return_t memcached_set_error(memcached_st *memc, memcached_return_t rc, memcached_string_t *str)
+{
+ if (rc == MEMCACHED_SUCCESS)
+ return MEMCACHED_SUCCESS;
+
+ memcached_error_st *error= _set(memc, str);
+
+ if (error)
+ {
+ error->local_errno= 0;
+ error->rc= rc;
+ }
+
+ return rc;
+}
+
+memcached_return_t memcached_set_errno(memcached_st *memc, int local_errno, memcached_string_t *str)
+{
+ memcached_error_st *error= _set(memc, str);
+
+ if (error)
+ {
+ error->local_errno= local_errno;
+ error->rc= MEMCACHED_ERRNO;
+ }
+
+ return error->rc;
+}
+
+static void _error_free(memcached_error_st *error)
+{
+ if (! error)
+ return;
+
+ _error_free(error->next);
+
+ if (error && error->root)
+ {
+ libmemcached_free(error->root, error);
+ }
+ else if (error)
+ {
+ free(error);
+ }
+}
+
+void memcached_error_free(memcached_st *self)
+{
+ if (! self)
+ return;
+
+ _error_free(self->error_messages);
+}
+
+const char *memcached_last_error_message(memcached_st *memc)
+{
+ if (! memc)
+ return memcached_strerror(memc, MEMCACHED_INVALID_ARGUMENTS);
+
+ if (! memc->error_messages)
+ return memcached_strerror(memc, MEMCACHED_SUCCESS);
+
+ if (! memc->error_messages->c_str)
+ {
+ return memcached_strerror(memc, memc->error_messages->rc);
+ }
+
+ return memc->error_messages->c_str;
+}
+
+memcached_return_t memcached_last_error(memcached_st *memc)
+{
+ if (! memc)
+ return MEMCACHED_INVALID_ARGUMENTS;
+
+ if (! memc->error_messages)
+ return MEMCACHED_SUCCESS;
+
+ return memc->error_messages->rc;
+}
+
+memcached_return_t memcached_last_error_errno(memcached_st *memc)
+{
+ if (! memc)
+ return MEMCACHED_INVALID_ARGUMENTS;
+
+ if (! memc->error_messages)
+ return MEMCACHED_SUCCESS;
+
+ return memc->error_messages->local_errno;
+}
--- /dev/null
+/* vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
+ *
+ * LibMemcached
+ *
+ * Copyright (C) 2011 Data Differential, http://datadifferential.com/
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * * The names of its contributors may not be used to endorse or
+ * promote products derived from this software without specific prior
+ * written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#pragma once
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+LIBMEMCACHED_LOCAL
+ memcached_return_t memcached_set_error(memcached_st *memc, memcached_return_t rc, memcached_string_t *str);
+
+LIBMEMCACHED_LOCAL
+ memcached_return_t memcached_set_errno(memcached_st *memc, int local_errno, memcached_string_t *str);
+
+LIBMEMCACHED_LOCAL
+ void memcached_error_free(memcached_st *error);
+
+LIBMEMCACHED_API
+ const char *memcached_last_error_message(memcached_st *memc);
+
+LIBMEMCACHED_API
+ memcached_return_t memcached_last_error(memcached_st *memc);
+
+LIBMEMCACHED_API
+ memcached_return_t memcached_last_error_errno(memcached_st *memc);
+
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
libmemcached/do.h \
libmemcached/internal.h \
libmemcached/io.h \
+ libmemcached/is.h \
libmemcached/libmemcached_probes.h \
libmemcached/protocol/ascii_handler.h \
libmemcached/protocol/binary_handler.h \
nobase_include_HEADERS+= \
libmemcached/allocators.h \
libmemcached/analyze.h \
+ libmemcached/array.h \
libmemcached/auto.h \
libmemcached/behavior.h \
libmemcached/callback.h \
libmemcached/constants.h \
libmemcached/delete.h \
libmemcached/dump.h \
+ libmemcached/error.h \
libmemcached/exception.hpp \
libmemcached/fetch.h \
libmemcached/flush.h \
libmemcached_libmemcached_la_SOURCES+= \
libmemcached/allocators.c \
libmemcached/analyze.c \
+ libmemcached/array.c \
libmemcached/auto.c \
libmemcached/behavior.c \
libmemcached/connect.c \
libmemcached/delete.c \
libmemcached/do.c \
libmemcached/dump.c \
+ libmemcached/error.c \
libmemcached/fetch.c \
libmemcached/flush.c \
libmemcached/flush_buffers.c \
libmemcached/get.c \
libmemcached/hash.c \
- libmemcached/options.cc \
libmemcached/hosts.c \
libmemcached/io.c \
libmemcached/key.c \
libmemcached/memcached.c \
+ libmemcached/options.cc \
libmemcached/parse.c \
libmemcached/purge.c \
libmemcached/quit.c \
--- /dev/null
+/* vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
+ *
+ * LibMemcached
+ *
+ * Copyright (C) 2011 Data Differential, http://datadifferential.com/
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * * The names of its contributors may not be used to endorse or
+ * promote products derived from this software without specific prior
+ * written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#pragma once
+
+/* These are private */
+#define memcached_is_allocated(__object) ((__object)->options.is_allocated)
+#define memcached_is_initialized(__object) ((__object)->options.is_initialized)
+#define memcached_is_purging(__object) ((__object)->state.is_purging)
+#define memcached_is_processing_input(__object) ((__object)->state.is_processing_input)
+#define memcached_set_purging(__object, __value) ((__object)->state.is_purging= (__value))
+#define memcached_set_processing_input(__object, __value) ((__object)->state.is_processing_input= (__value))
+#define memcached_set_initialized(__object, __value) ((__object)->options.is_initialized(= (__value))
+#define memcached_set_allocated(__object, __value) ((__object)->options.is_allocated= (__value))
self->sasl.callbacks= NULL;
self->sasl.is_allocated= false;
+ self->error_messages= NULL;
+
return true;
}
+static void _free(memcached_st *ptr, bool release_st)
+{
+ /* If we have anything open, lets close it now */
+ memcached_quit(ptr);
+ memcached_server_list_free(memcached_server_list(ptr));
+ memcached_result_free(&ptr->result);
+
+ if (ptr->last_disconnected_server)
+ memcached_server_free(ptr->last_disconnected_server);
+
+ if (ptr->on_cleanup)
+ ptr->on_cleanup(ptr);
+
+ if (ptr->continuum)
+ libmemcached_free(ptr, ptr->continuum);
+
+ memcached_error_free(ptr);
+
+ if (ptr->sasl.callbacks)
+ {
+#ifdef LIBMEMCACHED_WITH_SASL_SUPPORT
+ memcached_destroy_sasl_auth_data(ptr);
+#endif
+ }
+
+ if (memcached_is_allocated(ptr) && release_st)
+ {
+ libmemcached_free(ptr, ptr);
+ }
+}
+
memcached_st *memcached_create(memcached_st *ptr)
{
if (ptr == NULL)
return ptr;
}
+void memcached_reset(memcached_st *ptr)
+{
+ WATCHPOINT_ASSERT(ptr);
+ if (! ptr)
+ return;
+
+ bool stored_is_allocated= memcached_is_allocated(ptr);
+ _free(ptr, false);
+ memcached_create(ptr);
+ memcached_set_allocated(ptr, stored_is_allocated);
+}
+
void memcached_servers_reset(memcached_st *ptr)
{
memcached_server_list_free(memcached_server_list(ptr));
void memcached_free(memcached_st *ptr)
{
- /* If we have anything open, lets close it now */
- memcached_quit(ptr);
- memcached_server_list_free(memcached_server_list(ptr));
- memcached_result_free(&ptr->result);
-
- if (ptr->last_disconnected_server)
- memcached_server_free(ptr->last_disconnected_server);
-
- if (ptr->on_cleanup)
- ptr->on_cleanup(ptr);
-
- if (ptr->continuum)
- libmemcached_free(ptr, ptr->continuum);
-
- if (ptr->sasl.callbacks)
- {
-#ifdef LIBMEMCACHED_WITH_SASL_SUPPORT
- memcached_destroy_sasl_auth_data(ptr);
-#endif
- }
-
- if (memcached_is_allocated(ptr))
- {
- libmemcached_free(ptr, ptr);
- }
+ _free(ptr, true);
}
/*
#include <libmemcached/constants.h>
#include <libmemcached/types.h>
#include <libmemcached/string.h>
+#include <libmemcached/array.h>
+#include <libmemcached/error.h>
#include <libmemcached/stats.h>
#include <libhashkit/hashkit.h>
// Everything above this line must be in the order specified.
memcached_trigger_delete_key_fn delete_trigger;
memcached_callback_st *callbacks;
struct memcached_sasl_st sasl;
+ struct memcached_error_st *error_messages;
char prefix_key[MEMCACHED_PREFIX_KEY_MAX_SIZE];
struct {
bool is_allocated:1;
LIBMEMCACHED_API
void memcached_free(memcached_st *ptr);
+LIBMEMCACHED_API
+void memcached_reset(memcached_st *ptr);
+
LIBMEMCACHED_API
void memcached_reset_last_disconnected_server(memcached_st *ptr);
memset(&pp, 0, sizeof(type_st));
+ WATCHPOINT_ASSERT(self);
+ if (! self)
+ return MEMCACHED_INVALID_ARGUMENTS;
+
pp.buf= option_string;
pp.memc= self;
pp.length= length;
#pragma GCC diagnostic ignored "-Wold-style-cast"
#include <libmemcached/options/scanner.h>
-inline int libmemcached_error(YYLTYPE *locp, type_st *parser, yyscan_t *scanner, const char *str)
+inline void libmemcached_error(YYLTYPE *locp, type_st *parser, yyscan_t *scanner, const char *str)
{
-#if 0
- std::cerr << str << std::endl;
-#endif
- return 0;
+ memcached_string_t local_string;
+ local_string.size= strlen(str);
+ local_string.c_str= str;
+ memcached_set_error(parser->memc, MEMCACHED_FAILURE, &local_string);
}
%token USE_UDP
%token VERIFY_KEY
+/* Callbacks */
+%token PREFIX_KEY
+
/* Hash types */
%token MD5
%token CRC
%token <number> NUMBER
%token <number> FLOAT
-%token <string> IDENTIFIER
-%token <string> SERVER_WITH_PORT
+%token <string> HOSTNAME
+%token <string> HOSTNAME_WITH_PORT
%token <string> IPADDRESS
%token <string> IPADDRESS_WITH_PORT
+%token <string> STRING
+%token <string> QUOTED_STRING
%type <server> server
+%type <string> string
%type <distribution> distribution
%type <hash> hash
%type <behavior> behavior_boolean
;
behaviors:
+ PREFIX_KEY '=' string
+ {
+ memcached_callback_set(parser->memc, MEMCACHED_CALLBACK_PREFIX_KEY, std::string($3.c_str, $3.length).c_str());
+ }
| DISTRIBUTION '=' distribution
{
memcached_behavior_set(parser->memc, MEMCACHED_BEHAVIOR_DISTRIBUTION, $3);
;
server:
- SERVER_WITH_PORT NUMBER
+ HOSTNAME_WITH_PORT NUMBER
{
$$.c_str= $1.c_str;
$$.length= $1.length -1;
$$.port= $2;
}
- | IDENTIFIER
+ | HOSTNAME
+ {
+ $$.c_str= $1.c_str;
+ $$.length= $1.length;
+ $$.port= MEMCACHED_DEFAULT_PORT;
+ }
+ | STRING /* a match can be against "localhost" which is just a string */
{
$$.c_str= $1.c_str;
$$.length= $1.length;
}
;
+string:
+ STRING
+ {
+ $$= $1;
+ }
+ | QUOTED_STRING
+ {
+ $$.c_str= $1.c_str +1;
+ $$.length= $1.length -2;
+ }
+ ;
+
distribution:
CONSISTENT
{
USE_UDP { return USE_UDP; }
USE-UDP { return USE_UDP; }
+PREFIX-KEY { return PREFIX_KEY; }
+PREFIX_KEY { return PREFIX_KEY; }
+
CONSISTENT { return CONSISTENT; }
MODULA { return MODULA; }
RANDOM { return RANDOM; }
[[:alnum:]][[:alnum:].]*[[:alpha:]]: {
yylval->string.c_str = yytext;
yylval->string.length = yyleng;
- return SERVER_WITH_PORT;
+ return HOSTNAME_WITH_PORT;
}
-[[:alnum:]][[:alnum:].]*[[:alpha:]] {
+[[:alnum:]]+"."[[:alpha:].]+ {
yylval->string.c_str = yytext;
yylval->string.length = yyleng;
- return IDENTIFIER;
+ return HOSTNAME;
}
+
[[:digit:]]{1,3}"."[[:digit:]]{1,3}"."[[:digit:]]{1,3}"."[[:digit:]]{1,3}: {
yylval->string.c_str = yytext;
yylval->string.length = yyleng;
return IPADDRESS;
}
+[[:alnum:]]+ {
+ yylval->string.c_str = yytext;
+ yylval->string.length = yyleng;
+ return STRING;
+ }
+
+\"[[:alnum:]]*\" {
+ yylval->string.c_str = yytext;
+ yylval->string.length = yyleng;
+ return QUOTED_STRING;
+ }
+
. {
return UNKNOWN;
}
} options;
};
+struct memcached_string_t {
+ size_t size;
+ const char *c_str;
+};
+
#ifdef __cplusplus
extern "C" {
#endif
#endif
+#ifdef __cplusplus
+#define memcached_string_with_size(X) (X), (static_cast<size_t>((sizeof(X) - 1)))
+#else
+#define memcached_string_with_size(X) (X), ((size_t)((sizeof(X) - 1)))
+#endif
+
#endif /* __LIBMEMCACHED_STRING_H__ */
typedef struct memcached_stat_st memcached_stat_st;
typedef struct memcached_analysis_st memcached_analysis_st;
typedef struct memcached_result_st memcached_result_st;
+typedef struct memcached_array_st memcached_array_st;
+typedef struct memcached_error_st memcached_error_st;
// All of the flavors of memcache_server_st
typedef struct memcached_server_st memcached_server_st;
// The following two structures are internal, and never exposed to users.
typedef struct memcached_string_st memcached_string_st;
+typedef struct memcached_string_t memcached_string_t;
typedef struct memcached_continuum_item_st memcached_continuum_item_st;
static void kill_file(const char *file_buffer)
{
- FILE *fp= fopen(file_buffer, "r");
+ FILE *fp;
while ((fp= fopen(file_buffer, "r")))
{
--- /dev/null
+/* vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
+ *
+ * Libmemcached
+ *
+ * Copyright (C) 2011 Data Differential, http://datadifferential.com/
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * * The names of its contributors may not be used to endorse or
+ * promote products derived from this software without specific prior
+ * written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include <libmemcached/memcached.h>
+#include <libmemcached/is.h>
+#include <libtest/test.h>
+#include "tests/basic.h"
+
+test_return_t basic_init_test(memcached_st *junk)
+{
+ (void)junk;
+
+ memcached_st memc;
+ memcached_st *memc_ptr;
+
+ memc_ptr= memcached_create(&memc);
+ test_true(memc_ptr);
+ test_false(memcached_is_allocated(&memc));
+ memcached_free(memc_ptr);
+
+ return TEST_SUCCESS;
+}
+
+test_return_t basic_clone_test(memcached_st *memc)
+{
+ memcached_st *memc_ptr;
+
+ memc_ptr= memcached_clone(NULL, memc);
+ test_true(memc_ptr);
+ test_true(memcached_is_allocated(memc_ptr));
+ memcached_free(memc_ptr);
+
+ return TEST_SUCCESS;
+}
+
+test_return_t basic_reset_stack_test(memcached_st *junk)
+{
+ (void)junk;
+ memcached_st memc;
+
+ memcached_create(&memc);
+
+ memcached_reset(&memc);
+ test_false(memcached_is_allocated(&memc));
+
+ memcached_free(&memc);
+ test_false(memcached_is_allocated(&memc));
+
+ return TEST_SUCCESS;
+}
+
+test_return_t basic_reset_heap_test(memcached_st *junk)
+{
+ (void)junk;
+ memcached_st *memc_ptr;
+
+ memc_ptr= memcached_create(NULL);
+ test_true(memcached_is_allocated(memc_ptr));
+
+ memcached_reset(memc_ptr);
+ test_true(memcached_is_allocated(memc_ptr));
+
+ memcached_free(memc_ptr);
+
+ return TEST_SUCCESS;
+}
+
+test_return_t basic_reset_stack_clone_test(memcached_st *memc)
+{
+ memcached_st clone;
+ memcached_st *memc_ptr;
+
+ memset(&clone, 0, sizeof(clone));
+ memc_ptr= memcached_clone(&clone, memc);
+ test_true(memc_ptr);
+
+ memcached_reset(memc_ptr);
+
+ memcached_free(memc_ptr);
+
+ return TEST_SUCCESS;
+}
+
+test_return_t basic_reset_heap_clone_test(memcached_st *memc)
+{
+ memcached_st *memc_ptr;
+
+ memc_ptr= memcached_clone(NULL, memc);
+ test_true(memc_ptr);
+
+ memcached_reset(memc_ptr);
+
+ memcached_free(memc_ptr);
+
+ return TEST_SUCCESS;
+}
--- /dev/null
+/* vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
+ *
+ * Libmemcached
+ *
+ * Copyright (C) 2011 Data Differential, http://datadifferential.com/
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * * The names of its contributors may not be used to endorse or
+ * promote products derived from this software without specific prior
+ * written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#pragma once
+
+#include <libtest/visibility.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+LIBTEST_INTERNAL_API
+test_return_t basic_init_test(memcached_st *junk);
+
+LIBTEST_INTERNAL_API
+test_return_t basic_clone_test(memcached_st *memc);
+
+LIBTEST_INTERNAL_API
+test_return_t basic_reset_stack_test(memcached_st *junk);
+
+LIBTEST_INTERNAL_API
+test_return_t basic_reset_heap_test(memcached_st *junk);
+
+LIBTEST_INTERNAL_API
+test_return_t basic_reset_stack_clone_test(memcached_st *memc);
+
+LIBTEST_INTERNAL_API
+test_return_t basic_reset_heap_clone_test(memcached_st *memc);
+
+#ifdef __cplusplus
+}
+#endif
--- /dev/null
+/* vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
+ *
+ * Libmemcached
+ *
+ * Copyright (C) 2011 Data Differential, http://datadifferential.com/
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * * The names of its contributors may not be used to endorse or
+ * promote products derived from this software without specific prior
+ * written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include <config.h>
+
+#include <libmemcached/memcached.h>
+#include <libmemcached/is.h>
+#include <libtest/test.h>
+#include <tests/error_conditions.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+test_return_t memcached_increment_MEMCACHED_NO_SERVERS(memcached_st *junk)
+{
+ (void)junk;
+ memcached_st *memc_ptr;
+
+ memc_ptr= memcached_create(NULL);
+ test_true(memc_ptr);
+
+ memcached_increment(memc_ptr, memcached_string_with_size("dead key"), 1, NULL);
+ test_true(memcached_last_error(memc_ptr) == MEMCACHED_NO_SERVERS);
+
+ memcached_increment(memc_ptr, memcached_string_with_size("dead key"), 1, NULL);
+ test_true(memcached_last_error(memc_ptr) == MEMCACHED_NO_SERVERS);
+
+ memcached_free(memc_ptr);
+
+ return TEST_SUCCESS;
+}
+
+#ifdef __cplusplus
+}
+#endif
--- /dev/null
+/* vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
+ *
+ * Libmemcached
+ *
+ * Copyright (C) 2011 Data Differential, http://datadifferential.com/
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * * The names of its contributors may not be used to endorse or
+ * promote products derived from this software without specific prior
+ * written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#pragma once
+
+#include <libtest/test.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+test_return_t memcached_increment_MEMCACHED_NO_SERVERS(memcached_st *junk);
+
+#ifdef __cplusplus
+}
+#endif
tests/output_plus.res
noinst_HEADERS+= \
+ tests/basic.h \
+ tests/error_conditions.h \
tests/hash_results.h \
tests/ketama_test_cases.h \
tests/ketama_test_cases_spy.h \
tests_testapp_CFLAGS= $(AM_CFLAGS) $(NO_CONVERSION) $(NO_STRICT_ALIASING)
tests_testapp_SOURCES= \
+ tests/basic.cc \
+ tests/error_conditions.cc \
tests/mem_functions.c \
tests/parser.cc \
tests/print.cc \
#include <libtest/test.h>
#include "tests/parser.h"
#include "tests/replication.h"
+#include "tests/basic.h"
+#include "tests/error_conditions.h"
#include "tests/print.h"
{0, 0, 0}
};
+test_st basic_tests[] ={
+ {"init", 1, (test_callback_fn)basic_init_test},
+ {"clone", 1, (test_callback_fn)basic_clone_test},
+ {"reset", 1, (test_callback_fn)basic_reset_stack_test},
+ {"reset heap", 1, (test_callback_fn)basic_reset_heap_test},
+ {"reset stack clone", 1, (test_callback_fn)basic_reset_stack_clone_test},
+ {"reset heap clone", 1, (test_callback_fn)basic_reset_heap_clone_test},
+ {0, 0, 0}
+};
+
test_st regression_binary_vs_block[] ={
{"block add", 1, (test_callback_fn)block_add_regression},
{"binary add", 1, (test_callback_fn)binary_add_regression},
};
test_st error_conditions[] ={
- {"memcached_get_MEMCACHED_ERRNO", 0, (test_callback_fn)memcached_get_MEMCACHED_ERRNO },
- {"memcached_get_MEMCACHED_NOTFOUND", 0, (test_callback_fn)memcached_get_MEMCACHED_NOTFOUND },
- {"memcached_get_by_key_MEMCACHED_ERRNO", 0, (test_callback_fn)memcached_get_by_key_MEMCACHED_ERRNO },
- {"memcached_get_by_key_MEMCACHED_NOTFOUND", 0, (test_callback_fn)memcached_get_by_key_MEMCACHED_NOTFOUND },
+ {"memcached_get(MEMCACHED_ERRNO)", 0, (test_callback_fn)memcached_get_MEMCACHED_ERRNO },
+ {"memcached_get(MEMCACHED_NOTFOUND)", 0, (test_callback_fn)memcached_get_MEMCACHED_NOTFOUND },
+ {"memcached_get_by_key(MEMCACHED_ERRNO)", 0, (test_callback_fn)memcached_get_by_key_MEMCACHED_ERRNO },
+ {"memcached_get_by_key(MEMCACHED_NOTFOUND)", 0, (test_callback_fn)memcached_get_by_key_MEMCACHED_NOTFOUND },
+ {"memcached_get_by_key(MEMCACHED_NOTFOUND)", 0, (test_callback_fn)memcached_get_by_key_MEMCACHED_NOTFOUND },
+ {"memcached_increment(MEMCACHED_NO_SERVERS)", 0, (test_callback_fn)memcached_increment_MEMCACHED_NO_SERVERS },
{0, 0, (test_callback_fn)0}
};
{"number_options", 0, (test_callback_fn)parser_number_options_test },
{"server", 0, (test_callback_fn)server_test },
{"servers", 0, (test_callback_fn)servers_test },
+ {"prefix_key", 0, (test_callback_fn)parser_key_prefix_test },
{0, 0, (test_callback_fn)0}
};
#if 0
{"hash_sanity", 0, 0, hash_sanity},
#endif
+ {"basic", 0, 0, basic_tests},
{"hsieh_availability", 0, 0, hsieh_availability},
{"murmur_availability", 0, 0, murmur_availability},
{"block", 0, 0, tests},
#include "tests/parser.h"
#include "tests/print.h"
+enum scanner_type_t
+{
+ NIL,
+ UNSIGNED,
+ SIGNED,
+ ARRAY
+};
+
+
struct scanner_string_st {
- const char *c_ptr;
+ const char *c_str;
size_t size;
};
-test_return_t server_test(memcached_st *junk)
+static inline scanner_string_st scanner_string(const char *arg, size_t arg_size)
{
- (void)junk;
- memcached_return_t rc;
- memcached_st *memc;
- memc= memcached_create(NULL);
+ scanner_string_st local= { arg, arg_size };
+ return local;
+}
- scanner_string_st test_strings[]= {
- { STRING_WITH_LEN("--server=localhost") },
- { STRING_WITH_LEN("--server=10.0.2.1") },
- { STRING_WITH_LEN("--server=example.com") },
- { STRING_WITH_LEN("--server=localhost:30") },
- { STRING_WITH_LEN("--server=10.0.2.1:20") },
- { STRING_WITH_LEN("--server=example.com:1024") },
- { NULL, 0}
- };
-
- for (scanner_string_st *ptr= test_strings; ptr->size; ptr++)
- {
- rc= memcached_parse_options(memc, ptr->c_ptr, ptr->size);
- test_true(rc == MEMCACHED_SUCCESS);
- memcached_servers_reset(memc);
- }
+#define make_scanner_string(X) scanner_string((X), static_cast<size_t>(sizeof(X) - 1))
- memcached_free(memc);
+static struct scanner_string_st scanner_string_null= { 0, 0};
+
+struct scanner_variable_t {
+ enum scanner_type_t type;
+ struct scanner_string_st option;
+ struct scanner_string_st result;
+ test_return_t (*check_func)(memcached_st *memc, const scanner_string_st &hostname);
+};
+
+// Check and make sure the first host is what we expect it to be
+static test_return_t __check_host(memcached_st *memc, const scanner_string_st &hostname)
+{
+ memcached_server_instance_st instance=
+ memcached_server_instance_by_position(memc, 0);
+
+ test_true(instance);
+
+ const char *first_hostname = memcached_server_name(instance);
+ test_true(first_hostname);
+ test_strcmp(first_hostname, hostname.c_str);
return TEST_SUCCESS;
}
-test_return_t servers_test(memcached_st *junk)
+// Check and make sure the prefix_key is what we expect it to be
+static test_return_t __check_prefix_key(memcached_st *memc, const scanner_string_st &hostname)
{
- (void)junk;
- memcached_st *memc;
- memc= memcached_create(NULL);
+ memcached_server_instance_st instance=
+ memcached_server_instance_by_position(memc, 0);
- scanner_string_st test_strings[]= {
- { STRING_WITH_LEN("--servers=localhost:11221,localhost:11222,localhost:11223,localhost:11224,localhost:11225") },
- { STRING_WITH_LEN("--servers=a.example.com:81,localhost:82,b.example.com") },
- { STRING_WITH_LEN("--servers=localhost,localhost:80") },
- { NULL, 0}
- };
+ test_true(instance);
- for (scanner_string_st *ptr= test_strings; ptr->size; ptr++)
- {
- memcached_return_t rc;
- rc= memcached_parse_options(memc, ptr->c_ptr, ptr->size);
-
- test_true(rc == MEMCACHED_SUCCESS);
+ const char *first_hostname = memcached_server_name(instance);
+ test_true(first_hostname);
+ test_strcmp(first_hostname, hostname.c_str);
- memcached_server_fn callbacks[1];
- callbacks[0]= server_print_callback;
- memcached_server_cursor(memc, callbacks, NULL, 1);
+ return TEST_SUCCESS;
+}
- memcached_servers_reset(memc);
- }
+static test_return_t __check_IO_MSG_WATERMARK(memcached_st *memc, const scanner_string_st &value)
+{
+ uint64_t value_number;
- scanner_string_st bad_test_strings[]= {
- { STRING_WITH_LEN("-servers=localhost:11221,localhost:11222,localhost:11223,localhost:11224,localhost:11225") },
- { STRING_WITH_LEN("-- servers=a.example.com:81,localhost:82,b.example.com") },
- { STRING_WITH_LEN("--servers=localhost80") },
- { NULL, 0}
- };
+ value_number= atoll(value.c_str);
- for (scanner_string_st *ptr= bad_test_strings; ptr->size; ptr++)
- {
- memcached_return_t rc;
- rc= memcached_parse_options(memc, ptr->c_ptr, ptr->size);
+ test_true(memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_IO_MSG_WATERMARK) == value_number);
+ return TEST_SUCCESS;
+}
- test_false_with(rc == MEMCACHED_SUCCESS, ptr->c_ptr);
+static test_return_t __check_AUTO_EJECT_HOSTS(memcached_st *memc, const scanner_string_st &value)
+{
+ (void)value;
+ test_true(memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_AUTO_EJECT_HOSTS));
+ return TEST_SUCCESS;
+}
- memcached_server_fn callbacks[1];
- callbacks[0]= server_print_callback;
- memcached_server_cursor(memc, callbacks, NULL, 1);
+static test_return_t __check_CACHE_LOOKUPS(memcached_st *memc, const scanner_string_st &value)
+{
+ (void)value;
+ test_true(memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_CACHE_LOOKUPS));
+ return TEST_SUCCESS;
+}
- memcached_servers_reset(memc);
- }
+static test_return_t __check_NOREPLY(memcached_st *memc, const scanner_string_st &value)
+{
+ (void)value;
+ test_true(memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_NOREPLY));
+ return TEST_SUCCESS;
+}
- memcached_free(memc);
+static test_return_t __check_VERIFY_KEY(memcached_st *memc, const scanner_string_st &value)
+{
+ (void)value;
+ test_true(memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_VERIFY_KEY));
+ return TEST_SUCCESS;
+}
+static test_return_t __check_distribution_RANDOM(memcached_st *memc, const scanner_string_st &value)
+{
+ (void)value;
+ test_true(memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_DISTRIBUTION) == MEMCACHED_DISTRIBUTION_RANDOM);
return TEST_SUCCESS;
}
-scanner_string_st test_number_options[]= {
- { STRING_WITH_LEN("--CONNECT_TIMEOUT=456") },
- { STRING_WITH_LEN("--IO_MSG_WATERMARK=456") },
- { STRING_WITH_LEN("--IO_BYTES_WATERMARK=456") },
- { STRING_WITH_LEN("--IO_KEY_PREFETCH=456") },
- { STRING_WITH_LEN("--NUMBER_OF_REPLICAS=456") },
- { STRING_WITH_LEN("--POLL_TIMEOUT=456") },
- { STRING_WITH_LEN("--RCV_TIMEOUT=456") },
- { STRING_WITH_LEN("--RETRY_TIMEOUT=456") },
- { STRING_WITH_LEN("--SERVER_FAILURE_LIMIT=456") },
- { STRING_WITH_LEN("--SND_TIMEOUT=456") },
- { STRING_WITH_LEN("--SOCKET_RECV_SIZE=456") },
- { STRING_WITH_LEN("--SOCKET_SEND_SIZE=456") },
- { NULL, 0}
+scanner_variable_t test_server_strings[]= {
+ { ARRAY, make_scanner_string("--server=localhost"), make_scanner_string("localhost"), __check_host },
+ { ARRAY, make_scanner_string("--server=10.0.2.1"), make_scanner_string("10.0.2.1"), __check_host },
+ { ARRAY, make_scanner_string("--server=example.com"), make_scanner_string("example.com"), __check_host },
+ { ARRAY, make_scanner_string("--server=localhost:30"), make_scanner_string("localhost"), __check_host },
+ { ARRAY, make_scanner_string("--server=10.0.2.1:20"), make_scanner_string("10.0.2.1"), __check_host },
+ { ARRAY, make_scanner_string("--server=example.com:1024"), make_scanner_string("example.com"), __check_host },
+ { NIL, scanner_string_null, scanner_string_null, NULL }
};
-scanner_string_st test_boolean_options[]= {
- { STRING_WITH_LEN("--AUTO_EJECT_HOSTS") },
- { STRING_WITH_LEN("--BINARY_PROTOCOL") },
- { STRING_WITH_LEN("--BUFFER_REQUESTS") },
- { STRING_WITH_LEN("--CACHE_LOOKUPS") },
- { STRING_WITH_LEN("--CORK") },
- { STRING_WITH_LEN("--HASH_WITH_PREFIX_KEY") },
- { STRING_WITH_LEN("--KETAMA") },
- { STRING_WITH_LEN("--KETAMA_WEIGHTED") },
- { STRING_WITH_LEN("--NOREPLY") },
- { STRING_WITH_LEN("--RANDOMIZE_REPLICA_READ") },
- { STRING_WITH_LEN("--SORT_HOSTS") },
- { STRING_WITH_LEN("--SUPPORT_CAS") },
- { STRING_WITH_LEN("--TCP_NODELAY") },
- { STRING_WITH_LEN("--TCP_KEEPALIVE") },
- { STRING_WITH_LEN("--TCP_KEEPIDLE") },
- { STRING_WITH_LEN("--USE_UDP") },
- { STRING_WITH_LEN("--VERIFY_KEY") },
- { NULL, 0}
+scanner_variable_t test_servers_strings[]= {
+ { ARRAY, make_scanner_string("--servers=localhost:11221,localhost:11222,localhost:11223,localhost:11224,localhost:11225"), scanner_string_null, NULL },
+ { ARRAY, make_scanner_string("--servers=a.example.com:81,localhost:82,b.example.com"), scanner_string_null, NULL },
+ { ARRAY, make_scanner_string("--servers=localhost,localhost:80"), scanner_string_null, NULL },
+ { NIL, scanner_string_null, scanner_string_null, NULL}
};
-test_return_t parser_number_options_test(memcached_st *junk)
+
+scanner_variable_t bad_test_strings[]= {
+ { ARRAY, make_scanner_string("-servers=localhost:11221,localhost:11222,localhost:11223,localhost:11224,localhost:11225"), scanner_string_null, NULL },
+ { ARRAY, make_scanner_string("-- servers=a.example.com:81,localhost:82,b.example.com"), scanner_string_null, NULL },
+ { ARRAY, make_scanner_string("--servers=localhost+80"), scanner_string_null, NULL},
+ { NIL, scanner_string_null, scanner_string_null, NULL}
+};
+
+scanner_variable_t test_number_options[]= {
+ { ARRAY, make_scanner_string("--CONNECT_TIMEOUT=456"), scanner_string_null, NULL },
+ { ARRAY, make_scanner_string("--IO_MSG_WATERMARK=456"), make_scanner_string("456"), __check_IO_MSG_WATERMARK },
+ { ARRAY, make_scanner_string("--IO_BYTES_WATERMARK=456"), scanner_string_null, NULL },
+ { ARRAY, make_scanner_string("--IO_KEY_PREFETCH=456"), scanner_string_null, NULL },
+ { ARRAY, make_scanner_string("--NUMBER_OF_REPLICAS=456"), scanner_string_null, NULL },
+ { ARRAY, make_scanner_string("--POLL_TIMEOUT=456"), scanner_string_null, NULL },
+ { ARRAY, make_scanner_string("--RCV_TIMEOUT=456"), scanner_string_null, NULL },
+ { ARRAY, make_scanner_string("--RETRY_TIMEOUT=456"), scanner_string_null, NULL },
+ { ARRAY, make_scanner_string("--SERVER_FAILURE_LIMIT=456"), scanner_string_null, NULL },
+ { ARRAY, make_scanner_string("--SND_TIMEOUT=456"), scanner_string_null, NULL },
+ { ARRAY, make_scanner_string("--SOCKET_RECV_SIZE=456"), scanner_string_null, NULL },
+ { ARRAY, make_scanner_string("--SOCKET_SEND_SIZE=456"), scanner_string_null, NULL },
+ { NIL, scanner_string_null, scanner_string_null, NULL}
+};
+
+scanner_variable_t test_boolean_options[]= {
+ { ARRAY, make_scanner_string("--AUTO_EJECT_HOSTS"), scanner_string_null, __check_AUTO_EJECT_HOSTS },
+ { ARRAY, make_scanner_string("--BINARY_PROTOCOL"), scanner_string_null, NULL },
+ { ARRAY, make_scanner_string("--BUFFER_REQUESTS"), scanner_string_null, NULL },
+ { ARRAY, make_scanner_string("--CACHE_LOOKUPS"), scanner_string_null, __check_CACHE_LOOKUPS },
+ { ARRAY, make_scanner_string("--CORK"), scanner_string_null, NULL },
+ { ARRAY, make_scanner_string("--HASH_WITH_PREFIX_KEY"), scanner_string_null, NULL },
+ { ARRAY, make_scanner_string("--KETAMA"), scanner_string_null, NULL },
+ { ARRAY, make_scanner_string("--KETAMA_WEIGHTED"), scanner_string_null, NULL },
+ { ARRAY, make_scanner_string("--NOREPLY"), scanner_string_null, __check_NOREPLY },
+ { ARRAY, make_scanner_string("--RANDOMIZE_REPLICA_READ"), scanner_string_null, NULL },
+ { ARRAY, make_scanner_string("--SORT_HOSTS"), scanner_string_null, NULL },
+ { ARRAY, make_scanner_string("--SUPPORT_CAS"), scanner_string_null, NULL },
+ { ARRAY, make_scanner_string("--TCP_NODELAY"), scanner_string_null, NULL },
+ { ARRAY, make_scanner_string("--TCP_KEEPALIVE"), scanner_string_null, NULL },
+ { ARRAY, make_scanner_string("--TCP_KEEPIDLE"), scanner_string_null, NULL },
+ { ARRAY, make_scanner_string("--USE_UDP"), scanner_string_null, NULL },
+ { ARRAY, make_scanner_string("--VERIFY_KEY"), scanner_string_null, __check_VERIFY_KEY },
+ { NIL, scanner_string_null, scanner_string_null, NULL}
+};
+
+scanner_variable_t prefix_key_strings[]= {
+ { ARRAY, make_scanner_string("--PREFIX_KEY=foo"), make_scanner_string("foo"), __check_prefix_key },
+ { ARRAY, make_scanner_string("--PREFIX-KEY=\"foo\""), make_scanner_string("foo"), __check_prefix_key },
+ { ARRAY, make_scanner_string("--PREFIX-KEY=\"This is a very long key\""), make_scanner_string("This is a very long key"), __check_prefix_key },
+ { NIL, scanner_string_null, scanner_string_null, NULL}
+};
+
+scanner_variable_t distribution_strings[]= {
+ { ARRAY, make_scanner_string("--DISTRIBUTION=consistent"), scanner_string_null, NULL },
+ { ARRAY, make_scanner_string("--DISTRIBUTION=random"), scanner_string_null, __check_distribution_RANDOM },
+ { ARRAY, make_scanner_string("--DISTRIBUTION=modula"), scanner_string_null, NULL },
+ { NIL, scanner_string_null, scanner_string_null, NULL}
+};
+
+scanner_variable_t hash_strings[]= {
+ { ARRAY, make_scanner_string("--HASH=MD5"), scanner_string_null, NULL },
+ { ARRAY, make_scanner_string("--HASH=CRC"), scanner_string_null, NULL },
+ { ARRAY, make_scanner_string("--HASH=FNV1_64"), scanner_string_null, NULL },
+ { ARRAY, make_scanner_string("--HASH=FNV1A_64"), scanner_string_null, NULL },
+ { ARRAY, make_scanner_string("--HASH=FNV1_32"), scanner_string_null, NULL },
+ { ARRAY, make_scanner_string("--HASH=FNV1A_32"), scanner_string_null, NULL },
+ { ARRAY, make_scanner_string("--HASH=MURMUR"), scanner_string_null, NULL },
+ { ARRAY, make_scanner_string("--HASH=JENKINS"), scanner_string_null, NULL },
+ { NIL, scanner_string_null, scanner_string_null, NULL}
+};
+
+
+static test_return_t _test_option(scanner_variable_t *scanner, bool test_true= true)
{
- (void)junk;
+ (void)test_true;
memcached_st *memc;
memc= memcached_create(NULL);
- for (scanner_string_st *ptr= test_number_options; ptr->size; ptr++)
+ for (scanner_variable_t *ptr= scanner; ptr->type != NIL; ptr++)
{
memcached_return_t rc;
- rc= memcached_parse_options(memc, ptr->c_ptr, ptr->size);
- test_true_got(rc == MEMCACHED_SUCCESS, ptr->c_ptr);
+ rc= memcached_parse_options(memc, ptr->option.c_str, ptr->option.size);
+ if (test_true)
+ {
+ test_true_got(rc == MEMCACHED_SUCCESS, memcached_last_error_message(memc));
+
+ if (ptr->check_func)
+ {
+ (*ptr->check_func)(memc, ptr->result);
+ }
+ }
+ else
+ {
+ test_false_with(rc == MEMCACHED_SUCCESS, ptr->option.c_str);
+ }
+ memcached_reset(memc);
}
-
memcached_free(memc);
return TEST_SUCCESS;
}
-test_return_t parser_boolean_options_test(memcached_st *junk)
+test_return_t server_test(memcached_st *junk)
+{
+ (void)junk;
+ return _test_option(test_server_strings);
+}
+
+test_return_t servers_test(memcached_st *junk)
{
(void)junk;
- memcached_st *memc;
- memc= memcached_create(NULL);
- for (scanner_string_st *ptr= test_boolean_options; ptr->size; ptr++)
+ test_return_t rc;
+ if ((rc= _test_option(test_server_strings)) != TEST_SUCCESS)
{
- memcached_return_t rc;
- rc= memcached_parse_options(memc, ptr->c_ptr, ptr->size);
- test_true_got(rc == MEMCACHED_SUCCESS, ptr->c_ptr);
+ return rc;
}
- memcached_free(memc);
+#if 0
+ memcached_server_fn callbacks[1];
+ callbacks[0]= server_print_callback;
+ memcached_server_cursor(memc, callbacks, NULL, 1);
+#endif
+
+ if ((rc= _test_option(bad_test_strings, false)) != TEST_SUCCESS)
+ {
+ return rc;
+ }
return TEST_SUCCESS;
}
+test_return_t parser_number_options_test(memcached_st *junk)
+{
+ (void)junk;
+ return _test_option(test_number_options);
+}
+
+test_return_t parser_boolean_options_test(memcached_st *junk)
+{
+ (void)junk;
+ return _test_option(test_boolean_options);
+}
+
test_return_t behavior_parser_test(memcached_st *junk)
{
(void)junk;
test_return_t parser_hash_test(memcached_st *junk)
{
(void)junk;
- memcached_return_t rc;
- memcached_st *memc;
- memc= memcached_create(NULL);
-
- scanner_string_st test_strings[]= {
- { STRING_WITH_LEN("--HASH=MD5") },
- { STRING_WITH_LEN("--HASH=CRC") },
- { STRING_WITH_LEN("--HASH=FNV1_64") },
- { STRING_WITH_LEN("--HASH=FNV1A_64") },
- { STRING_WITH_LEN("--HASH=FNV1_32") },
- { STRING_WITH_LEN("--HASH=FNV1A_32") },
- { STRING_WITH_LEN("--HASH=HSIEH") },
- { STRING_WITH_LEN("--HASH=MURMUR") },
- { STRING_WITH_LEN("--HASH=JENKINS") },
- { NULL, 0}
- };
-
- for (scanner_string_st *ptr= test_strings; ptr->size; ptr++)
- {
- rc= memcached_parse_options(memc, ptr->c_ptr, ptr->size);
- test_true_got(rc == MEMCACHED_SUCCESS, ptr->c_ptr);
- }
-
- memcached_free(memc);
-
- return TEST_SUCCESS;
+ return _test_option(hash_strings);
}
test_return_t parser_distribution_test(memcached_st *junk)
{
(void)junk;
- memcached_return_t rc;
- memcached_st *memc;
- memc= memcached_create(NULL);
-
- scanner_string_st test_strings[]= {
- { STRING_WITH_LEN("--DISTRIBUTION=consistent") },
- { STRING_WITH_LEN("--DISTRIBUTION=random") },
- { STRING_WITH_LEN("--DISTRIBUTION=modula") },
- { NULL, 0}
- };
-
- for (scanner_string_st *ptr= test_strings; ptr->size; ptr++)
- {
- rc= memcached_parse_options(memc, ptr->c_ptr, ptr->size);
- test_true_got(rc == MEMCACHED_SUCCESS, ptr->c_ptr);
- }
-
- memcached_free(memc);
+ return _test_option(distribution_strings);
+}
- return TEST_SUCCESS;
+test_return_t parser_key_prefix_test(memcached_st *junk)
+{
+ (void)junk;
+ return _test_option(distribution_strings);
}
LIBTEST_INTERNAL_API
test_return_t parser_boolean_options_test(memcached_st *junk);
+LIBTEST_INTERNAL_API
+test_return_t parser_key_prefix_test(memcached_st *junk);
+
#ifdef __cplusplus
}
#endif