static void start_list(Visitor *v, const char *name, GenericList **list, size_t size, Error **errp) { StringInputVisitor *siv = to_siv(v); /* We don't support visits without a list */ assert(list); if (parse_str(siv, name, errp) < 0) { *list = NULL; return; } siv->cur_range = g_list_first(siv->ranges); if (siv->cur_range) { Range *r = siv->cur_range->data; if (r) { siv->cur = r->begin; } *list = g_malloc0(size); } else { *list = NULL; } }
static GenericList *next_list(Visitor *v, GenericList *tail, size_t size) { StringInputVisitor *siv = to_siv(v); Range *r; if (!siv->ranges || !siv->cur_range) { return NULL; } r = siv->cur_range->data; if (!r) { return NULL; } if (!range_contains(r, siv->cur)) { siv->cur_range = g_list_next(siv->cur_range); if (!siv->cur_range) { return NULL; } r = siv->cur_range->data; if (!r) { return NULL; } siv->cur = range_lob(r); } tail->next = g_malloc0(size); return tail->next; }
static GenericList *next_list(Visitor *v, GenericList *tail, size_t size) { StringInputVisitor *siv = to_siv(v); Range *r; if (!siv->ranges || !siv->cur_range) { return NULL; } r = siv->cur_range->data; if (!r) { return NULL; } if (siv->cur < r->begin || siv->cur >= r->end) { siv->cur_range = g_list_next(siv->cur_range); if (!siv->cur_range) { return NULL; } r = siv->cur_range->data; if (!r) { return NULL; } siv->cur = r->begin; } tail->next = g_malloc0(size); return tail->next; }
static void parse_type_str(Visitor *v, const char *name, char **obj, Error **errp) { StringInputVisitor *siv = to_siv(v); *obj = g_strdup(siv->string); }
static void check_list(Visitor *v, Error **errp) { const StringInputVisitor *siv = to_siv(v); Range *r; GList *cur_range; if (!siv->ranges || !siv->cur_range) { return; } r = siv->cur_range->data; if (!r) { return; } if (!range_contains(r, siv->cur)) { cur_range = g_list_next(siv->cur_range); if (!cur_range) { return; } r = cur_range->data; if (!r) { return; } } error_setg(errp, "Range contains too many values"); }
static void string_input_free(Visitor *v) { StringInputVisitor *siv = to_siv(v); g_list_foreach(siv->ranges, free_range, NULL); g_list_free(siv->ranges); g_free(siv); }
static void parse_optional(Visitor *v, const char *name, bool *present) { StringInputVisitor *siv = to_siv(v); if (!siv->string) { *present = false; return; } *present = true; }
static void parse_type_str(Visitor *v, const char *name, char **obj, Error **errp) { StringInputVisitor *siv = to_siv(v); if (siv->string) { *obj = g_strdup(siv->string); } else { error_setg(errp, QERR_INVALID_PARAMETER_TYPE, name ? name : "null", "string"); } }
static void start_list(Visitor *v, const char *name, Error **errp) { StringInputVisitor *siv = to_siv(v); parse_str(siv, errp); siv->cur_range = g_list_first(siv->ranges); if (siv->cur_range) { Range *r = siv->cur_range->data; if (r) { siv->cur = r->begin; } } }
static void parse_type_size(Visitor *v, const char *name, uint64_t *obj, Error **errp) { StringInputVisitor *siv = to_siv(v); Error *err = NULL; uint64_t val; parse_option_size(name, siv->string, &val, &err); if (err) { error_propagate(errp, err); return; } *obj = val; }
static void parse_type_number(Visitor *v, const char *name, double *obj, Error **errp) { StringInputVisitor *siv = to_siv(v); char *endp = (char *) siv->string; double val; errno = 0; val = strtod(siv->string, &endp); if (errno || endp == siv->string || *endp) { error_setg(errp, QERR_INVALID_PARAMETER_TYPE, name ? name : "null", "number"); return; } *obj = val; }
static void parse_type_int64(Visitor *v, const char *name, int64_t *obj, Error **errp) { StringInputVisitor *siv = to_siv(v); if (!siv->string) { error_setg(errp, QERR_INVALID_PARAMETER_TYPE, name ? name : "null", "integer"); return; } if (parse_str(siv, name, errp) < 0) { return; } if (!siv->ranges) { goto error; } if (!siv->cur_range) { Range *r; siv->cur_range = g_list_first(siv->ranges); if (!siv->cur_range) { goto error; } r = siv->cur_range->data; if (!r) { goto error; } siv->cur = r->begin; } *obj = siv->cur; siv->cur++; return; error: error_setg(errp, QERR_INVALID_PARAMETER_VALUE, name ? name : "null", "an int64 value or range"); }
static void parse_type_size(Visitor *v, const char *name, uint64_t *obj, Error **errp) { StringInputVisitor *siv = to_siv(v); Error *err = NULL; uint64_t val; if (siv->string) { parse_option_size(name, siv->string, &val, &err); } else { error_setg(errp, QERR_INVALID_PARAMETER_TYPE, name ? name : "null", "size"); return; } if (err) { error_propagate(errp, err); return; } *obj = val; }
static void parse_type_bool(Visitor *v, const char *name, bool *obj, Error **errp) { StringInputVisitor *siv = to_siv(v); if (!strcasecmp(siv->string, "on") || !strcasecmp(siv->string, "yes") || !strcasecmp(siv->string, "true")) { *obj = true; return; } if (!strcasecmp(siv->string, "off") || !strcasecmp(siv->string, "no") || !strcasecmp(siv->string, "false")) { *obj = false; return; } error_setg(errp, QERR_INVALID_PARAMETER_TYPE, name ? name : "null", "boolean"); }
static GenericList *next_list(Visitor *v, GenericList **list, size_t size) { StringInputVisitor *siv = to_siv(v); GenericList **link; Range *r; if (!siv->ranges || !siv->cur_range) { return NULL; } r = siv->cur_range->data; if (!r) { return NULL; } if (siv->cur < r->begin || siv->cur >= r->end) { siv->cur_range = g_list_next(siv->cur_range); if (!siv->cur_range) { return NULL; } r = siv->cur_range->data; if (!r) { return NULL; } siv->cur = r->begin; } if (siv->head) { link = list; siv->head = false; } else { link = &(*list)->next; } *link = g_malloc0(size); return *link; }
static void end_list(Visitor *v) { StringInputVisitor *siv = to_siv(v); siv->head = true; }
static void end_list(Visitor *v, void **obj) { StringInputVisitor *siv = to_siv(v); assert(siv->list == obj); }