X-Git-Url: https://git.proxmox.com/?a=blobdiff_plain;f=qapi%2Fstring-input-visitor.c;h=8dfa5612522b7c1c3add7363f7e10847a6c75e55;hb=7287e3556fdc56bfd0666a67d6b1d3ca9ce04083;hp=b55d1995a228f3e03eda4d322aca00ce1a4d9a5c;hpb=e58d695e6c3a5cfa0aa2fc91b87ade017ef28b05;p=mirror_qemu.git diff --git a/qapi/string-input-visitor.c b/qapi/string-input-visitor.c index b55d1995a2..8dfa561252 100644 --- a/qapi/string-input-visitor.c +++ b/qapi/string-input-visitor.c @@ -25,13 +25,12 @@ struct StringInputVisitor { Visitor visitor; - bool head; - GList *ranges; GList *cur_range; int64_t cur; const char *string; + void *list; /* Only needed for sanity checking the caller */ }; static StringInputVisitor *to_siv(Visitor *v) @@ -44,7 +43,7 @@ static void free_range(void *range, void *dummy) g_free(range); } -static void parse_str(StringInputVisitor *siv, Error **errp) +static int parse_str(StringInputVisitor *siv, const char *name, Error **errp) { char *str = (char *) siv->string; long long start, end; @@ -52,7 +51,7 @@ static void parse_str(StringInputVisitor *siv, Error **errp) char *endptr; if (siv->ranges) { - return; + return 0; } do { @@ -61,10 +60,8 @@ static void parse_str(StringInputVisitor *siv, Error **errp) if (errno == 0 && endptr > str) { if (*endptr == '\0') { cur = g_malloc0(sizeof(*cur)); - cur->begin = start; - cur->end = start + 1; - siv->ranges = g_list_insert_sorted_merged(siv->ranges, cur, - range_compare); + range_set_bounds(cur, start, start); + siv->ranges = range_list_insert(siv->ranges, cur); cur = NULL; str = NULL; } else if (*endptr == '-') { @@ -76,23 +73,15 @@ static void parse_str(StringInputVisitor *siv, Error **errp) end < start + 65536)) { if (*endptr == '\0') { cur = g_malloc0(sizeof(*cur)); - cur->begin = start; - cur->end = end + 1; - siv->ranges = - g_list_insert_sorted_merged(siv->ranges, - cur, - range_compare); + range_set_bounds(cur, start, end); + siv->ranges = range_list_insert(siv->ranges, cur); cur = NULL; str = NULL; } else if (*endptr == ',') { str = endptr + 1; cur = g_malloc0(sizeof(*cur)); - cur->begin = start; - cur->end = end + 1; - siv->ranges = - g_list_insert_sorted_merged(siv->ranges, - cur, - range_compare); + range_set_bounds(cur, start, end); + siv->ranges = range_list_insert(siv->ranges, cur); cur = NULL; } else { goto error; @@ -103,11 +92,8 @@ static void parse_str(StringInputVisitor *siv, Error **errp) } else if (*endptr == ',') { str = endptr + 1; cur = g_malloc0(sizeof(*cur)); - cur->begin = start; - cur->end = start + 1; - siv->ranges = g_list_insert_sorted_merged(siv->ranges, - cur, - range_compare); + range_set_bounds(cur, start, start); + siv->ranges = range_list_insert(siv->ranges, cur); cur = NULL; } else { goto error; @@ -117,33 +103,46 @@ static void parse_str(StringInputVisitor *siv, Error **errp) } } while (str); - return; + return 0; error: g_list_foreach(siv->ranges, free_range, NULL); g_list_free(siv->ranges); siv->ranges = NULL; + error_setg(errp, QERR_INVALID_PARAMETER_VALUE, name ? name : "null", + "an int64 value or range"); + return -1; } static void -start_list(Visitor *v, const char *name, Error **errp) +start_list(Visitor *v, const char *name, GenericList **list, size_t size, + Error **errp) { StringInputVisitor *siv = to_siv(v); - parse_str(siv, errp); + /* We don't support visits without a list */ + assert(list); + siv->list = 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; + siv->cur = range_lob(r); } + *list = g_malloc0(size); + } else { + *list = NULL; } } -static GenericList *next_list(Visitor *v, GenericList **list, size_t size) +static GenericList *next_list(Visitor *v, GenericList *tail, size_t size) { StringInputVisitor *siv = to_siv(v); - GenericList **link; Range *r; if (!siv->ranges || !siv->cur_range) { @@ -155,7 +154,7 @@ static GenericList *next_list(Visitor *v, GenericList **list, size_t size) return NULL; } - if (siv->cur < r->begin || siv->cur >= r->end) { + if (!range_contains(r, siv->cur)) { siv->cur_range = g_list_next(siv->cur_range); if (!siv->cur_range) { return NULL; @@ -164,24 +163,18 @@ static GenericList *next_list(Visitor *v, GenericList **list, size_t size) if (!r) { return NULL; } - siv->cur = r->begin; - } - - if (siv->head) { - link = list; - siv->head = false; - } else { - link = &(*list)->next; + siv->cur = range_lob(r); } - *link = g_malloc0(size); - return *link; + tail->next = g_malloc0(size); + return tail->next; } -static void end_list(Visitor *v) +static void end_list(Visitor *v, void **obj) { StringInputVisitor *siv = to_siv(v); - siv->head = true; + + assert(siv->list == obj); } static void parse_type_int64(Visitor *v, const char *name, int64_t *obj, @@ -195,7 +188,9 @@ static void parse_type_int64(Visitor *v, const char *name, int64_t *obj, return; } - parse_str(siv, errp); + if (parse_str(siv, name, errp) < 0) { + return; + } if (!siv->ranges) { goto error; @@ -214,7 +209,7 @@ static void parse_type_int64(Visitor *v, const char *name, int64_t *obj, goto error; } - siv->cur = r->begin; + siv->cur = range_lob(r); } *obj = siv->cur; @@ -331,19 +326,16 @@ static void parse_optional(Visitor *v, const char *name, bool *present) *present = true; } -Visitor *string_input_get_visitor(StringInputVisitor *v) +static void string_input_free(Visitor *v) { - return &v->visitor; -} + StringInputVisitor *siv = to_siv(v); -void string_input_visitor_cleanup(StringInputVisitor *v) -{ - g_list_foreach(v->ranges, free_range, NULL); - g_list_free(v->ranges); - g_free(v); + g_list_foreach(siv->ranges, free_range, NULL); + g_list_free(siv->ranges); + g_free(siv); } -StringInputVisitor *string_input_visitor_new(const char *str) +Visitor *string_input_visitor_new(const char *str) { StringInputVisitor *v; @@ -360,8 +352,8 @@ StringInputVisitor *string_input_visitor_new(const char *str) v->visitor.next_list = next_list; v->visitor.end_list = end_list; v->visitor.optional = parse_optional; + v->visitor.free = string_input_free; v->string = str; - v->head = true; - return v; + return &v->visitor; }