From 5a4bd047e5db46c6f9e8afa3a4aadebe349df3e6 Mon Sep 17 00:00:00 2001 From: Vladislav Shpilevoy <v.shpilevoy@tarantool.org> Date: Wed, 13 Sep 2017 12:49:43 +0300 Subject: [PATCH] Introduce opt_strptr for long string options Needed for #2754 --- src/box/alter.cc | 30 +++++++++++++++++++++++------- src/box/opt_def.c | 1 + src/box/opt_def.h | 1 + 3 files changed, 25 insertions(+), 7 deletions(-) diff --git a/src/box/alter.cc b/src/box/alter.cc index 573339e6ae..613aec3b48 100644 --- a/src/box/alter.cc +++ b/src/box/alter.cc @@ -174,12 +174,14 @@ index_def_check_tuple(const struct tuple *tuple, bool *is_166plus) } static int -opt_set(void *opts, const struct opt_def *def, const char **val) +opt_set(void *opts, const struct opt_def *def, const char **val, + struct region *region) { int64_t ival; double dval; uint32_t str_len; const char *str; + char *ptr; char *opt = ((char *) opts) + def->offset; switch (def->type) { case OPT_BOOL: @@ -205,6 +207,20 @@ opt_set(void *opts, const struct opt_def *def, const char **val) memcpy(opt, str, str_len); opt[str_len] = '\0'; break; + case OPT_STRPTR: + if (mp_typeof(**val) != MP_STR) + return -1; + str = mp_decode_str(val, &str_len); + if (str_len > 0) { + ptr = (char *) region_alloc_xc(region, str_len + 1); + memcpy(ptr, str, str_len); + ptr[str_len] = '\0'; + assert (strlen(ptr) == str_len); + } else { + ptr = NULL; + } + *(const char **)opt = ptr; + break; case OPT_ENUM: if (mp_typeof(**val) != MP_STR) return -1; @@ -236,7 +252,7 @@ opt_set(void *opts, const struct opt_def *def, const char **val) static void opts_parse_key(void *opts, const struct opt_def *reg, const char *key, uint32_t key_len, const char **data, uint32_t errcode, - uint32_t field_no) + uint32_t field_no, struct region *region) { char errmsg[DIAG_ERRMSG_MAX]; bool found = false; @@ -245,7 +261,7 @@ opts_parse_key(void *opts, const struct opt_def *reg, const char *key, memcmp(key, def->name, key_len) != 0) continue; - if (opt_set(opts, def, data) != 0) { + if (opt_set(opts, def, data, region) != 0) { snprintf(errmsg, sizeof(errmsg), "'%.*s' must be %s", key_len, key, opt_type_strs[def->type]); tnt_raise(ClientError, errcode, field_no, errmsg); @@ -266,7 +282,7 @@ opts_parse_key(void *opts, const struct opt_def *reg, const char *key, */ static void opts_decode(void *opts, const struct opt_def *reg, const char *map, - uint32_t errcode, uint32_t field_no) + uint32_t errcode, uint32_t field_no, struct region *region) { assert(mp_typeof(*map) == MP_MAP); @@ -283,7 +299,7 @@ opts_decode(void *opts, const struct opt_def *reg, const char *map, uint32_t key_len; const char *key = mp_decode_str(&map, &key_len); opts_parse_key(opts, reg, key, key_len, &map, errcode, - field_no); + field_no, region); } } @@ -296,7 +312,7 @@ index_opts_decode(struct index_opts *opts, const char *map) { index_opts_create(opts); opts_decode(opts, index_opts_reg, map, ER_WRONG_INDEX_OPTIONS, - BOX_INDEX_FIELD_OPTS); + BOX_INDEX_FIELD_OPTS, NULL); if (opts->distance == rtree_index_distance_type_MAX) { tnt_raise(ClientError, ER_WRONG_INDEX_OPTIONS, BOX_INDEX_FIELD_OPTS, "distance must be either "\ @@ -422,7 +438,7 @@ space_opts_decode(struct space_opts *opts, const char *data) } } else { opts_decode(opts, space_opts_reg, data, ER_WRONG_SPACE_OPTIONS, - BOX_SPACE_FIELD_OPTS); + BOX_SPACE_FIELD_OPTS, NULL); } } diff --git a/src/box/opt_def.c b/src/box/opt_def.c index 5fc4e698e1..3203945347 100644 --- a/src/box/opt_def.c +++ b/src/box/opt_def.c @@ -36,5 +36,6 @@ const char *opt_type_strs[] = { /* [OPT_INT] = */ "integer", /* [OPT_FLOAT] = */ "float", /* [OPT_STR] = */ "string", + /* [OPT_STRPTR] = */ "string", /* [OPT_ENUM] = */ "enum", }; diff --git a/src/box/opt_def.h b/src/box/opt_def.h index 73dc4ce48d..e858f7bbbd 100644 --- a/src/box/opt_def.h +++ b/src/box/opt_def.h @@ -39,6 +39,7 @@ enum opt_type { OPT_INT, /* int64_t */ OPT_FLOAT, /* double */ OPT_STR, /* char[] */ + OPT_STRPTR, /* char* */ OPT_ENUM, /* enum */ opt_type_MAX, }; -- GitLab