diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index 9971befdd26c6776890f02829616099befa2d2eb..10af063a50dee9642815f408db5a20389bfc9e9a 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -1733,6 +1733,7 @@ virTimeStringThenRaw; virTypedParameterArrayClear; virTypedParameterArrayValidate; virTypedParameterAssign; +virTypedParameterAssignFromStr; # viruri.h diff --git a/src/util/virtypedparam.c b/src/util/virtypedparam.c index d68d79f2fb01dd9387b2d21467aee5e3cb5918b4..3d920a23aaa69f7d4959411ec21352c79a207c12 100644 --- a/src/util/virtypedparam.c +++ b/src/util/virtypedparam.c @@ -181,3 +181,100 @@ cleanup: va_end(ap); return ret; } + +/* Assign name, type, and convert the argument from a const string. + * In case of a string, the string is copied. + * Return 0 on success, -1 after an error message on failure. */ +int +virTypedParameterAssignFromStr(virTypedParameterPtr param, const char *name, + int type, const char *val) +{ + int ret = -1; + + if (!val) { + virReportError(VIR_ERR_INVALID_ARG, _("NULL value for field '%s'"), + name); + goto cleanup; + } + + if (virStrcpyStatic(param->field, name) == NULL) { + virReportError(VIR_ERR_INTERNAL_ERROR, _("Field name '%s' too long"), + name); + goto cleanup; + } + + param->type = type; + switch (type) { + case VIR_TYPED_PARAM_INT: + if (virStrToLong_i(val, NULL, 10, ¶m->value.i) < 0) { + virReportError(VIR_ERR_INVALID_ARG, + _("Invalid value for field '%s': expected int"), + name); + goto cleanup; + } + break; + case VIR_TYPED_PARAM_UINT: + if (virStrToLong_ui(val, NULL, 10, ¶m->value.ui) < 0) { + virReportError(VIR_ERR_INVALID_ARG, + _("Invalid value for field '%s': " + "expected unsigned int"), + name); + goto cleanup; + } + break; + case VIR_TYPED_PARAM_LLONG: + if (virStrToLong_ll(val, NULL, 10, ¶m->value.l) < 0) { + virReportError(VIR_ERR_INVALID_ARG, + _("Invalid value for field '%s': " + "expected long long"), + name); + goto cleanup; + } + break; + case VIR_TYPED_PARAM_ULLONG: + if (virStrToLong_ull(val, NULL, 10, ¶m->value.ul) < 0) { + virReportError(VIR_ERR_INVALID_ARG, + _("Invalid value for field '%s': " + "expected unsigned long long"), + name); + goto cleanup; + } + break; + case VIR_TYPED_PARAM_DOUBLE: + if (virStrToDouble(val, NULL, ¶m->value.d) < 0) { + virReportError(VIR_ERR_INVALID_ARG, + _("Invalid value for field '%s': " + "expected double"), + name); + goto cleanup; + } + break; + case VIR_TYPED_PARAM_BOOLEAN: + if (STRCASEEQ(val, "true") || + STREQ(val, "1")) { + param->value.b = true; + } else if (STRCASEEQ(val, "false") || + STREQ(val, "0")) { + param->value.b = false; + } else { + virReportError(VIR_ERR_INVALID_ARG, + _("Invalid boolean value for field '%s'"), name); + goto cleanup; + } + break; + case VIR_TYPED_PARAM_STRING: + if (!(param->value.s = strdup(val))) { + virReportOOMError(); + goto cleanup; + } + break; + default: + virReportError(VIR_ERR_INTERNAL_ERROR, + _("unexpected type %d for field %s"), type, name); + goto cleanup; + } + + ret = 0; +cleanup: + return ret; +} diff --git a/src/util/virtypedparam.h b/src/util/virtypedparam.h index f117b84fff76d98b3e725fdbcde67c4b555251ee..581201cbb32461ebd94ddf6c01cbb16bc8bafcc0 100644 --- a/src/util/virtypedparam.h +++ b/src/util/virtypedparam.h @@ -35,4 +35,10 @@ int virTypedParameterAssign(virTypedParameterPtr param, const char *name, int type, /* TYPE arg */ ...) ATTRIBUTE_RETURN_CHECK; +int virTypedParameterAssignFromStr(virTypedParameterPtr param, + const char *name, + int type, + const char *val) + ATTRIBUTE_RETURN_CHECK; + #endif /* __VIR_TYPED_PARAM_H */