1====================== 2The Sphinx QAPI Domain 3====================== 4 5An extension to the `rST syntax 6<https://www.sphinx-doc.org/en/master/usage/restructuredtext/basics.html>`_ 7in Sphinx is provided by the QAPI Domain, located in 8``docs/sphinx/qapi_domain.py``. This extension is analogous to the 9`Python Domain 10<https://www.sphinx-doc.org/en/master/usage/domains/python.html>`_ 11included with Sphinx, but provides special directives and roles 12for annotating and documenting QAPI definitions 13specifically. 14 15A `Domain 16<https://www.sphinx-doc.org/en/master/usage/domains/index.html>`_ 17provides a set of special rST directives and cross-referencing roles to 18Sphinx for understanding rST markup written to document a specific 19language. By itself, this QAPI extension is only sufficient to parse rST 20markup written by hand; the `autodoc 21<https://www.sphinx-doc.org/en/master/usage/extensions/autodoc.html>`_ 22functionality is provided elsewhere, in ``docs/sphinx/qapidoc.py``, by 23the "Transmogrifier". 24 25It is not expected that any developer nor documentation writer would 26never need to write *nor* read these special rST forms. However, in the 27event that something needs to be debugged, knowing the syntax of the 28domain is quite handy. This reference may also be useful as a guide for 29understanding the QAPI Domain extension code itself. Although most of 30these forms will not be needed for documentation writing purposes, 31understanding the cross-referencing syntax *will* be helpful when 32writing rST documentation elsewhere, or for enriching the body of 33QAPIDoc blocks themselves. 34 35 36Concepts 37======== 38 39The QAPI Domain itself provides no mechanisms for reading the QAPI 40Schema or generating documentation from code that exists. It is merely 41the rST syntax used to describe things. For instance, the Sphinx Python 42domain adds syntax like ``:py:func:`` for describing Python functions in 43documentation, but it's the autodoc module that is responsible for 44reading Python code and generating such syntax. QAPI is analogous here: 45qapidoc.py is responsible for reading the QAPI Schema and generating rST 46syntax, and qapi_domain.py is responsible for translating that special 47syntax and providing APIs for Sphinx internals. 48 49In other words: 50 51qapi_domain.py adds syntax like ``.. qapi:command::`` to Sphinx, and 52qapidoc.py transforms the documentation in ``qapi/*.json`` into rST 53using directives defined by the domain. 54 55Or even shorter: 56 57``:py:`` is to ``:qapi:`` as *autodoc* is to *qapidoc*. 58 59 60Info Field Lists 61================ 62 63`Field lists 64<https://www.sphinx-doc.org/en/master/usage/restructuredtext/basics.html#field-lists>`_ 65are a standard syntax in reStructuredText. Sphinx `extends that syntax 66<https://www.sphinx-doc.org/en/master/usage/domains/python.html#info-field-lists>`_ 67to give certain field list entries special meaning and parsing to, for 68example, add cross-references. The QAPI Domain takes advantage of this 69field list extension to document things like Arguments, Members, Values, 70and so on. 71 72The special parsing and handling of info field lists in Sphinx is provided by 73three main classes; Field, GroupedField, and TypedField. The behavior 74and formatting for each configured field list entry in the domain 75changes depending on which class is used. 76 77Field: 78 * Creates an ungrouped field: i.e., each entry will create its own 79 section and they will not be combined. 80 * May *optionally* support an argument. 81 * May apply cross-reference roles to *either* the argument *or* the 82 content body, both, or neither. 83 84This is used primarily for entries which are not expected to be 85repeated, i.e., items that may only show up at most once. The QAPI 86domain uses this class for "Errors" section. 87 88GroupedField: 89 * Creates a grouped field: i.e. multiple adjacent entries will be 90 merged into one section, and the content will form a bulleted list. 91 * *Must* take an argument. 92 * May optionally apply a cross-reference role to the argument, but not 93 the body. 94 * Can be configured to remove the bulleted list if there is only a 95 single entry. 96 * All items will be generated with the form: "argument -- body" 97 98This is used for entries which are expected to be repeated, but aren't 99expected to have two arguments, i.e. types without names, or names 100without types. The QAPI domain uses this class for features, returns, 101and enum values. 102 103TypedField: 104 * Creates a grouped, typed field. Multiple adjacent entries will be 105 merged into one section, and the content will form a bulleted list. 106 * *Must* take at least one argument, but supports up to two - 107 nominally, a name and a type. 108 * May optionally apply a cross-reference role to the type or the name 109 argument, but not the body. 110 * Can be configured to remove the bulleted list if there is only a 111 single entry. 112 * All items will be generated with the form "name (type) -- body" 113 114This is used for entries that are expected to be repeated and will have 115a name, a type, and a description. The QAPI domain uses this class for 116arguments, alternatives, and members. Wherever type names are referenced 117below, They must be a valid, documented type that will be 118cross-referenced in the HTML output; or one of the built-in JSON types 119(string, number, int, boolean, null, value, q_empty). 120 121 122``:feat:`` 123---------- 124 125Document a feature attached to a QAPI definition. 126 127:availability: This field list is available in the body of Command, 128 Event, Enum, Object and Alternate directives. 129:syntax: ``:feat name: Lorem ipsum, dolor sit amet...`` 130:type: `sphinx.util.docfields.GroupedField 131 <https://pydoc.dev/sphinx/latest/sphinx.util.docfields.GroupedField.html?private=1>`_ 132 133Example:: 134 135 .. qapi:object:: BlockdevOptionsVirtioBlkVhostVdpa 136 :since: 7.2 137 :ifcond: CONFIG_BLKIO 138 139 Driver specific block device options for the virtio-blk-vhost-vdpa 140 backend. 141 142 :memb string path: path to the vhost-vdpa character device. 143 :feat fdset: Member ``path`` supports the special "/dev/fdset/N" path 144 (since 8.1) 145 146 147``:arg:`` 148--------- 149 150Document an argument to a QAPI command. 151 152:availability: This field list is only available in the body of the 153 Command directive. 154:syntax: ``:arg type name: description`` 155:type: `sphinx.util.docfields.TypedField 156 <https://pydoc.dev/sphinx/latest/sphinx.util.docfields.TypedField.html?private=1>`_ 157 158 159Example:: 160 161 .. qapi:command:: job-pause 162 :since: 3.0 163 164 Pause an active job. 165 166 This command returns immediately after marking the active job for 167 pausing. Pausing an already paused job is an error. 168 169 The job will pause as soon as possible, which means transitioning 170 into the PAUSED state if it was RUNNING, or into STANDBY if it was 171 READY. The corresponding JOB_STATUS_CHANGE event will be emitted. 172 173 Cancelling a paused job automatically resumes it. 174 175 :arg string id: The job identifier. 176 177 178``:error:`` 179----------- 180 181Document the error condition(s) of a QAPI command. 182 183:availability: This field list is only available in the body of the 184 Command directive. 185:syntax: ``:error: Lorem ipsum dolor sit amet ...`` 186:type: `sphinx.util.docfields.Field 187 <https://pydoc.dev/sphinx/latest/sphinx.util.docfields.Field.html?private=1>`_ 188 189The format of the :errors: field list description is free-form rST. The 190alternative spelling ":errors:" is also permitted, but strictly 191analogous. 192 193Example:: 194 195 .. qapi:command:: block-job-set-speed 196 :since: 1.1 197 198 Set maximum speed for a background block operation. 199 200 This command can only be issued when there is an active block job. 201 202 Throttling can be disabled by setting the speed to 0. 203 204 :arg string device: The job identifier. This used to be a device 205 name (hence the name of the parameter), but since QEMU 2.7 it 206 can have other values. 207 :arg int speed: the maximum speed, in bytes per second, or 0 for 208 unlimited. Defaults to 0. 209 :error: 210 - If no background operation is active on this device, 211 DeviceNotActive 212 213 214``:return:`` 215------------- 216 217Document the return type(s) and value(s) of a QAPI command. 218 219:availability: This field list is only available in the body of the 220 Command directive. 221:syntax: ``:return type: Lorem ipsum dolor sit amet ...`` 222:type: `sphinx.util.docfields.GroupedField 223 <https://pydoc.dev/sphinx/latest/sphinx.util.docfields.GroupedField.html?private=1>`_ 224 225 226Example:: 227 228 .. qapi:command:: query-replay 229 :since: 5.2 230 231 Retrieve the record/replay information. It includes current 232 instruction count which may be used for ``replay-break`` and 233 ``replay-seek`` commands. 234 235 :return ReplayInfo: record/replay information. 236 237 .. qmp-example:: 238 239 -> { "execute": "query-replay" } 240 <- { "return": { 241 "mode": "play", "filename": "log.rr", "icount": 220414 } 242 } 243 244 245``:return-nodesc:`` 246------------------- 247 248Document the return type of a QAPI command, without an accompanying 249description. 250 251:availability: This field list is only available in the body of the 252 Command directive. 253:syntax: ``:return-nodesc: type`` 254:type: `sphinx.util.docfields.Field 255 <https://pydoc.dev/sphinx/latest/sphinx.util.docfields.Field.html?private=1>`_ 256 257 258Example:: 259 260 .. qapi:command:: query-replay 261 :since: 5.2 262 263 Retrieve the record/replay information. It includes current 264 instruction count which may be used for ``replay-break`` and 265 ``replay-seek`` commands. 266 267 :return-nodesc: ReplayInfo 268 269 .. qmp-example:: 270 271 -> { "execute": "query-replay" } 272 <- { "return": { 273 "mode": "play", "filename": "log.rr", "icount": 220414 } 274 } 275 276``:value:`` 277----------- 278 279Document a possible value for a QAPI enum. 280 281:availability: This field list is only available in the body of the Enum 282 directive. 283:syntax: ``:value name: Lorem ipsum, dolor sit amet ...`` 284:type: `sphinx.util.docfields.GroupedField 285 <https://pydoc.dev/sphinx/latest/sphinx.util.docfields.GroupedField.html?private=1>`_ 286 287Example:: 288 289 .. qapi:enum:: QapiErrorClass 290 :since: 1.2 291 292 QEMU error classes 293 294 :value GenericError: this is used for errors that don't require a specific 295 error class. This should be the default case for most errors 296 :value CommandNotFound: the requested command has not been found 297 :value DeviceNotActive: a device has failed to be become active 298 :value DeviceNotFound: the requested device has not been found 299 :value KVMMissingCap: the requested operation can't be fulfilled because a 300 required KVM capability is missing 301 302 303``:alt:`` 304------------ 305 306Document a possible branch for a QAPI alternate. 307 308:availability: This field list is only available in the body of the 309 Alternate directive. 310:syntax: ``:alt type name: Lorem ipsum, dolor sit amet ...`` 311:type: `sphinx.util.docfields.TypedField 312 <https://pydoc.dev/sphinx/latest/sphinx.util.docfields.TypedField.html?private=1>`_ 313 314As a limitation of Sphinx, we must document the "name" of the branch in 315addition to the type, even though this information is not visible on the 316wire in the QMP protocol format. This limitation *may* be lifted at a 317future date. 318 319Example:: 320 321 .. qapi:alternate:: StrOrNull 322 :since: 2.10 323 324 This is a string value or the explicit lack of a string (null 325 pointer in C). Intended for cases when 'optional absent' already 326 has a different meaning. 327 328 :alt string s: the string value 329 :alt null n: no string value 330 331 332``:memb:`` 333---------- 334 335Document a member of an Event or Object. 336 337:availability: This field list is available in the body of Event or 338 Object directives. 339:syntax: ``:memb type name: Lorem ipsum, dolor sit amet ...`` 340:type: `sphinx.util.docfields.TypedField 341 <https://pydoc.dev/sphinx/latest/sphinx.util.docfields.TypedField.html?private=1>`_ 342 343This is fundamentally the same as ``:arg:`` and ``:alt:``, but uses the 344"Members" phrasing for Events and Objects (Structs and Unions). 345 346Example:: 347 348 .. qapi:event:: JOB_STATUS_CHANGE 349 :since: 3.0 350 351 Emitted when a job transitions to a different status. 352 353 :memb string id: The job identifier 354 :memb JobStatus status: The new job status 355 356 357Arbitrary field lists 358--------------------- 359 360Other field list names, while valid rST syntax, are prohibited inside of 361QAPI directives to help prevent accidental misspellings of info field 362list names. If you want to add a new arbitrary "non-value-added" field 363list to QAPI documentation, you must add the field name to the allow 364list in ``docs/conf.py`` 365 366For example:: 367 368 qapi_allowed_fields = { 369 "see also", 370 } 371 372Will allow you to add arbitrary field lists in QAPI directives:: 373 374 .. qapi:command:: x-fake-command 375 376 :see also: Lorem ipsum, dolor sit amet ... 377 378.. _QAPI-domain-cross-references: 379 380Cross-references 381================ 382 383Cross-reference `roles 384<https://www.sphinx-doc.org/en/master/usage/restructuredtext/roles.html>`_ 385in the QAPI domain are modeled closely after the `Python 386cross-referencing syntax 387<https://www.sphinx-doc.org/en/master/usage/domains/python.html#cross-referencing-python-objects>`_. 388 389QAPI definitions can be referenced using the standard `any 390<https://www.sphinx-doc.org/en/master/usage/referencing.html#role-any>`_ 391role cross-reference syntax, such as with ```query-blockstats```. In 392the event that disambiguation is needed, cross-references can also be 393written using a number of explicit cross-reference roles: 394 395* ``:qapi:mod:`block-core``` -- Reference a QAPI module. The link will 396 take you to the beginning of that section in the documentation. 397* ``:qapi:cmd:`query-block``` -- Reference a QAPI command. 398* ``:qapi:event:`JOB_STATUS_CHANGE``` -- Reference a QAPI event. 399* ``:qapi:enum:`QapiErrorClass``` -- Reference a QAPI enum. 400* ``:qapi:obj:`BlockdevOptionsVirtioBlkVhostVdpa`` -- Reference a QAPI 401 object (struct or union) 402* ``:qapi:alt:`StrOrNull``` -- Reference a QAPI alternate. 403* ``:qapi:type:`BlockDirtyInfo``` -- Reference *any* QAPI type; this 404 excludes modules, commands, and events. 405* ``:qapi:any:`block-job-set-speed``` -- Reference absolutely any QAPI entity. 406 407Type arguments in info field lists are converted into references as if 408you had used the ``:qapi:type:`` role. All of the special syntax below 409applies to both info field lists and standalone explicit 410cross-references. 411 412 413Type decorations 414---------------- 415 416Type names in references can be surrounded by brackets, like 417``[typename]``, to indicate an array of that type. The cross-reference 418will apply only to the type name between the brackets. For example; 419``:qapi:type:`[Qcow2BitmapInfoFlags]``` renders to: 420:qapi:type:`[QMP:Qcow2BitmapInfoFlags]` 421 422To indicate an optional argument/member in a field list, the type name 423can be suffixed with ``?``. The cross-reference will be transformed to 424"type, Optional" with the link applying only to the type name. For 425example; ``:qapi:type:`BitmapSyncMode?``` renders to: 426:qapi:type:`QMP:BitmapSyncMode?` 427 428 429Namespaces 430---------- 431 432Mimicking the `Python domain target specification syntax 433<https://www.sphinx-doc.org/en/master/usage/domains/python.html#target-specification>`_, 434QAPI allows you to specify the fully qualified path for a data 435type. 436 437* A namespace can be explicitly provided; 438 e.g. ``:qapi:type:`QMP:BitmapSyncMode`` 439* A module can be explicitly provided; 440 ``:qapi:type:`QMP:block-core.BitmapSyncMode``` will render to: 441 :qapi:type:`QMP:block-core.BitmapSyncMode` 442* If you don't want to display the "fully qualified" name, it can be 443 prefixed with a tilde; ``:qapi:type:`~QMP:block-core.BitmapSyncMode``` 444 will render to: :qapi:type:`~QMP:block-core.BitmapSyncMode` 445 446 447Target resolution 448----------------- 449 450Any cross-reference to a QAPI type, whether using the ```any``` style of 451reference or the more explicit ```:qapi:any:`target``` syntax, allows 452for the presence or absence of either the namespace or module 453information. 454 455When absent, their value will be inferred from context by the presence 456of any ``qapi:namespace`` or ``qapi:module`` directives preceding the 457cross-reference. 458 459If no results are found when using the inferred values, other 460namespaces/modules will be searched as a last resort; but any explicitly 461provided values must always match in order to succeed. 462 463This allows for efficient cross-referencing with a minimum of syntax in 464the large majority of cases, but additional context or namespace markup 465may be required outside of the QAPI reference documents when linking to 466items that share a name across multiple documented QAPI schema. 467 468 469Custom link text 470---------------- 471 472The name of a cross-reference link can be explicitly overridden like 473`most stock Sphinx references 474<https://www.sphinx-doc.org/en/master/usage/referencing.html#syntax>`_ 475using the ``custom text <target>`` syntax. 476 477For example, ``:qapi:cmd:`Merge dirty bitmaps 478<block-dirty-bitmap-merge>``` will render as: :qapi:cmd:`Merge dirty 479bitmaps <QMP:block-dirty-bitmap-merge>` 480 481 482Directives 483========== 484 485The QAPI domain adds a number of custom directives for documenting 486various QAPI/QMP entities. The syntax is plain rST, and follows this 487general format:: 488 489 .. qapi:directive:: argument 490 :option: 491 :another-option: with an argument 492 493 Content body, arbitrary rST is allowed here. 494 495 496Sphinx standard options 497----------------------- 498 499All QAPI directives inherit a number of `standard options 500<https://www.sphinx-doc.org/en/master/usage/domains/index.html#basic-markup>`_ 501from Sphinx's ObjectDescription class. 502 503The dashed spellings of the below options were added in Sphinx 7.2, the 504undashed spellings are currently retained as aliases, but will be 505removed in a future version. 506 507* ``:no-index:`` and ``:noindex:`` -- Do not add this item into the 508 Index, and do not make it available for cross-referencing. 509* ``no-index-entry:`` and ``:noindexentry:`` -- Do not add this item 510 into the Index, but allow it to be cross-referenced. 511* ``no-contents-entry`` and ``:nocontentsentry:`` -- Exclude this item 512 from the Table of Contents. 513* ``no-typesetting`` -- Create TOC, Index and cross-referencing 514 entities, but don't actually display the content. 515 516 517QAPI standard options 518--------------------- 519 520All QAPI directives -- *except* for namespace and module -- support 521these common options. 522 523* ``:namespace: name`` -- This option allows you to override the 524 namespace association of a given definition. 525* ``:module: modname`` -- Borrowed from the Python domain, this option allows 526 you to override the module association of a given definition. 527* ``:since: x.y`` -- Allows the documenting of "Since" information, which is 528 displayed in the signature bar. 529* ``:ifcond: CONDITION`` -- Allows the documenting of conditional availability 530 information, which is displayed in an eyecatch just below the 531 signature bar. 532* ``:deprecated:`` -- Adds an eyecatch just below the signature bar that 533 advertises that this definition is deprecated and should be avoided. 534* ``:unstable:`` -- Adds an eyecatch just below the signature bar that 535 advertises that this definition is unstable and should not be used in 536 production code. 537 538 539qapi:namespace 540-------------- 541 542The ``qapi:namespace`` directive marks the start of a QAPI namespace. It 543does not take a content body, nor any options. All subsequent QAPI 544directives are associated with the most recent namespace. This affects 545the definition's "fully qualified name", allowing two different 546namespaces to create an otherwise identically named definition. 547 548This directive also influences how reference resolution works for any 549references that do not explicitly specify a namespace, so this directive 550can be used to nudge references into preferring targets from within that 551namespace. 552 553Example:: 554 555 .. qapi:namespace:: QMP 556 557 558This directive has no visible effect. 559 560 561qapi:module 562----------- 563 564The ``qapi:module`` directive marks the start of a QAPI module. It may have 565a content body, but it can be omitted. All subsequent QAPI directives 566are associated with the most recent module; this effects their "fully 567qualified" name, but has no other effect. 568 569Example:: 570 571 .. qapi:module:: block-core 572 573 Welcome to the block-core module! 574 575Will be rendered as: 576 577.. qapi:module:: block-core 578 :noindex: 579 580 Welcome to the block-core module! 581 582 583qapi:command 584------------ 585 586This directive documents a QMP command. It may use any of the standard 587Sphinx or QAPI options, and the documentation body may contain 588``:arg:``, ``:feat:``, ``:error:``, or ``:return:`` info field list 589entries. 590 591Example:: 592 593 .. qapi:command:: x-fake-command 594 :since: 42.0 595 :unstable: 596 597 This command is fake, so it can't hurt you! 598 599 :arg int foo: Your favorite number. 600 :arg string? bar: Your favorite season. 601 :return [string]: A lovely computer-written poem for you. 602 603 604Will be rendered as: 605 606 .. qapi:command:: x-fake-command 607 :noindex: 608 :since: 42.0 609 :unstable: 610 611 This command is fake, so it can't hurt you! 612 613 :arg int foo: Your favorite number. 614 :arg string? bar: Your favorite season. 615 :return [string]: A lovely computer-written poem for you. 616 617 618qapi:event 619---------- 620 621This directive documents a QMP event. It may use any of the standard 622Sphinx or QAPI options, and the documentation body may contain 623``:memb:`` or ``:feat:`` info field list entries. 624 625Example:: 626 627 .. qapi:event:: COMPUTER_IS_RUINED 628 :since: 0.1 629 :deprecated: 630 631 This event is emitted when your computer is *extremely* ruined. 632 633 :memb string reason: Diagnostics as to what caused your computer to 634 be ruined. 635 :feat sadness: When present, the diagnostic message will also 636 explain how sad the computer is as a result of your wrongdoings. 637 638Will be rendered as: 639 640.. qapi:event:: COMPUTER_IS_RUINED 641 :noindex: 642 :since: 0.1 643 :deprecated: 644 645 This event is emitted when your computer is *extremely* ruined. 646 647 :memb string reason: Diagnostics as to what caused your computer to 648 be ruined. 649 :feat sadness: When present, the diagnostic message will also explain 650 how sad the computer is as a result of your wrongdoings. 651 652 653qapi:enum 654--------- 655 656This directive documents a QAPI enum. It may use any of the standard 657Sphinx or QAPI options, and the documentation body may contain 658``:value:`` or ``:feat:`` info field list entries. 659 660Example:: 661 662 .. qapi:enum:: Mood 663 :ifcond: LIB_PERSONALITY 664 665 This enum represents your virtual machine's current mood! 666 667 :value Happy: Your VM is content and well-fed. 668 :value Hungry: Your VM needs food. 669 :value Melancholic: Your VM is experiencing existential angst. 670 :value Petulant: Your VM is throwing a temper tantrum. 671 672Will be rendered as: 673 674.. qapi:enum:: Mood 675 :noindex: 676 :ifcond: LIB_PERSONALITY 677 678 This enum represents your virtual machine's current mood! 679 680 :value Happy: Your VM is content and well-fed. 681 :value Hungry: Your VM needs food. 682 :value Melancholic: Your VM is experiencing existential angst. 683 :value Petulant: Your VM is throwing a temper tantrum. 684 685 686qapi:object 687----------- 688 689This directive documents a QAPI structure or union and represents a QMP 690object. It may use any of the standard Sphinx or QAPI options, and the 691documentation body may contain ``:memb:`` or ``:feat:`` info field list 692entries. 693 694Example:: 695 696 .. qapi:object:: BigBlobOfStuff 697 698 This object has a bunch of disparate and unrelated things in it. 699 700 :memb int Birthday: Your birthday, represented in seconds since the 701 UNIX epoch. 702 :memb [string] Fav-Foods: A list of your favorite foods. 703 :memb boolean? Bizarre-Docs: True if the documentation reference 704 should be strange. 705 706Will be rendered as: 707 708.. qapi:object:: BigBlobOfStuff 709 :noindex: 710 711 This object has a bunch of disparate and unrelated things in it. 712 713 :memb int Birthday: Your birthday, represented in seconds since the 714 UNIX epoch. 715 :memb [string] Fav-Foods: A list of your favorite foods. 716 :memb boolean? Bizarre-Docs: True if the documentation reference 717 should be strange. 718 719 720qapi:alternate 721-------------- 722 723This directive documents a QAPI alternate. It may use any of the 724standard Sphinx or QAPI options, and the documentation body may contain 725``:alt:`` or ``:feat:`` info field list entries. 726 727Example:: 728 729 .. qapi:alternate:: ErrorCode 730 731 This alternate represents an Error Code from the VM. 732 733 :alt int ec: An error code, like the type you're used to. 734 :alt string em: An expletive-laced error message, if your 735 computer is feeling particularly cranky and tired of your 736 antics. 737 738Will be rendered as: 739 740.. qapi:alternate:: ErrorCode 741 :noindex: 742 743 This alternate represents an Error Code from the VM. 744 745 :alt int ec: An error code, like the type you're used to. 746 :alt string em: An expletive-laced error message, if your 747 computer is feeling particularly cranky and tired of your 748 antics. 749