)]}'
{
  "commit": "a16e3e5c5825c90887a863513916f93eeec16c55",
  "tree": "175ae43f51fac5213ccb7d130f9c9f83e42a46b3",
  "parents": [
    "9dbb8fa7eff6e5e4cfd83ea26dc67f8404b84aa2"
  ],
  "author": {
    "name": "Eric Blake",
    "email": "eblake@redhat.com",
    "time": "Fri Jan 29 06:48:46 2016 -0700"
  },
  "committer": {
    "name": "Markus Armbruster",
    "email": "armbru@redhat.com",
    "time": "Mon Feb 08 17:29:55 2016 +0100"
  },
  "message": "qapi: Improve generated event use of qapi visitor\n\nAll other successful clients of visit_start_struct() were paired\nwith an unconditional visit_end_struct(); but the generated\ncode for events was relying on qmp_output_visitor_cleanup() to\nwork on an incomplete visit.  Alter the code to guarantee that\nthe struct is completed, which will make a future patch to\nsplit visit_end_struct() easier to reason about.  While at it,\ndrop some assertions and comments that are not present in other\nuses of the qmp output visitor, and pass NULL rather than \"\" as\nthe \u0027kind\u0027 parameter (matching most other uses where obj is NULL).\n\nThe changes to the generated code look like:\n\n|     qmp \u003d qmp_event_build_dict(\"DEVICE_TRAY_MOVED\");\n|\n|     qov \u003d qmp_output_visitor_new();\n|-    g_assert(qov);\n|-\n|     v \u003d qmp_output_get_visitor(qov);\n|-    g_assert(v);\n|\n|-    /* Fake visit, as if all members are under a structure */\n|-    visit_start_struct(v, NULL, \"\", \"DEVICE_TRAY_MOVED\", 0, \u0026err);\n|+    visit_start_struct(v, NULL, NULL, \"DEVICE_TRAY_MOVED\", 0, \u0026err);\n|     if (err) {\n|         goto out;\n|     }\n|     visit_type_str(v, (char **)\u0026device, \"device\", \u0026err);\n|     if (err) {\n|-        goto out;\n|+        goto out_obj;\n|     }\n|     visit_type_bool(v, \u0026tray_open, \"tray-open\", \u0026err);\n|     if (err) {\n|-        goto out;\n|+        goto out_obj;\n|     }\n|-    visit_end_struct(v, \u0026err);\n|+out_obj:\n|+    visit_end_struct(v, err ? NULL : \u0026err);\n|     if (err) {\n|         goto out;\n|     }\n|\n|     obj \u003d qmp_output_get_qobject(qov);\n|-    g_assert(obj !\u003d NULL);\n|+    g_assert(obj);\n|\n|     qdict_put_obj(qmp, \"data\", obj);\n|     emit(QAPI_EVENT_DEVICE_TRAY_MOVED, qmp, \u0026err);\n\nNote that the \u0027goto out_obj\u0027 with no intervening code before the\nlabel, as well as the construct of \u0027err ? NULL : \u0026err\u0027, are both\na bit unusual but also temporary; they get fixed in a later patch\nthat splits visit_end_struct() to drop its errp parameter by moving\nsome checking before the label.  But until that time, this was the\nsimplest way to avoid the appearance of passing a possibly-set\nerror to visit_end_struct(), even though actual code inspection\nshows that visit_end_struct() for a QMP output visitor will never\nset an error.\n\nSigned-off-by: Eric Blake \u003ceblake@redhat.com\u003e\nMessage-Id: \u003c1454075341-13658-11-git-send-email-eblake@redhat.com\u003e\n[Commit message\u0027s code diff tweaked]\nSigned-off-by: Markus Armbruster \u003carmbru@redhat.com\u003e\n",
  "tree_diff": [
    {
      "type": "modify",
      "old_id": "720486f06c90e68a25dc74bff61955411eb33e16",
      "old_mode": 33188,
      "old_path": "scripts/qapi-event.py",
      "new_id": "0f5534f6c3f683d800087b54583c7750fd6a506d",
      "new_mode": 33188,
      "new_path": "scripts/qapi-event.py"
    },
    {
      "type": "modify",
      "old_id": "0f032c3e67ce63532e480f8085631405004cf176",
      "old_mode": 33188,
      "old_path": "scripts/qapi.py",
      "new_id": "9254e48fe37528cbe64f7858d08463331359b617",
      "new_mode": 33188,
      "new_path": "scripts/qapi.py"
    }
  ]
}
