Mercurial > libjeffpc
view nvl_convert.c @ 800:299dffade145
buffer: use the common buffer test string for read-only tests
Signed-off-by: Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
author | Josef 'Jeff' Sipek <jeffpc@josefsipek.net> |
---|---|
date | Fri, 03 Apr 2020 15:11:57 -0400 |
parents | b1e4c7607050 |
children |
line wrap: on
line source
/* * Copyright (c) 2014-2017 Josef 'Jeff' Sipek <jeffpc@josefsipek.net> * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ #include <jeffpc/nvl.h> /* * Check if a condition is true. Returns: * * 0 if true * -EBUSY if false * -EINVAL if args are wrong */ static int check_condition_str(struct str *str, enum nvcvtcond cond) { switch (cond) { case NVCVT_COND_ALWAYS: return 0; case NVCVT_COND_STR_EMPTY: return str_len(str) ? -EBUSY : 0; } return -EINVAL; } static int cvt_string(struct nvlist *nvl, const struct nvpair *pair, enum val_type tgt, enum nvcvtcond cond) { const char *name = nvpair_name(pair); struct str *str; uint64_t intval; int ret = -ENOTSUP; ASSERT3U(nvpair_type(pair), ==, VT_STR); str = nvpair_value_str(pair); if (IS_ERR(str)) { VERIFY3S(PTR_ERR(str), !=, -ENOENT); VERIFY3S(PTR_ERR(str), !=, -ERANGE); return PTR_ERR(str); } /* check if the specified condition is true */ ret = check_condition_str(str, cond); if (ret != 0) { str_putref(str); return (ret == -EBUSY) ? 0 : ret; } switch (tgt) { case VT_ARRAY: case VT_BLOB: case VT_BOOL: case VT_SYM: case VT_CONS: case VT_CHAR: ret = -ENOTSUP; break; case VT_INT: ret = str2u64(str_cstr(str), &intval); if (!ret) ret = nvl_set_int(nvl, name, intval); break; case VT_NULL: ret = nvl_set_null(nvl, name); break; case VT_NVL: ret = -ENOTSUP; break; case VT_STR: /* nothing to do */ ret = 0; break; } str_putref(str); return ret; } #define CHECK_ERROR(e, cvtall) \ ((!(cvtall) && (e)) || \ ((cvtall) && ((e) == -ENOTSUP))) int nvl_convert(struct nvlist *nvl, const struct nvl_convert_info *table, bool convert_all) { /* * If we weren't given a table, we have nothing to do. */ if (!table) return 0; for (; table->name; table++) { const struct nvpair *pair; int ret = -ENOTSUP; pair = nvl_lookup(nvl, table->name); if (IS_ERR(pair)) { ret = PTR_ERR(pair); if ((ret == -ENOENT) || !CHECK_ERROR(ret, convert_all)) continue; return ret; } switch (nvpair_type(pair)) { case VT_ARRAY: case VT_BLOB: case VT_BOOL: case VT_INT: case VT_NULL: case VT_NVL: case VT_SYM: case VT_CONS: case VT_CHAR: return -ENOTSUP; case VT_STR: ret = cvt_string(nvl, pair, table->tgt_type, table->cond); break; } if (CHECK_ERROR(ret, convert_all)) return ret; } return 0; }