qemu with hax to log dma reads & writes jcs.org/2018/11/12/vfio

qapi: Make visitor functions taking Error ** return bool, not void

See recent commit "error: Document Error API usage rules" for
rationale.

Signed-off-by: Markus Armbruster <armbru@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Reviewed-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
Message-Id: <20200707160613.848843-18-armbru@redhat.com>

+444 -349
+10 -5
audio/audio_legacy.c
··· 421 421 GList *path; 422 422 } LegacyPrintVisitor; 423 423 424 - static void lv_start_struct(Visitor *v, const char *name, void **obj, 424 + static bool lv_start_struct(Visitor *v, const char *name, void **obj, 425 425 size_t size, Error **errp) 426 426 { 427 427 LegacyPrintVisitor *lv = (LegacyPrintVisitor *) v; 428 428 lv->path = g_list_append(lv->path, g_strdup(name)); 429 + return true; 429 430 } 430 431 431 432 static void lv_end_struct(Visitor *v, void **obj) ··· 453 454 printf("%s=", name); 454 455 } 455 456 456 - static void lv_type_int64(Visitor *v, const char *name, int64_t *obj, 457 + static bool lv_type_int64(Visitor *v, const char *name, int64_t *obj, 457 458 Error **errp) 458 459 { 459 460 lv_print_key(v, name); 460 461 printf("%" PRIi64, *obj); 462 + return true; 461 463 } 462 464 463 - static void lv_type_uint64(Visitor *v, const char *name, uint64_t *obj, 465 + static bool lv_type_uint64(Visitor *v, const char *name, uint64_t *obj, 464 466 Error **errp) 465 467 { 466 468 lv_print_key(v, name); 467 469 printf("%" PRIu64, *obj); 470 + return true; 468 471 } 469 472 470 - static void lv_type_bool(Visitor *v, const char *name, bool *obj, Error **errp) 473 + static bool lv_type_bool(Visitor *v, const char *name, bool *obj, Error **errp) 471 474 { 472 475 lv_print_key(v, name); 473 476 printf("%s", *obj ? "on" : "off"); 477 + return true; 474 478 } 475 479 476 - static void lv_type_str(Visitor *v, const char *name, char **obj, Error **errp) 480 + static bool lv_type_str(Visitor *v, const char *name, char **obj, Error **errp) 477 481 { 478 482 const char *str = *obj; 479 483 lv_print_key(v, name); ··· 484 488 } 485 489 putchar(*str++); 486 490 } 491 + return true; 487 492 } 488 493 489 494 static void lv_complete(Visitor *v, void *opaque)
+22 -29
docs/devel/qapi-code-gen.txt
··· 1408 1408 #include "example-qapi-types.h" 1409 1409 1410 1410 1411 - void visit_type_UserDefOne_members(Visitor *v, UserDefOne *obj, Error **errp); 1412 - void visit_type_UserDefOne(Visitor *v, const char *name, UserDefOne **obj, Error **errp); 1413 - void visit_type_UserDefOneList(Visitor *v, const char *name, UserDefOneList **obj, Error **errp); 1411 + bool visit_type_UserDefOne_members(Visitor *v, UserDefOne *obj, Error **errp); 1412 + bool visit_type_UserDefOne(Visitor *v, const char *name, UserDefOne **obj, Error **errp); 1413 + bool visit_type_UserDefOneList(Visitor *v, const char *name, UserDefOneList **obj, Error **errp); 1414 1414 1415 - void visit_type_q_obj_my_command_arg_members(Visitor *v, q_obj_my_command_arg *obj, Error **errp); 1415 + bool visit_type_q_obj_my_command_arg_members(Visitor *v, q_obj_my_command_arg *obj, Error **errp); 1416 1416 1417 1417 #endif /* EXAMPLE_QAPI_VISIT_H */ 1418 1418 $ cat qapi-generated/example-qapi-visit.c 1419 1419 [Uninteresting stuff omitted...] 1420 1420 1421 - void visit_type_UserDefOne_members(Visitor *v, UserDefOne *obj, Error **errp) 1421 + bool visit_type_UserDefOne_members(Visitor *v, UserDefOne *obj, Error **errp) 1422 1422 { 1423 1423 Error *err = NULL; 1424 1424 1425 - visit_type_int(v, "integer", &obj->integer, &err); 1426 - if (err) { 1427 - goto out; 1425 + if (!visit_type_int(v, "integer", &obj->integer, errp)) { 1426 + return false; 1428 1427 } 1429 1428 if (visit_optional(v, "string", &obj->has_string)) { 1430 - visit_type_str(v, "string", &obj->string, &err); 1431 - if (err) { 1432 - goto out; 1429 + if (!visit_type_str(v, "string", &obj->string, errp)) { 1430 + return false; 1433 1431 } 1434 1432 } 1435 - 1436 - out: 1437 1433 error_propagate(errp, err); 1434 + return !err; 1438 1435 } 1439 1436 1440 - void visit_type_UserDefOne(Visitor *v, const char *name, UserDefOne **obj, Error **errp) 1437 + bool visit_type_UserDefOne(Visitor *v, const char *name, UserDefOne **obj, Error **errp) 1441 1438 { 1442 1439 Error *err = NULL; 1443 1440 1444 - visit_start_struct(v, name, (void **)obj, sizeof(UserDefOne), &err); 1445 - if (err) { 1446 - goto out; 1441 + if (!visit_start_struct(v, name, (void **)obj, sizeof(UserDefOne), errp)) { 1442 + return false; 1447 1443 } 1448 1444 if (!*obj) { 1449 1445 /* incomplete */ ··· 1461 1457 qapi_free_UserDefOne(*obj); 1462 1458 *obj = NULL; 1463 1459 } 1464 - out: 1465 1460 error_propagate(errp, err); 1461 + return !err; 1466 1462 } 1467 1463 1468 - void visit_type_UserDefOneList(Visitor *v, const char *name, UserDefOneList **obj, Error **errp) 1464 + bool visit_type_UserDefOneList(Visitor *v, const char *name, UserDefOneList **obj, Error **errp) 1469 1465 { 1470 1466 Error *err = NULL; 1471 1467 UserDefOneList *tail; 1472 1468 size_t size = sizeof(**obj); 1473 1469 1474 - visit_start_list(v, name, (GenericList **)obj, size, &err); 1475 - if (err) { 1476 - goto out; 1470 + if (!visit_start_list(v, name, (GenericList **)obj, size, errp)) { 1471 + return false; 1477 1472 } 1478 1473 1479 1474 for (tail = *obj; tail; ··· 1492 1487 qapi_free_UserDefOneList(*obj); 1493 1488 *obj = NULL; 1494 1489 } 1495 - out: 1496 1490 error_propagate(errp, err); 1491 + return !err; 1497 1492 } 1498 1493 1499 - void visit_type_q_obj_my_command_arg_members(Visitor *v, q_obj_my_command_arg *obj, Error **errp) 1494 + bool visit_type_q_obj_my_command_arg_members(Visitor *v, q_obj_my_command_arg *obj, Error **errp) 1500 1495 { 1501 1496 Error *err = NULL; 1502 1497 1503 - visit_type_UserDefOneList(v, "arg1", &obj->arg1, &err); 1504 - if (err) { 1505 - goto out; 1498 + if (!visit_type_UserDefOneList(v, "arg1", &obj->arg1, errp)) { 1499 + return false; 1506 1500 } 1507 - 1508 - out: 1509 1501 error_propagate(errp, err); 1502 + return !err; 1510 1503 } 1511 1504 1512 1505 [Uninteresting stuff omitted...]
+4 -4
include/qapi/clone-visitor.h
··· 20 20 */ 21 21 typedef struct QapiCloneVisitor QapiCloneVisitor; 22 22 23 - void *qapi_clone(const void *src, void (*visit_type)(Visitor *, const char *, 23 + void *qapi_clone(const void *src, bool (*visit_type)(Visitor *, const char *, 24 24 void **, Error **)); 25 25 void qapi_clone_members(void *dst, const void *src, size_t sz, 26 - void (*visit_type_members)(Visitor *, void *, 26 + bool (*visit_type_members)(Visitor *, void *, 27 27 Error **)); 28 28 29 29 /* ··· 34 34 */ 35 35 #define QAPI_CLONE(type, src) \ 36 36 ((type *)qapi_clone(src, \ 37 - (void (*)(Visitor *, const char *, void**, \ 37 + (bool (*)(Visitor *, const char *, void **, \ 38 38 Error **))visit_type_ ## type)) 39 39 40 40 /* ··· 45 45 */ 46 46 #define QAPI_CLONE_MEMBERS(type, dst, src) \ 47 47 qapi_clone_members(dst, src, sizeof(type), \ 48 - (void (*)(Visitor *, void *, \ 48 + (bool (*)(Visitor *, void *, \ 49 49 Error **))visit_type_ ## type ## _members) 50 50 51 51 #endif
+13 -13
include/qapi/visitor-impl.h
··· 48 48 */ 49 49 50 50 /* Must be set to visit structs */ 51 - void (*start_struct)(Visitor *v, const char *name, void **obj, 51 + bool (*start_struct)(Visitor *v, const char *name, void **obj, 52 52 size_t size, Error **errp); 53 53 54 54 /* Optional; intended for input visitors */ 55 - void (*check_struct)(Visitor *v, Error **errp); 55 + bool (*check_struct)(Visitor *v, Error **errp); 56 56 57 57 /* Must be set to visit structs */ 58 58 void (*end_struct)(Visitor *v, void **obj); 59 59 60 60 /* Must be set; implementations may require @list to be non-null, 61 61 * but must document it. */ 62 - void (*start_list)(Visitor *v, const char *name, GenericList **list, 62 + bool (*start_list)(Visitor *v, const char *name, GenericList **list, 63 63 size_t size, Error **errp); 64 64 65 65 /* Must be set */ 66 66 GenericList *(*next_list)(Visitor *v, GenericList *tail, size_t size); 67 67 68 68 /* Optional; intended for input visitors */ 69 - void (*check_list)(Visitor *v, Error **errp); 69 + bool (*check_list)(Visitor *v, Error **errp); 70 70 71 71 /* Must be set */ 72 72 void (*end_list)(Visitor *v, void **list); 73 73 74 74 /* Must be set by input and clone visitors to visit alternates */ 75 - void (*start_alternate)(Visitor *v, const char *name, 75 + bool (*start_alternate)(Visitor *v, const char *name, 76 76 GenericAlternate **obj, size_t size, 77 77 Error **errp); 78 78 ··· 80 80 void (*end_alternate)(Visitor *v, void **obj); 81 81 82 82 /* Must be set */ 83 - void (*type_int64)(Visitor *v, const char *name, int64_t *obj, 83 + bool (*type_int64)(Visitor *v, const char *name, int64_t *obj, 84 84 Error **errp); 85 85 86 86 /* Must be set */ 87 - void (*type_uint64)(Visitor *v, const char *name, uint64_t *obj, 87 + bool (*type_uint64)(Visitor *v, const char *name, uint64_t *obj, 88 88 Error **errp); 89 89 90 90 /* Optional; fallback is type_uint64() */ 91 - void (*type_size)(Visitor *v, const char *name, uint64_t *obj, 91 + bool (*type_size)(Visitor *v, const char *name, uint64_t *obj, 92 92 Error **errp); 93 93 94 94 /* Must be set */ 95 - void (*type_bool)(Visitor *v, const char *name, bool *obj, Error **errp); 95 + bool (*type_bool)(Visitor *v, const char *name, bool *obj, Error **errp); 96 96 97 97 /* Must be set */ 98 - void (*type_str)(Visitor *v, const char *name, char **obj, Error **errp); 98 + bool (*type_str)(Visitor *v, const char *name, char **obj, Error **errp); 99 99 100 100 /* Must be set to visit numbers */ 101 - void (*type_number)(Visitor *v, const char *name, double *obj, 101 + bool (*type_number)(Visitor *v, const char *name, double *obj, 102 102 Error **errp); 103 103 104 104 /* Must be set to visit arbitrary QTypes */ 105 - void (*type_any)(Visitor *v, const char *name, QObject **obj, 105 + bool (*type_any)(Visitor *v, const char *name, QObject **obj, 106 106 Error **errp); 107 107 108 108 /* Must be set to visit explicit null values. */ 109 - void (*type_null)(Visitor *v, const char *name, QNull **obj, 109 + bool (*type_null)(Visitor *v, const char *name, QNull **obj, 110 110 Error **errp); 111 111 112 112 /* Must be set for input visitors to visit structs, optional otherwise.
+62 -40
include/qapi/visitor.h
··· 60 60 * All QAPI types have a corresponding function with a signature 61 61 * roughly compatible with this: 62 62 * 63 - * void visit_type_FOO(Visitor *v, const char *name, T obj, Error **errp); 63 + * bool visit_type_FOO(Visitor *v, const char *name, T obj, Error **errp); 64 64 * 65 65 * where T is FOO for scalar types, and FOO * otherwise. The scalar 66 66 * visitors are declared here; the remaining visitors are generated in ··· 95 95 * incomplete object, such an object is possible only by manual 96 96 * construction. 97 97 * 98 + * visit_type_FOO() returns true on success, false on error. 99 + * 98 100 * For the QAPI object types (structs, unions, and alternates), there 99 101 * is an additional generated function in qapi-visit-MODULE.h 100 102 * compatible with: 101 103 * 102 - * void visit_type_FOO_members(Visitor *v, FOO *obj, Error **errp); 104 + * bool visit_type_FOO_members(Visitor *v, FOO *obj, Error **errp); 103 105 * 104 106 * for visiting the members of a type without also allocating the QAPI 105 - * struct. 107 + * struct. It also returns true on success, false on error. 106 108 * 107 109 * Additionally, QAPI pointer types (structs, unions, alternates, and 108 110 * lists) have a generated function in qapi-types-MODULE.h compatible ··· 131 133 * Visitor *v; 132 134 * 133 135 * v = FOO_visitor_new(...); 134 - * visit_type_Foo(v, NULL, &f, &err); 135 - * if (err) { 136 + * if (!visit_type_Foo(v, NULL, &f, &err)) { 136 137 * ...handle error... 137 138 * } else { 138 139 * ...use f... ··· 148 149 * Visitor *v; 149 150 * 150 151 * v = FOO_visitor_new(...); 151 - * visit_type_FooList(v, NULL, &l, &err); 152 - * if (err) { 152 + * if (!visit_type_FooList(v, NULL, &l, &err)) { 153 153 * ...handle error... 154 154 * } else { 155 155 * for ( ; l; l = l->next) { ··· 186 186 * <example> 187 187 * Visitor *v; 188 188 * Error *err = NULL; 189 + * bool ok = false; 189 190 * int value; 190 191 * 191 192 * v = FOO_visitor_new(...); 192 - * visit_start_struct(v, NULL, NULL, 0, &err); 193 - * if (err) { 193 + * if (!visit_start_struct(v, NULL, NULL, 0, &err)) { 194 194 * goto out; 195 195 * } 196 - * visit_start_list(v, "list", NULL, 0, &err); 197 - * if (err) { 196 + * if (!visit_start_list(v, "list", NULL, 0, &err)) { 198 197 * goto outobj; 199 198 * } 200 199 * value = 1; 201 - * visit_type_int(v, NULL, &value, &err); 202 - * if (err) { 200 + * if (!visit_type_int(v, NULL, &value, &err)) { 203 201 * goto outlist; 204 202 * } 205 203 * value = 2; 206 - * visit_type_int(v, NULL, &value, &err); 207 - * if (err) { 204 + * if (!visit_type_int(v, NULL, &value, &err)) { 208 205 * goto outlist; 209 206 * } 207 + * ok = true; 210 208 * outlist: 211 - * if (!err) { 212 - * visit_check_list(v, &err); 209 + * if (ok) { 210 + * ok = visit_check_list(v, &err); 213 211 * } 214 212 * visit_end_list(v, NULL); 215 - * if (!err) { 216 - * visit_check_struct(v, &err); 213 + * if (ok) { 214 + * ok = visit_check_struct(v, &err); 217 215 * } 218 216 * outobj: 219 217 * visit_end_struct(v, NULL); ··· 286 284 * On failure, set *@obj to NULL and store an error through @errp. 287 285 * Can happen only when @v is an input visitor. 288 286 * 287 + * Return true on success, false on failure. 288 + * 289 289 * After visit_start_struct() succeeds, the caller may visit its 290 290 * members one after the other, passing the member's name and address 291 291 * within the struct. Finally, visit_end_struct() needs to be called ··· 295 295 * FIXME Should this be named visit_start_object, since it is also 296 296 * used for QAPI unions, and maps to JSON objects? 297 297 */ 298 - void visit_start_struct(Visitor *v, const char *name, void **obj, 298 + bool visit_start_struct(Visitor *v, const char *name, void **obj, 299 299 size_t size, Error **errp); 300 300 301 301 /* ··· 304 304 * On failure, store an error through @errp. Can happen only when @v 305 305 * is an input visitor. 306 306 * 307 + * Return true on success, false on failure. 308 + * 307 309 * Should be called prior to visit_end_struct() if all other 308 310 * intermediate visit steps were successful, to allow the visitor one 309 311 * last chance to report errors. May be skipped on a cleanup path, 310 312 * where there is no need to check for further errors. 311 313 */ 312 - void visit_check_struct(Visitor *v, Error **errp); 314 + bool visit_check_struct(Visitor *v, Error **errp); 313 315 314 316 /* 315 317 * Complete an object visit started earlier. ··· 341 343 * On failure, set *@list to NULL and store an error through @errp. 342 344 * Can happen only when @v is an input visitor. 343 345 * 346 + * Return true on success, false on failure. 347 + * 344 348 * After visit_start_list() succeeds, the caller may visit its members 345 349 * one after the other. A real visit (where @list is non-NULL) uses 346 350 * visit_next_list() for traversing the linked list, while a virtual ··· 351 355 * same @list to clean up, even if intermediate visits fail. See the 352 356 * examples above. 353 357 */ 354 - void visit_start_list(Visitor *v, const char *name, GenericList **list, 358 + bool visit_start_list(Visitor *v, const char *name, GenericList **list, 355 359 size_t size, Error **errp); 356 360 357 361 /* ··· 376 380 * On failure, store an error through @errp. Can happen only when @v 377 381 * is an input visitor. 378 382 * 383 + * Return true on success, false on failure. 384 + * 379 385 * Should be called prior to visit_end_list() if all other 380 386 * intermediate visit steps were successful, to allow the visitor one 381 387 * last chance to report errors. May be skipped on a cleanup path, 382 388 * where there is no need to check for further errors. 383 389 */ 384 - void visit_check_list(Visitor *v, Error **errp); 390 + bool visit_check_list(Visitor *v, Error **errp); 385 391 386 392 /* 387 393 * Complete a list visit started earlier. ··· 412 418 * On failure, set *@obj to NULL and store an error through @errp. 413 419 * Can happen only when @v is an input visitor. 414 420 * 421 + * Return true on success, false on failure. 422 + * 415 423 * If successful, this must be paired with visit_end_alternate() with 416 424 * the same @obj to clean up, even if visiting the contents of the 417 425 * alternate fails. 418 426 */ 419 - void visit_start_alternate(Visitor *v, const char *name, 427 + bool visit_start_alternate(Visitor *v, const char *name, 420 428 GenericAlternate **obj, size_t size, 421 429 Error **errp); 422 430 ··· 467 475 * 468 476 * On failure, store an error through @errp. Can happen only when @v 469 477 * is an input visitor. 478 + * 479 + * Return true on success, false on failure. 470 480 * 471 481 * May call visit_type_str() under the hood, and the enum visit may 472 482 * fail even if the corresponding string visit succeeded; this implies 473 483 * that an input visitor's visit_type_str() must have no unwelcome 474 484 * side effects. 475 485 */ 476 - void visit_type_enum(Visitor *v, const char *name, int *obj, 486 + bool visit_type_enum(Visitor *v, const char *name, int *obj, 477 487 const QEnumLookup *lookup, Error **errp); 478 488 479 489 /* ··· 499 509 * 500 510 * On failure, store an error through @errp. Can happen only when @v 501 511 * is an input visitor. 512 + * 513 + * Return true on success, false on failure. 502 514 */ 503 - void visit_type_int(Visitor *v, const char *name, int64_t *obj, Error **errp); 515 + bool visit_type_int(Visitor *v, const char *name, int64_t *obj, Error **errp); 504 516 505 517 /* 506 518 * Visit a uint8_t value. 507 519 * Like visit_type_int(), except clamps the value to uint8_t range. 508 520 */ 509 - void visit_type_uint8(Visitor *v, const char *name, uint8_t *obj, 521 + bool visit_type_uint8(Visitor *v, const char *name, uint8_t *obj, 510 522 Error **errp); 511 523 512 524 /* 513 525 * Visit a uint16_t value. 514 526 * Like visit_type_int(), except clamps the value to uint16_t range. 515 527 */ 516 - void visit_type_uint16(Visitor *v, const char *name, uint16_t *obj, 528 + bool visit_type_uint16(Visitor *v, const char *name, uint16_t *obj, 517 529 Error **errp); 518 530 519 531 /* 520 532 * Visit a uint32_t value. 521 533 * Like visit_type_int(), except clamps the value to uint32_t range. 522 534 */ 523 - void visit_type_uint32(Visitor *v, const char *name, uint32_t *obj, 535 + bool visit_type_uint32(Visitor *v, const char *name, uint32_t *obj, 524 536 Error **errp); 525 537 526 538 /* ··· 528 540 * Like visit_type_int(), except clamps the value to uint64_t range, 529 541 * that is, ensures it is unsigned. 530 542 */ 531 - void visit_type_uint64(Visitor *v, const char *name, uint64_t *obj, 543 + bool visit_type_uint64(Visitor *v, const char *name, uint64_t *obj, 532 544 Error **errp); 533 545 534 546 /* 535 547 * Visit an int8_t value. 536 548 * Like visit_type_int(), except clamps the value to int8_t range. 537 549 */ 538 - void visit_type_int8(Visitor *v, const char *name, int8_t *obj, Error **errp); 550 + bool visit_type_int8(Visitor *v, const char *name, int8_t *obj, Error **errp); 539 551 540 552 /* 541 553 * Visit an int16_t value. 542 554 * Like visit_type_int(), except clamps the value to int16_t range. 543 555 */ 544 - void visit_type_int16(Visitor *v, const char *name, int16_t *obj, 556 + bool visit_type_int16(Visitor *v, const char *name, int16_t *obj, 545 557 Error **errp); 546 558 547 559 /* 548 560 * Visit an int32_t value. 549 561 * Like visit_type_int(), except clamps the value to int32_t range. 550 562 */ 551 - void visit_type_int32(Visitor *v, const char *name, int32_t *obj, 563 + bool visit_type_int32(Visitor *v, const char *name, int32_t *obj, 552 564 Error **errp); 553 565 554 566 /* 555 567 * Visit an int64_t value. 556 568 * Identical to visit_type_int(). 557 569 */ 558 - void visit_type_int64(Visitor *v, const char *name, int64_t *obj, 570 + bool visit_type_int64(Visitor *v, const char *name, int64_t *obj, 559 571 Error **errp); 560 572 561 573 /* ··· 564 576 * recognize additional syntax, such as suffixes for easily scaling 565 577 * values. 566 578 */ 567 - void visit_type_size(Visitor *v, const char *name, uint64_t *obj, 579 + bool visit_type_size(Visitor *v, const char *name, uint64_t *obj, 568 580 Error **errp); 569 581 570 582 /* ··· 578 590 * 579 591 * On failure, store an error through @errp. Can happen only when @v 580 592 * is an input visitor. 593 + * 594 + * Return true on success, false on failure. 581 595 */ 582 - void visit_type_bool(Visitor *v, const char *name, bool *obj, Error **errp); 596 + bool visit_type_bool(Visitor *v, const char *name, bool *obj, Error **errp); 583 597 584 598 /* 585 599 * Visit a string value. ··· 598 612 * On failure, set *@obj to NULL and store an error through @errp. 599 613 * Can happen only when @v is an input visitor. 600 614 * 615 + * Return true on success, false on failure. 616 + * 601 617 * FIXME: Callers that try to output NULL *obj should not be allowed. 602 618 */ 603 - void visit_type_str(Visitor *v, const char *name, char **obj, Error **errp); 619 + bool visit_type_str(Visitor *v, const char *name, char **obj, Error **errp); 604 620 605 621 /* 606 622 * Visit a number (i.e. double) value. ··· 614 630 * 615 631 * On failure, store an error through @errp. Can happen only when @v 616 632 * is an input visitor. 633 + * 634 + * Return true on success, false on failure. 617 635 */ 618 - void visit_type_number(Visitor *v, const char *name, double *obj, 636 + bool visit_type_number(Visitor *v, const char *name, double *obj, 619 637 Error **errp); 620 638 621 639 /* ··· 630 648 * 631 649 * On failure, set *@obj to NULL and store an error through @errp. 632 650 * Can happen only when @v is an input visitor. 651 + * 652 + * Return true on success, false on failure. 633 653 * 634 654 * Note that some kinds of input can't express arbitrary QObject. 635 655 * E.g. the visitor returned by qobject_input_visitor_new_keyval() 636 656 * can't create numbers or booleans, only strings. 637 657 */ 638 - void visit_type_any(Visitor *v, const char *name, QObject **obj, Error **errp); 658 + bool visit_type_any(Visitor *v, const char *name, QObject **obj, Error **errp); 639 659 640 660 /* 641 661 * Visit a JSON null value. ··· 648 668 * 649 669 * On failure, set *@obj to NULL and store an error through @errp. 650 670 * Can happen only when @v is an input visitor. 671 + * 672 + * Return true on success, false on failure. 651 673 */ 652 - void visit_type_null(Visitor *v, const char *name, QNull **obj, 674 + bool visit_type_null(Visitor *v, const char *name, QNull **obj, 653 675 Error **errp); 654 676 655 677 #endif
+38 -28
qapi/opts-visitor.c
··· 133 133 } 134 134 135 135 136 - static void 136 + static bool 137 137 opts_start_struct(Visitor *v, const char *name, void **obj, 138 138 size_t size, Error **errp) 139 139 { ··· 144 144 *obj = g_malloc0(size); 145 145 } 146 146 if (ov->depth++ > 0) { 147 - return; 147 + return true; 148 148 } 149 149 150 150 ov->unprocessed_opts = g_hash_table_new_full(&g_str_hash, &g_str_equal, ··· 163 163 ov->fake_id_opt->str = g_strdup(ov->opts_root->id); 164 164 opts_visitor_insert(ov->unprocessed_opts, ov->fake_id_opt); 165 165 } 166 + return true; 166 167 } 167 168 168 169 169 - static void 170 + static bool 170 171 opts_check_struct(Visitor *v, Error **errp) 171 172 { 172 173 OptsVisitor *ov = to_ov(v); ··· 174 175 GQueue *any; 175 176 176 177 if (ov->depth > 1) { 177 - return; 178 + return true; 178 179 } 179 180 180 181 /* we should have processed all (distinct) QemuOpt instances */ ··· 184 185 185 186 first = g_queue_peek_head(any); 186 187 error_setg(errp, QERR_INVALID_PARAMETER, first->name); 188 + return false; 187 189 } 190 + return true; 188 191 } 189 192 190 193 ··· 221 224 } 222 225 223 226 224 - static void 227 + static bool 225 228 opts_start_list(Visitor *v, const char *name, GenericList **list, size_t size, 226 229 Error **errp) 227 230 { ··· 232 235 /* we don't support visits without a list */ 233 236 assert(list); 234 237 ov->repeated_opts = lookup_distinct(ov, name, errp); 235 - if (ov->repeated_opts) { 236 - ov->list_mode = LM_IN_PROGRESS; 237 - *list = g_malloc0(size); 238 - } else { 238 + if (!ov->repeated_opts) { 239 239 *list = NULL; 240 + return false; 240 241 } 242 + ov->list_mode = LM_IN_PROGRESS; 243 + *list = g_malloc0(size); 244 + return true; 241 245 } 242 246 243 247 ··· 285 289 } 286 290 287 291 288 - static void 292 + static bool 289 293 opts_check_list(Visitor *v, Error **errp) 290 294 { 291 295 /* 292 296 * Unvisited list elements will be reported later when checking 293 297 * whether unvisited struct members remain. 294 298 */ 299 + return true; 295 300 } 296 301 297 302 ··· 341 346 } 342 347 343 348 344 - static void 349 + static bool 345 350 opts_type_str(Visitor *v, const char *name, char **obj, Error **errp) 346 351 { 347 352 OptsVisitor *ov = to_ov(v); ··· 350 355 opt = lookup_scalar(ov, name, errp); 351 356 if (!opt) { 352 357 *obj = NULL; 353 - return; 358 + return false; 354 359 } 355 360 *obj = g_strdup(opt->str ? opt->str : ""); 356 361 /* Note that we consume a string even if this is called as part of ··· 359 364 * consumed only matters to visit_end_struct() as the final error 360 365 * check if there were no other failures during the visit. */ 361 366 processed(ov, name); 367 + return true; 362 368 } 363 369 364 370 365 371 /* mimics qemu-option.c::parse_option_bool() */ 366 - static void 372 + static bool 367 373 opts_type_bool(Visitor *v, const char *name, bool *obj, Error **errp) 368 374 { 369 375 OptsVisitor *ov = to_ov(v); ··· 371 377 372 378 opt = lookup_scalar(ov, name, errp); 373 379 if (!opt) { 374 - return; 380 + return false; 375 381 } 376 382 377 383 if (opt->str) { ··· 386 392 } else { 387 393 error_setg(errp, QERR_INVALID_PARAMETER_VALUE, opt->name, 388 394 "on|yes|y|off|no|n"); 389 - return; 395 + return false; 390 396 } 391 397 } else { 392 398 *obj = true; 393 399 } 394 400 395 401 processed(ov, name); 402 + return true; 396 403 } 397 404 398 405 399 - static void 406 + static bool 400 407 opts_type_int64(Visitor *v, const char *name, int64_t *obj, Error **errp) 401 408 { 402 409 OptsVisitor *ov = to_ov(v); ··· 407 414 408 415 if (ov->list_mode == LM_SIGNED_INTERVAL) { 409 416 *obj = ov->range_next.s; 410 - return; 417 + return true; 411 418 } 412 419 413 420 opt = lookup_scalar(ov, name, errp); 414 421 if (!opt) { 415 - return; 422 + return false; 416 423 } 417 424 str = opt->str ? opt->str : ""; 418 425 ··· 425 432 if (*endptr == '\0') { 426 433 *obj = val; 427 434 processed(ov, name); 428 - return; 435 + return true; 429 436 } 430 437 if (*endptr == '-' && ov->list_mode == LM_IN_PROGRESS) { 431 438 long long val2; ··· 442 449 443 450 /* as if entering on the top */ 444 451 *obj = ov->range_next.s; 445 - return; 452 + return true; 446 453 } 447 454 } 448 455 } 449 456 error_setg(errp, QERR_INVALID_PARAMETER_VALUE, opt->name, 450 457 (ov->list_mode == LM_NONE) ? "an int64 value" : 451 458 "an int64 value or range"); 459 + return false; 452 460 } 453 461 454 462 455 - static void 463 + static bool 456 464 opts_type_uint64(Visitor *v, const char *name, uint64_t *obj, Error **errp) 457 465 { 458 466 OptsVisitor *ov = to_ov(v); ··· 463 471 464 472 if (ov->list_mode == LM_UNSIGNED_INTERVAL) { 465 473 *obj = ov->range_next.u; 466 - return; 474 + return true; 467 475 } 468 476 469 477 opt = lookup_scalar(ov, name, errp); 470 478 if (!opt) { 471 - return; 479 + return false; 472 480 } 473 481 str = opt->str; 474 482 ··· 479 487 if (*endptr == '\0') { 480 488 *obj = val; 481 489 processed(ov, name); 482 - return; 490 + return true; 483 491 } 484 492 if (*endptr == '-' && ov->list_mode == LM_IN_PROGRESS) { 485 493 unsigned long long val2; ··· 494 502 495 503 /* as if entering on the top */ 496 504 *obj = ov->range_next.u; 497 - return; 505 + return true; 498 506 } 499 507 } 500 508 } 501 509 error_setg(errp, QERR_INVALID_PARAMETER_VALUE, opt->name, 502 510 (ov->list_mode == LM_NONE) ? "a uint64 value" : 503 511 "a uint64 value or range"); 512 + return false; 504 513 } 505 514 506 515 507 - static void 516 + static bool 508 517 opts_type_size(Visitor *v, const char *name, uint64_t *obj, Error **errp) 509 518 { 510 519 OptsVisitor *ov = to_ov(v); ··· 513 522 514 523 opt = lookup_scalar(ov, name, errp); 515 524 if (!opt) { 516 - return; 525 + return false; 517 526 } 518 527 519 528 err = qemu_strtosz(opt->str ? opt->str : "", NULL, obj); 520 529 if (err < 0) { 521 530 error_setg(errp, QERR_INVALID_PARAMETER_VALUE, opt->name, 522 531 "a size value"); 523 - return; 532 + return false; 524 533 } 525 534 526 535 processed(ov, name); 536 + return true; 527 537 } 528 538 529 539
+26 -19
qapi/qapi-clone-visitor.c
··· 24 24 return container_of(v, QapiCloneVisitor, visitor); 25 25 } 26 26 27 - static void qapi_clone_start_struct(Visitor *v, const char *name, void **obj, 27 + static bool qapi_clone_start_struct(Visitor *v, const char *name, void **obj, 28 28 size_t size, Error **errp) 29 29 { 30 30 QapiCloneVisitor *qcv = to_qcv(v); ··· 34 34 /* Only possible when visiting an alternate's object 35 35 * branch. Nothing further to do here, since the earlier 36 36 * visit_start_alternate() already copied memory. */ 37 - return; 37 + return true; 38 38 } 39 39 40 40 *obj = g_memdup(*obj, size); 41 41 qcv->depth++; 42 + return true; 42 43 } 43 44 44 45 static void qapi_clone_end(Visitor *v, void **obj) ··· 51 52 } 52 53 } 53 54 54 - static void qapi_clone_start_list(Visitor *v, const char *name, 55 + static bool qapi_clone_start_list(Visitor *v, const char *name, 55 56 GenericList **listp, size_t size, 56 57 Error **errp) 57 58 { 58 - qapi_clone_start_struct(v, name, (void **)listp, size, errp); 59 + return qapi_clone_start_struct(v, name, (void **)listp, size, errp); 59 60 } 60 61 61 62 static GenericList *qapi_clone_next_list(Visitor *v, GenericList *tail, ··· 69 70 return tail->next; 70 71 } 71 72 72 - static void qapi_clone_start_alternate(Visitor *v, const char *name, 73 + static bool qapi_clone_start_alternate(Visitor *v, const char *name, 73 74 GenericAlternate **obj, size_t size, 74 75 Error **errp) 75 76 { 76 - qapi_clone_start_struct(v, name, (void **)obj, size, errp); 77 + return qapi_clone_start_struct(v, name, (void **)obj, size, errp); 77 78 } 78 79 79 - static void qapi_clone_type_int64(Visitor *v, const char *name, int64_t *obj, 80 - Error **errp) 80 + static bool qapi_clone_type_int64(Visitor *v, const char *name, int64_t *obj, 81 + Error **errp) 81 82 { 82 83 QapiCloneVisitor *qcv = to_qcv(v); 83 84 84 85 assert(qcv->depth); 85 86 /* Value was already cloned by g_memdup() */ 87 + return true; 86 88 } 87 89 88 - static void qapi_clone_type_uint64(Visitor *v, const char *name, 89 - uint64_t *obj, Error **errp) 90 + static bool qapi_clone_type_uint64(Visitor *v, const char *name, 91 + uint64_t *obj, Error **errp) 90 92 { 91 93 QapiCloneVisitor *qcv = to_qcv(v); 92 94 93 95 assert(qcv->depth); 94 96 /* Value was already cloned by g_memdup() */ 97 + return true; 95 98 } 96 99 97 - static void qapi_clone_type_bool(Visitor *v, const char *name, bool *obj, 98 - Error **errp) 100 + static bool qapi_clone_type_bool(Visitor *v, const char *name, bool *obj, 101 + Error **errp) 99 102 { 100 103 QapiCloneVisitor *qcv = to_qcv(v); 101 104 102 105 assert(qcv->depth); 103 106 /* Value was already cloned by g_memdup() */ 107 + return true; 104 108 } 105 109 106 - static void qapi_clone_type_str(Visitor *v, const char *name, char **obj, 107 - Error **errp) 110 + static bool qapi_clone_type_str(Visitor *v, const char *name, char **obj, 111 + Error **errp) 108 112 { 109 113 QapiCloneVisitor *qcv = to_qcv(v); 110 114 ··· 117 121 * string is intended. 118 122 */ 119 123 *obj = g_strdup(*obj ?: ""); 124 + return true; 120 125 } 121 126 122 - static void qapi_clone_type_number(Visitor *v, const char *name, double *obj, 123 - Error **errp) 127 + static bool qapi_clone_type_number(Visitor *v, const char *name, double *obj, 128 + Error **errp) 124 129 { 125 130 QapiCloneVisitor *qcv = to_qcv(v); 126 131 127 132 assert(qcv->depth); 128 133 /* Value was already cloned by g_memdup() */ 134 + return true; 129 135 } 130 136 131 - static void qapi_clone_type_null(Visitor *v, const char *name, QNull **obj, 137 + static bool qapi_clone_type_null(Visitor *v, const char *name, QNull **obj, 132 138 Error **errp) 133 139 { 134 140 QapiCloneVisitor *qcv = to_qcv(v); 135 141 136 142 assert(qcv->depth); 137 143 *obj = qnull(); 144 + return true; 138 145 } 139 146 140 147 static void qapi_clone_free(Visitor *v) ··· 167 174 return &v->visitor; 168 175 } 169 176 170 - void *qapi_clone(const void *src, void (*visit_type)(Visitor *, const char *, 177 + void *qapi_clone(const void *src, bool (*visit_type)(Visitor *, const char *, 171 178 void **, Error **)) 172 179 { 173 180 Visitor *v; ··· 184 191 } 185 192 186 193 void qapi_clone_members(void *dst, const void *src, size_t sz, 187 - void (*visit_type_members)(Visitor *, void *, 194 + bool (*visit_type_members)(Visitor *, void *, 188 195 Error **)) 189 196 { 190 197 Visitor *v;
+18 -9
qapi/qapi-dealloc-visitor.c
··· 22 22 Visitor visitor; 23 23 }; 24 24 25 - static void qapi_dealloc_start_struct(Visitor *v, const char *name, void **obj, 25 + static bool qapi_dealloc_start_struct(Visitor *v, const char *name, void **obj, 26 26 size_t unused, Error **errp) 27 27 { 28 + return true; 28 29 } 29 30 30 31 static void qapi_dealloc_end_struct(Visitor *v, void **obj) ··· 41 42 } 42 43 } 43 44 44 - static void qapi_dealloc_start_list(Visitor *v, const char *name, 45 + static bool qapi_dealloc_start_list(Visitor *v, const char *name, 45 46 GenericList **list, size_t size, 46 47 Error **errp) 47 48 { 49 + return true; 48 50 } 49 51 50 52 static GenericList *qapi_dealloc_next_list(Visitor *v, GenericList *tail, ··· 59 61 { 60 62 } 61 63 62 - static void qapi_dealloc_type_str(Visitor *v, const char *name, char **obj, 64 + static bool qapi_dealloc_type_str(Visitor *v, const char *name, char **obj, 63 65 Error **errp) 64 66 { 65 67 if (obj) { 66 68 g_free(*obj); 67 69 } 70 + return true; 68 71 } 69 72 70 - static void qapi_dealloc_type_int64(Visitor *v, const char *name, int64_t *obj, 73 + static bool qapi_dealloc_type_int64(Visitor *v, const char *name, int64_t *obj, 71 74 Error **errp) 72 75 { 76 + return true; 73 77 } 74 78 75 - static void qapi_dealloc_type_uint64(Visitor *v, const char *name, 79 + static bool qapi_dealloc_type_uint64(Visitor *v, const char *name, 76 80 uint64_t *obj, Error **errp) 77 81 { 82 + return true; 78 83 } 79 84 80 - static void qapi_dealloc_type_bool(Visitor *v, const char *name, bool *obj, 85 + static bool qapi_dealloc_type_bool(Visitor *v, const char *name, bool *obj, 81 86 Error **errp) 82 87 { 88 + return true; 83 89 } 84 90 85 - static void qapi_dealloc_type_number(Visitor *v, const char *name, double *obj, 91 + static bool qapi_dealloc_type_number(Visitor *v, const char *name, double *obj, 86 92 Error **errp) 87 93 { 94 + return true; 88 95 } 89 96 90 - static void qapi_dealloc_type_anything(Visitor *v, const char *name, 97 + static bool qapi_dealloc_type_anything(Visitor *v, const char *name, 91 98 QObject **obj, Error **errp) 92 99 { 93 100 if (obj) { 94 101 qobject_unref(*obj); 95 102 } 103 + return true; 96 104 } 97 105 98 - static void qapi_dealloc_type_null(Visitor *v, const char *name, 106 + static bool qapi_dealloc_type_null(Visitor *v, const char *name, 99 107 QNull **obj, Error **errp) 100 108 { 101 109 if (obj) { 102 110 qobject_unref(*obj); 103 111 } 112 + return true; 104 113 } 105 114 106 115 static void qapi_dealloc_free(Visitor *v)
+88 -77
qapi/qapi-visit-core.c
··· 36 36 } 37 37 } 38 38 39 - void visit_start_struct(Visitor *v, const char *name, void **obj, 39 + bool visit_start_struct(Visitor *v, const char *name, void **obj, 40 40 size_t size, Error **errp) 41 41 { 42 42 Error *err = NULL; ··· 51 51 assert(!err != !*obj); 52 52 } 53 53 error_propagate(errp, err); 54 + return !err; 54 55 } 55 56 56 - void visit_check_struct(Visitor *v, Error **errp) 57 + bool visit_check_struct(Visitor *v, Error **errp) 57 58 { 58 59 trace_visit_check_struct(v); 59 - if (v->check_struct) { 60 - v->check_struct(v, errp); 61 - } 60 + return v->check_struct ? v->check_struct(v, errp) : true; 62 61 } 63 62 64 63 void visit_end_struct(Visitor *v, void **obj) ··· 67 66 v->end_struct(v, obj); 68 67 } 69 68 70 - void visit_start_list(Visitor *v, const char *name, GenericList **list, 69 + bool visit_start_list(Visitor *v, const char *name, GenericList **list, 71 70 size_t size, Error **errp) 72 71 { 73 72 Error *err = NULL; ··· 79 78 assert(!(err && *list)); 80 79 } 81 80 error_propagate(errp, err); 81 + return !err; 82 82 } 83 83 84 84 GenericList *visit_next_list(Visitor *v, GenericList *tail, size_t size) ··· 88 88 return v->next_list(v, tail, size); 89 89 } 90 90 91 - void visit_check_list(Visitor *v, Error **errp) 91 + bool visit_check_list(Visitor *v, Error **errp) 92 92 { 93 93 trace_visit_check_list(v); 94 - if (v->check_list) { 95 - v->check_list(v, errp); 96 - } 94 + return v->check_list ? v->check_list(v, errp) : true; 97 95 } 98 96 99 97 void visit_end_list(Visitor *v, void **obj) ··· 102 100 v->end_list(v, obj); 103 101 } 104 102 105 - void visit_start_alternate(Visitor *v, const char *name, 103 + bool visit_start_alternate(Visitor *v, const char *name, 106 104 GenericAlternate **obj, size_t size, 107 105 Error **errp) 108 106 { ··· 118 116 assert(v->start_alternate && !err != !*obj); 119 117 } 120 118 error_propagate(errp, err); 119 + return !err; 121 120 } 122 121 123 122 void visit_end_alternate(Visitor *v, void **obj) ··· 147 146 return v->type == VISITOR_DEALLOC; 148 147 } 149 148 150 - void visit_type_int(Visitor *v, const char *name, int64_t *obj, Error **errp) 149 + bool visit_type_int(Visitor *v, const char *name, int64_t *obj, Error **errp) 151 150 { 152 151 assert(obj); 153 152 trace_visit_type_int(v, name, obj); 154 - v->type_int64(v, name, obj, errp); 153 + return v->type_int64(v, name, obj, errp); 155 154 } 156 155 157 - static void visit_type_uintN(Visitor *v, uint64_t *obj, const char *name, 156 + static bool visit_type_uintN(Visitor *v, uint64_t *obj, const char *name, 158 157 uint64_t max, const char *type, Error **errp) 159 158 { 160 - Error *err = NULL; 161 159 uint64_t value = *obj; 162 160 163 161 assert(v->type == VISITOR_INPUT || value <= max); 164 162 165 - v->type_uint64(v, name, &value, &err); 166 - if (err) { 167 - error_propagate(errp, err); 168 - } else if (value > max) { 163 + if (!v->type_uint64(v, name, &value, errp)) { 164 + return false; 165 + } 166 + if (value > max) { 169 167 assert(v->type == VISITOR_INPUT); 170 168 error_setg(errp, QERR_INVALID_PARAMETER_VALUE, 171 169 name ? name : "null", type); 172 - } else { 173 - *obj = value; 170 + return false; 174 171 } 172 + *obj = value; 173 + return true; 175 174 } 176 175 177 - void visit_type_uint8(Visitor *v, const char *name, uint8_t *obj, 176 + bool visit_type_uint8(Visitor *v, const char *name, uint8_t *obj, 178 177 Error **errp) 179 178 { 180 179 uint64_t value; 180 + bool ok; 181 181 182 182 trace_visit_type_uint8(v, name, obj); 183 183 value = *obj; 184 - visit_type_uintN(v, &value, name, UINT8_MAX, "uint8_t", errp); 184 + ok = visit_type_uintN(v, &value, name, UINT8_MAX, "uint8_t", errp); 185 185 *obj = value; 186 + return ok; 186 187 } 187 188 188 - void visit_type_uint16(Visitor *v, const char *name, uint16_t *obj, 189 + bool visit_type_uint16(Visitor *v, const char *name, uint16_t *obj, 189 190 Error **errp) 190 191 { 191 192 uint64_t value; 193 + bool ok; 192 194 193 195 trace_visit_type_uint16(v, name, obj); 194 196 value = *obj; 195 - visit_type_uintN(v, &value, name, UINT16_MAX, "uint16_t", errp); 197 + ok = visit_type_uintN(v, &value, name, UINT16_MAX, "uint16_t", errp); 196 198 *obj = value; 199 + return ok; 197 200 } 198 201 199 - void visit_type_uint32(Visitor *v, const char *name, uint32_t *obj, 202 + bool visit_type_uint32(Visitor *v, const char *name, uint32_t *obj, 200 203 Error **errp) 201 204 { 202 205 uint64_t value; 206 + bool ok; 203 207 204 208 trace_visit_type_uint32(v, name, obj); 205 209 value = *obj; 206 - visit_type_uintN(v, &value, name, UINT32_MAX, "uint32_t", errp); 210 + ok = visit_type_uintN(v, &value, name, UINT32_MAX, "uint32_t", errp); 207 211 *obj = value; 212 + return ok; 208 213 } 209 214 210 - void visit_type_uint64(Visitor *v, const char *name, uint64_t *obj, 215 + bool visit_type_uint64(Visitor *v, const char *name, uint64_t *obj, 211 216 Error **errp) 212 217 { 213 218 assert(obj); 214 219 trace_visit_type_uint64(v, name, obj); 215 - v->type_uint64(v, name, obj, errp); 220 + return v->type_uint64(v, name, obj, errp); 216 221 } 217 222 218 - static void visit_type_intN(Visitor *v, int64_t *obj, const char *name, 223 + static bool visit_type_intN(Visitor *v, int64_t *obj, const char *name, 219 224 int64_t min, int64_t max, const char *type, 220 225 Error **errp) 221 226 { 222 - Error *err = NULL; 223 227 int64_t value = *obj; 224 228 225 229 assert(v->type == VISITOR_INPUT || (value >= min && value <= max)); 226 230 227 - v->type_int64(v, name, &value, &err); 228 - if (err) { 229 - error_propagate(errp, err); 230 - } else if (value < min || value > max) { 231 + if (!v->type_int64(v, name, &value, errp)) { 232 + return false; 233 + } 234 + if (value < min || value > max) { 231 235 assert(v->type == VISITOR_INPUT); 232 236 error_setg(errp, QERR_INVALID_PARAMETER_VALUE, 233 237 name ? name : "null", type); 234 - } else { 235 - *obj = value; 238 + return false; 236 239 } 240 + *obj = value; 241 + return true; 237 242 } 238 243 239 - void visit_type_int8(Visitor *v, const char *name, int8_t *obj, Error **errp) 244 + bool visit_type_int8(Visitor *v, const char *name, int8_t *obj, Error **errp) 240 245 { 241 246 int64_t value; 247 + bool ok; 242 248 243 249 trace_visit_type_int8(v, name, obj); 244 250 value = *obj; 245 - visit_type_intN(v, &value, name, INT8_MIN, INT8_MAX, "int8_t", errp); 251 + ok = visit_type_intN(v, &value, name, INT8_MIN, INT8_MAX, "int8_t", errp); 246 252 *obj = value; 253 + return ok; 247 254 } 248 255 249 - void visit_type_int16(Visitor *v, const char *name, int16_t *obj, 256 + bool visit_type_int16(Visitor *v, const char *name, int16_t *obj, 250 257 Error **errp) 251 258 { 252 259 int64_t value; 260 + bool ok; 253 261 254 262 trace_visit_type_int16(v, name, obj); 255 263 value = *obj; 256 - visit_type_intN(v, &value, name, INT16_MIN, INT16_MAX, "int16_t", errp); 264 + ok = visit_type_intN(v, &value, name, INT16_MIN, INT16_MAX, "int16_t", 265 + errp); 257 266 *obj = value; 267 + return ok; 258 268 } 259 269 260 - void visit_type_int32(Visitor *v, const char *name, int32_t *obj, 270 + bool visit_type_int32(Visitor *v, const char *name, int32_t *obj, 261 271 Error **errp) 262 272 { 263 273 int64_t value; 274 + bool ok; 264 275 265 276 trace_visit_type_int32(v, name, obj); 266 277 value = *obj; 267 - visit_type_intN(v, &value, name, INT32_MIN, INT32_MAX, "int32_t", errp); 278 + ok = visit_type_intN(v, &value, name, INT32_MIN, INT32_MAX, "int32_t", 279 + errp); 268 280 *obj = value; 281 + return ok; 269 282 } 270 283 271 - void visit_type_int64(Visitor *v, const char *name, int64_t *obj, 284 + bool visit_type_int64(Visitor *v, const char *name, int64_t *obj, 272 285 Error **errp) 273 286 { 274 287 assert(obj); 275 288 trace_visit_type_int64(v, name, obj); 276 - v->type_int64(v, name, obj, errp); 289 + return v->type_int64(v, name, obj, errp); 277 290 } 278 291 279 - void visit_type_size(Visitor *v, const char *name, uint64_t *obj, 292 + bool visit_type_size(Visitor *v, const char *name, uint64_t *obj, 280 293 Error **errp) 281 294 { 282 295 assert(obj); 283 296 trace_visit_type_size(v, name, obj); 284 297 if (v->type_size) { 285 - v->type_size(v, name, obj, errp); 286 - } else { 287 - v->type_uint64(v, name, obj, errp); 298 + return v->type_size(v, name, obj, errp); 288 299 } 300 + return v->type_uint64(v, name, obj, errp); 289 301 } 290 302 291 - void visit_type_bool(Visitor *v, const char *name, bool *obj, Error **errp) 303 + bool visit_type_bool(Visitor *v, const char *name, bool *obj, Error **errp) 292 304 { 293 305 assert(obj); 294 306 trace_visit_type_bool(v, name, obj); 295 - v->type_bool(v, name, obj, errp); 307 + return v->type_bool(v, name, obj, errp); 296 308 } 297 309 298 - void visit_type_str(Visitor *v, const char *name, char **obj, Error **errp) 310 + bool visit_type_str(Visitor *v, const char *name, char **obj, Error **errp) 299 311 { 300 312 Error *err = NULL; 301 313 ··· 310 322 assert(!err != !*obj); 311 323 } 312 324 error_propagate(errp, err); 325 + return !err; 313 326 } 314 327 315 - void visit_type_number(Visitor *v, const char *name, double *obj, 328 + bool visit_type_number(Visitor *v, const char *name, double *obj, 316 329 Error **errp) 317 330 { 318 331 assert(obj); 319 332 trace_visit_type_number(v, name, obj); 320 - v->type_number(v, name, obj, errp); 333 + return v->type_number(v, name, obj, errp); 321 334 } 322 335 323 - void visit_type_any(Visitor *v, const char *name, QObject **obj, Error **errp) 336 + bool visit_type_any(Visitor *v, const char *name, QObject **obj, Error **errp) 324 337 { 325 - Error *err = NULL; 338 + bool ok; 326 339 327 340 assert(obj); 328 341 assert(v->type != VISITOR_OUTPUT || *obj); 329 342 trace_visit_type_any(v, name, obj); 330 - v->type_any(v, name, obj, &err); 343 + ok = v->type_any(v, name, obj, errp); 331 344 if (v->type == VISITOR_INPUT) { 332 - assert(!err != !*obj); 345 + assert(ok != !*obj); 333 346 } 334 - error_propagate(errp, err); 347 + return ok; 335 348 } 336 349 337 - void visit_type_null(Visitor *v, const char *name, QNull **obj, 350 + bool visit_type_null(Visitor *v, const char *name, QNull **obj, 338 351 Error **errp) 339 352 { 340 353 trace_visit_type_null(v, name, obj); 341 - v->type_null(v, name, obj, errp); 354 + return v->type_null(v, name, obj, errp); 342 355 } 343 356 344 - static void output_type_enum(Visitor *v, const char *name, int *obj, 357 + static bool output_type_enum(Visitor *v, const char *name, int *obj, 345 358 const QEnumLookup *lookup, Error **errp) 346 359 { 347 360 int value = *obj; 348 361 char *enum_str; 349 362 350 363 enum_str = (char *)qapi_enum_lookup(lookup, value); 351 - visit_type_str(v, name, &enum_str, errp); 364 + return visit_type_str(v, name, &enum_str, errp); 352 365 } 353 366 354 - static void input_type_enum(Visitor *v, const char *name, int *obj, 367 + static bool input_type_enum(Visitor *v, const char *name, int *obj, 355 368 const QEnumLookup *lookup, Error **errp) 356 369 { 357 - Error *local_err = NULL; 358 370 int64_t value; 359 371 char *enum_str; 360 372 361 - visit_type_str(v, name, &enum_str, &local_err); 362 - if (local_err) { 363 - error_propagate(errp, local_err); 364 - return; 373 + if (!visit_type_str(v, name, &enum_str, errp)) { 374 + return false; 365 375 } 366 376 367 377 value = qapi_enum_parse(lookup, enum_str, -1, NULL); 368 378 if (value < 0) { 369 379 error_setg(errp, QERR_INVALID_PARAMETER, enum_str); 370 380 g_free(enum_str); 371 - return; 381 + return false; 372 382 } 373 383 374 384 g_free(enum_str); 375 385 *obj = value; 386 + return true; 376 387 } 377 388 378 - void visit_type_enum(Visitor *v, const char *name, int *obj, 389 + bool visit_type_enum(Visitor *v, const char *name, int *obj, 379 390 const QEnumLookup *lookup, Error **errp) 380 391 { 381 392 assert(obj && lookup); 382 393 trace_visit_type_enum(v, name, obj); 383 394 switch (v->type) { 384 395 case VISITOR_INPUT: 385 - input_type_enum(v, name, obj, lookup, errp); 386 - break; 396 + return input_type_enum(v, name, obj, lookup, errp); 387 397 case VISITOR_OUTPUT: 388 - output_type_enum(v, name, obj, lookup, errp); 389 - break; 398 + return output_type_enum(v, name, obj, lookup, errp); 390 399 case VISITOR_CLONE: 391 400 /* nothing further to do, scalar value was already copied by 392 401 * g_memdup() during visit_start_*() */ 393 - break; 402 + return true; 394 403 case VISITOR_DEALLOC: 395 404 /* nothing to deallocate for a scalar */ 396 - break; 405 + return true; 406 + default: 407 + abort(); 397 408 } 398 409 }
+67 -42
qapi/qobject-input-visitor.c
··· 237 237 } 238 238 239 239 240 - static void qobject_input_check_struct(Visitor *v, Error **errp) 240 + static bool qobject_input_check_struct(Visitor *v, Error **errp) 241 241 { 242 242 QObjectInputVisitor *qiv = to_qiv(v); 243 243 StackObject *tos = QSLIST_FIRST(&qiv->stack); ··· 250 250 if (g_hash_table_iter_next(&iter, (void **)&key, NULL)) { 251 251 error_setg(errp, "Parameter '%s' is unexpected", 252 252 full_name(qiv, key)); 253 + return false; 253 254 } 255 + return true; 254 256 } 255 257 256 258 static void qobject_input_stack_object_free(StackObject *tos) ··· 272 274 qobject_input_stack_object_free(tos); 273 275 } 274 276 275 - static void qobject_input_start_struct(Visitor *v, const char *name, void **obj, 277 + static bool qobject_input_start_struct(Visitor *v, const char *name, void **obj, 276 278 size_t size, Error **errp) 277 279 { 278 280 QObjectInputVisitor *qiv = to_qiv(v); ··· 282 284 *obj = NULL; 283 285 } 284 286 if (!qobj) { 285 - return; 287 + return false; 286 288 } 287 289 if (qobject_type(qobj) != QTYPE_QDICT) { 288 290 error_setg(errp, QERR_INVALID_PARAMETER_TYPE, 289 291 full_name(qiv, name), "object"); 290 - return; 292 + return false; 291 293 } 292 294 293 295 qobject_input_push(qiv, name, qobj, obj); ··· 295 297 if (obj) { 296 298 *obj = g_malloc0(size); 297 299 } 300 + return true; 298 301 } 299 302 300 303 static void qobject_input_end_struct(Visitor *v, void **obj) ··· 307 310 } 308 311 309 312 310 - static void qobject_input_start_list(Visitor *v, const char *name, 313 + static bool qobject_input_start_list(Visitor *v, const char *name, 311 314 GenericList **list, size_t size, 312 315 Error **errp) 313 316 { ··· 319 322 *list = NULL; 320 323 } 321 324 if (!qobj) { 322 - return; 325 + return false; 323 326 } 324 327 if (qobject_type(qobj) != QTYPE_QLIST) { 325 328 error_setg(errp, QERR_INVALID_PARAMETER_TYPE, 326 329 full_name(qiv, name), "array"); 327 - return; 330 + return false; 328 331 } 329 332 330 333 entry = qobject_input_push(qiv, name, qobj, list); 331 334 if (entry && list) { 332 335 *list = g_malloc0(size); 333 336 } 337 + return true; 334 338 } 335 339 336 340 static GenericList *qobject_input_next_list(Visitor *v, GenericList *tail, ··· 348 352 return tail->next; 349 353 } 350 354 351 - static void qobject_input_check_list(Visitor *v, Error **errp) 355 + static bool qobject_input_check_list(Visitor *v, Error **errp) 352 356 { 353 357 QObjectInputVisitor *qiv = to_qiv(v); 354 358 StackObject *tos = QSLIST_FIRST(&qiv->stack); ··· 358 362 if (tos->entry) { 359 363 error_setg(errp, "Only %u list elements expected in %s", 360 364 tos->index + 1, full_name_nth(qiv, NULL, 1)); 365 + return false; 361 366 } 367 + return true; 362 368 } 363 369 364 370 static void qobject_input_end_list(Visitor *v, void **obj) ··· 370 376 qobject_input_pop(v, obj); 371 377 } 372 378 373 - static void qobject_input_start_alternate(Visitor *v, const char *name, 379 + static bool qobject_input_start_alternate(Visitor *v, const char *name, 374 380 GenericAlternate **obj, size_t size, 375 381 Error **errp) 376 382 { ··· 379 385 380 386 if (!qobj) { 381 387 *obj = NULL; 382 - return; 388 + return false; 383 389 } 384 390 *obj = g_malloc0(size); 385 391 (*obj)->type = qobject_type(qobj); 392 + return true; 386 393 } 387 394 388 - static void qobject_input_type_int64(Visitor *v, const char *name, int64_t *obj, 395 + static bool qobject_input_type_int64(Visitor *v, const char *name, int64_t *obj, 389 396 Error **errp) 390 397 { 391 398 QObjectInputVisitor *qiv = to_qiv(v); ··· 393 400 QNum *qnum; 394 401 395 402 if (!qobj) { 396 - return; 403 + return false; 397 404 } 398 405 qnum = qobject_to(QNum, qobj); 399 406 if (!qnum || !qnum_get_try_int(qnum, obj)) { 400 407 error_setg(errp, QERR_INVALID_PARAMETER_TYPE, 401 408 full_name(qiv, name), "integer"); 409 + return false; 402 410 } 411 + return true; 403 412 } 404 413 405 - static void qobject_input_type_int64_keyval(Visitor *v, const char *name, 414 + static bool qobject_input_type_int64_keyval(Visitor *v, const char *name, 406 415 int64_t *obj, Error **errp) 407 416 { 408 417 QObjectInputVisitor *qiv = to_qiv(v); 409 418 const char *str = qobject_input_get_keyval(qiv, name, errp); 410 419 411 420 if (!str) { 412 - return; 421 + return false; 413 422 } 414 423 415 424 if (qemu_strtoi64(str, NULL, 0, obj) < 0) { 416 425 /* TODO report -ERANGE more nicely */ 417 426 error_setg(errp, QERR_INVALID_PARAMETER_VALUE, 418 427 full_name(qiv, name), "integer"); 428 + return false; 419 429 } 430 + return true; 420 431 } 421 432 422 - static void qobject_input_type_uint64(Visitor *v, const char *name, 433 + static bool qobject_input_type_uint64(Visitor *v, const char *name, 423 434 uint64_t *obj, Error **errp) 424 435 { 425 436 QObjectInputVisitor *qiv = to_qiv(v); ··· 428 439 int64_t val; 429 440 430 441 if (!qobj) { 431 - return; 442 + return false; 432 443 } 433 444 qnum = qobject_to(QNum, qobj); 434 445 if (!qnum) { ··· 436 447 } 437 448 438 449 if (qnum_get_try_uint(qnum, obj)) { 439 - return; 450 + return true; 440 451 } 441 452 442 453 /* Need to accept negative values for backward compatibility */ 443 454 if (qnum_get_try_int(qnum, &val)) { 444 455 *obj = val; 445 - return; 456 + return true; 446 457 } 447 458 448 459 err: 449 460 error_setg(errp, QERR_INVALID_PARAMETER_VALUE, 450 461 full_name(qiv, name), "uint64"); 462 + return false; 451 463 } 452 464 453 - static void qobject_input_type_uint64_keyval(Visitor *v, const char *name, 465 + static bool qobject_input_type_uint64_keyval(Visitor *v, const char *name, 454 466 uint64_t *obj, Error **errp) 455 467 { 456 468 QObjectInputVisitor *qiv = to_qiv(v); 457 469 const char *str = qobject_input_get_keyval(qiv, name, errp); 458 470 459 471 if (!str) { 460 - return; 472 + return false; 461 473 } 462 474 463 475 if (qemu_strtou64(str, NULL, 0, obj) < 0) { 464 476 /* TODO report -ERANGE more nicely */ 465 477 error_setg(errp, QERR_INVALID_PARAMETER_VALUE, 466 478 full_name(qiv, name), "integer"); 479 + return false; 467 480 } 481 + return true; 468 482 } 469 483 470 - static void qobject_input_type_bool(Visitor *v, const char *name, bool *obj, 484 + static bool qobject_input_type_bool(Visitor *v, const char *name, bool *obj, 471 485 Error **errp) 472 486 { 473 487 QObjectInputVisitor *qiv = to_qiv(v); ··· 475 489 QBool *qbool; 476 490 477 491 if (!qobj) { 478 - return; 492 + return false; 479 493 } 480 494 qbool = qobject_to(QBool, qobj); 481 495 if (!qbool) { 482 496 error_setg(errp, QERR_INVALID_PARAMETER_TYPE, 483 497 full_name(qiv, name), "boolean"); 484 - return; 498 + return false; 485 499 } 486 500 487 501 *obj = qbool_get_bool(qbool); 502 + return true; 488 503 } 489 504 490 - static void qobject_input_type_bool_keyval(Visitor *v, const char *name, 505 + static bool qobject_input_type_bool_keyval(Visitor *v, const char *name, 491 506 bool *obj, Error **errp) 492 507 { 493 508 QObjectInputVisitor *qiv = to_qiv(v); 494 509 const char *str = qobject_input_get_keyval(qiv, name, errp); 495 510 496 511 if (!str) { 497 - return; 512 + return false; 498 513 } 499 514 500 515 if (!strcmp(str, "on")) { ··· 504 519 } else { 505 520 error_setg(errp, QERR_INVALID_PARAMETER_VALUE, 506 521 full_name(qiv, name), "'on' or 'off'"); 522 + return false; 507 523 } 524 + return true; 508 525 } 509 526 510 - static void qobject_input_type_str(Visitor *v, const char *name, char **obj, 527 + static bool qobject_input_type_str(Visitor *v, const char *name, char **obj, 511 528 Error **errp) 512 529 { 513 530 QObjectInputVisitor *qiv = to_qiv(v); ··· 516 533 517 534 *obj = NULL; 518 535 if (!qobj) { 519 - return; 536 + return false; 520 537 } 521 538 qstr = qobject_to(QString, qobj); 522 539 if (!qstr) { 523 540 error_setg(errp, QERR_INVALID_PARAMETER_TYPE, 524 541 full_name(qiv, name), "string"); 525 - return; 542 + return false; 526 543 } 527 544 528 545 *obj = g_strdup(qstring_get_str(qstr)); 546 + return true; 529 547 } 530 548 531 - static void qobject_input_type_str_keyval(Visitor *v, const char *name, 549 + static bool qobject_input_type_str_keyval(Visitor *v, const char *name, 532 550 char **obj, Error **errp) 533 551 { 534 552 QObjectInputVisitor *qiv = to_qiv(v); 535 553 const char *str = qobject_input_get_keyval(qiv, name, errp); 536 554 537 555 *obj = g_strdup(str); 556 + return !!str; 538 557 } 539 558 540 - static void qobject_input_type_number(Visitor *v, const char *name, double *obj, 559 + static bool qobject_input_type_number(Visitor *v, const char *name, double *obj, 541 560 Error **errp) 542 561 { 543 562 QObjectInputVisitor *qiv = to_qiv(v); ··· 545 564 QNum *qnum; 546 565 547 566 if (!qobj) { 548 - return; 567 + return false; 549 568 } 550 569 qnum = qobject_to(QNum, qobj); 551 570 if (!qnum) { 552 571 error_setg(errp, QERR_INVALID_PARAMETER_TYPE, 553 572 full_name(qiv, name), "number"); 554 - return; 573 + return false; 555 574 } 556 575 557 576 *obj = qnum_get_double(qnum); 577 + return true; 558 578 } 559 579 560 - static void qobject_input_type_number_keyval(Visitor *v, const char *name, 580 + static bool qobject_input_type_number_keyval(Visitor *v, const char *name, 561 581 double *obj, Error **errp) 562 582 { 563 583 QObjectInputVisitor *qiv = to_qiv(v); ··· 565 585 double val; 566 586 567 587 if (!str) { 568 - return; 588 + return false; 569 589 } 570 590 571 591 if (qemu_strtod_finite(str, NULL, &val)) { 572 592 /* TODO report -ERANGE more nicely */ 573 593 error_setg(errp, QERR_INVALID_PARAMETER_TYPE, 574 594 full_name(qiv, name), "number"); 575 - return; 595 + return false; 576 596 } 577 597 578 598 *obj = val; 599 + return true; 579 600 } 580 601 581 - static void qobject_input_type_any(Visitor *v, const char *name, QObject **obj, 602 + static bool qobject_input_type_any(Visitor *v, const char *name, QObject **obj, 582 603 Error **errp) 583 604 { 584 605 QObjectInputVisitor *qiv = to_qiv(v); ··· 586 607 587 608 *obj = NULL; 588 609 if (!qobj) { 589 - return; 610 + return false; 590 611 } 591 612 592 613 *obj = qobject_ref(qobj); 614 + return true; 593 615 } 594 616 595 - static void qobject_input_type_null(Visitor *v, const char *name, 617 + static bool qobject_input_type_null(Visitor *v, const char *name, 596 618 QNull **obj, Error **errp) 597 619 { 598 620 QObjectInputVisitor *qiv = to_qiv(v); ··· 600 622 601 623 *obj = NULL; 602 624 if (!qobj) { 603 - return; 625 + return false; 604 626 } 605 627 606 628 if (qobject_type(qobj) != QTYPE_QNULL) { 607 629 error_setg(errp, QERR_INVALID_PARAMETER_TYPE, 608 630 full_name(qiv, name), "null"); 609 - return; 631 + return false; 610 632 } 611 633 *obj = qnull(); 634 + return true; 612 635 } 613 636 614 - static void qobject_input_type_size_keyval(Visitor *v, const char *name, 637 + static bool qobject_input_type_size_keyval(Visitor *v, const char *name, 615 638 uint64_t *obj, Error **errp) 616 639 { 617 640 QObjectInputVisitor *qiv = to_qiv(v); 618 641 const char *str = qobject_input_get_keyval(qiv, name, errp); 619 642 620 643 if (!str) { 621 - return; 644 + return false; 622 645 } 623 646 624 647 if (qemu_strtosz(str, NULL, obj) < 0) { 625 648 /* TODO report -ERANGE more nicely */ 626 649 error_setg(errp, QERR_INVALID_PARAMETER_VALUE, 627 650 full_name(qiv, name), "size"); 651 + return false; 628 652 } 653 + return true; 629 654 } 630 655 631 656 static void qobject_input_optional(Visitor *v, const char *name, bool *present)
+18 -9
qapi/qobject-output-visitor.c
··· 103 103 } 104 104 } 105 105 106 - static void qobject_output_start_struct(Visitor *v, const char *name, 106 + static bool qobject_output_start_struct(Visitor *v, const char *name, 107 107 void **obj, size_t unused, Error **errp) 108 108 { 109 109 QObjectOutputVisitor *qov = to_qov(v); ··· 111 111 112 112 qobject_output_add(qov, name, dict); 113 113 qobject_output_push(qov, dict, obj); 114 + return true; 114 115 } 115 116 116 117 static void qobject_output_end_struct(Visitor *v, void **obj) ··· 120 121 assert(qobject_type(value) == QTYPE_QDICT); 121 122 } 122 123 123 - static void qobject_output_start_list(Visitor *v, const char *name, 124 + static bool qobject_output_start_list(Visitor *v, const char *name, 124 125 GenericList **listp, size_t size, 125 126 Error **errp) 126 127 { ··· 129 130 130 131 qobject_output_add(qov, name, list); 131 132 qobject_output_push(qov, list, listp); 133 + return true; 132 134 } 133 135 134 136 static GenericList *qobject_output_next_list(Visitor *v, GenericList *tail, ··· 144 146 assert(qobject_type(value) == QTYPE_QLIST); 145 147 } 146 148 147 - static void qobject_output_type_int64(Visitor *v, const char *name, 149 + static bool qobject_output_type_int64(Visitor *v, const char *name, 148 150 int64_t *obj, Error **errp) 149 151 { 150 152 QObjectOutputVisitor *qov = to_qov(v); 151 153 qobject_output_add(qov, name, qnum_from_int(*obj)); 154 + return true; 152 155 } 153 156 154 - static void qobject_output_type_uint64(Visitor *v, const char *name, 157 + static bool qobject_output_type_uint64(Visitor *v, const char *name, 155 158 uint64_t *obj, Error **errp) 156 159 { 157 160 QObjectOutputVisitor *qov = to_qov(v); 158 161 qobject_output_add(qov, name, qnum_from_uint(*obj)); 162 + return true; 159 163 } 160 164 161 - static void qobject_output_type_bool(Visitor *v, const char *name, bool *obj, 165 + static bool qobject_output_type_bool(Visitor *v, const char *name, bool *obj, 162 166 Error **errp) 163 167 { 164 168 QObjectOutputVisitor *qov = to_qov(v); 165 169 qobject_output_add(qov, name, qbool_from_bool(*obj)); 170 + return true; 166 171 } 167 172 168 - static void qobject_output_type_str(Visitor *v, const char *name, char **obj, 173 + static bool qobject_output_type_str(Visitor *v, const char *name, char **obj, 169 174 Error **errp) 170 175 { 171 176 QObjectOutputVisitor *qov = to_qov(v); ··· 174 179 } else { 175 180 qobject_output_add(qov, name, qstring_from_str("")); 176 181 } 182 + return true; 177 183 } 178 184 179 - static void qobject_output_type_number(Visitor *v, const char *name, 185 + static bool qobject_output_type_number(Visitor *v, const char *name, 180 186 double *obj, Error **errp) 181 187 { 182 188 QObjectOutputVisitor *qov = to_qov(v); 183 189 qobject_output_add(qov, name, qnum_from_double(*obj)); 190 + return true; 184 191 } 185 192 186 - static void qobject_output_type_any(Visitor *v, const char *name, 193 + static bool qobject_output_type_any(Visitor *v, const char *name, 187 194 QObject **obj, Error **errp) 188 195 { 189 196 QObjectOutputVisitor *qov = to_qov(v); 190 197 191 198 qobject_output_add_obj(qov, name, qobject_ref(*obj)); 199 + return true; 192 200 } 193 201 194 - static void qobject_output_type_null(Visitor *v, const char *name, 202 + static bool qobject_output_type_null(Visitor *v, const char *name, 195 203 QNull **obj, Error **errp) 196 204 { 197 205 QObjectOutputVisitor *qov = to_qov(v); 198 206 qobject_output_add(qov, name, qnull()); 207 + return true; 199 208 } 200 209 201 210 /* Finish building, and return the root object.
+34 -28
qapi/string-input-visitor.c
··· 60 60 return container_of(v, StringInputVisitor, visitor); 61 61 } 62 62 63 - static void start_list(Visitor *v, const char *name, GenericList **list, 63 + static bool start_list(Visitor *v, const char *name, GenericList **list, 64 64 size_t size, Error **errp) 65 65 { 66 66 StringInputVisitor *siv = to_siv(v); ··· 80 80 } 81 81 siv->lm = LM_UNPARSED; 82 82 } 83 + return true; 83 84 } 84 85 85 86 static GenericList *next_list(Visitor *v, GenericList *tail, size_t size) ··· 102 103 return tail->next; 103 104 } 104 105 105 - static void check_list(Visitor *v, Error **errp) 106 + static bool check_list(Visitor *v, Error **errp) 106 107 { 107 108 const StringInputVisitor *siv = to_siv(v); 108 109 ··· 111 112 case LM_UINT64_RANGE: 112 113 case LM_UNPARSED: 113 114 error_setg(errp, "Fewer list elements expected"); 114 - return; 115 + return false; 115 116 case LM_END: 116 - return; 117 + return true; 117 118 default: 118 119 abort(); 119 120 } ··· 178 179 return 0; 179 180 } 180 181 181 - static void parse_type_int64(Visitor *v, const char *name, int64_t *obj, 182 + static bool parse_type_int64(Visitor *v, const char *name, int64_t *obj, 182 183 Error **errp) 183 184 { 184 185 StringInputVisitor *siv = to_siv(v); ··· 188 189 case LM_NONE: 189 190 /* just parse a simple int64, bail out if not completely consumed */ 190 191 if (qemu_strtoi64(siv->string, NULL, 0, &val)) { 191 - error_setg(errp, QERR_INVALID_PARAMETER_VALUE, 192 - name ? name : "null", "int64"); 193 - return; 192 + error_setg(errp, QERR_INVALID_PARAMETER_VALUE, 193 + name ? name : "null", "int64"); 194 + return false; 194 195 } 195 196 *obj = val; 196 - return; 197 + return true; 197 198 case LM_UNPARSED: 198 199 if (try_parse_int64_list_entry(siv, obj)) { 199 200 error_setg(errp, QERR_INVALID_PARAMETER_VALUE, name ? name : "null", 200 201 "list of int64 values or ranges"); 201 - return; 202 + return false; 202 203 } 203 204 assert(siv->lm == LM_INT64_RANGE); 204 205 /* fall through */ ··· 211 212 /* end of range, check if there is more to parse */ 212 213 siv->lm = siv->unparsed_string[0] ? LM_UNPARSED : LM_END; 213 214 } 214 - return; 215 + return true; 215 216 case LM_END: 216 217 error_setg(errp, "Fewer list elements expected"); 217 - return; 218 + return false; 218 219 default: 219 220 abort(); 220 221 } ··· 268 269 return 0; 269 270 } 270 271 271 - static void parse_type_uint64(Visitor *v, const char *name, uint64_t *obj, 272 + static bool parse_type_uint64(Visitor *v, const char *name, uint64_t *obj, 272 273 Error **errp) 273 274 { 274 275 StringInputVisitor *siv = to_siv(v); ··· 280 281 if (qemu_strtou64(siv->string, NULL, 0, &val)) { 281 282 error_setg(errp, QERR_INVALID_PARAMETER_VALUE, name ? name : "null", 282 283 "uint64"); 283 - return; 284 + return false; 284 285 } 285 286 *obj = val; 286 - return; 287 + return true; 287 288 case LM_UNPARSED: 288 289 if (try_parse_uint64_list_entry(siv, obj)) { 289 290 error_setg(errp, QERR_INVALID_PARAMETER_VALUE, name ? name : "null", 290 291 "list of uint64 values or ranges"); 291 - return; 292 + return false; 292 293 } 293 294 assert(siv->lm == LM_UINT64_RANGE); 294 295 /* fall through */ ··· 301 302 /* end of range, check if there is more to parse */ 302 303 siv->lm = siv->unparsed_string[0] ? LM_UNPARSED : LM_END; 303 304 } 304 - return; 305 + return true; 305 306 case LM_END: 306 307 error_setg(errp, "Fewer list elements expected"); 307 - return; 308 + return false; 308 309 default: 309 310 abort(); 310 311 } 311 312 } 312 313 313 - static void parse_type_size(Visitor *v, const char *name, uint64_t *obj, 314 + static bool parse_type_size(Visitor *v, const char *name, uint64_t *obj, 314 315 Error **errp) 315 316 { 316 317 StringInputVisitor *siv = to_siv(v); ··· 320 321 assert(siv->lm == LM_NONE); 321 322 if (!parse_option_size(name, siv->string, &val, &err)) { 322 323 error_propagate(errp, err); 323 - return; 324 + return false; 324 325 } 325 326 326 327 *obj = val; 328 + return true; 327 329 } 328 330 329 - static void parse_type_bool(Visitor *v, const char *name, bool *obj, 331 + static bool parse_type_bool(Visitor *v, const char *name, bool *obj, 330 332 Error **errp) 331 333 { 332 334 StringInputVisitor *siv = to_siv(v); ··· 336 338 !strcasecmp(siv->string, "yes") || 337 339 !strcasecmp(siv->string, "true")) { 338 340 *obj = true; 339 - return; 341 + return true; 340 342 } 341 343 if (!strcasecmp(siv->string, "off") || 342 344 !strcasecmp(siv->string, "no") || 343 345 !strcasecmp(siv->string, "false")) { 344 346 *obj = false; 345 - return; 347 + return true; 346 348 } 347 349 348 350 error_setg(errp, QERR_INVALID_PARAMETER_TYPE, name ? name : "null", 349 351 "boolean"); 352 + return false; 350 353 } 351 354 352 - static void parse_type_str(Visitor *v, const char *name, char **obj, 355 + static bool parse_type_str(Visitor *v, const char *name, char **obj, 353 356 Error **errp) 354 357 { 355 358 StringInputVisitor *siv = to_siv(v); 356 359 357 360 assert(siv->lm == LM_NONE); 358 361 *obj = g_strdup(siv->string); 362 + return true; 359 363 } 360 364 361 - static void parse_type_number(Visitor *v, const char *name, double *obj, 365 + static bool parse_type_number(Visitor *v, const char *name, double *obj, 362 366 Error **errp) 363 367 { 364 368 StringInputVisitor *siv = to_siv(v); ··· 368 372 if (qemu_strtod_finite(siv->string, NULL, &val)) { 369 373 error_setg(errp, QERR_INVALID_PARAMETER_TYPE, name ? name : "null", 370 374 "number"); 371 - return; 375 + return false; 372 376 } 373 377 374 378 *obj = val; 379 + return true; 375 380 } 376 381 377 - static void parse_type_null(Visitor *v, const char *name, QNull **obj, 382 + static bool parse_type_null(Visitor *v, const char *name, QNull **obj, 378 383 Error **errp) 379 384 { 380 385 StringInputVisitor *siv = to_siv(v); ··· 385 390 if (siv->string[0]) { 386 391 error_setg(errp, QERR_INVALID_PARAMETER_TYPE, name ? name : "null", 387 392 "null"); 388 - return; 393 + return false; 389 394 } 390 395 391 396 *obj = qnull(); 397 + return true; 392 398 } 393 399 394 400 static void string_input_free(Visitor *v)
+20 -12
qapi/string-output-visitor.c
··· 123 123 } 124 124 } 125 125 126 - static void print_type_int64(Visitor *v, const char *name, int64_t *obj, 126 + static bool print_type_int64(Visitor *v, const char *name, int64_t *obj, 127 127 Error **errp) 128 128 { 129 129 StringOutputVisitor *sov = to_sov(v); ··· 138 138 sov->range_start.s = *obj; 139 139 sov->range_end.s = *obj; 140 140 sov->list_mode = LM_IN_PROGRESS; 141 - return; 141 + return true; 142 142 143 143 case LM_IN_PROGRESS: 144 144 if (sov->range_end.s + 1 == *obj) { ··· 155 155 sov->range_start.s = *obj; 156 156 sov->range_end.s = *obj; 157 157 } 158 - return; 158 + return true; 159 159 160 160 case LM_END: 161 161 if (sov->range_end.s + 1 == *obj) { ··· 197 197 } 198 198 g_string_append(sov->string, ")"); 199 199 } 200 + 201 + return true; 200 202 } 201 203 202 - static void print_type_uint64(Visitor *v, const char *name, uint64_t *obj, 204 + static bool print_type_uint64(Visitor *v, const char *name, uint64_t *obj, 203 205 Error **errp) 204 206 { 205 207 /* FIXME: print_type_int64 mishandles values over INT64_MAX */ 206 208 int64_t i = *obj; 207 - print_type_int64(v, name, &i, errp); 209 + return print_type_int64(v, name, &i, errp); 208 210 } 209 211 210 - static void print_type_size(Visitor *v, const char *name, uint64_t *obj, 212 + static bool print_type_size(Visitor *v, const char *name, uint64_t *obj, 211 213 Error **errp) 212 214 { 213 215 StringOutputVisitor *sov = to_sov(v); ··· 217 219 if (!sov->human) { 218 220 out = g_strdup_printf("%"PRIu64, *obj); 219 221 string_output_set(sov, out); 220 - return; 222 + return true; 221 223 } 222 224 223 225 val = *obj; ··· 226 228 string_output_set(sov, out); 227 229 228 230 g_free(psize); 231 + return true; 229 232 } 230 233 231 - static void print_type_bool(Visitor *v, const char *name, bool *obj, 234 + static bool print_type_bool(Visitor *v, const char *name, bool *obj, 232 235 Error **errp) 233 236 { 234 237 StringOutputVisitor *sov = to_sov(v); 235 238 string_output_set(sov, g_strdup(*obj ? "true" : "false")); 239 + return true; 236 240 } 237 241 238 - static void print_type_str(Visitor *v, const char *name, char **obj, 242 + static bool print_type_str(Visitor *v, const char *name, char **obj, 239 243 Error **errp) 240 244 { 241 245 StringOutputVisitor *sov = to_sov(v); ··· 247 251 out = g_strdup(*obj ? *obj : ""); 248 252 } 249 253 string_output_set(sov, out); 254 + return true; 250 255 } 251 256 252 - static void print_type_number(Visitor *v, const char *name, double *obj, 257 + static bool print_type_number(Visitor *v, const char *name, double *obj, 253 258 Error **errp) 254 259 { 255 260 StringOutputVisitor *sov = to_sov(v); 256 261 string_output_set(sov, g_strdup_printf("%f", *obj)); 262 + return true; 257 263 } 258 264 259 - static void print_type_null(Visitor *v, const char *name, QNull **obj, 265 + static bool print_type_null(Visitor *v, const char *name, QNull **obj, 260 266 Error **errp) 261 267 { 262 268 StringOutputVisitor *sov = to_sov(v); ··· 268 274 out = g_strdup(""); 269 275 } 270 276 string_output_set(sov, out); 277 + return true; 271 278 } 272 279 273 - static void 280 + static bool 274 281 start_list(Visitor *v, const char *name, GenericList **list, size_t size, 275 282 Error **errp) 276 283 { ··· 285 292 if (*list && (*list)->next) { 286 293 sov->list_mode = LM_STARTED; 287 294 } 295 + return true; 288 296 } 289 297 290 298 static GenericList *next_list(Visitor *v, GenericList *tail, size_t size)
+24 -34
scripts/qapi/visit.py
··· 23 23 if not scalar: 24 24 c_type += '*' 25 25 return mcgen(''' 26 - void visit_type_%(c_name)s(Visitor *v, const char *name, %(c_type)sobj, Error **errp); 26 + bool visit_type_%(c_name)s(Visitor *v, const char *name, %(c_type)sobj, Error **errp); 27 27 ''', 28 28 c_name=c_name(name), c_type=c_type) 29 29 ··· 31 31 def gen_visit_members_decl(name): 32 32 return mcgen(''' 33 33 34 - void visit_type_%(c_name)s_members(Visitor *v, %(c_name)s *obj, Error **errp); 34 + bool visit_type_%(c_name)s_members(Visitor *v, %(c_name)s *obj, Error **errp); 35 35 ''', 36 36 c_name=c_name(name)) 37 37 ··· 39 39 def gen_visit_object_members(name, base, members, variants): 40 40 ret = mcgen(''' 41 41 42 - void visit_type_%(c_name)s_members(Visitor *v, %(c_name)s *obj, Error **errp) 42 + bool visit_type_%(c_name)s_members(Visitor *v, %(c_name)s *obj, Error **errp) 43 43 { 44 44 Error *err = NULL; 45 45 ··· 48 48 49 49 if base: 50 50 ret += mcgen(''' 51 - visit_type_%(c_type)s_members(v, (%(c_type)s *)obj, &err); 52 - if (err) { 53 - goto out; 51 + if (!visit_type_%(c_type)s_members(v, (%(c_type)s *)obj, errp)) { 52 + return false; 54 53 } 55 54 ''', 56 55 c_type=base.c_name()) ··· 64 63 name=memb.name, c_name=c_name(memb.name)) 65 64 push_indent() 66 65 ret += mcgen(''' 67 - visit_type_%(c_type)s(v, "%(name)s", &obj->%(c_name)s, &err); 68 - if (err) { 69 - goto out; 66 + if (!visit_type_%(c_type)s(v, "%(name)s", &obj->%(c_name)s, errp)) { 67 + return false; 70 68 } 71 69 ''', 72 70 c_type=memb.type.c_name(), name=memb.name, ··· 112 110 } 113 111 ''') 114 112 115 - # 'goto out' produced for base, for each member, and if variants were 116 - # present 117 - if base or members or variants: 118 - ret += mcgen(''' 119 - 120 - out: 121 - ''') 122 113 ret += mcgen(''' 123 114 error_propagate(errp, err); 115 + return !err; 124 116 } 125 117 ''') 126 118 return ret ··· 129 121 def gen_visit_list(name, element_type): 130 122 return mcgen(''' 131 123 132 - void visit_type_%(c_name)s(Visitor *v, const char *name, %(c_name)s **obj, Error **errp) 124 + bool visit_type_%(c_name)s(Visitor *v, const char *name, %(c_name)s **obj, Error **errp) 133 125 { 134 126 Error *err = NULL; 135 127 %(c_name)s *tail; 136 128 size_t size = sizeof(**obj); 137 129 138 - visit_start_list(v, name, (GenericList **)obj, size, &err); 139 - if (err) { 140 - goto out; 130 + if (!visit_start_list(v, name, (GenericList **)obj, size, errp)) { 131 + return false; 141 132 } 142 133 143 134 for (tail = *obj; tail; ··· 156 147 qapi_free_%(c_name)s(*obj); 157 148 *obj = NULL; 158 149 } 159 - out: 160 150 error_propagate(errp, err); 151 + return !err; 161 152 } 162 153 ''', 163 154 c_name=c_name(name), c_elt_type=element_type.c_name()) ··· 166 157 def gen_visit_enum(name): 167 158 return mcgen(''' 168 159 169 - void visit_type_%(c_name)s(Visitor *v, const char *name, %(c_name)s *obj, Error **errp) 160 + bool visit_type_%(c_name)s(Visitor *v, const char *name, %(c_name)s *obj, Error **errp) 170 161 { 171 162 int value = *obj; 172 - visit_type_enum(v, name, &value, &%(c_name)s_lookup, errp); 163 + bool ok = visit_type_enum(v, name, &value, &%(c_name)s_lookup, errp); 173 164 *obj = value; 165 + return ok; 174 166 } 175 167 ''', 176 168 c_name=c_name(name)) ··· 179 171 def gen_visit_alternate(name, variants): 180 172 ret = mcgen(''' 181 173 182 - void visit_type_%(c_name)s(Visitor *v, const char *name, %(c_name)s **obj, Error **errp) 174 + bool visit_type_%(c_name)s(Visitor *v, const char *name, %(c_name)s **obj, Error **errp) 183 175 { 184 176 Error *err = NULL; 185 177 186 - visit_start_alternate(v, name, (GenericAlternate **)obj, sizeof(**obj), 187 - &err); 188 - if (err) { 189 - goto out; 178 + if (!visit_start_alternate(v, name, (GenericAlternate **)obj, 179 + sizeof(**obj), errp)) { 180 + return false; 190 181 } 191 182 if (!*obj) { 192 183 /* incomplete */ ··· 245 236 qapi_free_%(c_name)s(*obj); 246 237 *obj = NULL; 247 238 } 248 - out: 249 239 error_propagate(errp, err); 240 + return !err; 250 241 } 251 242 ''', 252 243 name=name, c_name=c_name(name)) ··· 257 248 def gen_visit_object(name, base, members, variants): 258 249 return mcgen(''' 259 250 260 - void visit_type_%(c_name)s(Visitor *v, const char *name, %(c_name)s **obj, Error **errp) 251 + bool visit_type_%(c_name)s(Visitor *v, const char *name, %(c_name)s **obj, Error **errp) 261 252 { 262 253 Error *err = NULL; 263 254 264 - visit_start_struct(v, name, (void **)obj, sizeof(%(c_name)s), &err); 265 - if (err) { 266 - goto out; 255 + if (!visit_start_struct(v, name, (void **)obj, sizeof(%(c_name)s), errp)) { 256 + return false; 267 257 } 268 258 if (!*obj) { 269 259 /* incomplete */ ··· 281 271 qapi_free_%(c_name)s(*obj); 282 272 *obj = NULL; 283 273 } 284 - out: 285 274 error_propagate(errp, err); 275 + return !err; 286 276 } 287 277 ''', 288 278 c_name=c_name(name))