static GenericList *next_list(Visitor *v, GenericList **list, size_t size) { StringOutputVisitor *sov = to_sov(v); GenericList *ret = NULL; if (*list) { if (sov->head) { ret = *list; } else { ret = (*list)->next; } if (sov->head) { if (ret && ret->next == NULL) { sov->list_mode = LM_NONE; } sov->head = false; } else { if (ret && ret->next == NULL) { sov->list_mode = LM_END; } } } return ret; }
static void print_type_size(Visitor *v, const char *name, uint64_t *obj, Error **errp) { StringOutputVisitor *sov = to_sov(v); static const char suffixes[] = { 'B', 'K', 'M', 'G', 'T', 'P', 'E' }; uint64_t div, val; char *out; int i; if (!sov->human) { out = g_strdup_printf("%"PRIu64, *obj); string_output_set(sov, out); return; } val = *obj; /* The exponent (returned in i) minus one gives us * floor(log2(val * 1024 / 1000). The correction makes us * switch to the higher power when the integer part is >= 1000. */ frexp(val / (1000.0 / 1024.0), &i); i = (i - 1) / 10; assert(i < ARRAY_SIZE(suffixes)); div = 1ULL << (i * 10); out = g_strdup_printf("%"PRIu64" (%0.3g %c%s)", val, (double)val/div, suffixes[i], i ? "iB" : ""); string_output_set(sov, out); }
static void string_output_complete(Visitor *v, void *opaque) { StringOutputVisitor *sov = to_sov(v); assert(opaque == sov->result); *sov->result = g_string_free(sov->string, false); sov->string = NULL; }
static GenericList *next_list(Visitor *v, GenericList *tail, size_t size) { StringOutputVisitor *sov = to_sov(v); GenericList *ret = tail->next; if (ret && !ret->next) { sov->list_mode = LM_END; } return ret; }
static void start_list(Visitor *v, const char *name, Error **errp) { StringOutputVisitor *sov = to_sov(v); /* we can't traverse a list in a list */ assert(sov->list_mode == LM_NONE); sov->list_mode = LM_STARTED; sov->head = true; }
static void end_list(Visitor *v, void **obj) { StringOutputVisitor *sov = to_sov(v); assert(sov->list == obj); assert(sov->list_mode == LM_STARTED || sov->list_mode == LM_END || sov->list_mode == LM_NONE || sov->list_mode == LM_IN_PROGRESS); sov->list_mode = LM_NONE; }
static void string_output_free(Visitor *v) { StringOutputVisitor *sov = to_sov(v); if (sov->string) { g_string_free(sov->string, true); } g_list_foreach(sov->ranges, free_range, NULL); g_list_free(sov->ranges); g_free(sov); }
static void end_list(Visitor *v) { StringOutputVisitor *sov = to_sov(v); assert(sov->list_mode == LM_STARTED || sov->list_mode == LM_END || sov->list_mode == LM_NONE || sov->list_mode == LM_IN_PROGRESS); sov->list_mode = LM_NONE; sov->head = true; }
static void print_type_null(Visitor *v, const char *name, QNull **obj, Error **errp) { StringOutputVisitor *sov = to_sov(v); char *out; if (sov->human) { out = g_strdup("<null>"); } else { out = g_strdup(""); } string_output_set(sov, out); }
static void print_type_str(Visitor *v, const char *name, char **obj, Error **errp) { StringOutputVisitor *sov = to_sov(v); char *out; if (sov->human) { out = *obj ? g_strdup_printf("\"%s\"", *obj) : g_strdup("<null>"); } else { out = g_strdup(*obj ? *obj : ""); } string_output_set(sov, out); }
static void start_list(Visitor *v, const char *name, GenericList **list, size_t size, Error **errp) { StringOutputVisitor *sov = to_sov(v); /* we can't traverse a list in a list */ assert(sov->list_mode == LM_NONE); /* We don't support visits without a list */ assert(list); sov->list = list; /* List handling is only needed if there are at least two elements */ if (*list && (*list)->next) { sov->list_mode = LM_STARTED; } }
static void print_type_size(Visitor *v, const char *name, uint64_t *obj, Error **errp) { StringOutputVisitor *sov = to_sov(v); uint64_t val; char *out, *psize; if (!sov->human) { out = g_strdup_printf("%"PRIu64, *obj); string_output_set(sov, out); return; } val = *obj; psize = size_to_str(val); out = g_strdup_printf("%"PRIu64" (%s)", val, psize); string_output_set(sov, out); g_free(psize); }
static void print_type_number(Visitor *v, const char *name, double *obj, Error **errp) { StringOutputVisitor *sov = to_sov(v); string_output_set(sov, g_strdup_printf("%f", *obj)); }
static void print_type_bool(Visitor *v, const char *name, bool *obj, Error **errp) { StringOutputVisitor *sov = to_sov(v); string_output_set(sov, g_strdup(*obj ? "true" : "false")); }
static void print_type_int64(Visitor *v, const char *name, int64_t *obj, Error **errp) { StringOutputVisitor *sov = to_sov(v); GList *l; switch (sov->list_mode) { case LM_NONE: string_output_append(sov, *obj); break; case LM_STARTED: sov->range_start.s = *obj; sov->range_end.s = *obj; sov->list_mode = LM_IN_PROGRESS; return; case LM_IN_PROGRESS: if (sov->range_end.s + 1 == *obj) { sov->range_end.s++; } else { if (sov->range_start.s == sov->range_end.s) { string_output_append(sov, sov->range_end.s); } else { assert(sov->range_start.s < sov->range_end.s); string_output_append_range(sov, sov->range_start.s, sov->range_end.s); } sov->range_start.s = *obj; sov->range_end.s = *obj; } return; case LM_END: if (sov->range_end.s + 1 == *obj) { sov->range_end.s++; assert(sov->range_start.s < sov->range_end.s); string_output_append_range(sov, sov->range_start.s, sov->range_end.s); } else { if (sov->range_start.s == sov->range_end.s) { string_output_append(sov, sov->range_end.s); } else { assert(sov->range_start.s < sov->range_end.s); string_output_append_range(sov, sov->range_start.s, sov->range_end.s); } string_output_append(sov, *obj); } break; default: abort(); } l = sov->ranges; while (l) { Range *r = l->data; format_string(sov, r, l->next != NULL, false); l = l->next; } if (sov->human) { l = sov->ranges; g_string_append(sov->string, " ("); while (l) { Range *r = l->data; format_string(sov, r, l->next != NULL, true); l = l->next; } g_string_append(sov->string, ")"); } }