|
@@ -24,7 +24,8 @@ enum ListMode
|
|
{
|
|
{
|
|
LM_NONE, /* not traversing a list of repeated options */
|
|
LM_NONE, /* not traversing a list of repeated options */
|
|
|
|
|
|
- LM_IN_PROGRESS, /* opts_next_list() ready to be called.
|
|
|
|
|
|
+ LM_IN_PROGRESS, /*
|
|
|
|
+ * opts_next_list() ready to be called.
|
|
*
|
|
*
|
|
* Generating the next list link will consume the most
|
|
* Generating the next list link will consume the most
|
|
* recently parsed QemuOpt instance of the repeated
|
|
* recently parsed QemuOpt instance of the repeated
|
|
@@ -36,7 +37,8 @@ enum ListMode
|
|
* LM_UNSIGNED_INTERVAL.
|
|
* LM_UNSIGNED_INTERVAL.
|
|
*/
|
|
*/
|
|
|
|
|
|
- LM_SIGNED_INTERVAL, /* opts_next_list() has been called.
|
|
|
|
|
|
+ LM_SIGNED_INTERVAL, /*
|
|
|
|
+ * opts_next_list() has been called.
|
|
*
|
|
*
|
|
* Generating the next list link will consume the most
|
|
* Generating the next list link will consume the most
|
|
* recently stored element from the signed interval,
|
|
* recently stored element from the signed interval,
|
|
@@ -48,7 +50,14 @@ enum ListMode
|
|
* next element of the signed interval.
|
|
* next element of the signed interval.
|
|
*/
|
|
*/
|
|
|
|
|
|
- LM_UNSIGNED_INTERVAL /* Same as above, only for an unsigned interval. */
|
|
|
|
|
|
+ LM_UNSIGNED_INTERVAL, /* Same as above, only for an unsigned interval. */
|
|
|
|
+
|
|
|
|
+ LM_TRAVERSED /*
|
|
|
|
+ * opts_next_list() has been called.
|
|
|
|
+ *
|
|
|
|
+ * No more QemuOpt instance in the list.
|
|
|
|
+ * The traversal has been completed.
|
|
|
|
+ */
|
|
};
|
|
};
|
|
|
|
|
|
typedef enum ListMode ListMode;
|
|
typedef enum ListMode ListMode;
|
|
@@ -238,6 +247,8 @@ opts_next_list(Visitor *v, GenericList *tail, size_t size)
|
|
OptsVisitor *ov = to_ov(v);
|
|
OptsVisitor *ov = to_ov(v);
|
|
|
|
|
|
switch (ov->list_mode) {
|
|
switch (ov->list_mode) {
|
|
|
|
+ case LM_TRAVERSED:
|
|
|
|
+ return NULL;
|
|
case LM_SIGNED_INTERVAL:
|
|
case LM_SIGNED_INTERVAL:
|
|
case LM_UNSIGNED_INTERVAL:
|
|
case LM_UNSIGNED_INTERVAL:
|
|
if (ov->list_mode == LM_SIGNED_INTERVAL) {
|
|
if (ov->list_mode == LM_SIGNED_INTERVAL) {
|
|
@@ -258,6 +269,8 @@ opts_next_list(Visitor *v, GenericList *tail, size_t size)
|
|
opt = g_queue_pop_head(ov->repeated_opts);
|
|
opt = g_queue_pop_head(ov->repeated_opts);
|
|
if (g_queue_is_empty(ov->repeated_opts)) {
|
|
if (g_queue_is_empty(ov->repeated_opts)) {
|
|
g_hash_table_remove(ov->unprocessed_opts, opt->name);
|
|
g_hash_table_remove(ov->unprocessed_opts, opt->name);
|
|
|
|
+ ov->repeated_opts = NULL;
|
|
|
|
+ ov->list_mode = LM_TRAVERSED;
|
|
return NULL;
|
|
return NULL;
|
|
}
|
|
}
|
|
break;
|
|
break;
|
|
@@ -289,7 +302,8 @@ opts_end_list(Visitor *v, void **obj)
|
|
|
|
|
|
assert(ov->list_mode == LM_IN_PROGRESS ||
|
|
assert(ov->list_mode == LM_IN_PROGRESS ||
|
|
ov->list_mode == LM_SIGNED_INTERVAL ||
|
|
ov->list_mode == LM_SIGNED_INTERVAL ||
|
|
- ov->list_mode == LM_UNSIGNED_INTERVAL);
|
|
|
|
|
|
+ ov->list_mode == LM_UNSIGNED_INTERVAL ||
|
|
|
|
+ ov->list_mode == LM_TRAVERSED);
|
|
ov->repeated_opts = NULL;
|
|
ov->repeated_opts = NULL;
|
|
ov->list_mode = LM_NONE;
|
|
ov->list_mode = LM_NONE;
|
|
}
|
|
}
|
|
@@ -306,6 +320,10 @@ lookup_scalar(const OptsVisitor *ov, const char *name, Error **errp)
|
|
list = lookup_distinct(ov, name, errp);
|
|
list = lookup_distinct(ov, name, errp);
|
|
return list ? g_queue_peek_tail(list) : NULL;
|
|
return list ? g_queue_peek_tail(list) : NULL;
|
|
}
|
|
}
|
|
|
|
+ if (ov->list_mode == LM_TRAVERSED) {
|
|
|
|
+ error_setg(errp, "Fewer list elements than expected");
|
|
|
|
+ return NULL;
|
|
|
|
+ }
|
|
assert(ov->list_mode == LM_IN_PROGRESS);
|
|
assert(ov->list_mode == LM_IN_PROGRESS);
|
|
return g_queue_peek_head(ov->repeated_opts);
|
|
return g_queue_peek_head(ov->repeated_opts);
|
|
}
|
|
}
|