memc= memcached_create(NULL);
- memcached_return_t rc= memcached_parse_options(memc, argv[1], strlen(argv[1]));
+ memcached_return_t rc= memcached_parse_configuration(memc, argv[1], strlen(argv[1]));
memcached_free(memc);
if (rc != MEMCACHED_SUCCESS)
array->root= memc;
array->size= str_length -1; // We don't count the NULL ending
memcpy(array->c_str, str, str_length);
- array->c_str[str_length +1]= 0;
+ array->c_str[str_length]= 0;
return array;
}
+memcached_string_t memcached_array_to_string(memcached_array_st *array)
+{
+ memcached_string_t tmp;
+ tmp.c_str= array->c_str;
+ tmp.size= array->size;
+
+ return tmp;
+}
+
void memcached_array_free(memcached_array_st *array)
{
if (! array)
LIBMEMCACHED_LOCAL
const char *memcached_array_string(memcached_array_st *array);
+LIBMEMCACHED_LOCAL
+memcached_string_t memcached_array_to_string(memcached_array_st *array);
+
#ifdef __cplusplus
-#define memcached_print_array(X) static_cast<int>(memcached_array_size(X)), memcached_array_string(X)
-#else
-#define memcached_print_array(X) (int)memcached_array_size((X)), memcached_array_string((X))
+} // extern "C"
#endif
-
#ifdef __cplusplus
-} // extern "C"
+#define memcached_print_array(X) static_cast<int>(memcached_array_size(X)), memcached_array_string(X)
+#define memcached_param_array(X) memcached_array_string(X), memcached_array_size(X)
+#else
+#define memcached_print_array(X) (int)memcached_array_size((X)), memcached_array_string((X))
+#define memcached_param_array(X) memcached_array_string(X), memcached_array_size(X)
#endif
}
break;
case MEMCACHED_BEHAVIOR_LOAD_FROM_FILE:
- ptr->flags.load_from_file= set_flag(data);
- break;
+ return MEMCACHED_FAILURE;
case MEMCACHED_BEHAVIOR_MAX:
default:
/* Shouldn't get here */
case MEMCACHED_BEHAVIOR_TCP_KEEPALIVE:
return ptr->flags.tcp_keepalive;
case MEMCACHED_BEHAVIOR_LOAD_FROM_FILE:
- return ptr->flags.load_from_file;
+ return ptr->configure.filename ? true : false;
case MEMCACHED_BEHAVIOR_MAX:
default:
WATCHPOINT_ASSERT(0); /* Programming mistake if it gets this far */
.use_udp= false,
.verify_key= false,
.tcp_keepalive= false,
- .load_from_file= false,
.ping_service= false
}
};
self->error_messages= NULL;
self->prefix_key= NULL;
+ self->configure.filename= NULL;
return true;
}
#endif
}
+ if (release_st)
+ {
+ memcached_array_free(ptr->configure.filename);
+ ptr->configure.filename= NULL;
+ }
+
if (memcached_is_allocated(ptr) && release_st)
{
libmemcached_free(ptr, ptr);
if (! self)
return NULL;
- memcached_parse_options(self, string, length);
+ memcached_return_t rc;
+ if ((rc= memcached_parse_configuration(self, string, length)) != MEMCACHED_SUCCESS)
+ {
+ return self;
+ }
+
+ if (memcached_parse_filename(self))
+ {
+ rc= memcached_parse_configure_file(self, memcached_parse_filename(self), memcached_parse_filename_length(self));
+ }
return self;
}
-void memcached_reset(memcached_st *ptr)
+memcached_return_t memcached_reset(memcached_st *ptr)
{
WATCHPOINT_ASSERT(ptr);
if (! ptr)
- return;
+ return MEMCACHED_INVALID_ARGUMENTS;
bool stored_is_allocated= memcached_is_allocated(ptr);
_free(ptr, false);
memcached_create(ptr);
memcached_set_allocated(ptr, stored_is_allocated);
+
+ if (ptr->configure.filename)
+ {
+ return memcached_parse_configure_file(ptr, memcached_param_array(ptr->configure.filename));
+ }
+
+ return MEMCACHED_SUCCESS;
}
void memcached_servers_reset(memcached_st *ptr)
bool use_udp:1;
bool verify_key:1;
bool tcp_keepalive:1;
- bool load_from_file:1;
bool ping_service:1;
} flags;
memcached_server_distribution_t distribution;
struct memcached_sasl_st sasl;
struct memcached_error_st *error_messages;
struct memcached_array_st *prefix_key;
+ struct {
+ struct memcached_array_st *filename;
+ } configure;
struct {
bool is_allocated:1;
} options;
void memcached_free(memcached_st *ptr);
LIBMEMCACHED_API
-void memcached_reset(memcached_st *ptr);
+memcached_return_t memcached_reset(memcached_st *ptr);
LIBMEMCACHED_API
void memcached_reset_last_disconnected_server(memcached_st *ptr);
int libmemcached_parse(type_st *, yyscan_t *);
-memcached_return_t memcached_check_options(const char *option_string, size_t length, const char *error_buffer, size_t error_buffer_size)
+const char *memcached_parse_filename(memcached_st *memc)
{
- memcached_st memc;
- if (! memcached_create(&memc))
+ return memcached_array_string(memc->configure.filename);
+}
+
+size_t memcached_parse_filename_length(memcached_st *memc)
+{
+ return memcached_array_size(memc->configure.filename);
+}
+
+static memcached_return_t _parse_file_options(memcached_st *self, memcached_string_t *filename)
+{
+ FILE *fp= fopen(filename->c_str, "r");
+ if (! fp)
+ return memcached_set_errno(self, errno, NULL);
+
+ char buffer[BUFSIZ];
+ memcached_return_t rc= MEMCACHED_INVALID_ARGUMENTS;
+ while (fgets(buffer, sizeof(buffer), fp))
+ {
+ size_t length= strlen(buffer);
+
+ if (length == 1 and buffer[0] == '\n')
+ continue;
+
+ rc= memcached_parse_configuration(self, buffer, length);
+ if (rc != MEMCACHED_SUCCESS)
+ break;
+ }
+ fclose(fp);
+
+ return rc;
+}
+
+memcached_return_t libmemcached_check_configuration(const char *option_string, size_t length, const char *error_buffer, size_t error_buffer_size)
+{
+ memcached_st memc, *memc_ptr;
+
+ if (! (memc_ptr= memcached_create(&memc)))
return MEMCACHED_MEMORY_ALLOCATION_FAILURE;
- memcached_return_t rc= memcached_parse_options(&memc, option_string, length);
+ memcached_return_t rc= memcached_parse_configuration(memc_ptr, option_string, length);
if (rc != MEMCACHED_SUCCESS && error_buffer && error_buffer_size)
{
- strncpy(error_buffer, error_buffer_size, memcached_last_error_message(&memc));
+ strncpy(error_buffer, error_buffer_size, memcached_last_error_message(memc_ptr));
}
- memcached_free(&memc);
+ if (rc== MEMCACHED_SUCCESS && memcached_behavior_get(memc_ptr, MEMCACHED_BEHAVIOR_LOAD_FROM_FILE))
+ {
+ memcached_string_t filename= memcached_array_to_string(memc_ptr->configure.filename);
+ rc= _parse_file_options(memc_ptr, &filename);
+
+ if (rc != MEMCACHED_SUCCESS && error_buffer && error_buffer_size)
+ {
+ strncpy(error_buffer, error_buffer_size, memcached_last_error_message(memc_ptr));
+ }
+ }
+
+ memcached_free(memc_ptr);
return rc;
}
-memcached_return_t memcached_parse_options(memcached_st *self, char const *option_string, size_t length)
+memcached_return_t memcached_parse_configuration(memcached_st *self, char const *option_string, size_t length)
{
type_st pp;
-
memset(&pp, 0, sizeof(type_st));
WATCHPOINT_ASSERT(self);
if (! self)
- return MEMCACHED_INVALID_ARGUMENTS;
+ return memcached_set_error(self, MEMCACHED_INVALID_ARGUMENTS, NULL);
pp.buf= option_string;
pp.memc= self;
return MEMCACHED_SUCCESS;
}
-memcached_return_t memcached_parse_file_options(memcached_st *self, const char *filename)
+void memcached_set_configuration_file(memcached_st *self, const char *filename, size_t filename_length)
{
- FILE *fp= fopen(filename, "r");
-
- if (! fp)
- return memcached_set_errno(self, errno, NULL);
+ memcached_array_free(self->configure.filename);
+ self->configure.filename= memcached_strcpy(self, filename, filename_length);
+}
- char buffer[BUFSIZ];
- memcached_return_t rc= MEMCACHED_INVALID_ARGUMENTS;
- while (fgets(buffer, sizeof(buffer), fp))
- {
- size_t length= strlen(buffer);
-
- if (length == 1 and buffer[0] == '\n')
- continue;
+memcached_return_t memcached_parse_configure_file(memcached_st *self, const char *filename, size_t filename_length)
+{
+ if (! self)
+ return memcached_set_error(self, MEMCACHED_INVALID_ARGUMENTS, NULL);
- rc= memcached_parse_options(self, buffer, length);
- if (rc != MEMCACHED_SUCCESS)
- break;
- }
- fclose(fp);
+ if (! filename || filename_length == 0)
+ return memcached_set_error(self, MEMCACHED_INVALID_ARGUMENTS, NULL);
+
+ memcached_string_t tmp;
+ tmp.c_str= filename;
+ tmp.size= filename_length;
- return rc;
+ return _parse_file_options(self, &tmp);
}
#endif
LIBMEMCACHED_API
- memcached_return_t memcached_check_options(const char *option_string, size_t length, const char *error_buffer, size_t error_buffer_size);
+ memcached_return_t libmemcached_check_configuration(const char *option_string, size_t length, const char *error_buffer, size_t error_buffer_size);
LIBMEMCACHED_API
- memcached_return_t memcached_parse_options(memcached_st *ptr, const char *option_string, size_t length);
+ memcached_return_t memcached_parse_configuration(memcached_st *ptr, const char *option_string, size_t length);
LIBMEMCACHED_API
- memcached_return_t memcached_parse_file_options(memcached_st *ptr, const char *filename);
+ memcached_return_t memcached_parse_configure_file(memcached_st *ptr, const char *filename, size_t filename_length);
+
+LIBMEMCACHED_API
+ void memcached_set_configuration_file(memcached_st *self, const char *filename, size_t filename_length);
+
+LIBMEMCACHED_API
+ const char *memcached_parse_filename(memcached_st *memc);
+
+LIBMEMCACHED_LOCAL
+ size_t memcached_parse_filename_length(memcached_st *memc);
#ifdef __cplusplus
}
%start statement
%verbose
+%token COMMENT
+%token CONFIGURE_FILE
+%token EMPTY_LINE
%token SERVER
%token SERVERS
%token UNKNOWN
-%token COMMENT
-%token EMPTY_LINE
%token DASH_OPTION
| SERVERS '=' server_list
{
}
+ | CONFIGURE_FILE '=' string
+ {
+ memcached_set_configuration_file(parser->memc, $3.c_str, $3.length);
+ }
| behaviors
;
BUFFER-REQUESTS { return BUFFER_REQUESTS; }
CACHE_LOOKUPS { return CACHE_LOOKUPS; }
CACHE-LOOKUPS { return CACHE_LOOKUPS; }
+CONFIGURE_FILE { return CONFIGURE_FILE; }
+CONFIGURE-FILE { return CONFIGURE_FILE; }
CONNECT_TIMEOUT { return CONNECT_TIMEOUT; }
CONNECT-TIMEOUT { return CONNECT_TIMEOUT; }
CORK { return _CORK; }
*
*/
-#ifndef __LIBMEMCACHED_PARSE_H__
-#define __LIBMEMCACHED_PARSE_H__
+#pragma once
#ifdef __cplusplus
extern "C" {
#ifdef __cplusplus
}
#endif
-
-#endif /* __LIBMEMCACHED_PARSE_H__ */
test_st parser_tests[] ={
{"behavior", 0, (test_callback_fn)behavior_parser_test },
{"boolean_options", 0, (test_callback_fn)parser_boolean_options_test },
+ {"configure_file", 0, (test_callback_fn)memcached_create_with_options_with_filename },
{"distribtions", 0, (test_callback_fn)parser_distribution_test },
{"hash", 0, (test_callback_fn)parser_hash_test },
- {"memcached_check_options", 0, (test_callback_fn)memcached_check_options_test },
- {"memcached_parse_file_options", 0, (test_callback_fn)memcached_parse_file_options_test },
+ {"libmemcached_check_configuration", 0, (test_callback_fn)libmemcached_check_configuration_test },
+ {"libmemcached_check_configuration_with_filename", 0, (test_callback_fn)libmemcached_check_configuration_with_filename_test },
+ {"memcached_parse_configure_file", 0, (test_callback_fn)memcached_parse_configure_file_test },
{"number_options", 0, (test_callback_fn)parser_number_options_test },
{"prefix_key", 0, (test_callback_fn)parser_key_prefix_test },
{"server", 0, (test_callback_fn)server_test },
for (scanner_variable_t *ptr= scanner; ptr->type != NIL; ptr++)
{
memcached_return_t rc;
- rc= memcached_parse_options(memc, ptr->option.c_str, ptr->option.size);
+ rc= memcached_parse_configuration(memc, ptr->option.c_str, ptr->option.size);
if (test_true)
{
test_true_got(rc == MEMCACHED_SUCCESS, memcached_last_error_message(memc));
return _test_option(distribution_strings);
}
-test_return_t memcached_parse_file_options_test(memcached_st *junk)
+test_return_t memcached_parse_configure_file_test(memcached_st *junk)
{
(void)junk;
memcached_st memc;
test_true(memc_ptr);
- memcached_return_t rc= memcached_parse_file_options(memc_ptr, "support/example.cnf");
- test_true_got(rc == MEMCACHED_SUCCESS, rc == MEMCACHED_INVALID_ARGUMENTS ? memcached_last_error_message(&memc) : memcached_strerror(NULL, rc));
+ memcached_return_t rc= memcached_parse_configure_file(memc_ptr, memcached_string_with_size("support/example.cnf"));
+ test_true_got(rc == MEMCACHED_SUCCESS, memcached_last_error_message(memc_ptr) ? memcached_last_error_message(memc_ptr) : memcached_strerror(NULL, rc));
memcached_free(memc_ptr);
return TEST_SUCCESS;
}
-test_return_t memcached_check_options_test(memcached_st *junk)
+test_return_t memcached_create_with_options_with_filename(memcached_st *junk)
+{
+ (void)junk;
+
+ memcached_st *memc_ptr;
+ memc_ptr= memcached_create_with_options(STRING_WITH_LEN("--CONFIGURE-FILE=\"support/example.cnf\""));
+ test_true(memc_ptr);
+ memcached_free(memc_ptr);
+
+ return TEST_SUCCESS;
+}
+
+test_return_t libmemcached_check_configuration_with_filename_test(memcached_st *junk)
+{
+ (void)junk;
+ memcached_return_t rc;
+
+ rc= libmemcached_check_configuration(STRING_WITH_LEN("--CONFIGURE-FILE=\"support/example.cnf\""), NULL, 0);
+ test_true(rc == MEMCACHED_SUCCESS);
+
+ rc= libmemcached_check_configuration(STRING_WITH_LEN("--CONFIGURE-FILE=support/example.cnf"), NULL, 0);
+ test_false(rc == MEMCACHED_SUCCESS);
+
+ rc= libmemcached_check_configuration(STRING_WITH_LEN("--CONFIGURE-FILE=\"bad-path/example.cnf\""), NULL, 0);
+ test_true_got(rc == MEMCACHED_ERRNO, memcached_strerror(NULL, rc));
+
+ return TEST_SUCCESS;
+}
+
+test_return_t libmemcached_check_configuration_test(memcached_st *junk)
{
(void)junk;
memcached_return_t rc;
- rc= memcached_check_options(STRING_WITH_LEN("--server=localhost"), NULL, 0);
+ rc= libmemcached_check_configuration(STRING_WITH_LEN("--server=localhost"), NULL, 0);
test_true(rc == MEMCACHED_SUCCESS);
- rc= memcached_check_options(STRING_WITH_LEN("--dude=localhost"), NULL, 0);
+ rc= libmemcached_check_configuration(STRING_WITH_LEN("--dude=localhost"), NULL, 0);
test_false(rc == MEMCACHED_SUCCESS);
test_true(rc == MEMCACHED_PARSE_ERROR);
test_return_t parser_key_prefix_test(memcached_st *junk);
LIBTEST_INTERNAL_API
-test_return_t memcached_parse_file_options_test(memcached_st *junk);
+test_return_t memcached_parse_configure_file_test(memcached_st *junk);
LIBTEST_INTERNAL_API
- test_return_t memcached_check_options_test(memcached_st *junk);
+ test_return_t libmemcached_check_configuration_test(memcached_st *junk);
LIBTEST_INTERNAL_API
test_return_t memcached_create_with_options_test(memcached_st *junk);
+LIBTEST_INTERNAL_API
+ test_return_t memcached_create_with_options_with_filename(memcached_st *junk);
+
+LIBTEST_INTERNAL_API
+ test_return_t libmemcached_check_configuration_with_filename_test(memcached_st *junk);
+
#ifdef __cplusplus
}
#endif