diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index fd3f2fb..4fe3435 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -262,6 +262,7 @@ jobs: rpm -qp --qf '[%{FILEMODES:perms} %{FILENAMES}\n]' "$rpm" | grep -v '^d' | cut -d' ' -f2 | sort > files.txt printf '%s\n' /usr/include/plugin-hostd/protocol.h /usr/include/plugin-hostd/pin.h /usr/share/pkgconfig/plugin-hostd.pc \ /usr/include/plugin-hostd/plugin_hostd_host_verbs.h /usr/include/plugin-hostd/plugin_hostd_vocabulary.h \ + /usr/include/plugin-hostd/omx_clap_core_host_verbs.h /usr/include/plugin-hostd/omx_clap_core_vocabulary.h \ /usr/share/plugin-hostd/protocol.schema.json /usr/share/plugin-hostd/probe-output.schema.json /usr/share/plugin-hostd/preset.schema.json \ /usr/share/licenses/plugin-hostd-devel/COPYING | sort > expected.txt diff -u expected.txt files.txt diff --git a/Makefile b/Makefile index 1532cd4..8a4e904 100644 --- a/Makefile +++ b/Makefile @@ -64,9 +64,11 @@ SRC = src/main.c src/conf.c src/proc.c src/supervisor.c src/verbs.c src/pins.c s src/descriptors.c src/describe.c src/transforms.c src/json.c src/fsutil.c src/machine.c src/history.c src/planner.c src/qualcost.c OBJ = $(SRC:.c=.o) -# the C names of the daemon's verbs and reply codes, rendered from data/verbs.json (render-verbs below); protocol.h +# the C names of the daemon's verbs and reply codes, rendered from data/verbs.json (render-verbs below), and of the verbs +# and reply codes it shares with omx-clap-host, rendered from omx-clap-core's package of the contract directory; protocol.h # includes them -RENDERED = include/plugin-hostd/plugin_hostd_host_verbs.h include/plugin-hostd/plugin_hostd_vocabulary.h +RENDERED = include/plugin-hostd/plugin_hostd_host_verbs.h include/plugin-hostd/plugin_hostd_vocabulary.h \ + include/plugin-hostd/omx_clap_core_host_verbs.h include/plugin-hostd/omx_clap_core_vocabulary.h # default build all: $(PROG) $(PROBE) @@ -157,6 +159,12 @@ render-verbs check-rendered: sh $(INSTALL_CONTRACT_DIR) $(PROG) $(VERSION) $(CONTRACT_SCHEMA_MAJOR) data $$tmp data >/dev/null; \ OMX_CONTRACT_PATH=$$tmp$(if $(OMX_CONTRACT_PATH),:$(OMX_CONTRACT_PATH)):$(CONTRACTDIR) \ $(OMX_CONTRACT) render --target c --package $(PROG) --installed --out include/plugin-hostd $(if $(filter check-rendered,$@),--check) + @set -e; tmp=$$(mktemp -d); trap 'rm -rf $$tmp' EXIT; \ + OMX_CONTRACT_PATH=$(if $(OMX_CONTRACT_PATH),$(OMX_CONTRACT_PATH):)$(CONTRACTDIR) \ + $(OMX_CONTRACT) render --target c --package omx-clap-core --installed --out $$tmp; \ + for f in omx_clap_core_host_verbs.h omx_clap_core_vocabulary.h; do \ + $(if $(filter check-rendered,$@),cmp -s $$tmp/$$f include/plugin-hostd/$$f || { echo "include/plugin-hostd/$$f is not the render of omx-clap-core's package" >&2; exit 1; },cp $$tmp/$$f include/plugin-hostd/$$f); \ + done # the tables cover their format (tests/format_coverage.py, docs/formats.md#the-coverage-test): every term of # omx-contract's installed TERM files and every row with a from, once per format, each field one row; then its sabotage diff --git a/README.md b/README.md index 3632576..76890a0 100644 --- a/README.md +++ b/README.md @@ -376,38 +376,38 @@ Error codes the daemon adds to mod-host's: | code | name | meaning | |---|---|---| -| `-501` | `PHD_ERR_PLACEMENT_INVALID` | placement invalid: not a placement, or not valid here, as a pool: for a plugin of a format whose pin holds only in a world of the plugin's own, while require_pins is on | -| `-502` | `PHD_ERR_NO_BACKEND` | no worker program for the scheme | -| `-503` | `PHD_ERR_WORKER_SPAWN` | the worker is not up: the spawn failed, or it is in backoff; ask again after instance_restored | -| `-504` | `PHD_ERR_REPLAY` | the name of a refused replay, never a reply: a replayed add that its pin or the worker refuses is announced by the instance_replay_refused event with the refusal's own code, and written to stderr with this one and the step that refused it | -| `-505` | `PHD_ERR_GAVE_UP` | the storm bound is spent for that placement | -| `-506` | `PHD_ERR_NO_SUCH_WORKER` | no such worker | -| `-507` | `PHD_ERR_VERB_DROPPED` | the worker died on this very command and the daemon dropped it: it is not replayed, and the instance_verb_dropped event names it; or it died on, or did not answer in rpc_timeout_ms, the pin_expect of an add, which is then never forwarded | -| `-508` | `PHD_ERR_PIN_ABSENT` | pin_mode strict and the plugin has no pin, or its layout pin is in a scheme this version does not know: add is refused and no worker sees it | -| `-509` | `PHD_ERR_PIN_BINARY_MISMATCH` | a pinned file is missing or its SHA-256 differs, or the plugin's manifest names a file the pin does not hold: add is refused and no worker sees it | -| `-510` | `PHD_ERR_PIN_LAYOUT_MISMATCH` | the worker found the parameter layout after init differs from the layout pin: the instance is destroyed before activate | -| `-511` | `PHD_ERR_NO_PARAM_CONTRACT` | the host holds no checked unit and scale for this parameter: fall back to qualification | -| `-512` | `PHD_ERR_LV2_ADAPTER_REFUSED` | the lv2-clap worker's LV2 adapter cannot run this plugin (MIDI it does not feed, a required feature it lacks, a layout it does not take): the worker answered the add -102, the lv2_adapter_refused event carries the hosting.* code of that reply, and under lv2_worker auto the plugin is run by the lv2 row instead and this code is never answered; a plugin no bundle of the worker's world holds is no refusal: the worker's -101 is answered | -| `-513` | `PHD_ERR_NO_NOTE_INPUT` | the instance's plugin takes no notes (an effect): its worker answers note_on, note_off and all_notes_off with this code | -| `-514` | `PHD_ERR_NOTES_BY_JACK` | the instance's worker takes no notes on its socket (mod-host): the daemon answers the note verbs and note_input with this code, and the plugin is played through its jack MIDI input with connect | -| `-515` | `PHD_ERR_NO_PRESET_LIST` | the instance's worker cannot list the plugin's presets (mod-host): the daemon answers preset_list and preset_get with this code; preset_load still takes a preset the controller knows | -| `-516` | `PHD_ERR_PIN_REFUSED` | the plugin's pin carries verdict=refused: its files are the ones that failed qualification, so add is refused and no worker sees it, and a replayed add is refused the same way; files that differ from the pin answer (-509) first. A pins_dir pin of that verdict is never overridden: pin_set and pin_accept of its plugin answer this code | -| `-517` | `PHD_ERR_NOTE_QUEUE_FULL` | the instance's worker has no room for this note_on, note_off or all_notes_off before its next block: the line was not taken and nothing of it is kept; the controller may send it again | -| `-518` | `PHD_ERR_CHAIN_UNKNOWN_INSTANCE` | a member of chain is an instance no add made: the chain is not declared | -| `-519` | `PHD_ERR_CHAIN_DUPLICATE` | an instance is named twice in one chain: the chain is not declared | -| `-520` | `PHD_ERR_CHAIN_INSTANCE_BUSY` | a member of chain is already in another chain: the chain is not declared; chain_clear of the other chain frees it | -| `-521` | `PHD_ERR_CHAIN_MIXED_FORMAT` | the members of chain are not all run by one worker program, or are of two rows of one program and a row does not run chains in one client, so no one worker runs them: the chain is not declared | -| `-522` | `PHD_ERR_NO_SUCH_CHAIN` | chain_clear or chain_get of a chain no chain declared | -| `-523` | `PHD_ERR_PRESET_NOT_OFFERED` | the worker: preset_load or preset_show of a stable name the plugin does not offer, or of a plugin with no preset system and no state | -| `-524` | `PHD_ERR_PRESET_INVALID` | preset_save with a file path that is not absolute or with no name, or preset_load or preset_show of a file that cannot be read, is no JSON, is of a format version other than org.openmixer.preset/1 and org.openmixer.preset/2, or breaks the format (docs/presets.md): the daemon answers it and no worker sees the file | -| `-525` | `PHD_ERR_PRESET_NEEDS_STATE` | the worker: a preset file that carries state for a worker that cannot take state yet | -| `-526` | `PHD_ERR_PRESET_PLUGIN_CHANGED` | the worker: the preset file's plugin id, version or fingerprint is not the instance's; nothing of it is applied | -| `-527` | `PHD_ERR_LOAD_REFUSED` | the worker: the plugin refused the preset or the state its file carries | -| `-528` | `PHD_ERR_DIR_NOT_WRITABLE` | descriptor_dir or qualification_dir cannot be made or written: the daemon does not start, and says which key and which path on stderr with this code; a directory that turns read-only later makes the scan of an add write nothing, and descriptor_get and panel_get of that plugin answer this code | -| `-529` | `PHD_ERR_DESCRIPTOR_ABSENT` | descriptor_get (panel_get) of a plugin that has no descriptor (panel) in descriptor_dir for its binary as it is now, and none being written: no add since it changed, or a binary that cannot be found | -| `-530` | `PHD_ERR_DESCRIPTOR_PENDING` | descriptor_get (panel_get) of a plugin whose scan, started by its add, has not written its descriptor (panel) yet: ask again | -| `-531` | `PHD_ERR_DESCRIPTOR_SCAN_FAILED` | descriptor_get (panel_get) of a plugin whose last scan wrote no descriptor (panel): the scanner refused the plugin, made no dump or no panel, or is not installed; the add it ran for stands, and stderr and the scan's log say why. The next add scans again | -| `-532` | `PHD_ERR_NO_SUCH_PLAN` | plan_get or plan_clear of a chain no plan planned | +| `-501` | `OMX_REPLY_PLUGIN_HOSTD_PLACEMENT_INVALID_RESP` | placement invalid: not a placement, or not valid here, as a pool: for a plugin of a format whose pin holds only in a world of the plugin's own, while require_pins is on | +| `-502` | `OMX_REPLY_PLUGIN_HOSTD_NO_BACKEND_RESP` | no worker program for the scheme | +| `-503` | `OMX_REPLY_PLUGIN_HOSTD_WORKER_SPAWN_RESP` | the worker is not up: the spawn failed, or it is in backoff; ask again after instance_restored | +| `-504` | `OMX_REPLY_PLUGIN_HOSTD_REPLAY_RESP` | the name of a refused replay, never a reply: a replayed add that its pin or the worker refuses is announced by the instance_replay_refused event with the refusal's own code, and written to stderr with this one and the step that refused it | +| `-505` | `OMX_REPLY_PLUGIN_HOSTD_GAVE_UP_RESP` | the storm bound is spent for that placement | +| `-506` | `OMX_REPLY_PLUGIN_HOSTD_NO_SUCH_WORKER_RESP` | no such worker | +| `-507` | `OMX_REPLY_PLUGIN_HOSTD_VERB_DROPPED_RESP` | the worker died on this very command and the daemon dropped it: it is not replayed, and the instance_verb_dropped event names it; or it died on, or did not answer in rpc_timeout_ms, the pin_expect of an add, which is then never forwarded | +| `-508` | `OMX_REPLY_HOST_PIN_ABSENT_RESP` | pin_mode strict and the plugin has no pin, or its layout pin is in a scheme this version does not know: add is refused and no worker sees it | +| `-509` | `OMX_REPLY_PLUGIN_HOSTD_PIN_BINARY_MISMATCH_RESP` | a pinned file is missing or its SHA-256 differs, or the plugin's manifest names a file the pin does not hold: add is refused and no worker sees it | +| `-510` | `OMX_REPLY_HOST_PIN_LAYOUT_MISMATCH_RESP` | the worker found the parameter layout after init differs from the layout pin: the instance is destroyed before activate | +| `-511` | `OMX_REPLY_HOST_NO_PARAM_CONTRACT_RESP` | the host holds no checked unit and scale for this parameter: fall back to qualification | +| `-512` | `OMX_REPLY_PLUGIN_HOSTD_LV2_ADAPTER_REFUSED_RESP` | the lv2-clap worker's LV2 adapter cannot run this plugin (MIDI it does not feed, a required feature it lacks, a layout it does not take): the worker answered the add -102, the lv2_adapter_refused event carries the hosting.* code of that reply, and under lv2_worker auto the plugin is run by the lv2 row instead and this code is never answered; a plugin no bundle of the worker's world holds is no refusal: the worker's -101 is answered | +| `-513` | `OMX_REPLY_HOST_NO_NOTE_INPUT_RESP` | the instance's plugin takes no notes (an effect): its worker answers note_on, note_off and all_notes_off with this code | +| `-514` | `OMX_REPLY_HOST_NOTES_BY_JACK_RESP` | the instance's worker takes no notes on its socket (mod-host): the daemon answers the note verbs and note_input with this code, and the plugin is played through its jack MIDI input with connect | +| `-515` | `OMX_REPLY_PLUGIN_HOSTD_NO_PRESET_LIST_RESP` | the instance's worker cannot list the plugin's presets (mod-host): the daemon answers preset_list and preset_get with this code; preset_load still takes a preset the controller knows | +| `-516` | `OMX_REPLY_PLUGIN_HOSTD_PIN_REFUSED_RESP` | the plugin's pin carries verdict=refused: its files are the ones that failed qualification, so add is refused and no worker sees it, and a replayed add is refused the same way; files that differ from the pin answer (-509) first. A pins_dir pin of that verdict is never overridden: pin_set and pin_accept of its plugin answer this code | +| `-517` | `OMX_REPLY_HOST_NOTE_QUEUE_FULL_RESP` | the instance's worker has no room for this note_on, note_off or all_notes_off before its next block: the line was not taken and nothing of it is kept; the controller may send it again | +| `-518` | `OMX_REPLY_PLUGIN_HOSTD_CHAIN_UNKNOWN_INSTANCE_RESP` | a member of chain is an instance no add made: the chain is not declared | +| `-519` | `OMX_REPLY_PLUGIN_HOSTD_CHAIN_DUPLICATE_RESP` | an instance is named twice in one chain: the chain is not declared | +| `-520` | `OMX_REPLY_PLUGIN_HOSTD_CHAIN_INSTANCE_BUSY_RESP` | a member of chain is already in another chain: the chain is not declared; chain_clear of the other chain frees it | +| `-521` | `OMX_REPLY_PLUGIN_HOSTD_CHAIN_MIXED_FORMAT_RESP` | the members of chain are not all run by one worker program, or are of two rows of one program and a row does not run chains in one client, so no one worker runs them: the chain is not declared | +| `-522` | `OMX_REPLY_PLUGIN_HOSTD_NO_SUCH_CHAIN_RESP` | chain_clear or chain_get of a chain no chain declared | +| `-523` | `OMX_REPLY_PLUGIN_HOSTD_PRESET_NOT_OFFERED_RESP` | the worker: preset_load or preset_show of a stable name the plugin does not offer, or of a plugin with no preset system and no state | +| `-524` | `OMX_REPLY_PLUGIN_HOSTD_PRESET_INVALID_RESP` | preset_save with a file path that is not absolute or with no name, or preset_load or preset_show of a file that cannot be read, is no JSON, is of a format version other than org.openmixer.preset/1 and org.openmixer.preset/2, or breaks the format (docs/presets.md): the daemon answers it and no worker sees the file | +| `-525` | `OMX_REPLY_PLUGIN_HOSTD_PRESET_NEEDS_STATE_RESP` | the worker: a preset file that carries state for a worker that cannot take state yet | +| `-526` | `OMX_REPLY_PLUGIN_HOSTD_PRESET_PLUGIN_CHANGED_RESP` | the worker: the preset file's plugin id, version or fingerprint is not the instance's; nothing of it is applied | +| `-527` | `OMX_REPLY_PLUGIN_HOSTD_LOAD_REFUSED_RESP` | the worker: the plugin refused the preset or the state its file carries | +| `-528` | `OMX_REPLY_PLUGIN_HOSTD_DIR_NOT_WRITABLE_RESP` | descriptor_dir or qualification_dir cannot be made or written: the daemon does not start, and says which key and which path on stderr with this code; a directory that turns read-only later makes the scan of an add write nothing, and descriptor_get and panel_get of that plugin answer this code | +| `-529` | `OMX_REPLY_PLUGIN_HOSTD_DESCRIPTOR_ABSENT_RESP` | descriptor_get (panel_get) of a plugin that has no descriptor (panel) in descriptor_dir for its binary as it is now, and none being written: no add since it changed, or a binary that cannot be found | +| `-530` | `OMX_REPLY_PLUGIN_HOSTD_DESCRIPTOR_PENDING_RESP` | descriptor_get (panel_get) of a plugin whose scan, started by its add, has not written its descriptor (panel) yet: ask again | +| `-531` | `OMX_REPLY_PLUGIN_HOSTD_DESCRIPTOR_SCAN_FAILED_RESP` | descriptor_get (panel_get) of a plugin whose last scan wrote no descriptor (panel): the scanner refused the plugin, made no dump or no panel, or is not installed; the add it ran for stands, and stderr and the scan's log say why. The next add scans again | +| `-532` | `OMX_REPLY_PLUGIN_HOSTD_NO_SUCH_PLAN_RESP` | plan_get or plan_clear of a chain no plan planned | A worker's own refusal is returned as it said it. An `add` that killed its worker answers mod-host's `-102`. @@ -586,7 +586,7 @@ What cannot be pinned: - a path holding ',', '=' or whitespace cannot be pinned: they are the separators of pin_set's words, and pin_set refuses it as a token outside its grammar. - a pin_set line is at most line_max, 4096 bytes, the protocol socket's buffer; a longer one is refused as outside the grammar. -- a manifest that uses @base, or names a file of the plugin by a percent-encoded IRI, makes add answer PHD_ERR_PIN_BINARY_MISMATCH (-509): the daemon does not resolve either, so it cannot know the file the host would load. +- a manifest that uses @base, or names a file of the plugin by a percent-encoded IRI, makes add answer OMX_REPLY_PLUGIN_HOSTD_PIN_BINARY_MISMATCH_RESP (-509): the daemon does not resolve either, so it cannot know the file the host would load. Pins are the controller's policy, like `policy_set`: not in the ledger, gone with the daemon, set again by a controller diff --git a/data/verbs.json b/data/verbs.json index 332fd4a..c0b29bf 100644 --- a/data/verbs.json +++ b/data/verbs.json @@ -12,132 +12,132 @@ "placementInvalid": { "code": "reply.plugin-hostd.placement-invalid", "resp": -501, - "doc": "PHD_ERR_PLACEMENT_INVALID: not a placement, or not valid here" + "doc": "not a placement, or not valid here" }, "noBackend": { "code": "reply.plugin-hostd.no-backend", "resp": -502, - "doc": "PHD_ERR_NO_BACKEND: no worker program for the scheme" + "doc": "no worker program for the scheme" }, "workerSpawn": { "code": "reply.plugin-hostd.worker-spawn", "resp": -503, - "doc": "PHD_ERR_WORKER_SPAWN: the worker is not up" + "doc": "the worker is not up" }, "replay": { "code": "reply.plugin-hostd.replay", "resp": -504, - "doc": "PHD_ERR_REPLAY: the name of a refused replay on stderr, never a reply" + "doc": "the name of a refused replay on stderr, never a reply" }, "gaveUp": { "code": "reply.plugin-hostd.gave-up", "resp": -505, - "doc": "PHD_ERR_GAVE_UP: the storm bound is spent for that placement" + "doc": "the storm bound is spent for that placement" }, "noSuchWorker": { "code": "reply.plugin-hostd.no-such-worker", "resp": -506, - "doc": "PHD_ERR_NO_SUCH_WORKER: no such worker" + "doc": "no such worker" }, "verbDropped": { "code": "reply.plugin-hostd.verb-dropped", "resp": -507, - "doc": "PHD_ERR_VERB_DROPPED: the worker died on this very command and the daemon dropped it" + "doc": "the worker died on this very command and the daemon dropped it" }, "pinBinaryMismatch": { "code": "reply.plugin-hostd.pin-binary-mismatch", "resp": -509, - "doc": "PHD_ERR_PIN_BINARY_MISMATCH: a pinned file is missing or its SHA-256 differs" + "doc": "a pinned file is missing or its SHA-256 differs" }, "lv2AdapterRefused": { "code": "reply.plugin-hostd.lv2-adapter-refused", "resp": -512, - "doc": "PHD_ERR_LV2_ADAPTER_REFUSED: the lv2-clap worker's LV2 adapter cannot run this plugin" + "doc": "the lv2-clap worker's LV2 adapter cannot run this plugin" }, "noPresetList": { "code": "reply.plugin-hostd.no-preset-list", "resp": -515, - "doc": "PHD_ERR_NO_PRESET_LIST: the instance's worker cannot list the plugin's presets" + "doc": "the instance's worker cannot list the plugin's presets" }, "pinRefused": { "code": "reply.plugin-hostd.pin-refused", "resp": -516, - "doc": "PHD_ERR_PIN_REFUSED: the plugin's pin carries verdict=refused" + "doc": "the plugin's pin carries verdict=refused" }, "chainUnknownInstance": { "code": "reply.plugin-hostd.chain-unknown-instance", "resp": -518, - "doc": "PHD_ERR_CHAIN_UNKNOWN_INSTANCE: a member is an instance no add made" + "doc": "a member is an instance no add made" }, "chainDuplicate": { "code": "reply.plugin-hostd.chain-duplicate", "resp": -519, - "doc": "PHD_ERR_CHAIN_DUPLICATE: an instance is named twice in one chain" + "doc": "an instance is named twice in one chain" }, "chainInstanceBusy": { "code": "reply.plugin-hostd.chain-instance-busy", "resp": -520, - "doc": "PHD_ERR_CHAIN_INSTANCE_BUSY: a member is already in another chain" + "doc": "a member is already in another chain" }, "chainMixedFormat": { "code": "reply.plugin-hostd.chain-mixed-format", "resp": -521, - "doc": "PHD_ERR_CHAIN_MIXED_FORMAT: no one worker program runs every member" + "doc": "no one worker program runs every member" }, "noSuchChain": { "code": "reply.plugin-hostd.no-such-chain", "resp": -522, - "doc": "PHD_ERR_NO_SUCH_CHAIN: a chain no chain line declared" + "doc": "a chain no chain line declared" }, "presetNotOffered": { "code": "reply.plugin-hostd.preset-not-offered", "resp": -523, - "doc": "PHD_ERR_PRESET_NOT_OFFERED: a stable name the plugin does not offer" + "doc": "a stable name the plugin does not offer" }, "presetInvalid": { "code": "reply.plugin-hostd.preset-invalid", "resp": -524, - "doc": "PHD_ERR_PRESET_INVALID: a preset file or path that is not the preset format" + "doc": "a preset file or path that is not the preset format" }, "presetNeedsState": { "code": "reply.plugin-hostd.preset-needs-state", "resp": -525, - "doc": "PHD_ERR_PRESET_NEEDS_STATE: a preset file that carries state for a worker that cannot take state" + "doc": "a preset file that carries state for a worker that cannot take state" }, "presetPluginChanged": { "code": "reply.plugin-hostd.preset-plugin-changed", "resp": -526, - "doc": "PHD_ERR_PRESET_PLUGIN_CHANGED: the preset file's plugin id, version or fingerprint is not the instance's" + "doc": "the preset file's plugin id, version or fingerprint is not the instance's" }, "loadRefused": { "code": "reply.plugin-hostd.load-refused", "resp": -527, - "doc": "PHD_ERR_LOAD_REFUSED: the plugin refused the preset or the state its file carries" + "doc": "the plugin refused the preset or the state its file carries" }, "dirNotWritable": { "code": "reply.plugin-hostd.dir-not-writable", "resp": -528, - "doc": "PHD_ERR_DIR_NOT_WRITABLE: descriptor_dir or qualification_dir cannot be made or written" + "doc": "descriptor_dir or qualification_dir cannot be made or written" }, "descriptorAbsent": { "code": "reply.plugin-hostd.descriptor-absent", "resp": -529, - "doc": "PHD_ERR_DESCRIPTOR_ABSENT: no descriptor (panel) for the plugin's binary as it is now" + "doc": "no descriptor (panel) for the plugin's binary as it is now" }, "descriptorPending": { "code": "reply.plugin-hostd.descriptor-pending", "resp": -530, - "doc": "PHD_ERR_DESCRIPTOR_PENDING: the scan its add started has not written the descriptor (panel) yet" + "doc": "the scan its add started has not written the descriptor (panel) yet" }, "descriptorScanFailed": { "code": "reply.plugin-hostd.descriptor-scan-failed", "resp": -531, - "doc": "PHD_ERR_DESCRIPTOR_SCAN_FAILED: the plugin's last scan wrote no descriptor (panel)" + "doc": "the plugin's last scan wrote no descriptor (panel)" }, "noSuchPlan": { "code": "reply.plugin-hostd.no-such-plan", "resp": -532, - "doc": "PHD_ERR_NO_SUCH_PLAN: a chain no plan verb planned" + "doc": "a chain no plan verb planned" } } }, diff --git a/debian/plugin-hostd-dev.install b/debian/plugin-hostd-dev.install index df1330b..9881379 100644 --- a/debian/plugin-hostd-dev.install +++ b/debian/plugin-hostd-dev.install @@ -1,5 +1,7 @@ usr/include/plugin-hostd/protocol.h usr/include/plugin-hostd/plugin_hostd_host_verbs.h +usr/include/plugin-hostd/omx_clap_core_host_verbs.h +usr/include/plugin-hostd/omx_clap_core_vocabulary.h usr/include/plugin-hostd/plugin_hostd_vocabulary.h usr/include/plugin-hostd/pin.h usr/share/pkgconfig/plugin-hostd.pc diff --git a/doc/plugin-hostd.1 b/doc/plugin-hostd.1 index ffef62c..34f4d58 100644 --- a/doc/plugin-hostd.1 +++ b/doc/plugin-hostd.1 @@ -175,7 +175,7 @@ a path holding ',', '=' or whitespace cannot be pinned: they are the separators .IP \(bu 2 a pin_set line is at most line_max, 4096 bytes, the protocol socket's buffer; a longer one is refused as outside the grammar. .IP \(bu 2 -a manifest that uses @base, or names a file of the plugin by a percent\-encoded IRI, makes add answer PHD_ERR_PIN_BINARY_MISMATCH (\-509): the daemon does not resolve either, so it cannot know the file the host would load. +a manifest that uses @base, or names a file of the plugin by a percent\-encoded IRI, makes add answer OMX_REPLY_PLUGIN_HOSTD_PIN_BINARY_MISMATCH_RESP (\-509): the daemon does not resolve either, so it cannot know the file the host would load. .\" END GENERATED protocol:man-pin-limits .SH WORKER FEEDBACK What a worker writes on its feedback port reaches the controller on the daemon's: diff --git a/fuzz/fuzz_command.c b/fuzz/fuzz_command.c index ffde610..d0b5d52 100644 --- a/fuzz/fuzz_command.c +++ b/fuzz/fuzz_command.c @@ -264,7 +264,7 @@ __attribute__((noinline)) static void check_reply(const struct words *w) * grammar is mod-host's, so each worker's mod-host refuses them */ static int passed_on(const char *verb) { - return !strcmp(verb, OMX_VERB_PIN_LAYOUT) || !strcmp(verb, PHD_VERB_PIN_EXPECT) || verb_is(verb, EFFECT_CONNECT) || + return !strcmp(verb, OMX_VERB_PIN_LAYOUT) || !strcmp(verb, OMX_VERB_PIN_EXPECT) || verb_is(verb, EFFECT_CONNECT) || verb_is(verb, EFFECT_DISCONNECT); } diff --git a/fuzz/recorder.c b/fuzz/recorder.c index 5fb20b9..67290a2 100644 --- a/fuzz/recorder.c +++ b/fuzz/recorder.c @@ -48,7 +48,7 @@ const int rec_codes[] = { ERR_ASSIGNMENT_ALREADY_EXISTS, ERR_ASSIGNMENT_INVALID_OP, ERR_ASSIGNMENT_LIST_FULL, ERR_ASSIGNMENT_FAILED, ERR_ASSIGNMENT_UNUSED, ERR_CONTROL_CHAIN_UNAVAILABLE, ERR_ABLETON_LINK_UNAVAILABLE, ERR_HMI_UNAVAILABLE, ERR_EXTERNAL_UI_UNAVAILABLE, ERR_MEMORY_ALLOCATION, ERR_INVALID_OPERATION, -#define X(id, meaning) PHD_ERR_##id, +#define X(id, resp, meaning) resp, PHD_ERRORS(X) #undef X }; @@ -261,7 +261,7 @@ static char *answer(struct rec_call *c, const char *shape, int changes) if (changes) g_rec.state = mix_call(g_rec.state, c); /* the reply a verb declares fits one line of the protocol - * mutant: include/plugin-hostd/protocol.h:53 `4096` -> `4` + * mutant: include/plugin-hostd/protocol.h:56 `4096` -> `4` * input: mod-host-bypass */ if (syntax_instantiate(shape, buf, sizeof(buf)) < 0) abort(); diff --git a/include/plugin-hostd/omx_clap_core_host_verbs.h b/include/plugin-hostd/omx_clap_core_host_verbs.h new file mode 100644 index 0000000..0a1812f --- /dev/null +++ b/include/plugin-hostd/omx_clap_core_host_verbs.h @@ -0,0 +1,173 @@ +// SPDX-License-Identifier: GPL-3.0-or-later +// Copyright (C) 2026 Pau Aliagas +#ifndef OMX_CLAP_CORE_HOST_VERBS_H +#define OMX_CLAP_CORE_HOST_VERBS_H +/* + * GENERATED: DO NOT EDIT BY HAND. + * Produced by `omx-contract render --target c` from omx-clap-core's files. + * The host verbs (docs/contract-dir.md): a verb is OMX_VERB_, its word, OMX_VERB__FMT, the line + * protocol_add_command takes, and OMX_VERB__REPLY; a verb that answers refusals carries their resp numbers + * in OMX_VERB__CODES_INIT. omx_clap_core_host_verbs() is the table of what each host owes each verb. + */ + +#include + +#ifndef OMX_HOST_VERB_TYPES_H +#define OMX_HOST_VERB_TYPES_H +/* What a host owes a verb: required, answered as its grammar says; optional, answered or refused, never misread; + * unsupported, refused on purpose. */ +enum omx_host_verb_level { + OMX_HOST_VERB_UNSUPPORTED = 0, + OMX_HOST_VERB_OPTIONAL = 1, + OMX_HOST_VERB_REQUIRED = 2, +}; +/* The hosts of VERB_HOSTS, a column each of a verb's level, in this order. */ +#define OMX_HOST_VERB_HOST_PLUGIN_HOSTD 0u +#define OMX_HOST_VERB_HOST_OMX_CLAP_HOST 1u +#define OMX_HOST_VERB_HOST_MOD_HOST 2u +#define OMX_HOST_VERB_HOST_COUNT 3u +#define OMX_HOST_VERB_HOSTS_INIT { "plugin-hostd", "omx-clap-host", "mod-host" } +struct omx_host_verb { + const char *verb; + const char *format; + const char *reply; + enum omx_host_verb_level level[OMX_HOST_VERB_HOST_COUNT]; +}; +#endif /* OMX_HOST_VERB_TYPES_H */ + +/* OMX_CLAP_CORE_SHARED_VERBS.trackInfo (data/verbs.json): The strip's name, colour and kind: <#RRGGBB | -> [bus | return | master]; a string word is at most 255 bytes of UTF-8 with no control character, and any other word is -902. A CLAP plugin reads them through clap.track-info. */ +#define OMX_VERB_TRACK_INFO "track_info" +#define OMX_VERB_TRACK_INFO_FMT "track_info %i %s %s ..." +#define OMX_VERB_TRACK_INFO_REPLY "resp 0" +#define OMX_VERB_TRACK_INFO_CODES_COUNT 2u +#define OMX_VERB_TRACK_INFO_CODES_INIT { -902, -3 } /* reply.host.invalid-operation, reply.host.instance-non-exists */ + +/* OMX_CLAP_CORE_SHARED_VERBS.remotePages (data/verbs.json): The plugin's remote-control pages, from clap.remote-controls; 0 for a plugin that has none. */ +#define OMX_VERB_REMOTE_PAGES "remote_pages" +#define OMX_VERB_REMOTE_PAGES_FMT "remote_pages %i" +#define OMX_VERB_REMOTE_PAGES_REPLY "resp " +#define OMX_VERB_REMOTE_PAGES_CODES_COUNT 2u +#define OMX_VERB_REMOTE_PAGES_CODES_INIT { -902, -3 } /* reply.host.invalid-operation, reply.host.instance-non-exists */ + +/* OMX_CLAP_CORE_SHARED_VERBS.remotePageGet (data/verbs.json): One page, 0 to count - 1: its section and name as quoted words, and each slot the symbol param_set takes, - for an empty one; -902 for a page that is not one. */ +#define OMX_VERB_REMOTE_PAGE_GET "remote_page_get" +#define OMX_VERB_REMOTE_PAGE_GET_FMT "remote_page_get %i %i" +#define OMX_VERB_REMOTE_PAGE_GET_REPLY "resp 0
" +#define OMX_VERB_REMOTE_PAGE_GET_CODES_COUNT 2u +#define OMX_VERB_REMOTE_PAGE_GET_CODES_INIT { -902, -3 } /* reply.host.invalid-operation, reply.host.instance-non-exists */ + +/* OMX_CLAP_CORE_SHARED_VERBS.paramInfo (data/verbs.json): What a parameter's value means: its unit, its scale (linear, log or stepped), its range, default and step, and the symbol it keeps across hosts and versions. */ +#define OMX_VERB_PARAM_INFO "param_info" +#define OMX_VERB_PARAM_INFO_FMT "param_info %i %s" +#define OMX_VERB_PARAM_INFO_REPLY "resp 0 " +#define OMX_VERB_PARAM_INFO_CODES_COUNT 4u +#define OMX_VERB_PARAM_INFO_CODES_INIT { -103, -511, -3, -902 } /* reply.host.param-symbol-invalid, reply.host.no-param-contract, reply.host.instance-non-exists, reply.host.invalid-operation */ + +/* OMX_CLAP_CORE_SHARED_VERBS.pinExpect (data/verbs.json): The layout pin : the next add of the instance checks after init and before activate; plugin-hostd sends it to a worker of a format that checks layouts, and refuses the add with any other answer than resp 0. */ +#define OMX_VERB_PIN_EXPECT "pin_expect" +#define OMX_VERB_PIN_EXPECT_FMT "pin_expect %i %s" +#define OMX_VERB_PIN_EXPECT_REPLY "resp 0" +#define OMX_VERB_PIN_EXPECT_CODES_COUNT 3u +#define OMX_VERB_PIN_EXPECT_CODES_INIT { -1, -902, -508 } /* reply.host.instance-invalid, reply.host.invalid-operation, reply.host.pin-absent */ + +/* OMX_CLAP_CORE_SHARED_VERBS.noteInput (data/verbs.json): Whether the instance takes notes: the name of its note input on its worker's jack client, - for a plugin that takes none. */ +#define OMX_VERB_NOTE_INPUT "note_input" +#define OMX_VERB_NOTE_INPUT_FMT "note_input %i" +#define OMX_VERB_NOTE_INPUT_REPLY "resp 0 " +#define OMX_VERB_NOTE_INPUT_CODES_COUNT 3u +#define OMX_VERB_NOTE_INPUT_CODES_INIT { -3, -902, -514 } /* reply.host.instance-non-exists, reply.host.invalid-operation, reply.host.notes-by-jack */ + +/* OMX_CLAP_CORE_SHARED_VERBS.noteOn (data/verbs.json): Play a key: , channel 0 to 15, key 0 to 127, velocity 1 to 127, a MIDI note on at the start of the worker's next cycle; -902 for a word out of its range. */ +#define OMX_VERB_NOTE_ON "note_on" +#define OMX_VERB_NOTE_ON_FMT "note_on %i %i %i %i" +#define OMX_VERB_NOTE_ON_REPLY "resp 0" +#define OMX_VERB_NOTE_ON_CODES_COUNT 5u +#define OMX_VERB_NOTE_ON_CODES_INIT { -513, -514, -517, -3, -902 } /* reply.host.no-note-input, reply.host.notes-by-jack, reply.host.note-queue-full, reply.host.instance-non-exists, reply.host.invalid-operation */ + +/* OMX_CLAP_CORE_SHARED_VERBS.noteOff (data/verbs.json): Release a key: , velocity 0 to 127, a MIDI note off; answered as note_on is. */ +#define OMX_VERB_NOTE_OFF "note_off" +#define OMX_VERB_NOTE_OFF_FMT "note_off %i %i %i %i" +#define OMX_VERB_NOTE_OFF_REPLY "resp 0" +#define OMX_VERB_NOTE_OFF_CODES_COUNT 5u +#define OMX_VERB_NOTE_OFF_CODES_INIT { -513, -514, -517, -3, -902 } /* reply.host.no-note-input, reply.host.notes-by-jack, reply.host.note-queue-full, reply.host.instance-non-exists, reply.host.invalid-operation */ + +/* OMX_CLAP_CORE_SHARED_VERBS.allNotesOff (data/verbs.json): Release every key of every channel, MIDI's all notes off (controller 123) on each; answered as note_on is. */ +#define OMX_VERB_ALL_NOTES_OFF "all_notes_off" +#define OMX_VERB_ALL_NOTES_OFF_FMT "all_notes_off %i" +#define OMX_VERB_ALL_NOTES_OFF_REPLY "resp 0" +#define OMX_VERB_ALL_NOTES_OFF_CODES_COUNT 5u +#define OMX_VERB_ALL_NOTES_OFF_CODES_INIT { -513, -514, -517, -3, -902 } /* reply.host.no-note-input, reply.host.notes-by-jack, reply.host.note-queue-full, reply.host.instance-non-exists, reply.host.invalid-operation */ + +/* OMX_CLAP_HOST_VERBS.audioPorts (data/verbs.json): The instance's audio ports, inputs first and each side's main port first, each with the JACK ports that carry it; dry while the instance passes its input through. */ +#define OMX_VERB_AUDIO_PORTS "audio_ports" +#define OMX_VERB_AUDIO_PORTS_FMT "audio_ports %i" +#define OMX_VERB_AUDIO_PORTS_REPLY "resp 0 [dry] ..." +#define OMX_VERB_AUDIO_PORTS_CODES_COUNT 2u +#define OMX_VERB_AUDIO_PORTS_CODES_INIT { -3, -901 } /* reply.host.instance-non-exists, reply.host.memory-allocation */ + +/* OMX_CLAP_HOST_VERBS.hideExternalUi (data/verbs.json): Hide the plugin's own window that show_external_ui showed. */ +#define OMX_VERB_HIDE_EXTERNAL_UI "hide_external_ui" +#define OMX_VERB_HIDE_EXTERNAL_UI_FMT "hide_external_ui %i" +#define OMX_VERB_HIDE_EXTERNAL_UI_REPLY "resp 0" +#define OMX_VERB_HIDE_EXTERNAL_UI_CODES_COUNT 1u +#define OMX_VERB_HIDE_EXTERNAL_UI_CODES_INIT { -3 } /* reply.host.instance-non-exists */ + +/* OMX_CLAP_HOST_VERBS.idleHold (data/verbs.json): The CPU idle hold as it stands; idle_hold changes its target at once and answers resp 0. */ +#define OMX_VERB_IDLE_HOLD "idle_hold" +#define OMX_VERB_IDLE_HOLD_FMT "idle_hold ..." +#define OMX_VERB_IDLE_HOLD_REPLY "resp 0 " +#define OMX_VERB_IDLE_HOLD_CODES_COUNT 1u +#define OMX_VERB_IDLE_HOLD_CODES_INIT { -902 } /* reply.host.invalid-operation */ + +/* OMX_CLAP_HOST_VERBS.noteDrops (data/verbs.json): The note events the instance's blocks had no room for, of them the releases, the sysex past a block's pool, and the messages no dialect of the plugin carries. */ +#define OMX_VERB_NOTE_DROPS "note_drops" +#define OMX_VERB_NOTE_DROPS_FMT "note_drops %i" +#define OMX_VERB_NOTE_DROPS_REPLY "resp 0 " +#define OMX_VERB_NOTE_DROPS_CODES_COUNT 1u +#define OMX_VERB_NOTE_DROPS_CODES_INIT { -3 } /* reply.host.instance-non-exists */ + +/* OMX_CLAP_HOST_VERBS.noteOutDrops (data/verbs.json): The plugin's note output counters: the events the ring had no room for, those with no MIDI form, and the messages midi_out had no room for. */ +#define OMX_VERB_NOTE_OUT_DROPS "note_out_drops" +#define OMX_VERB_NOTE_OUT_DROPS_FMT "note_out_drops %i" +#define OMX_VERB_NOTE_OUT_DROPS_REPLY "resp 0 " +#define OMX_VERB_NOTE_OUT_DROPS_CODES_COUNT 1u +#define OMX_VERB_NOTE_OUT_DROPS_CODES_INIT { -3 } /* reply.host.instance-non-exists */ + +#define OMX_CLAP_CORE_HOST_VERB_COUNT 14u + +/* Every verb, in the order of its items, with what each host owes it. */ +static inline const struct omx_host_verb *omx_clap_core_host_verbs(void) { + static const struct omx_host_verb table[OMX_CLAP_CORE_HOST_VERB_COUNT] = { + { OMX_VERB_TRACK_INFO, OMX_VERB_TRACK_INFO_FMT, OMX_VERB_TRACK_INFO_REPLY, { OMX_HOST_VERB_OPTIONAL, OMX_HOST_VERB_REQUIRED, OMX_HOST_VERB_UNSUPPORTED } }, + { OMX_VERB_REMOTE_PAGES, OMX_VERB_REMOTE_PAGES_FMT, OMX_VERB_REMOTE_PAGES_REPLY, { OMX_HOST_VERB_OPTIONAL, OMX_HOST_VERB_REQUIRED, OMX_HOST_VERB_UNSUPPORTED } }, + { OMX_VERB_REMOTE_PAGE_GET, OMX_VERB_REMOTE_PAGE_GET_FMT, OMX_VERB_REMOTE_PAGE_GET_REPLY, { OMX_HOST_VERB_OPTIONAL, OMX_HOST_VERB_REQUIRED, OMX_HOST_VERB_UNSUPPORTED } }, + { OMX_VERB_PARAM_INFO, OMX_VERB_PARAM_INFO_FMT, OMX_VERB_PARAM_INFO_REPLY, { OMX_HOST_VERB_OPTIONAL, OMX_HOST_VERB_REQUIRED, OMX_HOST_VERB_UNSUPPORTED } }, + { OMX_VERB_PIN_EXPECT, OMX_VERB_PIN_EXPECT_FMT, OMX_VERB_PIN_EXPECT_REPLY, { OMX_HOST_VERB_UNSUPPORTED, OMX_HOST_VERB_REQUIRED, OMX_HOST_VERB_UNSUPPORTED } }, + { OMX_VERB_NOTE_INPUT, OMX_VERB_NOTE_INPUT_FMT, OMX_VERB_NOTE_INPUT_REPLY, { OMX_HOST_VERB_OPTIONAL, OMX_HOST_VERB_REQUIRED, OMX_HOST_VERB_UNSUPPORTED } }, + { OMX_VERB_NOTE_ON, OMX_VERB_NOTE_ON_FMT, OMX_VERB_NOTE_ON_REPLY, { OMX_HOST_VERB_OPTIONAL, OMX_HOST_VERB_REQUIRED, OMX_HOST_VERB_UNSUPPORTED } }, + { OMX_VERB_NOTE_OFF, OMX_VERB_NOTE_OFF_FMT, OMX_VERB_NOTE_OFF_REPLY, { OMX_HOST_VERB_OPTIONAL, OMX_HOST_VERB_REQUIRED, OMX_HOST_VERB_UNSUPPORTED } }, + { OMX_VERB_ALL_NOTES_OFF, OMX_VERB_ALL_NOTES_OFF_FMT, OMX_VERB_ALL_NOTES_OFF_REPLY, { OMX_HOST_VERB_OPTIONAL, OMX_HOST_VERB_REQUIRED, OMX_HOST_VERB_UNSUPPORTED } }, + { OMX_VERB_AUDIO_PORTS, OMX_VERB_AUDIO_PORTS_FMT, OMX_VERB_AUDIO_PORTS_REPLY, { OMX_HOST_VERB_UNSUPPORTED, OMX_HOST_VERB_REQUIRED, OMX_HOST_VERB_UNSUPPORTED } }, + { OMX_VERB_HIDE_EXTERNAL_UI, OMX_VERB_HIDE_EXTERNAL_UI_FMT, OMX_VERB_HIDE_EXTERNAL_UI_REPLY, { OMX_HOST_VERB_UNSUPPORTED, OMX_HOST_VERB_REQUIRED, OMX_HOST_VERB_UNSUPPORTED } }, + { OMX_VERB_IDLE_HOLD, OMX_VERB_IDLE_HOLD_FMT, OMX_VERB_IDLE_HOLD_REPLY, { OMX_HOST_VERB_UNSUPPORTED, OMX_HOST_VERB_REQUIRED, OMX_HOST_VERB_UNSUPPORTED } }, + { OMX_VERB_NOTE_DROPS, OMX_VERB_NOTE_DROPS_FMT, OMX_VERB_NOTE_DROPS_REPLY, { OMX_HOST_VERB_UNSUPPORTED, OMX_HOST_VERB_REQUIRED, OMX_HOST_VERB_UNSUPPORTED } }, + { OMX_VERB_NOTE_OUT_DROPS, OMX_VERB_NOTE_OUT_DROPS_FMT, OMX_VERB_NOTE_OUT_DROPS_REPLY, { OMX_HOST_VERB_UNSUPPORTED, OMX_HOST_VERB_REQUIRED, OMX_HOST_VERB_UNSUPPORTED } }, + }; + return table; +} + +/* The verb whose word is `verb`, or NULL. */ +static inline const struct omx_host_verb *omx_clap_core_host_verb_find(const char *verb) { + const struct omx_host_verb *t = omx_clap_core_host_verbs(); + for (unsigned i = 0; i < OMX_CLAP_CORE_HOST_VERB_COUNT; i++) + if (!strcmp(t[i].verb, verb)) return &t[i]; + return NULL; +} + +/* What the host at column `host` (an OMX_HOST_VERB_HOST_* index) owes `verb`: unsupported for a verb not here. */ +static inline enum omx_host_verb_level omx_clap_core_host_verb_level(const char *verb, unsigned host) { + const struct omx_host_verb *v = omx_clap_core_host_verb_find(verb); + return v && host < OMX_HOST_VERB_HOST_COUNT ? v->level[host] : OMX_HOST_VERB_UNSUPPORTED; +} + +#endif /* OMX_CLAP_CORE_HOST_VERBS_H */ diff --git a/include/plugin-hostd/omx_clap_core_vocabulary.h b/include/plugin-hostd/omx_clap_core_vocabulary.h new file mode 100644 index 0000000..cf52c86 --- /dev/null +++ b/include/plugin-hostd/omx_clap_core_vocabulary.h @@ -0,0 +1,157 @@ +// SPDX-License-Identifier: GPL-3.0-or-later +// Copyright (C) 2026 Pau Aliagas +#ifndef OMX_CLAP_CORE_VOCABULARY_H +#define OMX_CLAP_CORE_VOCABULARY_H +/* + * GENERATED — DO NOT EDIT BY HAND. + * Produced by `omx-contract render --target c` from FreeMixer/omx-clap-core's data/: the vocabulary + * (docs/data-layout.md). A code is OMX_ and the code in upper snake case, and a reply code that carries a resp has it as that name and _RESP; a word is OMX__, each words + * item with its _COUNT and an _INIT of its words in their order. A consumer writes and compares these, never a + * literal of its own. + */ + +/* HOSTING_CLAP_CODES (data/hosting/clap.json) */ +#define OMX_HOSTING_CLAP_EXTENSIONS_NOT_COVERED "hosting.clap.extensions-not-covered" +#define OMX_HOSTING_CLAP_FORMAT_NOT_HOSTED "hosting.clap.format-not-hosted" +#define OMX_HOSTING_CLAP_HEADLESS_FAILED "hosting.clap.headless-failed" +#define OMX_HOSTING_CLAP_LATENCY_MISMATCH "hosting.clap.latency-mismatch" +#define OMX_HOSTING_CLAP_NOTE_INPUT "hosting.clap.note-input" ///< the plugin declares a note input the configuration refuses +#define OMX_HOSTING_CLAP_PROCESS_ERROR "hosting.clap.process-error" +#define OMX_HOSTING_CLAP_THREAD_VIOLATION "hosting.clap.thread-violation" +#define OMX_HOSTING_CLAP_UNQUALIFIED "hosting.clap.unqualified" + +/* HOSTING_COST_CODES (data/hosting/cost.json) */ +#define OMX_HOSTING_COST_ABOVE_CEILING "hosting.cost.above-ceiling" +#define OMX_HOSTING_COST_FIELDS_MISSING "hosting.cost.fields-missing" +#define OMX_HOSTING_COST_SPIKY_TAIL "hosting.cost.spiky-tail" +#define OMX_HOSTING_COST_UNMEASURED_AT_RATE_AND_QUANTUM "hosting.cost.unmeasured-at-rate-and-quantum" +#define OMX_HOSTING_COST_WITHIN_CEILING "hosting.cost.within-ceiling" + +/* HOSTING_FEATURES_CODES (data/hosting/features.json) */ +#define OMX_HOSTING_FEATURES_ATOM_IN_UNFED "hosting.features.atom-in-unfed" ///< a non-MIDI atom input no buffer here can feed +#define OMX_HOSTING_FEATURES_HOST_NOT_PROVIDED "hosting.features.host-not-provided" +#define OMX_HOSTING_FEATURES_MIDI_IN_FED_EMPTY "hosting.features.midi-in-fed-empty" +#define OMX_HOSTING_FEATURES_MISSING "hosting.features.missing" +#define OMX_HOSTING_FEATURES_PORTS_UNREADABLE "hosting.features.ports-unreadable" ///< the plugin declares ports its reader cannot read (a port node shared by several plugins of one bundle, a port with no symbol), so none reaches the host: the bundle's data is the fault, not the layout (omx-clap-core#255) +#define OMX_HOSTING_FEATURES_ALL_PROVIDED "hosting.features.all-provided" +#define OMX_HOSTING_FEATURES_SCAN_PREDATES_FIELD "hosting.features.scan-predates-field" + +/* HOSTING_LATENCY_CODES (data/hosting/latency.json) */ +#define OMX_HOSTING_LATENCY_NONCONFORMING "hosting.latency.nonconforming" +#define OMX_HOSTING_LATENCY_PARAMETER_DEPENDENT "hosting.latency.parameter-dependent" +#define OMX_HOSTING_LATENCY_RESOLVED "hosting.latency.resolved" +#define OMX_HOSTING_LATENCY_UNMEASURED "hosting.latency.unmeasured" + +/* HOSTING_OUTPUT_CODES (data/hosting/output.json) */ +#define OMX_HOSTING_OUTPUT_NON_FINITE "hosting.output.non-finite" ///< the plugin produced non-finite output + +/* HOSTING_OVERRIDE_CODES (data/hosting/override.json) */ +#define OMX_HOSTING_OVERRIDE_CURATOR_ISOLATED "hosting.override.curator-isolated" + +/* HOSTING_PATCH_CODES (data/hosting/patch.json) */ +#define OMX_HOSTING_PATCH_BUSY "hosting.patch.busy" +#define OMX_HOSTING_PATCH_NOT_WRITABLE "hosting.patch.not-writable" +#define OMX_HOSTING_PATCH_TOO_LARGE "hosting.patch.too-large" + +/* HOSTING_PRESET_CODES (data/hosting/preset.json) */ +#define OMX_HOSTING_PRESET_NOT_FOUND "hosting.preset.not-found" + +/* HOSTING_PROVENANCE_CODES (data/hosting/provenance.json) */ +#define OMX_HOSTING_PROVENANCE_HOST_DIFFERS "hosting.provenance.host-differs" +#define OMX_HOSTING_PROVENANCE_SWEEP_CONTROL_DID_NOT_FIRE "hosting.provenance.sweep-control-did-not-fire" + +/* HOSTING_REALISED_CODES (data/hosting/realised.json) */ +#define OMX_HOSTING_DISABLED "hosting.disabled" +#define OMX_HOSTING_LINKED "hosting.linked" +#define OMX_HOSTING_NO_REALISATION "hosting.no-realisation" +#define OMX_HOSTING_REALISED_IN_PROCESS "hosting.realised.in-process" +#define OMX_HOSTING_UNJUDGED "hosting.unjudged" + +/* HOSTING_RESOURCE_HINTS_CODES (data/hosting/resource-hints.json) */ +#define OMX_HOSTING_RESOURCE_HINTS_OUT_OF_RANGE "hosting.resource-hints.out-of-range" ///< a figure below zero, or past what its hint's member holds +#define OMX_HOSTING_RESOURCE_HINTS_UNKNOWN_HINT "hosting.resource-hints.unknown-hint" ///< the declared mask sets a bit RESOURCE_HINTS has no hint for +#define OMX_HOSTING_RESOURCE_HINTS_WRONG_UNIT "hosting.resource-hints.wrong-unit" ///< a figure not in its hint's unit: a flag that is not a boolean, a count, a time or a size that is not an integer + +/* HOSTING_RT_SAFETY_CODES (data/hosting/rt-safety.json) */ +#define OMX_HOSTING_RT_SAFETY_CLEAN_UNDER_SWEEP "hosting.rt-safety.clean-under-sweep" +#define OMX_HOSTING_RT_SAFETY_NOT_REPRODUCIBLE "hosting.rt-safety.not-reproducible" +#define OMX_HOSTING_RT_SAFETY_CLEAN_UNDER_NOTES "hosting.rt-safety.clean-under-notes" +#define OMX_HOSTING_RT_SAFETY_NOTES_UNMEASURED "hosting.rt-safety.notes-unmeasured" +#define OMX_HOSTING_RT_SAFETY_VIOLATIONS_UNDER_NOTES "hosting.rt-safety.violations-under-notes" +#define OMX_HOSTING_RT_SAFETY_UNMEASURED "hosting.rt-safety.unmeasured" +#define OMX_HOSTING_RT_SAFETY_VIOLATIONS_IN_RUN "hosting.rt-safety.violations-in-run" + +/* HOSTING_STABILITY_CODES (data/hosting/stability.json) */ +#define OMX_HOSTING_STABILITY_CYCLES_BELOW_FLOOR "hosting.stability.cycles-below-floor" +#define OMX_HOSTING_STABILITY_CRASH_UNATTRIBUTED "hosting.stability.crash-unattributed" +#define OMX_HOSTING_STABILITY_CRASHED_ATTRIBUTED_PLUGIN "hosting.stability.crashed-attributed-plugin" +#define OMX_HOSTING_STABILITY_CRASHED_LIVE_ON_THIS_RIG "hosting.stability.crashed-live-on-this-rig" ///< the plugin crashed live on this rig +#define OMX_HOSTING_STABILITY_LINKS_GUI_TOOLKIT "hosting.stability.links-gui-toolkit" +#define OMX_HOSTING_STABILITY_SOAK_FAILED_AT_RATE "hosting.stability.soak-failed-at-rate" +#define OMX_HOSTING_STABILITY_SOAKED "hosting.stability.soaked" +#define OMX_HOSTING_STABILITY_SPAWNS_THREADS "hosting.stability.spawns-threads" +#define OMX_HOSTING_STABILITY_UNMEASURED "hosting.stability.unmeasured" +#define OMX_HOSTING_STABILITY_UNSOAKED "hosting.stability.unsoaked" + +/* HOSTING_STATE_CODES (data/hosting/state.json) */ +#define OMX_HOSTING_STATE_NOT_A_COPY "hosting.state.not-a-copy" ///< not a save's copy directory of the root +#define OMX_HOSTING_STATE_PATH_ON_AUDIO "hosting.state.path-on-audio" ///< makePath: called on the audio role +#define OMX_HOSTING_STATE_PATH_OUTSIDE "hosting.state.path-outside" ///< makePath: empty, absolute, or a `..` component +#define OMX_HOSTING_STATE_PATH_SYMLINK "hosting.state.path-symlink" ///< makePath: a component is a symbolic link +#define OMX_HOSTING_STATE_PATH_TOO_LONG "hosting.state.path-too-long" ///< makePath: PATH_MAX or more, or a long component +#define OMX_HOSTING_STATE_PATH_UNMAKEABLE "hosting.state.path-unmakeable" ///< makePath: a directory could not be made +#define OMX_HOSTING_STATE_UNREADABLE "hosting.state.unreadable" + +/* HOSTING_TOPOLOGY_CODES (data/hosting/topology.json) */ +#define OMX_HOSTING_TOPOLOGY_AMBISONIC_CONFIG "hosting.topology.ambisonic-config" ///< an ambisonic port refuses the carrier's ordering or normalisation +#define OMX_HOSTING_TOPOLOGY_CHANNEL_MAP_UNKNOWN "hosting.topology.channel-map-unknown" ///< a surround port names a channel id the host does not know, or refuses the carrier's channel mask +#define OMX_HOSTING_TOPOLOGY_INSTRUMENT "hosting.topology.instrument" +#define OMX_HOSTING_TOPOLOGY_MATCHED "hosting.topology.matched" +#define OMX_HOSTING_TOPOLOGY_NO_AUDIO_INPUT "hosting.topology.no-audio-input" ///< the plugin has no audio input +#define OMX_HOSTING_TOPOLOGY_NO_AUDIO_OUTPUT "hosting.topology.no-audio-output" ///< the plugin has no audio output +#define OMX_HOSTING_TOPOLOGY_PORT_TOO_WIDE "hosting.topology.port-too-wide" ///< a port of more channels than the limit, or an ambisonic port whose channels are not (order+1)² +#define OMX_HOSTING_TOPOLOGY_PORT_WITHOUT_CHANNELS "hosting.topology.port-without-channels" ///< a port of zero channels +#define OMX_HOSTING_TOPOLOGY_TOO_MANY_PORTS "hosting.topology.too-many-ports" ///< more than the limit of auxiliary ports on one side, or more than one main port on a side +#define OMX_HOSTING_TOPOLOGY_WIDER_THAN_STRIP "hosting.topology.wider-than-strip" ///< a main port is wider than the lane the caller runs the plugin on + +/* HOSTING_WORKER_CODES (data/hosting/worker.json) */ +#define OMX_HOSTING_WORKER_NONCONFORMING "hosting.worker.nonconforming" + +/* HOST_REPLY_CODES (data/verbs.json) */ +#define OMX_REPLY_HOST_INSTANCE_INVALID "reply.host.instance-invalid" ///< mod-host's ERR_INSTANCE_INVALID: an instance number outside the host's table +#define OMX_REPLY_HOST_INSTANCE_INVALID_RESP (-1) +#define OMX_REPLY_HOST_INSTANCE_NON_EXISTS "reply.host.instance-non-exists" ///< mod-host's ERR_INSTANCE_NON_EXISTS: an instance no add made +#define OMX_REPLY_HOST_INSTANCE_NON_EXISTS_RESP (-3) +#define OMX_REPLY_HOST_PARAM_SYMBOL_INVALID "reply.host.param-symbol-invalid" ///< mod-host's ERR_LV2_INVALID_PARAM_SYMBOL: a symbol that is not a parameter param_set takes, the plugin's own bypass included +#define OMX_REPLY_HOST_PARAM_SYMBOL_INVALID_RESP (-103) +#define OMX_REPLY_HOST_MEMORY_ALLOCATION "reply.host.memory-allocation" ///< mod-host's ERR_MEMORY_ALLOCATION: the reply could not be built +#define OMX_REPLY_HOST_MEMORY_ALLOCATION_RESP (-901) +#define OMX_REPLY_HOST_INVALID_OPERATION "reply.host.invalid-operation" ///< mod-host's ERR_INVALID_OPERATION: a word outside the verb's grammar, or a verb the host refuses on purpose +#define OMX_REPLY_HOST_INVALID_OPERATION_RESP (-902) +#define OMX_REPLY_HOST_PIN_ABSENT "reply.host.pin-absent" ///< a layout pin in a scheme this host does not know, refused as no pin at all +#define OMX_REPLY_HOST_PIN_ABSENT_RESP (-508) +#define OMX_REPLY_HOST_PIN_LAYOUT_MISMATCH "reply.host.pin-layout-mismatch" ///< the add of an instance whose layout after init is not the one pin_expect named: the plugin is not activated +#define OMX_REPLY_HOST_PIN_LAYOUT_MISMATCH_RESP (-510) +#define OMX_REPLY_HOST_NO_PARAM_CONTRACT "reply.host.no-param-contract" ///< the host holds no checked unit and scale for this parameter: the controller falls back to the layout the scan gives +#define OMX_REPLY_HOST_NO_PARAM_CONTRACT_RESP (-511) +#define OMX_REPLY_HOST_NO_NOTE_INPUT "reply.host.no-note-input" ///< the instance's plugin takes no notes +#define OMX_REPLY_HOST_NO_NOTE_INPUT_RESP (-513) +#define OMX_REPLY_HOST_NOTES_BY_JACK "reply.host.notes-by-jack" ///< the instance's worker takes no notes on its socket (mod-host): the plugin is played through its jack MIDI input +#define OMX_REPLY_HOST_NOTES_BY_JACK_RESP (-514) +#define OMX_REPLY_HOST_NOTE_QUEUE_FULL "reply.host.note-queue-full" ///< the worker has no room for the line's notes before its next block: nothing of it is kept, and the line may be sent again +#define OMX_REPLY_HOST_NOTE_QUEUE_FULL_RESP (-517) + +/* HOST_TRACK_KINDS (data/verbs.json) */ +#define OMX_HOST_TRACK_KINDS_BUS "bus" +#define OMX_HOST_TRACK_KINDS_RETURN "return" +#define OMX_HOST_TRACK_KINDS_MASTER "master" +#define OMX_HOST_TRACK_KINDS_COUNT 3u +#define OMX_HOST_TRACK_KINDS_INIT { "bus", "return", "master" } + +/* HOST_EVENTS (data/verbs.json) */ +#define OMX_HOST_EVENTS_REMOTE_PAGES_CHANGED "remote_pages_changed" ///< the plugin changed its remote pages: a controller reads remote_pages and remote_page_get again +#define OMX_HOST_EVENTS_XRUNS "xruns" ///< the worker's JACK xrun count since its start, written when it changes and at most once a second; a worker that never writes it reports no xruns +#define OMX_HOST_EVENTS_COUNT 2u +#define OMX_HOST_EVENTS_INIT { "remote_pages_changed", "xruns" } + +#endif /* OMX_CLAP_CORE_VOCABULARY_H */ diff --git a/include/plugin-hostd/plugin_hostd_vocabulary.h b/include/plugin-hostd/plugin_hostd_vocabulary.h index 73ec129..3e25e57 100644 --- a/include/plugin-hostd/plugin_hostd_vocabulary.h +++ b/include/plugin-hostd/plugin_hostd_vocabulary.h @@ -50,57 +50,57 @@ #define OMX_PLUGIN_HOSTD_HISTORY_KEYS_INIT { "first", "last", "windows_solo", "windows_grouped", "cpu_p95_solo", "cpu_max_solo", "pss_mb_solo", "xrun_windows_solo", "xrun_windows_grouped", "crashes_solo", "crashes_grouped", "restarts_grouped", "quarantines", "last_crash", "last_crash_grouped" } /* PLUGIN_HOSTD_REPLY_CODES (data/verbs.json) */ -#define OMX_REPLY_PLUGIN_HOSTD_PLACEMENT_INVALID "reply.plugin-hostd.placement-invalid" ///< PHD_ERR_PLACEMENT_INVALID: not a placement, or not valid here +#define OMX_REPLY_PLUGIN_HOSTD_PLACEMENT_INVALID "reply.plugin-hostd.placement-invalid" ///< not a placement, or not valid here #define OMX_REPLY_PLUGIN_HOSTD_PLACEMENT_INVALID_RESP (-501) -#define OMX_REPLY_PLUGIN_HOSTD_NO_BACKEND "reply.plugin-hostd.no-backend" ///< PHD_ERR_NO_BACKEND: no worker program for the scheme +#define OMX_REPLY_PLUGIN_HOSTD_NO_BACKEND "reply.plugin-hostd.no-backend" ///< no worker program for the scheme #define OMX_REPLY_PLUGIN_HOSTD_NO_BACKEND_RESP (-502) -#define OMX_REPLY_PLUGIN_HOSTD_WORKER_SPAWN "reply.plugin-hostd.worker-spawn" ///< PHD_ERR_WORKER_SPAWN: the worker is not up +#define OMX_REPLY_PLUGIN_HOSTD_WORKER_SPAWN "reply.plugin-hostd.worker-spawn" ///< the worker is not up #define OMX_REPLY_PLUGIN_HOSTD_WORKER_SPAWN_RESP (-503) -#define OMX_REPLY_PLUGIN_HOSTD_REPLAY "reply.plugin-hostd.replay" ///< PHD_ERR_REPLAY: the name of a refused replay on stderr, never a reply +#define OMX_REPLY_PLUGIN_HOSTD_REPLAY "reply.plugin-hostd.replay" ///< the name of a refused replay on stderr, never a reply #define OMX_REPLY_PLUGIN_HOSTD_REPLAY_RESP (-504) -#define OMX_REPLY_PLUGIN_HOSTD_GAVE_UP "reply.plugin-hostd.gave-up" ///< PHD_ERR_GAVE_UP: the storm bound is spent for that placement +#define OMX_REPLY_PLUGIN_HOSTD_GAVE_UP "reply.plugin-hostd.gave-up" ///< the storm bound is spent for that placement #define OMX_REPLY_PLUGIN_HOSTD_GAVE_UP_RESP (-505) -#define OMX_REPLY_PLUGIN_HOSTD_NO_SUCH_WORKER "reply.plugin-hostd.no-such-worker" ///< PHD_ERR_NO_SUCH_WORKER: no such worker +#define OMX_REPLY_PLUGIN_HOSTD_NO_SUCH_WORKER "reply.plugin-hostd.no-such-worker" ///< no such worker #define OMX_REPLY_PLUGIN_HOSTD_NO_SUCH_WORKER_RESP (-506) -#define OMX_REPLY_PLUGIN_HOSTD_VERB_DROPPED "reply.plugin-hostd.verb-dropped" ///< PHD_ERR_VERB_DROPPED: the worker died on this very command and the daemon dropped it +#define OMX_REPLY_PLUGIN_HOSTD_VERB_DROPPED "reply.plugin-hostd.verb-dropped" ///< the worker died on this very command and the daemon dropped it #define OMX_REPLY_PLUGIN_HOSTD_VERB_DROPPED_RESP (-507) -#define OMX_REPLY_PLUGIN_HOSTD_PIN_BINARY_MISMATCH "reply.plugin-hostd.pin-binary-mismatch" ///< PHD_ERR_PIN_BINARY_MISMATCH: a pinned file is missing or its SHA-256 differs +#define OMX_REPLY_PLUGIN_HOSTD_PIN_BINARY_MISMATCH "reply.plugin-hostd.pin-binary-mismatch" ///< a pinned file is missing or its SHA-256 differs #define OMX_REPLY_PLUGIN_HOSTD_PIN_BINARY_MISMATCH_RESP (-509) -#define OMX_REPLY_PLUGIN_HOSTD_LV2_ADAPTER_REFUSED "reply.plugin-hostd.lv2-adapter-refused" ///< PHD_ERR_LV2_ADAPTER_REFUSED: the lv2-clap worker's LV2 adapter cannot run this plugin +#define OMX_REPLY_PLUGIN_HOSTD_LV2_ADAPTER_REFUSED "reply.plugin-hostd.lv2-adapter-refused" ///< the lv2-clap worker's LV2 adapter cannot run this plugin #define OMX_REPLY_PLUGIN_HOSTD_LV2_ADAPTER_REFUSED_RESP (-512) -#define OMX_REPLY_PLUGIN_HOSTD_NO_PRESET_LIST "reply.plugin-hostd.no-preset-list" ///< PHD_ERR_NO_PRESET_LIST: the instance's worker cannot list the plugin's presets +#define OMX_REPLY_PLUGIN_HOSTD_NO_PRESET_LIST "reply.plugin-hostd.no-preset-list" ///< the instance's worker cannot list the plugin's presets #define OMX_REPLY_PLUGIN_HOSTD_NO_PRESET_LIST_RESP (-515) -#define OMX_REPLY_PLUGIN_HOSTD_PIN_REFUSED "reply.plugin-hostd.pin-refused" ///< PHD_ERR_PIN_REFUSED: the plugin's pin carries verdict=refused +#define OMX_REPLY_PLUGIN_HOSTD_PIN_REFUSED "reply.plugin-hostd.pin-refused" ///< the plugin's pin carries verdict=refused #define OMX_REPLY_PLUGIN_HOSTD_PIN_REFUSED_RESP (-516) -#define OMX_REPLY_PLUGIN_HOSTD_CHAIN_UNKNOWN_INSTANCE "reply.plugin-hostd.chain-unknown-instance" ///< PHD_ERR_CHAIN_UNKNOWN_INSTANCE: a member is an instance no add made +#define OMX_REPLY_PLUGIN_HOSTD_CHAIN_UNKNOWN_INSTANCE "reply.plugin-hostd.chain-unknown-instance" ///< a member is an instance no add made #define OMX_REPLY_PLUGIN_HOSTD_CHAIN_UNKNOWN_INSTANCE_RESP (-518) -#define OMX_REPLY_PLUGIN_HOSTD_CHAIN_DUPLICATE "reply.plugin-hostd.chain-duplicate" ///< PHD_ERR_CHAIN_DUPLICATE: an instance is named twice in one chain +#define OMX_REPLY_PLUGIN_HOSTD_CHAIN_DUPLICATE "reply.plugin-hostd.chain-duplicate" ///< an instance is named twice in one chain #define OMX_REPLY_PLUGIN_HOSTD_CHAIN_DUPLICATE_RESP (-519) -#define OMX_REPLY_PLUGIN_HOSTD_CHAIN_INSTANCE_BUSY "reply.plugin-hostd.chain-instance-busy" ///< PHD_ERR_CHAIN_INSTANCE_BUSY: a member is already in another chain +#define OMX_REPLY_PLUGIN_HOSTD_CHAIN_INSTANCE_BUSY "reply.plugin-hostd.chain-instance-busy" ///< a member is already in another chain #define OMX_REPLY_PLUGIN_HOSTD_CHAIN_INSTANCE_BUSY_RESP (-520) -#define OMX_REPLY_PLUGIN_HOSTD_CHAIN_MIXED_FORMAT "reply.plugin-hostd.chain-mixed-format" ///< PHD_ERR_CHAIN_MIXED_FORMAT: no one worker program runs every member +#define OMX_REPLY_PLUGIN_HOSTD_CHAIN_MIXED_FORMAT "reply.plugin-hostd.chain-mixed-format" ///< no one worker program runs every member #define OMX_REPLY_PLUGIN_HOSTD_CHAIN_MIXED_FORMAT_RESP (-521) -#define OMX_REPLY_PLUGIN_HOSTD_NO_SUCH_CHAIN "reply.plugin-hostd.no-such-chain" ///< PHD_ERR_NO_SUCH_CHAIN: a chain no chain line declared +#define OMX_REPLY_PLUGIN_HOSTD_NO_SUCH_CHAIN "reply.plugin-hostd.no-such-chain" ///< a chain no chain line declared #define OMX_REPLY_PLUGIN_HOSTD_NO_SUCH_CHAIN_RESP (-522) -#define OMX_REPLY_PLUGIN_HOSTD_PRESET_NOT_OFFERED "reply.plugin-hostd.preset-not-offered" ///< PHD_ERR_PRESET_NOT_OFFERED: a stable name the plugin does not offer +#define OMX_REPLY_PLUGIN_HOSTD_PRESET_NOT_OFFERED "reply.plugin-hostd.preset-not-offered" ///< a stable name the plugin does not offer #define OMX_REPLY_PLUGIN_HOSTD_PRESET_NOT_OFFERED_RESP (-523) -#define OMX_REPLY_PLUGIN_HOSTD_PRESET_INVALID "reply.plugin-hostd.preset-invalid" ///< PHD_ERR_PRESET_INVALID: a preset file or path that is not the preset format +#define OMX_REPLY_PLUGIN_HOSTD_PRESET_INVALID "reply.plugin-hostd.preset-invalid" ///< a preset file or path that is not the preset format #define OMX_REPLY_PLUGIN_HOSTD_PRESET_INVALID_RESP (-524) -#define OMX_REPLY_PLUGIN_HOSTD_PRESET_NEEDS_STATE "reply.plugin-hostd.preset-needs-state" ///< PHD_ERR_PRESET_NEEDS_STATE: a preset file that carries state for a worker that cannot take state +#define OMX_REPLY_PLUGIN_HOSTD_PRESET_NEEDS_STATE "reply.plugin-hostd.preset-needs-state" ///< a preset file that carries state for a worker that cannot take state #define OMX_REPLY_PLUGIN_HOSTD_PRESET_NEEDS_STATE_RESP (-525) -#define OMX_REPLY_PLUGIN_HOSTD_PRESET_PLUGIN_CHANGED "reply.plugin-hostd.preset-plugin-changed" ///< PHD_ERR_PRESET_PLUGIN_CHANGED: the preset file's plugin id, version or fingerprint is not the instance's +#define OMX_REPLY_PLUGIN_HOSTD_PRESET_PLUGIN_CHANGED "reply.plugin-hostd.preset-plugin-changed" ///< the preset file's plugin id, version or fingerprint is not the instance's #define OMX_REPLY_PLUGIN_HOSTD_PRESET_PLUGIN_CHANGED_RESP (-526) -#define OMX_REPLY_PLUGIN_HOSTD_LOAD_REFUSED "reply.plugin-hostd.load-refused" ///< PHD_ERR_LOAD_REFUSED: the plugin refused the preset or the state its file carries +#define OMX_REPLY_PLUGIN_HOSTD_LOAD_REFUSED "reply.plugin-hostd.load-refused" ///< the plugin refused the preset or the state its file carries #define OMX_REPLY_PLUGIN_HOSTD_LOAD_REFUSED_RESP (-527) -#define OMX_REPLY_PLUGIN_HOSTD_DIR_NOT_WRITABLE "reply.plugin-hostd.dir-not-writable" ///< PHD_ERR_DIR_NOT_WRITABLE: descriptor_dir or qualification_dir cannot be made or written +#define OMX_REPLY_PLUGIN_HOSTD_DIR_NOT_WRITABLE "reply.plugin-hostd.dir-not-writable" ///< descriptor_dir or qualification_dir cannot be made or written #define OMX_REPLY_PLUGIN_HOSTD_DIR_NOT_WRITABLE_RESP (-528) -#define OMX_REPLY_PLUGIN_HOSTD_DESCRIPTOR_ABSENT "reply.plugin-hostd.descriptor-absent" ///< PHD_ERR_DESCRIPTOR_ABSENT: no descriptor (panel) for the plugin's binary as it is now +#define OMX_REPLY_PLUGIN_HOSTD_DESCRIPTOR_ABSENT "reply.plugin-hostd.descriptor-absent" ///< no descriptor (panel) for the plugin's binary as it is now #define OMX_REPLY_PLUGIN_HOSTD_DESCRIPTOR_ABSENT_RESP (-529) -#define OMX_REPLY_PLUGIN_HOSTD_DESCRIPTOR_PENDING "reply.plugin-hostd.descriptor-pending" ///< PHD_ERR_DESCRIPTOR_PENDING: the scan its add started has not written the descriptor (panel) yet +#define OMX_REPLY_PLUGIN_HOSTD_DESCRIPTOR_PENDING "reply.plugin-hostd.descriptor-pending" ///< the scan its add started has not written the descriptor (panel) yet #define OMX_REPLY_PLUGIN_HOSTD_DESCRIPTOR_PENDING_RESP (-530) -#define OMX_REPLY_PLUGIN_HOSTD_DESCRIPTOR_SCAN_FAILED "reply.plugin-hostd.descriptor-scan-failed" ///< PHD_ERR_DESCRIPTOR_SCAN_FAILED: the plugin's last scan wrote no descriptor (panel) +#define OMX_REPLY_PLUGIN_HOSTD_DESCRIPTOR_SCAN_FAILED "reply.plugin-hostd.descriptor-scan-failed" ///< the plugin's last scan wrote no descriptor (panel) #define OMX_REPLY_PLUGIN_HOSTD_DESCRIPTOR_SCAN_FAILED_RESP (-531) -#define OMX_REPLY_PLUGIN_HOSTD_NO_SUCH_PLAN "reply.plugin-hostd.no-such-plan" ///< PHD_ERR_NO_SUCH_PLAN: a chain no plan verb planned +#define OMX_REPLY_PLUGIN_HOSTD_NO_SUCH_PLAN "reply.plugin-hostd.no-such-plan" ///< a chain no plan verb planned #define OMX_REPLY_PLUGIN_HOSTD_NO_SUCH_PLAN_RESP (-532) #endif /* PLUGIN_HOSTD_VOCABULARY_H */ diff --git a/include/plugin-hostd/protocol.h b/include/plugin-hostd/protocol.h index 9f2cbe4..7e1b28b 100644 --- a/include/plugin-hostd/protocol.h +++ b/include/plugin-hostd/protocol.h @@ -33,7 +33,10 @@ #include +#include "omx_clap_core_host_verbs.h" +#include "omx_clap_core_vocabulary.h" #include "plugin_hostd_host_verbs.h" +#include "plugin_hostd_vocabulary.h" /* bumped when a name, a code or the shape of a verb or an event changes incompatibly */ #define PLUGIN_HOSTD_PROTOCOL_VERSION 1 @@ -264,123 +267,89 @@ static inline int phd_pool_name_valid(const char *name) /* ---------------------------------------------------------------- error codes */ /* the codes the supervisor adds to mod-host's, the -5xx hundred; a reply is "resp ". Each number has one name in - * the contract: the ones omx-clap-host answers too are omx-clap-core's reply.host.* codes (its HOST_REPLY_CODES), the - * others plugin-hostd's reply.plugin-hostd.* (data/verbs.json PLUGIN_HOSTD_REPLY_CODES); tests/verbs_declared.py - * holds every number below to exactly one of them */ -#define PHD_ERR_PLACEMENT_INVALID (-501) -#define PHD_ERR_NO_BACKEND (-502) -#define PHD_ERR_WORKER_SPAWN (-503) -#define PHD_ERR_REPLAY (-504) -#define PHD_ERR_GAVE_UP (-505) -#define PHD_ERR_NO_SUCH_WORKER (-506) -#define PHD_ERR_VERB_DROPPED (-507) -#define PHD_ERR_PIN_ABSENT (-508) -#define PHD_ERR_PIN_BINARY_MISMATCH (-509) -#define PHD_ERR_PIN_LAYOUT_MISMATCH (-510) -#define PHD_ERR_NO_PARAM_CONTRACT (-511) -#define PHD_ERR_LV2_ADAPTER_REFUSED (-512) -#define PHD_ERR_NO_NOTE_INPUT (-513) -#define PHD_ERR_NOTES_BY_JACK (-514) -#define PHD_ERR_NO_PRESET_LIST (-515) -#define PHD_ERR_PIN_REFUSED (-516) -#define PHD_ERR_NOTE_QUEUE_FULL (-517) -#define PHD_ERR_CHAIN_UNKNOWN_INSTANCE (-518) -#define PHD_ERR_CHAIN_DUPLICATE (-519) -#define PHD_ERR_CHAIN_INSTANCE_BUSY (-520) -#define PHD_ERR_CHAIN_MIXED_FORMAT (-521) -#define PHD_ERR_NO_SUCH_CHAIN (-522) -#define PHD_ERR_PRESET_NOT_OFFERED (-523) -#define PHD_ERR_PRESET_INVALID (-524) -#define PHD_ERR_PRESET_NEEDS_STATE (-525) -#define PHD_ERR_PRESET_PLUGIN_CHANGED (-526) -#define PHD_ERR_LOAD_REFUSED (-527) -#define PHD_ERR_DIR_NOT_WRITABLE (-528) -#define PHD_ERR_DESCRIPTOR_ABSENT (-529) -#define PHD_ERR_DESCRIPTOR_PENDING (-530) -#define PHD_ERR_DESCRIPTOR_SCAN_FAILED (-531) -#define PHD_ERR_NO_SUCH_PLAN (-532) - -/* X(id, meaning) */ + * the contract, rendered as OMX_REPLY___RESP: the ones omx-clap-host answers too are omx-clap-core's + * reply.host.* codes (its HOST_REPLY_CODES, omx_clap_core_vocabulary.h), the others plugin-hostd's + * reply.plugin-hostd.* (data/verbs.json PLUGIN_HOSTD_REPLY_CODES, plugin_hostd_vocabulary.h); the header defines none */ +/* X(id, resp, meaning): resp is the rendered number of the code */ #define PHD_ERRORS(X) \ - X(PLACEMENT_INVALID, "placement invalid: not a placement, or not valid here, as a " PHD_PLACE_POOL_PREFIX \ + X(PLACEMENT_INVALID, OMX_REPLY_PLUGIN_HOSTD_PLACEMENT_INVALID_RESP, "placement invalid: not a placement, or not valid here, as a " PHD_PLACE_POOL_PREFIX \ " for a plugin of a format whose pin holds only in a world of the plugin's own, while require_pins is on") \ - X(NO_BACKEND, "no worker program for the scheme") \ - X(WORKER_SPAWN, "the worker is not up: the spawn failed, or it is in backoff; ask again after instance_restored") \ - X(REPLAY, "the name of a refused replay, never a reply: a replayed add that its pin or the worker refuses is " \ + X(NO_BACKEND, OMX_REPLY_PLUGIN_HOSTD_NO_BACKEND_RESP, "no worker program for the scheme") \ + X(WORKER_SPAWN, OMX_REPLY_PLUGIN_HOSTD_WORKER_SPAWN_RESP, "the worker is not up: the spawn failed, or it is in backoff; ask again after instance_restored") \ + X(REPLAY, OMX_REPLY_PLUGIN_HOSTD_REPLAY_RESP, "the name of a refused replay, never a reply: a replayed add that its pin or the worker refuses is " \ "announced by the instance_replay_refused event with the refusal's own code, and written to stderr " \ "with this one and the step that refused it") \ - X(GAVE_UP, "the storm bound is spent for that placement") \ - X(NO_SUCH_WORKER, "no such worker") \ - X(VERB_DROPPED, "the worker died on this very command and the daemon dropped it: it is not replayed, " \ + X(GAVE_UP, OMX_REPLY_PLUGIN_HOSTD_GAVE_UP_RESP, "the storm bound is spent for that placement") \ + X(NO_SUCH_WORKER, OMX_REPLY_PLUGIN_HOSTD_NO_SUCH_WORKER_RESP, "no such worker") \ + X(VERB_DROPPED, OMX_REPLY_PLUGIN_HOSTD_VERB_DROPPED_RESP, "the worker died on this very command and the daemon dropped it: it is not replayed, " \ "and the instance_verb_dropped event names it; or it died on, or did not answer in rpc_timeout_ms, " \ - "the " PHD_VERB_PIN_EXPECT " of an add, which is then never forwarded") \ - X(PIN_ABSENT, "pin_mode strict and the plugin has no pin, or its layout pin is in a scheme this version does " \ + "the " OMX_VERB_PIN_EXPECT " of an add, which is then never forwarded") \ + X(PIN_ABSENT, OMX_REPLY_HOST_PIN_ABSENT_RESP, "pin_mode strict and the plugin has no pin, or its layout pin is in a scheme this version does " \ "not know: add is refused and no worker sees it") \ - X(PIN_BINARY_MISMATCH, "a pinned file is missing or its SHA-256 differs, or the plugin's manifest names a file the " \ + X(PIN_BINARY_MISMATCH, OMX_REPLY_PLUGIN_HOSTD_PIN_BINARY_MISMATCH_RESP, "a pinned file is missing or its SHA-256 differs, or the plugin's manifest names a file the " \ "pin does not hold: add is refused and no worker sees it") \ - X(PIN_LAYOUT_MISMATCH, "the worker found the parameter layout after init differs from the layout pin: the " \ + X(PIN_LAYOUT_MISMATCH, OMX_REPLY_HOST_PIN_LAYOUT_MISMATCH_RESP, "the worker found the parameter layout after init differs from the layout pin: the " \ "instance is destroyed before activate") \ - X(NO_PARAM_CONTRACT, "the host holds no checked unit and scale for this parameter: fall back to qualification") \ - X(LV2_ADAPTER_REFUSED, "the " PHD_FORMAT_LV2_CLAP " worker's LV2 adapter cannot run this plugin (MIDI it does not feed, a " \ + X(NO_PARAM_CONTRACT, OMX_REPLY_HOST_NO_PARAM_CONTRACT_RESP, "the host holds no checked unit and scale for this parameter: fall back to qualification") \ + X(LV2_ADAPTER_REFUSED, OMX_REPLY_PLUGIN_HOSTD_LV2_ADAPTER_REFUSED_RESP, "the " PHD_FORMAT_LV2_CLAP " worker's LV2 adapter cannot run this plugin (MIDI it does not feed, a " \ "required feature it lacks, a layout it does not take): the worker answered the add -102, the " \ PHD_EVENT_LV2_ADAPTER_REFUSED " event carries the hosting.* code of that reply, and under lv2_worker " \ PHD_LV2_WORKER_AUTO " the plugin is run by the " PHD_FORMAT_LV2 " row instead and this code is never " \ "answered; a plugin no bundle of the worker's world holds is no refusal: the worker's -101 is answered") \ - X(NO_NOTE_INPUT, "the instance's plugin takes no notes (an effect): its worker answers " PHD_VERB_NOTE_ON ", " \ - PHD_VERB_NOTE_OFF " and " PHD_VERB_ALL_NOTES_OFF " with this code") \ - X(NOTES_BY_JACK, "the instance's worker takes no notes on its socket (mod-host): the daemon answers the note verbs " \ - "and " PHD_VERB_NOTE_INPUT " with this code, and the plugin is played through its jack MIDI input " \ + X(NO_NOTE_INPUT, OMX_REPLY_HOST_NO_NOTE_INPUT_RESP, "the instance's plugin takes no notes (an effect): its worker answers " OMX_VERB_NOTE_ON ", " \ + OMX_VERB_NOTE_OFF " and " OMX_VERB_ALL_NOTES_OFF " with this code") \ + X(NOTES_BY_JACK, OMX_REPLY_HOST_NOTES_BY_JACK_RESP, "the instance's worker takes no notes on its socket (mod-host): the daemon answers the note verbs " \ + "and " OMX_VERB_NOTE_INPUT " with this code, and the plugin is played through its jack MIDI input " \ "with connect") \ - X(NO_PRESET_LIST, "the instance's worker cannot list the plugin's presets (mod-host): the daemon answers " \ + X(NO_PRESET_LIST, OMX_REPLY_PLUGIN_HOSTD_NO_PRESET_LIST_RESP, "the instance's worker cannot list the plugin's presets (mod-host): the daemon answers " \ OMX_VERB_PRESET_LIST " and " OMX_VERB_PRESET_GET " with this code; preset_load still takes a preset " \ "the controller knows") \ - X(PIN_REFUSED, "the plugin's pin carries " PHD_PIN_VERDICT_KEY PHD_PIN_VERDICT_REFUSED ": its files are the ones that " \ + X(PIN_REFUSED, OMX_REPLY_PLUGIN_HOSTD_PIN_REFUSED_RESP, "the plugin's pin carries " PHD_PIN_VERDICT_KEY PHD_PIN_VERDICT_REFUSED ": its files are the ones that " \ "failed qualification, so add is refused and no worker sees it, and a replayed add is refused the " \ - "same way; files that differ from the pin answer " PHD_STR(PHD_ERR_PIN_BINARY_MISMATCH) " first. A pins_dir " \ + "same way; files that differ from the pin answer " PHD_STR(OMX_REPLY_PLUGIN_HOSTD_PIN_BINARY_MISMATCH_RESP) " first. A pins_dir " \ "pin of that verdict is never overridden: " OMX_VERB_PIN_SET " and " OMX_VERB_PIN_ACCEPT " of its plugin " \ "answer this code") \ - X(NOTE_QUEUE_FULL, "the instance's worker has no room for this " PHD_VERB_NOTE_ON ", " PHD_VERB_NOTE_OFF " or " \ - PHD_VERB_ALL_NOTES_OFF " before its next block: the line was not taken and nothing of it is kept; the " \ + X(NOTE_QUEUE_FULL, OMX_REPLY_HOST_NOTE_QUEUE_FULL_RESP, "the instance's worker has no room for this " OMX_VERB_NOTE_ON ", " OMX_VERB_NOTE_OFF " or " \ + OMX_VERB_ALL_NOTES_OFF " before its next block: the line was not taken and nothing of it is kept; the " \ "controller may send it again") \ - X(CHAIN_UNKNOWN_INSTANCE, "a member of " OMX_VERB_CHAIN " is an instance no add made: the chain is not declared") \ - X(CHAIN_DUPLICATE, "an instance is named twice in one " OMX_VERB_CHAIN ": the chain is not declared") \ - X(CHAIN_INSTANCE_BUSY, "a member of " OMX_VERB_CHAIN " is already in another chain: the chain is not declared; " \ + X(CHAIN_UNKNOWN_INSTANCE, OMX_REPLY_PLUGIN_HOSTD_CHAIN_UNKNOWN_INSTANCE_RESP, "a member of " OMX_VERB_CHAIN " is an instance no add made: the chain is not declared") \ + X(CHAIN_DUPLICATE, OMX_REPLY_PLUGIN_HOSTD_CHAIN_DUPLICATE_RESP, "an instance is named twice in one " OMX_VERB_CHAIN ": the chain is not declared") \ + X(CHAIN_INSTANCE_BUSY, OMX_REPLY_PLUGIN_HOSTD_CHAIN_INSTANCE_BUSY_RESP, "a member of " OMX_VERB_CHAIN " is already in another chain: the chain is not declared; " \ OMX_VERB_CHAIN_CLEAR " of the other chain frees it") \ - X(CHAIN_MIXED_FORMAT, "the members of " OMX_VERB_CHAIN " are not all run by one worker program, or are of two " \ + X(CHAIN_MIXED_FORMAT, OMX_REPLY_PLUGIN_HOSTD_CHAIN_MIXED_FORMAT_RESP, "the members of " OMX_VERB_CHAIN " are not all run by one worker program, or are of two " \ "rows of one program and a row does not run chains in one client, so no one worker runs " \ "them: the chain is not declared") \ - X(NO_SUCH_CHAIN, OMX_VERB_CHAIN_CLEAR " or " OMX_VERB_CHAIN_GET " of a chain no " OMX_VERB_CHAIN " declared") \ - X(PRESET_NOT_OFFERED, "the worker: preset_load or preset_show of a stable name the plugin does not offer, or of a " \ + X(NO_SUCH_CHAIN, OMX_REPLY_PLUGIN_HOSTD_NO_SUCH_CHAIN_RESP, OMX_VERB_CHAIN_CLEAR " or " OMX_VERB_CHAIN_GET " of a chain no " OMX_VERB_CHAIN " declared") \ + X(PRESET_NOT_OFFERED, OMX_REPLY_PLUGIN_HOSTD_PRESET_NOT_OFFERED_RESP, "the worker: preset_load or preset_show of a stable name the plugin does not offer, or of a " \ "plugin with no preset system and no state") \ - X(PRESET_INVALID, "preset_save with a file path that is not absolute or with no name, or preset_load or " \ + X(PRESET_INVALID, OMX_REPLY_PLUGIN_HOSTD_PRESET_INVALID_RESP, "preset_save with a file path that is not absolute or with no name, or preset_load or " \ "preset_show of a file that cannot be read, is no JSON, is of a format version other than " \ PHD_PRESET_FORMAT_1 " and " PHD_PRESET_FORMAT_2 ", or breaks the format (docs/presets.md): the " \ "daemon answers it and no worker sees the file") \ - X(PRESET_NEEDS_STATE, "the worker: a preset file that carries state for a worker that cannot take state yet") \ - X(PRESET_PLUGIN_CHANGED, "the worker: the preset file's plugin id, version or fingerprint is not the instance's; " \ + X(PRESET_NEEDS_STATE, OMX_REPLY_PLUGIN_HOSTD_PRESET_NEEDS_STATE_RESP, "the worker: a preset file that carries state for a worker that cannot take state yet") \ + X(PRESET_PLUGIN_CHANGED, OMX_REPLY_PLUGIN_HOSTD_PRESET_PLUGIN_CHANGED_RESP, "the worker: the preset file's plugin id, version or fingerprint is not the instance's; " \ "nothing of it is applied") \ - X(LOAD_REFUSED, "the worker: the plugin refused the preset or the state its file carries") \ - X(DIR_NOT_WRITABLE, "descriptor_dir or qualification_dir cannot be made or written: the daemon does not start, and " \ + X(LOAD_REFUSED, OMX_REPLY_PLUGIN_HOSTD_LOAD_REFUSED_RESP, "the worker: the plugin refused the preset or the state its file carries") \ + X(DIR_NOT_WRITABLE, OMX_REPLY_PLUGIN_HOSTD_DIR_NOT_WRITABLE_RESP, "descriptor_dir or qualification_dir cannot be made or written: the daemon does not start, and " \ "says which key and which path on stderr with this code; a directory that turns read-only " \ "later makes the scan of an add write nothing, and " OMX_VERB_DESCRIPTOR_GET " and " \ OMX_VERB_PANEL_GET " of that plugin answer this code") \ - X(DESCRIPTOR_ABSENT, OMX_VERB_DESCRIPTOR_GET " (" OMX_VERB_PANEL_GET ") of a plugin that has no descriptor (panel) " \ + X(DESCRIPTOR_ABSENT, OMX_REPLY_PLUGIN_HOSTD_DESCRIPTOR_ABSENT_RESP, OMX_VERB_DESCRIPTOR_GET " (" OMX_VERB_PANEL_GET ") of a plugin that has no descriptor (panel) " \ "in descriptor_dir for its binary as it is now, and none being written: no add since it " \ "changed, or a binary that cannot be found") \ - X(DESCRIPTOR_PENDING, OMX_VERB_DESCRIPTOR_GET " (" OMX_VERB_PANEL_GET ") of a plugin whose scan, started by its " \ + X(DESCRIPTOR_PENDING, OMX_REPLY_PLUGIN_HOSTD_DESCRIPTOR_PENDING_RESP, OMX_VERB_DESCRIPTOR_GET " (" OMX_VERB_PANEL_GET ") of a plugin whose scan, started by its " \ "add, has not written its descriptor (panel) yet: ask again") \ - X(DESCRIPTOR_SCAN_FAILED, OMX_VERB_DESCRIPTOR_GET " (" OMX_VERB_PANEL_GET ") of a plugin whose last scan wrote no " \ + X(DESCRIPTOR_SCAN_FAILED, OMX_REPLY_PLUGIN_HOSTD_DESCRIPTOR_SCAN_FAILED_RESP, OMX_VERB_DESCRIPTOR_GET " (" OMX_VERB_PANEL_GET ") of a plugin whose last scan wrote no " \ "descriptor (panel): the scanner refused the plugin, made no dump or no panel, or is not " \ "installed; the add it ran for stands, and stderr and the scan's log say why. The next add " \ "scans again") \ - X(NO_SUCH_PLAN, OMX_VERB_PLAN_GET " or " OMX_VERB_PLAN_CLEAR " of a chain no " OMX_VERB_PLAN " planned") + X(NO_SUCH_PLAN, OMX_REPLY_PLUGIN_HOSTD_NO_SUCH_PLAN_RESP, OMX_VERB_PLAN_GET " or " OMX_VERB_PLAN_CLEAR " of a chain no " OMX_VERB_PLAN " planned") /* ---------------------------------------------------------------- verbs */ /* mod-host's add, which the daemon extends with a placement; every verb of its own is OMX_VERB_ of - * plugin_hostd_host_verbs.h */ + * plugin_hostd_host_verbs.h, and pin_expect is omx-clap-core's, OMX_VERB_PIN_EXPECT */ #define PHD_VERB_ADD "add" -#define PHD_VERB_PIN_EXPECT "pin_expect" /* the words of a pin: =, joined by ',', and : */ #define PHD_PIN_FILE_SEPARATOR "," @@ -433,7 +402,7 @@ static inline int phd_pool_name_valid(const char *name) X(LINE, "a " OMX_VERB_PIN_SET " line is at most line_max, " PHD_STR(PHD_LINE_MAX) " bytes, the protocol socket's " \ "buffer; a longer one is refused as outside the grammar") \ X(MANIFEST, "a manifest that uses @base, or names a file of the plugin by a percent-encoded IRI, makes add answer " \ - "PHD_ERR_PIN_BINARY_MISMATCH " PHD_STR(PHD_ERR_PIN_BINARY_MISMATCH) ": the daemon does not resolve " \ + "OMX_REPLY_PLUGIN_HOSTD_PIN_BINARY_MISMATCH_RESP " PHD_STR(OMX_REPLY_PLUGIN_HOSTD_PIN_BINARY_MISMATCH_RESP) ": the daemon does not resolve " \ "either, so it cannot know the file the host would load") /* the verbs the daemon adds to mod-host's, or extends: X(id, name, arguments, reply, meaning) */ @@ -476,7 +445,7 @@ static inline int phd_pool_name_valid(const char *name) X(PIN_LAYOUT, OMX_VERB_PIN_LAYOUT, "", OMX_VERB_PIN_LAYOUT_REPLY, \ "sent by the daemon to a worker of a format that checks layouts, after it accepted the add of a plugin whose layout pin is " \ "still unknown: the layout the worker found after init, which the daemon records in the pin") \ - X(PIN_EXPECT, PHD_VERB_PIN_EXPECT, " " PHD_PIN_SCHEME_SEPARATOR "", "resp 0", \ + X(PIN_EXPECT, OMX_VERB_PIN_EXPECT, " " PHD_PIN_SCHEME_SEPARATOR "", "resp 0", \ "sent by the daemon to a worker of a format that checks layouts, just before the instance's add: the layout pin that add " \ "checks after init and before activate; any other reply than resp 0 refuses the add with that code, and the " \ "add is never forwarded") \ @@ -549,31 +518,13 @@ static inline int phd_pool_name_valid(const char *name) * worker of a format whose workers answer them from the plugin; for a format whose worker does not, it answers them * itself and never forwards them. A string word is quoted when it is not a plain word, and always in a reply, with \" inside it * for a quote: mod-host's own tokenizer reads them. */ -#define PHD_VERB_TRACK_INFO "track_info" -#define PHD_VERB_REMOTE_PAGES "remote_pages" -#define PHD_VERB_REMOTE_PAGE_GET "remote_page_get" -#define PHD_VERB_PARAM_INFO "param_info" - -/* the same verbs as a host registers them with protocol_add_command; preset_list and preset_get are the daemon's, +/* The words and the lines of these verbs, and of the note verbs below, are omx-clap-core's declarations (its HOST_VERBS, + * omx_clap_core_host_verbs.h): OMX_VERB_ and OMX_VERB__FMT. preset_list and preset_get are the daemon's, * OMX_VERB_PRESET_LIST and OMX_VERB_PRESET_GET */ -#define PHD_VERB_TRACK_INFO_FMT PHD_VERB_TRACK_INFO " %i %s %s ..." -#define PHD_VERB_REMOTE_PAGES_FMT PHD_VERB_REMOTE_PAGES " %i" -#define PHD_VERB_REMOTE_PAGE_GET_FMT PHD_VERB_REMOTE_PAGE_GET " %i %i" -#define PHD_VERB_PARAM_INFO_FMT PHD_VERB_PARAM_INFO " %i %s" /* Notes, played on an instance by a controller that is not a jack client: the worker delivers each one as a MIDI * message at the start of its next cycle, on the plugin's note input. Nothing of them is kept: a note is an act, not a * setting, and a respawned instance starts silent. */ -#define PHD_VERB_NOTE_INPUT "note_input" -#define PHD_VERB_NOTE_ON "note_on" -#define PHD_VERB_NOTE_OFF "note_off" -#define PHD_VERB_ALL_NOTES_OFF "all_notes_off" - -#define PHD_VERB_NOTE_INPUT_FMT PHD_VERB_NOTE_INPUT " %i" -#define PHD_VERB_NOTE_ON_FMT PHD_VERB_NOTE_ON " %i %i %i %i" -#define PHD_VERB_NOTE_OFF_FMT PHD_VERB_NOTE_OFF " %i %i %i %i" -#define PHD_VERB_ALL_NOTES_OFF_FMT PHD_VERB_ALL_NOTES_OFF " %i" - /* the ranges of a note's words: MIDI's */ #define PHD_NOTE_CHANNEL_MAX 15 #define PHD_NOTE_KEY_MAX 127 @@ -597,7 +548,8 @@ static inline int phd_pool_name_valid(const char *name) #define PHD_NO_COLOR PHD_WORD_NONE /* the kind of strip, the fourth word of track_info; none for an input channel: X(id, name) */ -#define PHD_TRACK_KINDS(X) X(BUS, "bus") X(RETURN, "return") X(MASTER, "master") +#define PHD_TRACK_KINDS(X) \ + X(BUS, OMX_HOST_TRACK_KINDS_BUS) X(RETURN, OMX_HOST_TRACK_KINDS_RETURN) X(MASTER, OMX_HOST_TRACK_KINDS_MASTER) /* how a parameter's plain value maps to a control's travel: X(id, name, meaning) */ #define PHD_PARAM_SCALES(X) \ @@ -611,38 +563,38 @@ static inline int phd_pool_name_valid(const char *name) /* X(id, name, arguments, reply, ledger, meaning) */ #define PHD_INSTANCE_VERBS(X) \ - X(TRACK_INFO, PHD_VERB_TRACK_INFO, " <#RRGGBB | " PHD_NO_COLOR "> [bus | return | master]", \ + X(TRACK_INFO, OMX_VERB_TRACK_INFO, " <#RRGGBB | " PHD_NO_COLOR "> [bus | return | master]", \ "resp 0", REPLACE, \ "the strip's name (\"\" for none), colour and kind, absent for an input channel; a worker whose plugin format " \ "has a track-info extension passes them on; any other word is -902") \ - X(REMOTE_PAGES, PHD_VERB_REMOTE_PAGES, "", "resp ", NONE, \ + X(REMOTE_PAGES, OMX_VERB_REMOTE_PAGES, "", "resp ", NONE, \ "the plugin's remote-control pages, from clap.remote-controls; 0 for an instance of a format whose worker has none") \ - X(REMOTE_PAGE_GET, PHD_VERB_REMOTE_PAGE_GET, " ", \ + X(REMOTE_PAGE_GET, OMX_VERB_REMOTE_PAGE_GET, " ", \ "resp 0
", NONE, \ "one page, 0 to count - 1: each slot the symbol param_set takes, " PHD_EMPTY_SLOT " for an empty one; -902 " \ "for a page that is not one") \ - X(PARAM_INFO, PHD_VERB_PARAM_INFO, " ", \ + X(PARAM_INFO, OMX_VERB_PARAM_INFO, " ", \ "resp 0 ", NONE, \ "what a parameter's value means: its unit, its scale, and the symbol it keeps across hosts and versions; -103 " \ "for a symbol that is not a parameter, the plugin's own bypass and :bypass included; " \ "-511 for a parameter whose unit and scale the worker holds no checked contract for") \ X(PRESET_LIST, OMX_VERB_PRESET_LIST, "", OMX_VERB_PRESET_LIST_REPLY, NONE, \ - "the plugin's presets, the ones its preset discovery or its bundle lists; " PHD_STR(PHD_ERR_NO_PRESET_LIST) \ + "the plugin's presets, the ones its preset discovery or its bundle lists; " PHD_STR(OMX_REPLY_PLUGIN_HOSTD_NO_PRESET_LIST_RESP) \ " for an instance of a worker that cannot list them") \ X(PRESET_GET, OMX_VERB_PRESET_GET, " ", OMX_VERB_PRESET_GET_REPLY, NONE, \ "one preset, 0 to count - 1: the key preset_load takes for it, and its name; -902 for an index that is not one") \ - X(NOTE_INPUT, PHD_VERB_NOTE_INPUT, "", "resp 0 ", NONE, \ + X(NOTE_INPUT, OMX_VERB_NOTE_INPUT, "", "resp 0 ", NONE, \ "whether the instance takes notes: the name of its note input on its worker's jack client, " PHD_NO_NOTE_INPUT \ - " for a plugin that takes none; " PHD_STR(PHD_ERR_NOTES_BY_JACK) " for an instance of a worker that cannot say") \ - X(NOTE_ON, PHD_VERB_NOTE_ON, " ", "resp 0", NONE, \ + " for a plugin that takes none; " PHD_STR(OMX_REPLY_HOST_NOTES_BY_JACK_RESP) " for an instance of a worker that cannot say") \ + X(NOTE_ON, OMX_VERB_NOTE_ON, " ", "resp 0", NONE, \ "play a key: channel 0 to " PHD_STR(PHD_NOTE_CHANNEL_MAX) ", key 0 to " PHD_STR(PHD_NOTE_KEY_MAX) ", velocity 1 to " \ PHD_STR(PHD_NOTE_VELOCITY_MAX) ", a MIDI note on at the start of the worker's next cycle; " \ - PHD_STR(PHD_ERR_NO_NOTE_INPUT) " for a plugin that takes no notes, " PHD_STR(PHD_ERR_NOTES_BY_JACK) \ + PHD_STR(OMX_REPLY_HOST_NO_NOTE_INPUT_RESP) " for a plugin that takes no notes, " PHD_STR(OMX_REPLY_HOST_NOTES_BY_JACK_RESP) \ " for an instance of a worker that takes none on its socket, -902 for a word out of its range") \ - X(NOTE_OFF, PHD_VERB_NOTE_OFF, " ", "resp 0", NONE, \ - "release a key, velocity 0 to " PHD_STR(PHD_NOTE_VELOCITY_MAX) ", a MIDI note off; answered as " PHD_VERB_NOTE_ON " is") \ - X(ALL_NOTES_OFF, PHD_VERB_ALL_NOTES_OFF, "", "resp 0", NONE, \ - "release every key of every channel, MIDI's all notes off (controller 123) on each; answered as " PHD_VERB_NOTE_ON " is") + X(NOTE_OFF, OMX_VERB_NOTE_OFF, " ", "resp 0", NONE, \ + "release a key, velocity 0 to " PHD_STR(PHD_NOTE_VELOCITY_MAX) ", a MIDI note off; answered as " OMX_VERB_NOTE_ON " is") \ + X(ALL_NOTES_OFF, OMX_VERB_ALL_NOTES_OFF, "", "resp 0", NONE, \ + "release every key of every channel, MIDI's all notes off (controller 123) on each; answered as " OMX_VERB_NOTE_ON " is") /* whether s is a string word: valid UTF-8, at most PHD_STRING_MAX bytes, no byte below 0x20 */ static inline int phd_string_valid(const char *s) @@ -745,14 +697,14 @@ static inline int phd_number_in(const char *word, int lo, int hi) /* whether the words of a note verb's line, the verb first, are its grammar; 0 for a line of another verb */ static inline int phd_note_valid(char *const *word, int count) { - int on = !strcmp(word[0], PHD_VERB_NOTE_ON); + int on = !strcmp(word[0], OMX_VERB_NOTE_ON); if (count < 2 || !phd_number_in(word[1], 0, 1 << 20)) return 0; - if (on || !strcmp(word[0], PHD_VERB_NOTE_OFF)) + if (on || !strcmp(word[0], OMX_VERB_NOTE_OFF)) return count == 5 && phd_number_in(word[2], 0, PHD_NOTE_CHANNEL_MAX) && phd_number_in(word[3], 0, PHD_NOTE_KEY_MAX) && phd_number_in(word[4], on ? 1 : 0, PHD_NOTE_VELOCITY_MAX); - if (!strcmp(word[0], PHD_VERB_ALL_NOTES_OFF) || !strcmp(word[0], PHD_VERB_NOTE_INPUT)) + if (!strcmp(word[0], OMX_VERB_ALL_NOTES_OFF) || !strcmp(word[0], OMX_VERB_NOTE_INPUT)) return count == 2; return 0; } @@ -760,8 +712,8 @@ static inline int phd_note_valid(char *const *word, int count) /* whether a verb is one of the note verbs */ static inline int phd_is_note_verb(const char *verb) { - return !strcmp(verb, PHD_VERB_NOTE_ON) || !strcmp(verb, PHD_VERB_NOTE_OFF) || !strcmp(verb, PHD_VERB_ALL_NOTES_OFF) || - !strcmp(verb, PHD_VERB_NOTE_INPUT); + return !strcmp(verb, OMX_VERB_NOTE_ON) || !strcmp(verb, OMX_VERB_NOTE_OFF) || !strcmp(verb, OMX_VERB_ALL_NOTES_OFF) || + !strcmp(verb, OMX_VERB_NOTE_INPUT); } /* ---------------------------------------------------------------- the host verb table */ @@ -844,16 +796,16 @@ static inline int phd_is_note_verb(const char *verb) X("load", MOD_HOST, OPTIONAL, OPTIONAL, OPTIONAL, OPTIONAL) \ X("save", MOD_HOST, OPTIONAL, OPTIONAL, OPTIONAL, OPTIONAL) \ X("help", MOD_HOST, OPTIONAL, OPTIONAL, OPTIONAL, OPTIONAL) \ - X(PHD_VERB_TRACK_INFO, MOD_HOST, OPTIONAL, OPTIONAL, OPTIONAL, OPTIONAL) \ - X(PHD_VERB_REMOTE_PAGES, MOD_HOST, OPTIONAL, OPTIONAL, OPTIONAL, OPTIONAL) \ - X(PHD_VERB_REMOTE_PAGE_GET, MOD_HOST, OPTIONAL, OPTIONAL, OPTIONAL, OPTIONAL) \ - X(PHD_VERB_PARAM_INFO, MOD_HOST, OPTIONAL, OPTIONAL, OPTIONAL, OPTIONAL) \ + X(OMX_VERB_TRACK_INFO, MOD_HOST, OPTIONAL, OPTIONAL, OPTIONAL, OPTIONAL) \ + X(OMX_VERB_REMOTE_PAGES, MOD_HOST, OPTIONAL, OPTIONAL, OPTIONAL, OPTIONAL) \ + X(OMX_VERB_REMOTE_PAGE_GET, MOD_HOST, OPTIONAL, OPTIONAL, OPTIONAL, OPTIONAL) \ + X(OMX_VERB_PARAM_INFO, MOD_HOST, OPTIONAL, OPTIONAL, OPTIONAL, OPTIONAL) \ X(OMX_VERB_PRESET_LIST, DAEMON, OPTIONAL, OPTIONAL, OPTIONAL, OPTIONAL) \ X(OMX_VERB_PRESET_GET, DAEMON, OPTIONAL, OPTIONAL, OPTIONAL, OPTIONAL) \ - X(PHD_VERB_NOTE_INPUT, DAEMON, OPTIONAL, OPTIONAL, OPTIONAL, OPTIONAL) \ - X(PHD_VERB_NOTE_ON, DAEMON, OPTIONAL, OPTIONAL, OPTIONAL, OPTIONAL) \ - X(PHD_VERB_NOTE_OFF, DAEMON, OPTIONAL, OPTIONAL, OPTIONAL, OPTIONAL) \ - X(PHD_VERB_ALL_NOTES_OFF, DAEMON, OPTIONAL, OPTIONAL, OPTIONAL, OPTIONAL) \ + X(OMX_VERB_NOTE_INPUT, DAEMON, OPTIONAL, OPTIONAL, OPTIONAL, OPTIONAL) \ + X(OMX_VERB_NOTE_ON, DAEMON, OPTIONAL, OPTIONAL, OPTIONAL, OPTIONAL) \ + X(OMX_VERB_NOTE_OFF, DAEMON, OPTIONAL, OPTIONAL, OPTIONAL, OPTIONAL) \ + X(OMX_VERB_ALL_NOTES_OFF, DAEMON, OPTIONAL, OPTIONAL, OPTIONAL, OPTIONAL) \ X(OMX_VERB_WORKER_LIST, DAEMON, REQUIRED, REQUIRED, REQUIRED, REQUIRED) \ X(OMX_VERB_INSTANCE_INFO, DAEMON, REQUIRED, REQUIRED, REQUIRED, REQUIRED) \ X(OMX_VERB_SUPERVISOR_RESET, DAEMON, REQUIRED, REQUIRED, REQUIRED, REQUIRED) \ @@ -942,7 +894,7 @@ static inline int phd_is_note_verb(const char *verb) "a worker died; the instances it held, or - for none") \ X(PHD_EVENT_INSTANCE_VERB_DROPPED, " ", \ "the command a worker died on, dropped from the ledger; or the add it died on, the add as the worker was given it, " \ - "which names the plugin, or the " PHD_VERB_PIN_EXPECT " of that add") \ + "which names the plugin, or the " OMX_VERB_PIN_EXPECT " of that add") \ X(PHD_EVENT_INSTANCE_VERB_DROPPED, " " PHD_EVENT_SUSPECT_PREFIX " ", \ "the last verb a worker answered when it died inside suspect_window_ms, the age of the reply") \ X(PHD_EVENT_WORKER_BACKOFF, " ", "the respawn waits this long") \ @@ -967,11 +919,11 @@ static inline int phd_is_note_verb(const char *verb) "the LV2 adapter of the " PHD_FORMAT_LV2_CLAP " worker refused a plugin: is the hosting.* code after -102 on the " \ "worker's reply to that add (" PHD_WORD_NONE " when it named none); the last word is the lv2_worker in force, " PHD_LV2_WORKER_AUTO " for a plugin " \ "the " PHD_FORMAT_LV2 " row runs from now on, " PHD_LV2_WORKER_CLAP_HOST " for an add answered " \ - PHD_STR(PHD_ERR_LV2_ADAPTER_REFUSED)) \ + PHD_STR(OMX_REPLY_PLUGIN_HOSTD_LV2_ADAPTER_REFUSED_RESP)) \ X(PHD_EVENT_REMOTE_PAGES_CHANGED, "", \ "relayed from a worker: the plugin changed its remote pages; read them again") \ X(PHD_EVENT_REMOTE_PAGE_SUGGEST, " ", \ - "relayed from a worker: the plugin suggests the remote page of that id (a page_id of " PHD_VERB_REMOTE_PAGE_GET \ + "relayed from a worker: the plugin suggests the remote page of that id (a page_id of " OMX_VERB_REMOTE_PAGE_GET \ "); a surface may follow it") \ X(PHD_EVENT_PARAM_GESTURE, " " PHD_GESTURE_BEGIN " | " PHD_GESTURE_END, \ "relayed from a worker: the user took hold of a control of the plugin's own, or let it go; a controller writes no " \ @@ -1059,7 +1011,7 @@ static inline int phd_is_note_verb(const char *verb) /* The directories of what the scan of an add gathers: state, kept across a reboot. An empty setting is the default: * /, where the state home is $XDG_STATE_HOME, else /var/lib for a daemon run as root (a system - * service), else $HOME/.local/state. A missing directory is made, mode 0700; one that cannot be written stops the daemon with PHD_ERR_DIR_NOT_WRITABLE. */ + * service), else $HOME/.local/state. A missing directory is made, mode 0700; one that cannot be written stops the daemon with OMX_REPLY_PLUGIN_HOSTD_DIR_NOT_WRITABLE_RESP. */ #define PHD_DIR_DESCRIPTORS_SUBDIR "omx/descriptors" #define PHD_DIR_QUALIFICATION_SUBDIR "omx/qualification" #define PHD_DIR_SYSTEM_STATE_HOME "/var/lib" diff --git a/packaging/plugin-hostd.spec b/packaging/plugin-hostd.spec index 022d4bf..c3bc827 100644 --- a/packaging/plugin-hostd.spec +++ b/packaging/plugin-hostd.spec @@ -137,6 +137,8 @@ make test-daemon check-generated check-rendered %license COPYING %{_includedir}/plugin-hostd/protocol.h %{_includedir}/plugin-hostd/plugin_hostd_host_verbs.h +%{_includedir}/plugin-hostd/omx_clap_core_host_verbs.h +%{_includedir}/plugin-hostd/omx_clap_core_vocabulary.h %{_includedir}/plugin-hostd/plugin_hostd_vocabulary.h %{_includedir}/plugin-hostd/pin.h %{_datadir}/pkgconfig/plugin-hostd.pc diff --git a/protocol/plugin-hostd.json b/protocol/plugin-hostd.json index 78de361..335ba2a 100644 --- a/protocol/plugin-hostd.json +++ b/protocol/plugin-hostd.json @@ -26,38 +26,38 @@ {"name": "given-up", "meaning": "the storm bound is spent for its placement"} ], "errors": [ - {"name": "PLACEMENT_INVALID", "macro": "PHD_ERR_PLACEMENT_INVALID", "code": -501, "meaning": "placement invalid: not a placement, or not valid here, as a pool: for a plugin of a format whose pin holds only in a world of the plugin's own, while require_pins is on"}, - {"name": "NO_BACKEND", "macro": "PHD_ERR_NO_BACKEND", "code": -502, "meaning": "no worker program for the scheme"}, - {"name": "WORKER_SPAWN", "macro": "PHD_ERR_WORKER_SPAWN", "code": -503, "meaning": "the worker is not up: the spawn failed, or it is in backoff; ask again after instance_restored"}, - {"name": "REPLAY", "macro": "PHD_ERR_REPLAY", "code": -504, "meaning": "the name of a refused replay, never a reply: a replayed add that its pin or the worker refuses is announced by the instance_replay_refused event with the refusal's own code, and written to stderr with this one and the step that refused it"}, - {"name": "GAVE_UP", "macro": "PHD_ERR_GAVE_UP", "code": -505, "meaning": "the storm bound is spent for that placement"}, - {"name": "NO_SUCH_WORKER", "macro": "PHD_ERR_NO_SUCH_WORKER", "code": -506, "meaning": "no such worker"}, - {"name": "VERB_DROPPED", "macro": "PHD_ERR_VERB_DROPPED", "code": -507, "meaning": "the worker died on this very command and the daemon dropped it: it is not replayed, and the instance_verb_dropped event names it; or it died on, or did not answer in rpc_timeout_ms, the pin_expect of an add, which is then never forwarded"}, - {"name": "PIN_ABSENT", "macro": "PHD_ERR_PIN_ABSENT", "code": -508, "meaning": "pin_mode strict and the plugin has no pin, or its layout pin is in a scheme this version does not know: add is refused and no worker sees it"}, - {"name": "PIN_BINARY_MISMATCH", "macro": "PHD_ERR_PIN_BINARY_MISMATCH", "code": -509, "meaning": "a pinned file is missing or its SHA-256 differs, or the plugin's manifest names a file the pin does not hold: add is refused and no worker sees it"}, - {"name": "PIN_LAYOUT_MISMATCH", "macro": "PHD_ERR_PIN_LAYOUT_MISMATCH", "code": -510, "meaning": "the worker found the parameter layout after init differs from the layout pin: the instance is destroyed before activate"}, - {"name": "NO_PARAM_CONTRACT", "macro": "PHD_ERR_NO_PARAM_CONTRACT", "code": -511, "meaning": "the host holds no checked unit and scale for this parameter: fall back to qualification"}, - {"name": "LV2_ADAPTER_REFUSED", "macro": "PHD_ERR_LV2_ADAPTER_REFUSED", "code": -512, "meaning": "the lv2-clap worker's LV2 adapter cannot run this plugin (MIDI it does not feed, a required feature it lacks, a layout it does not take): the worker answered the add -102, the lv2_adapter_refused event carries the hosting.* code of that reply, and under lv2_worker auto the plugin is run by the lv2 row instead and this code is never answered; a plugin no bundle of the worker's world holds is no refusal: the worker's -101 is answered"}, - {"name": "NO_NOTE_INPUT", "macro": "PHD_ERR_NO_NOTE_INPUT", "code": -513, "meaning": "the instance's plugin takes no notes (an effect): its worker answers note_on, note_off and all_notes_off with this code"}, - {"name": "NOTES_BY_JACK", "macro": "PHD_ERR_NOTES_BY_JACK", "code": -514, "meaning": "the instance's worker takes no notes on its socket (mod-host): the daemon answers the note verbs and note_input with this code, and the plugin is played through its jack MIDI input with connect"}, - {"name": "NO_PRESET_LIST", "macro": "PHD_ERR_NO_PRESET_LIST", "code": -515, "meaning": "the instance's worker cannot list the plugin's presets (mod-host): the daemon answers preset_list and preset_get with this code; preset_load still takes a preset the controller knows"}, - {"name": "PIN_REFUSED", "macro": "PHD_ERR_PIN_REFUSED", "code": -516, "meaning": "the plugin's pin carries verdict=refused: its files are the ones that failed qualification, so add is refused and no worker sees it, and a replayed add is refused the same way; files that differ from the pin answer (-509) first. A pins_dir pin of that verdict is never overridden: pin_set and pin_accept of its plugin answer this code"}, - {"name": "NOTE_QUEUE_FULL", "macro": "PHD_ERR_NOTE_QUEUE_FULL", "code": -517, "meaning": "the instance's worker has no room for this note_on, note_off or all_notes_off before its next block: the line was not taken and nothing of it is kept; the controller may send it again"}, - {"name": "CHAIN_UNKNOWN_INSTANCE", "macro": "PHD_ERR_CHAIN_UNKNOWN_INSTANCE", "code": -518, "meaning": "a member of chain is an instance no add made: the chain is not declared"}, - {"name": "CHAIN_DUPLICATE", "macro": "PHD_ERR_CHAIN_DUPLICATE", "code": -519, "meaning": "an instance is named twice in one chain: the chain is not declared"}, - {"name": "CHAIN_INSTANCE_BUSY", "macro": "PHD_ERR_CHAIN_INSTANCE_BUSY", "code": -520, "meaning": "a member of chain is already in another chain: the chain is not declared; chain_clear of the other chain frees it"}, - {"name": "CHAIN_MIXED_FORMAT", "macro": "PHD_ERR_CHAIN_MIXED_FORMAT", "code": -521, "meaning": "the members of chain are not all run by one worker program, or are of two rows of one program and a row does not run chains in one client, so no one worker runs them: the chain is not declared"}, - {"name": "NO_SUCH_CHAIN", "macro": "PHD_ERR_NO_SUCH_CHAIN", "code": -522, "meaning": "chain_clear or chain_get of a chain no chain declared"}, - {"name": "PRESET_NOT_OFFERED", "macro": "PHD_ERR_PRESET_NOT_OFFERED", "code": -523, "meaning": "the worker: preset_load or preset_show of a stable name the plugin does not offer, or of a plugin with no preset system and no state"}, - {"name": "PRESET_INVALID", "macro": "PHD_ERR_PRESET_INVALID", "code": -524, "meaning": "preset_save with a file path that is not absolute or with no name, or preset_load or preset_show of a file that cannot be read, is no JSON, is of a format version other than org.openmixer.preset/1 and org.openmixer.preset/2, or breaks the format (docs/presets.md): the daemon answers it and no worker sees the file"}, - {"name": "PRESET_NEEDS_STATE", "macro": "PHD_ERR_PRESET_NEEDS_STATE", "code": -525, "meaning": "the worker: a preset file that carries state for a worker that cannot take state yet"}, - {"name": "PRESET_PLUGIN_CHANGED", "macro": "PHD_ERR_PRESET_PLUGIN_CHANGED", "code": -526, "meaning": "the worker: the preset file's plugin id, version or fingerprint is not the instance's; nothing of it is applied"}, - {"name": "LOAD_REFUSED", "macro": "PHD_ERR_LOAD_REFUSED", "code": -527, "meaning": "the worker: the plugin refused the preset or the state its file carries"}, - {"name": "DIR_NOT_WRITABLE", "macro": "PHD_ERR_DIR_NOT_WRITABLE", "code": -528, "meaning": "descriptor_dir or qualification_dir cannot be made or written: the daemon does not start, and says which key and which path on stderr with this code; a directory that turns read-only later makes the scan of an add write nothing, and descriptor_get and panel_get of that plugin answer this code"}, - {"name": "DESCRIPTOR_ABSENT", "macro": "PHD_ERR_DESCRIPTOR_ABSENT", "code": -529, "meaning": "descriptor_get (panel_get) of a plugin that has no descriptor (panel) in descriptor_dir for its binary as it is now, and none being written: no add since it changed, or a binary that cannot be found"}, - {"name": "DESCRIPTOR_PENDING", "macro": "PHD_ERR_DESCRIPTOR_PENDING", "code": -530, "meaning": "descriptor_get (panel_get) of a plugin whose scan, started by its add, has not written its descriptor (panel) yet: ask again"}, - {"name": "DESCRIPTOR_SCAN_FAILED", "macro": "PHD_ERR_DESCRIPTOR_SCAN_FAILED", "code": -531, "meaning": "descriptor_get (panel_get) of a plugin whose last scan wrote no descriptor (panel): the scanner refused the plugin, made no dump or no panel, or is not installed; the add it ran for stands, and stderr and the scan's log say why. The next add scans again"}, - {"name": "NO_SUCH_PLAN", "macro": "PHD_ERR_NO_SUCH_PLAN", "code": -532, "meaning": "plan_get or plan_clear of a chain no plan planned"} + {"name": "PLACEMENT_INVALID", "macro": "OMX_REPLY_PLUGIN_HOSTD_PLACEMENT_INVALID_RESP", "code": -501, "meaning": "placement invalid: not a placement, or not valid here, as a pool: for a plugin of a format whose pin holds only in a world of the plugin's own, while require_pins is on"}, + {"name": "NO_BACKEND", "macro": "OMX_REPLY_PLUGIN_HOSTD_NO_BACKEND_RESP", "code": -502, "meaning": "no worker program for the scheme"}, + {"name": "WORKER_SPAWN", "macro": "OMX_REPLY_PLUGIN_HOSTD_WORKER_SPAWN_RESP", "code": -503, "meaning": "the worker is not up: the spawn failed, or it is in backoff; ask again after instance_restored"}, + {"name": "REPLAY", "macro": "OMX_REPLY_PLUGIN_HOSTD_REPLAY_RESP", "code": -504, "meaning": "the name of a refused replay, never a reply: a replayed add that its pin or the worker refuses is announced by the instance_replay_refused event with the refusal's own code, and written to stderr with this one and the step that refused it"}, + {"name": "GAVE_UP", "macro": "OMX_REPLY_PLUGIN_HOSTD_GAVE_UP_RESP", "code": -505, "meaning": "the storm bound is spent for that placement"}, + {"name": "NO_SUCH_WORKER", "macro": "OMX_REPLY_PLUGIN_HOSTD_NO_SUCH_WORKER_RESP", "code": -506, "meaning": "no such worker"}, + {"name": "VERB_DROPPED", "macro": "OMX_REPLY_PLUGIN_HOSTD_VERB_DROPPED_RESP", "code": -507, "meaning": "the worker died on this very command and the daemon dropped it: it is not replayed, and the instance_verb_dropped event names it; or it died on, or did not answer in rpc_timeout_ms, the pin_expect of an add, which is then never forwarded"}, + {"name": "PIN_ABSENT", "macro": "OMX_REPLY_HOST_PIN_ABSENT_RESP", "code": -508, "meaning": "pin_mode strict and the plugin has no pin, or its layout pin is in a scheme this version does not know: add is refused and no worker sees it"}, + {"name": "PIN_BINARY_MISMATCH", "macro": "OMX_REPLY_PLUGIN_HOSTD_PIN_BINARY_MISMATCH_RESP", "code": -509, "meaning": "a pinned file is missing or its SHA-256 differs, or the plugin's manifest names a file the pin does not hold: add is refused and no worker sees it"}, + {"name": "PIN_LAYOUT_MISMATCH", "macro": "OMX_REPLY_HOST_PIN_LAYOUT_MISMATCH_RESP", "code": -510, "meaning": "the worker found the parameter layout after init differs from the layout pin: the instance is destroyed before activate"}, + {"name": "NO_PARAM_CONTRACT", "macro": "OMX_REPLY_HOST_NO_PARAM_CONTRACT_RESP", "code": -511, "meaning": "the host holds no checked unit and scale for this parameter: fall back to qualification"}, + {"name": "LV2_ADAPTER_REFUSED", "macro": "OMX_REPLY_PLUGIN_HOSTD_LV2_ADAPTER_REFUSED_RESP", "code": -512, "meaning": "the lv2-clap worker's LV2 adapter cannot run this plugin (MIDI it does not feed, a required feature it lacks, a layout it does not take): the worker answered the add -102, the lv2_adapter_refused event carries the hosting.* code of that reply, and under lv2_worker auto the plugin is run by the lv2 row instead and this code is never answered; a plugin no bundle of the worker's world holds is no refusal: the worker's -101 is answered"}, + {"name": "NO_NOTE_INPUT", "macro": "OMX_REPLY_HOST_NO_NOTE_INPUT_RESP", "code": -513, "meaning": "the instance's plugin takes no notes (an effect): its worker answers note_on, note_off and all_notes_off with this code"}, + {"name": "NOTES_BY_JACK", "macro": "OMX_REPLY_HOST_NOTES_BY_JACK_RESP", "code": -514, "meaning": "the instance's worker takes no notes on its socket (mod-host): the daemon answers the note verbs and note_input with this code, and the plugin is played through its jack MIDI input with connect"}, + {"name": "NO_PRESET_LIST", "macro": "OMX_REPLY_PLUGIN_HOSTD_NO_PRESET_LIST_RESP", "code": -515, "meaning": "the instance's worker cannot list the plugin's presets (mod-host): the daemon answers preset_list and preset_get with this code; preset_load still takes a preset the controller knows"}, + {"name": "PIN_REFUSED", "macro": "OMX_REPLY_PLUGIN_HOSTD_PIN_REFUSED_RESP", "code": -516, "meaning": "the plugin's pin carries verdict=refused: its files are the ones that failed qualification, so add is refused and no worker sees it, and a replayed add is refused the same way; files that differ from the pin answer (-509) first. A pins_dir pin of that verdict is never overridden: pin_set and pin_accept of its plugin answer this code"}, + {"name": "NOTE_QUEUE_FULL", "macro": "OMX_REPLY_HOST_NOTE_QUEUE_FULL_RESP", "code": -517, "meaning": "the instance's worker has no room for this note_on, note_off or all_notes_off before its next block: the line was not taken and nothing of it is kept; the controller may send it again"}, + {"name": "CHAIN_UNKNOWN_INSTANCE", "macro": "OMX_REPLY_PLUGIN_HOSTD_CHAIN_UNKNOWN_INSTANCE_RESP", "code": -518, "meaning": "a member of chain is an instance no add made: the chain is not declared"}, + {"name": "CHAIN_DUPLICATE", "macro": "OMX_REPLY_PLUGIN_HOSTD_CHAIN_DUPLICATE_RESP", "code": -519, "meaning": "an instance is named twice in one chain: the chain is not declared"}, + {"name": "CHAIN_INSTANCE_BUSY", "macro": "OMX_REPLY_PLUGIN_HOSTD_CHAIN_INSTANCE_BUSY_RESP", "code": -520, "meaning": "a member of chain is already in another chain: the chain is not declared; chain_clear of the other chain frees it"}, + {"name": "CHAIN_MIXED_FORMAT", "macro": "OMX_REPLY_PLUGIN_HOSTD_CHAIN_MIXED_FORMAT_RESP", "code": -521, "meaning": "the members of chain are not all run by one worker program, or are of two rows of one program and a row does not run chains in one client, so no one worker runs them: the chain is not declared"}, + {"name": "NO_SUCH_CHAIN", "macro": "OMX_REPLY_PLUGIN_HOSTD_NO_SUCH_CHAIN_RESP", "code": -522, "meaning": "chain_clear or chain_get of a chain no chain declared"}, + {"name": "PRESET_NOT_OFFERED", "macro": "OMX_REPLY_PLUGIN_HOSTD_PRESET_NOT_OFFERED_RESP", "code": -523, "meaning": "the worker: preset_load or preset_show of a stable name the plugin does not offer, or of a plugin with no preset system and no state"}, + {"name": "PRESET_INVALID", "macro": "OMX_REPLY_PLUGIN_HOSTD_PRESET_INVALID_RESP", "code": -524, "meaning": "preset_save with a file path that is not absolute or with no name, or preset_load or preset_show of a file that cannot be read, is no JSON, is of a format version other than org.openmixer.preset/1 and org.openmixer.preset/2, or breaks the format (docs/presets.md): the daemon answers it and no worker sees the file"}, + {"name": "PRESET_NEEDS_STATE", "macro": "OMX_REPLY_PLUGIN_HOSTD_PRESET_NEEDS_STATE_RESP", "code": -525, "meaning": "the worker: a preset file that carries state for a worker that cannot take state yet"}, + {"name": "PRESET_PLUGIN_CHANGED", "macro": "OMX_REPLY_PLUGIN_HOSTD_PRESET_PLUGIN_CHANGED_RESP", "code": -526, "meaning": "the worker: the preset file's plugin id, version or fingerprint is not the instance's; nothing of it is applied"}, + {"name": "LOAD_REFUSED", "macro": "OMX_REPLY_PLUGIN_HOSTD_LOAD_REFUSED_RESP", "code": -527, "meaning": "the worker: the plugin refused the preset or the state its file carries"}, + {"name": "DIR_NOT_WRITABLE", "macro": "OMX_REPLY_PLUGIN_HOSTD_DIR_NOT_WRITABLE_RESP", "code": -528, "meaning": "descriptor_dir or qualification_dir cannot be made or written: the daemon does not start, and says which key and which path on stderr with this code; a directory that turns read-only later makes the scan of an add write nothing, and descriptor_get and panel_get of that plugin answer this code"}, + {"name": "DESCRIPTOR_ABSENT", "macro": "OMX_REPLY_PLUGIN_HOSTD_DESCRIPTOR_ABSENT_RESP", "code": -529, "meaning": "descriptor_get (panel_get) of a plugin that has no descriptor (panel) in descriptor_dir for its binary as it is now, and none being written: no add since it changed, or a binary that cannot be found"}, + {"name": "DESCRIPTOR_PENDING", "macro": "OMX_REPLY_PLUGIN_HOSTD_DESCRIPTOR_PENDING_RESP", "code": -530, "meaning": "descriptor_get (panel_get) of a plugin whose scan, started by its add, has not written its descriptor (panel) yet: ask again"}, + {"name": "DESCRIPTOR_SCAN_FAILED", "macro": "OMX_REPLY_PLUGIN_HOSTD_DESCRIPTOR_SCAN_FAILED_RESP", "code": -531, "meaning": "descriptor_get (panel_get) of a plugin whose last scan wrote no descriptor (panel): the scanner refused the plugin, made no dump or no panel, or is not installed; the add it ran for stands, and stderr and the scan's log say why. The next add scans again"}, + {"name": "NO_SUCH_PLAN", "macro": "OMX_REPLY_PLUGIN_HOSTD_NO_SUCH_PLAN_RESP", "code": -532, "meaning": "plan_get or plan_clear of a chain no plan planned"} ], "verbs": [ {"name": "add", "arguments": " [own | pool: | default] [client_name]", "reply": "resp ", "meaning": "mod-host's add with a placement; a token after the instance that is not a placement is the jack client name"}, @@ -213,7 +213,7 @@ "pin_limits": [ {"name": "PATH", "meaning": "a path holding ',', '=' or whitespace cannot be pinned: they are the separators of pin_set's words, and pin_set refuses it as a token outside its grammar"}, {"name": "LINE", "meaning": "a pin_set line is at most line_max, 4096 bytes, the protocol socket's buffer; a longer one is refused as outside the grammar"}, - {"name": "MANIFEST", "meaning": "a manifest that uses @base, or names a file of the plugin by a percent-encoded IRI, makes add answer PHD_ERR_PIN_BINARY_MISMATCH (-509): the daemon does not resolve either, so it cannot know the file the host would load"} + {"name": "MANIFEST", "meaning": "a manifest that uses @base, or names a file of the plugin by a percent-encoded IRI, makes add answer OMX_REPLY_PLUGIN_HOSTD_PIN_BINARY_MISMATCH_RESP (-509): the daemon does not resolve either, so it cannot know the file the host would load"} ], "relay": { "worker_arguments": "-n -p -f ", diff --git a/src/descriptors.c b/src/descriptors.c index dff79d4..d6dd22c 100644 --- a/src/descriptors.c +++ b/src/descriptors.c @@ -128,8 +128,8 @@ static int dir_ready(const char *key, char *dir, size_t size, const char *subdir state_default(dir, size, subdir); if (make_dirs(dir) != 0 || writable(dir) != 0) { - fprintf(stderr, "plugin-hostd: %s %s: %s: resp %d\n", key, dir, strerror(errno), PHD_ERR_DIR_NOT_WRITABLE); - return PHD_ERR_DIR_NOT_WRITABLE; + fprintf(stderr, "plugin-hostd: %s %s: %s: resp %d\n", key, dir, strerror(errno), OMX_REPLY_PLUGIN_HOSTD_DIR_NOT_WRITABLE_RESP); + return OMX_REPLY_PLUGIN_HOSTD_DIR_NOT_WRITABLE_RESP; } return SUCCESS; } @@ -138,10 +138,10 @@ int descriptors_init(conf_t *conf) { g_conf = conf; if (dir_ready("descriptor_dir", conf->descriptor_dir, sizeof(conf->descriptor_dir), PHD_DIR_DESCRIPTORS_SUBDIR)) - return PHD_ERR_DIR_NOT_WRITABLE; + return OMX_REPLY_PLUGIN_HOSTD_DIR_NOT_WRITABLE_RESP; if (dir_ready("qualification_dir", conf->qualification_dir, sizeof(conf->qualification_dir), PHD_DIR_QUALIFICATION_SUBDIR)) - return PHD_ERR_DIR_NOT_WRITABLE; + return OMX_REPLY_PLUGIN_HOSTD_DIR_NOT_WRITABLE_RESP; return SUCCESS; } @@ -266,8 +266,8 @@ static void scan_start(scan_t *s, int panel) s->panel = panel; if (!panel) - s->code = PHD_ERR_DESCRIPTOR_PENDING; - s->panel_code = PHD_ERR_DESCRIPTOR_PENDING; + s->code = OMX_REPLY_PLUGIN_HOSTD_DESCRIPTOR_PENDING_RESP; + s->panel_code = OMX_REPLY_PLUGIN_HOSTD_DESCRIPTOR_PENDING_RESP; s->tmp[0] = '\0'; if (panel) snprintf(dir, sizeof(dir), "%s/" PHD_PANEL_SUBDIR, g_conf->descriptor_dir); @@ -276,7 +276,7 @@ static void scan_start(scan_t *s, int panel) snprintf(s->log, sizeof(s->log), "%s/scan-%s-%s%s.log", sup_root(), s->format, s->hash, panel ? "-panel" : ""); if (!proc_have_binary(g_conf->probe)) { - scan_failed(s, PHD_ERR_DESCRIPTOR_SCAN_FAILED, "the probe is not installed"); + scan_failed(s, OMX_REPLY_PLUGIN_HOSTD_DESCRIPTOR_SCAN_FAILED_RESP, "the probe is not installed"); return; } snprintf(s->tmp, sizeof(s->tmp), "%s/.%s.%d.%u.tmp", dir, s->hash, (int)getpid(), g_seq++); @@ -286,7 +286,7 @@ static void scan_start(scan_t *s, int panel) snprintf(why, sizeof(why), "descriptor_dir %s: %s", dir, strerror(errno)); s->tmp[0] = '\0'; - scan_failed(s, PHD_ERR_DIR_NOT_WRITABLE, why); + scan_failed(s, OMX_REPLY_PLUGIN_HOSTD_DIR_NOT_WRITABLE_RESP, why); return; } log = open(s->log, O_WRONLY | O_CREAT | O_TRUNC | O_CLOEXEC, 0644); @@ -311,7 +311,7 @@ static void scan_start(scan_t *s, int panel) close(null); if (pid < 0) { - scan_failed(s, PHD_ERR_DESCRIPTOR_SCAN_FAILED, strerror(errno)); + scan_failed(s, OMX_REPLY_PLUGIN_HOSTD_DESCRIPTOR_SCAN_FAILED_RESP, strerror(errno)); return; } s->pid = pid; @@ -399,7 +399,7 @@ static int scan_file(scan_t *s, const char *final) else if (rename(s->tmp, final) != 0) { snprintf(why, sizeof(why), "%s", strerror(errno)); - scan_failed(s, PHD_ERR_DIR_NOT_WRITABLE, why); + scan_failed(s, OMX_REPLY_PLUGIN_HOSTD_DIR_NOT_WRITABLE_RESP, why); return -1; } else @@ -434,12 +434,12 @@ static void scan_ended(scan_t *s, int status) snprintf(why, sizeof(why), "killed by signal %d", WTERMSIG(status)); else snprintf(why, sizeof(why), "the probe exited %d", WEXITSTATUS(status)); - scan_failed(s, PHD_ERR_DESCRIPTOR_SCAN_FAILED, why); + scan_failed(s, OMX_REPLY_PLUGIN_HOSTD_DESCRIPTOR_SCAN_FAILED_RESP, why); return; } if ((doc = scan_output(s)) == NULL) { - scan_failed(s, PHD_ERR_DESCRIPTOR_SCAN_FAILED, s->panel ? "its output is no panel" : "its output is no descriptor"); + scan_failed(s, OMX_REPLY_PLUGIN_HOSTD_DESCRIPTOR_SCAN_FAILED_RESP, s->panel ? "its output is no panel" : "its output is no descriptor"); return; } if (s->panel) @@ -496,7 +496,7 @@ static char *resp_path(const char *path) /* what a scan ended with, for a file that is not there: a scan that wrote one that is gone since wrote none */ static char *resp_missing(const scan_t *s, int code) { - return sup_resp(s && code != SUCCESS ? code : PHD_ERR_DESCRIPTOR_ABSENT); + return sup_resp(s && code != SUCCESS ? code : OMX_REPLY_PLUGIN_HOSTD_DESCRIPTOR_ABSENT_RESP); } char *descriptors_get(const char *uri) @@ -506,7 +506,7 @@ char *descriptors_get(const char *uri) scan_t *s; if (!g_conf || identify(uri, target, sizeof(target), &format, &id, hash) != 0) - return sup_resp(PHD_ERR_DESCRIPTOR_ABSENT); + return sup_resp(OMX_REPLY_PLUGIN_HOSTD_DESCRIPTOR_ABSENT_RESP); if (lookup(id, hash, path, sizeof(path)) != 0) { s = scan_of(format, id, hash); @@ -523,7 +523,7 @@ char *descriptors_panel_get(const char *uri) scan_t *s; if (!g_conf || identify(uri, target, sizeof(target), &format, &id, hash) != 0) - return sup_resp(PHD_ERR_DESCRIPTOR_ABSENT); + return sup_resp(OMX_REPLY_PLUGIN_HOSTD_DESCRIPTOR_ABSENT_RESP); s = scan_of(format, id, hash); if (lookup(id, hash, path, sizeof(path)) != 0) return resp_missing(s, s ? s->code : SUCCESS); diff --git a/src/descriptors.h b/src/descriptors.h index 6dcf4d4..16ef736 100644 --- a/src/descriptors.h +++ b/src/descriptors.h @@ -15,7 +15,7 @@ #include "conf.h" /* descriptor_dir and qualification_dir resolved (an empty setting is the default of protocol.h), made when missing - * and tried for a write; SUCCESS, or PHD_ERR_DIR_NOT_WRITABLE with the key, the path and why on stderr. The resolved + * and tried for a write; SUCCESS, or OMX_REPLY_PLUGIN_HOSTD_DIR_NOT_WRITABLE_RESP with the key, the path and why on stderr. The resolved * paths are written back into conf, which is kept for the scans. */ int descriptors_init(conf_t *conf); diff --git a/src/formats.h b/src/formats.h index 9ea22f5..120d214 100644 --- a/src/formats.h +++ b/src/formats.h @@ -39,7 +39,7 @@ typedef struct FORMAT_T { const char *worker_prefix; /* put before the uri the worker is given, NULL for nothing */ /* the row a uri of this format is run by, as a name of the table, or NULL for this one; malloc'd nothing */ const char *(*route)(const conf_t *conf, const char *uri); - /* the worker runs the plugin through an adapter that may refuse it: its instantiation error is PHD_ERR_LV2_ADAPTER_REFUSED */ + /* the worker runs the plugin through an adapter that may refuse it: its instantiation error is OMX_REPLY_PLUGIN_HOSTD_LV2_ADAPTER_REFUSED_RESP */ int adapter; const char *(*worker)(const conf_t *conf); /* the program that serves it */ @@ -50,7 +50,7 @@ typedef struct FORMAT_T { char *(*narrow_world)(const conf_t *conf, const char *dir, const char *const *uris, int n); /* the root and the relative files a host loads for the uri: what a pin holds. SUCCESS, or - * PHD_ERR_PIN_BINARY_MISMATCH with the reason on stderr for what cannot be pinned */ + * OMX_REPLY_PLUGIN_HOSTD_PIN_BINARY_MISMATCH_RESP with the reason on stderr for what cannot be pinned */ int (*pin_collect)(const char *uri, const char *search, char *root, size_t size, names_t *files); /* the one file the host loads the plugin's code from, as a path: what the name of its scanned descriptor hashes. 0, * or -1 when it cannot be told; NULL for a format whose plugins get no descriptor */ diff --git a/src/lv2.c b/src/lv2.c index afa9c37..43ce793 100644 --- a/src/lv2.c +++ b/src/lv2.c @@ -430,7 +430,7 @@ char *lv2_param_info(int id, const char *symbol) reply = sup_call(id, line); code = sup_reply_code(reply); free(reply); - return sup_resp(code == ERR_HOST_INVALID_PARAM_SYMBOL ? ERR_HOST_INVALID_PARAM_SYMBOL : PHD_ERR_NO_PARAM_CONTRACT); + return sup_resp(code == ERR_HOST_INVALID_PARAM_SYMBOL ? ERR_HOST_INVALID_PARAM_SYMBOL : OMX_REPLY_HOST_NO_PARAM_CONTRACT_RESP); } /* ---------------------------------------------------------------- which worker runs a plugin */ diff --git a/src/pins.c b/src/pins.c index 1b3cba7..e2e6a7e 100644 --- a/src/pins.c +++ b/src/pins.c @@ -565,7 +565,7 @@ int pins_set(const char *uri, const char *files, const char *layout, const char fprintf(stderr, "plugin-hostd: %s: its pins.d pin carries " PHD_PIN_VERDICT_KEY PHD_PIN_VERDICT_REFUSED ", which pin_set does not override\n", pin.uri); pin_free(&pin); - return PHD_ERR_PIN_REFUSED; + return OMX_REPLY_PLUGIN_HOSTD_PIN_REFUSED_RESP; } pin_put(&pin); return SUCCESS; @@ -646,7 +646,7 @@ void pins_finish(void) int pin_refuse(const char *uri, const char *path, const char *why) { fprintf(stderr, "plugin-hostd: %s: %s %s\n", uri, path, why); - return PHD_ERR_PIN_BINARY_MISMATCH; + return OMX_REPLY_PLUGIN_HOSTD_PIN_BINARY_MISMATCH_RESP; } /* the file of a pin hashed over one open descriptor */ @@ -701,7 +701,7 @@ static int record(const format_t *format, const char *uri, const char *search) { fprintf(stderr, "plugin-hostd: %s: %s; not learned\n", uri, g_store_unreadable ? "the pin store could not be read" : "its line in the pin store is corrupt"); - rc = PHD_ERR_PIN_BINARY_MISMATCH; + rc = OMX_REPLY_PLUGIN_HOSTD_PIN_BINARY_MISMATCH_RESP; } if (rc != SUCCESS) { @@ -745,12 +745,12 @@ int pins_learn(const format_t *format, const char *uri, const char *search) int pins_accept(const format_t *format, const char *uri, const char *search) { if (!find(bare(uri))) - return PHD_ERR_PIN_ABSENT; + return OMX_REPLY_HOST_PIN_ABSENT_RESP; if (pkg_refusal(bare(uri))) { fprintf(stderr, "plugin-hostd: %s: its pins.d pin carries " PHD_PIN_VERDICT_KEY PHD_PIN_VERDICT_REFUSED ", which pin_accept does not override\n", uri); - return PHD_ERR_PIN_REFUSED; + return OMX_REPLY_PLUGIN_HOSTD_PIN_REFUSED_RESP; } return record(format, uri, search); } @@ -781,7 +781,7 @@ int pins_check(const format_t *format, const char *uri, const char *search, cons { fprintf(stderr, "plugin-hostd: %s: %s\n", uri, p ? "its layout pin is in a scheme this version does not know" : "no pin"); - return PHD_ERR_PIN_ABSENT; + return OMX_REPLY_HOST_PIN_ABSENT_RESP; } /* what the format says the host loads for the plugin, each held by the pin, then every file the pin holds hashed */ rc = format->pin_collect(uri, search, root, sizeof(root), &files); @@ -795,7 +795,7 @@ int pins_check(const format_t *format, const char *uri, const char *search, cons if (rc == SUCCESS && !strcmp(p->verdict, PHD_PIN_VERDICT_REFUSED)) { fprintf(stderr, "plugin-hostd: %s: its pin carries " PHD_PIN_VERDICT_KEY PHD_PIN_VERDICT_REFUSED "\n", uri); - rc = PHD_ERR_PIN_REFUSED; + rc = OMX_REPLY_PLUGIN_HOSTD_PIN_REFUSED_RESP; } if (rc == SUCCESS) *layout = strcmp(p->layout, PHD_PIN_LAYOUT_UNKNOWN) ? p->layout : NULL; diff --git a/src/pins.h b/src/pins.h index 3bc3de2..16c5148 100644 --- a/src/pins.h +++ b/src/pins.h @@ -39,7 +39,7 @@ * no pins */ int pins_init(const char *store, const char *file, const char *dir); -/* pin_set: SUCCESS, or ERR_INVALID_OPERATION for a word outside the grammar, or PHD_ERR_PIN_REFUSED when the package pin +/* pin_set: SUCCESS, or ERR_INVALID_OPERATION for a word outside the grammar, or OMX_REPLY_PLUGIN_HOSTD_PIN_REFUSED_RESP when the package pin * of the uri carries verdict=refused; it replaces an earlier pin of the uri. `verdict` is NULL, or one of * PHD_PIN_VERDICTS */ int pins_set(const char *uri, const char *files, const char *layout, const char *verdict); @@ -58,12 +58,12 @@ int pins_in_process(const char *uri); const char *pins_verdict(const char *uri); /* first use: the files the format loads for the uri, hashed, recorded with an unknown layout and written to the store. - * SUCCESS, or PHD_ERR_PIN_BINARY_MISMATCH when they cannot be collected (nothing is recorded) */ + * SUCCESS, or OMX_REPLY_PLUGIN_HOSTD_PIN_BINARY_MISMATCH_RESP when they cannot be collected (nothing is recorded) */ int pins_learn(const format_t *format, const char *uri, const char *search); /* pin_accept: the same collection for a uri that has a pin, which it replaces; the layout is unknown again and the - * verdict gone; over a package pin it is the host's that then holds. PHD_ERR_PIN_ABSENT when there is no pin to replace, - * PHD_ERR_PIN_REFUSED when the package pin carries verdict=refused */ + * verdict gone; over a package pin it is the host's that then holds. OMX_REPLY_HOST_PIN_ABSENT_RESP when there is no pin to replace, + * OMX_REPLY_PLUGIN_HOSTD_PIN_REFUSED_RESP when the package pin carries verdict=refused */ int pins_accept(const format_t *format, const char *uri, const char *search); /* the layout a worker found after init, for a pin that has none; false for a layout that is not omx-layout/1 */ @@ -73,11 +73,11 @@ int pins_set_layout(const char *uri, const char *layout); * loads for it (format->pin_collect, searched in `search`) all held by the pin, then every file the pin names hashed * over one open descriptor. SUCCESS, with *layout the * layout pin ":" (the table's, valid until the next pin verb) or NULL while the pin's layout is - * unknown, or PHD_ERR_PIN_ABSENT or PHD_ERR_PIN_BINARY_MISMATCH, or PHD_ERR_PIN_REFUSED for the pinned files under a + * unknown, or OMX_REPLY_HOST_PIN_ABSENT_RESP or OMX_REPLY_PLUGIN_HOSTD_PIN_BINARY_MISMATCH_RESP, or OMX_REPLY_PLUGIN_HOSTD_PIN_REFUSED_RESP for the pinned files under a * verdict of refused. */ int pins_check(const format_t *format, const char *uri, const char *search, const char **layout); -/* a refusal of a pin, with the reason on stderr: PHD_ERR_PIN_BINARY_MISMATCH */ +/* a refusal of a pin, with the reason on stderr: OMX_REPLY_PLUGIN_HOSTD_PIN_BINARY_MISMATCH_RESP */ int pin_refuse(const char *uri, const char *path, const char *why); void pins_finish(void); diff --git a/src/supervisor.c b/src/supervisor.c index 73f842a..ab3e897 100644 --- a/src/supervisor.c +++ b/src/supervisor.c @@ -596,7 +596,7 @@ static int worker_start(worker_t *w, const char *uri) int rc, attempt; if (!proc_have_binary(bin_of(w->fmt))) - return PHD_ERR_NO_BACKEND; + return OMX_REPLY_PLUGIN_HOSTD_NO_BACKEND_RESP; snprintf(logfile, sizeof(logfile), "%s/w%d.log", g_root, w->k); world = narrow_world(w, uri); w->state = W_STARTING; @@ -608,7 +608,7 @@ static int worker_start(worker_t *w, const char *uri) { free(world); w->pid = 0; - return PHD_ERR_WORKER_SPAWN; + return OMX_REPLY_PLUGIN_HOSTD_WORKER_SPAWN_RESP; } w->fd = proc_connect(&g_conf, w->pid, w->port, w->fb_port, logfile, &w->fb_fd); /* a worker that was gone before it listened lost the race for its ports: ask for fresh ones, a bounded few times */ @@ -621,7 +621,7 @@ static int worker_start(worker_t *w, const char *uri) { proc_stop(w->pid); w->pid = 0; - return PHD_ERR_WORKER_SPAWN; + return OMX_REPLY_PLUGIN_HOSTD_WORKER_SPAWN_RESP; } if (host_settings_replay(w) != 0) { @@ -629,7 +629,7 @@ static int worker_start(worker_t *w, const char *uri) close(w->fb_fd); proc_stop(w->pid); w->pid = 0; - return PHD_ERR_WORKER_SPAWN; + return OMX_REPLY_PLUGIN_HOSTD_WORKER_SPAWN_RESP; } proc_env_report(w->pid, &g_env[w->fmt]); /* what the worker reports goes to the controller from now on, the lines of its replay among them; with no memory @@ -641,7 +641,7 @@ static int worker_start(worker_t *w, const char *uri) w->fd = -1; proc_stop(w->pid); w->pid = 0; - return PHD_ERR_WORKER_SPAWN; + return OMX_REPLY_PLUGIN_HOSTD_WORKER_SPAWN_RESP; } w->state = W_UP; return SUCCESS; @@ -1054,7 +1054,7 @@ static const char *pin_expect_line(int id, const char *layout) { static char line[PHD_SHA256_HEX_LEN + 128]; - snprintf(line, sizeof(line), PHD_VERB_PIN_EXPECT " %d %s", id, layout); + snprintf(line, sizeof(line), OMX_VERB_PIN_EXPECT " %d %s", id, layout); return line; } @@ -1116,17 +1116,17 @@ static void pend_retry(worker_t *w, int64_t now) /* the event of a refusal that says the plugin is not the one that was pinned */ static void pin_changed_event(const char *uri, int code) { - if (code == PHD_ERR_PIN_BINARY_MISMATCH) + if (code == OMX_REPLY_PLUGIN_HOSTD_PIN_BINARY_MISMATCH_RESP) event(PHD_EVENT_PIN_CHANGED_FMT, uri, PHD_PIN_CHANGED_FILES); - else if (code == PHD_ERR_PIN_LAYOUT_MISMATCH) + else if (code == OMX_REPLY_HOST_PIN_LAYOUT_MISMATCH_RESP) event(PHD_EVENT_PIN_CHANGED_FMT, uri, PHD_PIN_CHANGED_LAYOUT); } /* a replayed add refused, by its pin or by the worker: announced with the refusal's own code, written with - * PHD_ERR_REPLAY and the step that refused it, and the worker does not hold the instance until it is replayed again */ + * OMX_REPLY_PLUGIN_HOSTD_REPLAY_RESP and the step that refused it, and the worker does not hold the instance until it is replayed again */ static void replay_refused(worker_t *w, instance_t *i, const char *step, int code) { - fprintf(stderr, "plugin-hostd: w%d did not replay instance %d: resp %d, its %s resp %d\n", w->k, i->id, PHD_ERR_REPLAY, + fprintf(stderr, "plugin-hostd: w%d did not replay instance %d: resp %d, its %s resp %d\n", w->k, i->id, OMX_REPLY_PLUGIN_HOSTD_REPLAY_RESP, step, code); event(PHD_EVENT_REPLAY_REFUSED_FMT, i->id, code); pin_changed_event(i->uri, code); @@ -1156,7 +1156,7 @@ static int replay_pin(worker_t *w, instance_t *i) return rc; if (code < 0) { - replay_refused(w, i, PHD_VERB_PIN_EXPECT, code); + replay_refused(w, i, OMX_VERB_PIN_EXPECT, code); return PIN_REFUSED; } } @@ -1471,12 +1471,12 @@ static worker_t *pool_worker(int fmt, const char *name, int *full, int *unavaila continue; if (w->state == W_GIVEN_UP) { - *unavailable = PHD_ERR_GAVE_UP; + *unavailable = OMX_REPLY_PLUGIN_HOSTD_GAVE_UP_RESP; continue; } if (w->state != W_UP) { - *unavailable = PHD_ERR_WORKER_SPAWN; + *unavailable = OMX_REPLY_PLUGIN_HOSTD_WORKER_SPAWN_RESP; continue; } if (w->ninst < max) @@ -1524,14 +1524,14 @@ static void learn_layout(worker_t *w, int id, const char *uri) static char *add(const char *uri, int id, const char *placement, const char *client, int row); /* the adapter of a worker refused the add of `uri`, for the reason `why`: say so on the feedback port; under auto the plugin - * goes to the lv2 row from now on and this add is made again there, otherwise the add answers PHD_ERR_LV2_ADAPTER_REFUSED */ + * goes to the lv2 row from now on and this add is made again there, otherwise the add answers OMX_REPLY_PLUGIN_HOSTD_LV2_ADAPTER_REFUSED_RESP */ static char *adapter_refused(const char *uri, const char *why, int id, const char *placement, const char *client) { int automatic = lv2_worker_is_auto(&g_conf, uri); event(PHD_EVENT_LV2_ADAPTER_REFUSED_FMT, uri, why, automatic ? PHD_LV2_WORKER_AUTO : PHD_LV2_WORKER_CLAP_HOST); if (!automatic) - return sup_resp(PHD_ERR_LV2_ADAPTER_REFUSED); + return sup_resp(OMX_REPLY_PLUGIN_HOSTD_LV2_ADAPTER_REFUSED_RESP); lv2_adapter_refused(uri); return sup_add(uri, id, placement, client); } @@ -1566,7 +1566,7 @@ static char *add(const char *uri, int id, const char *placement, const char *cli if (g_inst[id]) return sup_resp(ERR_INSTANCE_ALREADY_EXISTS); if (placement && strcmp(placement, PHD_PLACE_DEFAULT) && !valid_place(placement)) - return sup_resp(PHD_ERR_PLACEMENT_INVALID); + return sup_resp(OMX_REPLY_PLUGIN_HOSTD_PLACEMENT_INVALID_RESP); if (!placement || !strcmp(placement, PHD_PLACE_DEFAULT)) snprintf(place, sizeof(place), "%s", g_policy[fmt]); else @@ -1579,16 +1579,16 @@ static char *add(const char *uri, int id, const char *placement, const char *cli if (m->quarantined) snprintf(place, sizeof(place), PHD_PLACE_OWN); if (!proc_have_binary(bin_of(fmt))) - return sup_resp(PHD_ERR_NO_BACKEND); + return sup_resp(OMX_REPLY_PLUGIN_HOSTD_NO_BACKEND_RESP); if (recent(m->deaths, &m->ndeaths, now) >= g_conf.storm_deaths) - return sup_resp(PHD_ERR_GAVE_UP); + return sup_resp(OMX_REPLY_PLUGIN_HOSTD_GAVE_UP_RESP); if (g_conf.require_pins) { int first_use = conf_pins_first_use(&g_conf); rc = pins_check(format, fwd, search_of(fmt), &layout); /* a plugin that has no pin gets one, from the files as they are now; it is not asked about again */ - if (rc == PHD_ERR_PIN_ABSENT && first_use && !pins_known(fwd)) + if (rc == OMX_REPLY_HOST_PIN_ABSENT_RESP && first_use && !pins_known(fwd)) { rc = pins_learn(format, fwd, search_of(fmt)); if (rc == SUCCESS) @@ -1601,14 +1601,14 @@ static char *add(const char *uri, int id, const char *placement, const char *cli if (format->pinned_own_only) { if (placement && !strncmp(placement, PHD_PLACE_POOL_PREFIX, strlen(PHD_PLACE_POOL_PREFIX))) - return sup_resp(PHD_ERR_PLACEMENT_INVALID); + return sup_resp(OMX_REPLY_PLUGIN_HOSTD_PLACEMENT_INVALID_RESP); snprintf(place, sizeof(place), PHD_PLACE_OWN); } /* first-use: only a plugin qualified for a shared worker is placed in one */ else if (first_use && !pins_in_process(fwd)) { if (placement && !strncmp(placement, PHD_PLACE_POOL_PREFIX, strlen(PHD_PLACE_POOL_PREFIX))) - return sup_resp(PHD_ERR_PLACEMENT_INVALID); + return sup_resp(OMX_REPLY_PLUGIN_HOSTD_PLACEMENT_INVALID_RESP); snprintf(place, sizeof(place), PHD_PLACE_OWN); } } @@ -1659,7 +1659,7 @@ static char *add(const char *uri, int id, const char *placement, const char *cli { /* the worker went with pin_expect on the wire: the add is never forwarded */ event(PHD_EVENT_VERB_DROPPED_FMT, id, pin_expect_line(id, layout)); - code = PHD_ERR_VERB_DROPPED; + code = OMX_REPLY_PLUGIN_HOSTD_VERB_DROPPED_RESP; } } snprintf(line, sizeof(line), "%.*s %s%s %d%s%s", verb_len(EFFECT_ADD), EFFECT_ADD, @@ -1670,7 +1670,7 @@ static char *add(const char *uri, int id, const char *placement, const char *cli { /* the worker went with `add` or its pin_expect on the wire: the instance is the suspect, and the event names * the plugin it died adding (the pin_expect's own was sent above) */ - if (code != PHD_ERR_VERB_DROPPED) + if (code != OMX_REPLY_PLUGIN_HOSTD_VERB_DROPPED_RESP) event(PHD_EVENT_VERB_DROPPED_FMT, id, line); m->crashes++; note_death(m->deaths, &m->ndeaths, now); @@ -1788,7 +1788,7 @@ static void chain_tell(worker_t *w) static char *refuse_worker(worker_t *w) { - return sup_resp(w->state == W_GIVEN_UP ? PHD_ERR_GAVE_UP : PHD_ERR_WORKER_SPAWN); + return sup_resp(w->state == W_GIVEN_UP ? OMX_REPLY_PLUGIN_HOSTD_GAVE_UP_RESP : OMX_REPLY_PLUGIN_HOSTD_WORKER_SPAWN_RESP); } static int64_t g_sus_seq; @@ -1845,7 +1845,7 @@ static void ledger_verb(instance_t *i, const char *line) static char *verb_dropped(instance_t *i, const char *line) { event(PHD_EVENT_VERB_DROPPED_FMT, i->id, line); - return sup_resp(PHD_ERR_VERB_DROPPED); + return sup_resp(OMX_REPLY_PLUGIN_HOSTD_VERB_DROPPED_RESP); } char *sup_call(int id, const char *line) @@ -1864,7 +1864,7 @@ char *sup_call(int id, const char *line) if (rc == RPC_WAS_DEAD) { on_death(w, -1); - return sup_resp(PHD_ERR_WORKER_SPAWN); + return sup_resp(OMX_REPLY_PLUGIN_HOSTD_WORKER_SPAWN_RESP); } if (rc == RPC_DIED) { @@ -1951,7 +1951,7 @@ char *sup_connect(const char *verb, const char *line, const char *port_a, const if (rc != RPC_OK) { on_death(w, -1); - return sup_resp(PHD_ERR_WORKER_SPAWN); + return sup_resp(OMX_REPLY_PLUGIN_HOSTD_WORKER_SPAWN_RESP); } if (resp_code(reply) >= 0) { @@ -2035,7 +2035,7 @@ char *sup_instance_verb(const char *line, int ledger) reply = sup_resp(ERR_INVALID_OPERATION); else if (!(i = (id >= 0 && id < MAX_INSTANCE) ? g_inst[id] : NULL)) reply = sup_resp(ERR_INSTANCE_NON_EXISTS); - else if (!strcmp(word[0], PHD_VERB_TRACK_INFO) && !phd_track_info_valid(word, count)) + else if (!strcmp(word[0], OMX_VERB_TRACK_INFO) && !phd_track_info_valid(word, count)) reply = sup_resp(ERR_INVALID_OPERATION); else if (phd_is_note_verb(word[0]) && !phd_note_valid(word, count)) reply = sup_resp(ERR_INVALID_OPERATION); @@ -2049,20 +2049,20 @@ char *sup_instance_verb(const char *line, int ledger) } } /* a format whose worker has none of these: the daemon answers, and nothing goes to the worker */ - else if (!strcmp(word[0], PHD_VERB_TRACK_INFO)) + else if (!strcmp(word[0], OMX_VERB_TRACK_INFO)) { free(i->track_info); i->track_info = strdup(line); reply = sup_resp(SUCCESS); } - else if (!strcmp(word[0], PHD_VERB_REMOTE_PAGES)) + else if (!strcmp(word[0], OMX_VERB_REMOTE_PAGES)) reply = sup_resp(count == 2 ? 0 : ERR_INVALID_OPERATION); - else if (!strcmp(word[0], PHD_VERB_PARAM_INFO)) + else if (!strcmp(word[0], OMX_VERB_PARAM_INFO)) reply = count == 3 ? format_at(i->fmt)->param_info(id, word[2]) : sup_resp(ERR_INVALID_OPERATION); else if (phd_is_note_verb(word[0])) - reply = sup_resp(PHD_ERR_NOTES_BY_JACK); + reply = sup_resp(OMX_REPLY_HOST_NOTES_BY_JACK_RESP); else if (!strcmp(word[0], OMX_VERB_PRESET_LIST) || !strcmp(word[0], OMX_VERB_PRESET_GET)) - reply = sup_resp(PHD_ERR_NO_PRESET_LIST); + reply = sup_resp(OMX_REPLY_PLUGIN_HOSTD_NO_PRESET_LIST_RESP); else reply = sup_resp(ERR_INVALID_OPERATION); free(word); @@ -2192,7 +2192,7 @@ char *sup_reset(const char *which) for (id = 0; id < MAX_INSTANCE; id++) if (g_meta[id]) g_meta[id]->ndeaths = 0; - return sup_resp(all || found ? SUCCESS : PHD_ERR_NO_SUCH_WORKER); + return sup_resp(all || found ? SUCCESS : OMX_REPLY_PLUGIN_HOSTD_NO_SUCH_WORKER_RESP); } char *sup_quarantine_clear(const char *which) @@ -2252,7 +2252,7 @@ char *sup_policy_set(const char *format, const char *place) int f; if (!valid_place(place)) - return sup_resp(PHD_ERR_PLACEMENT_INVALID); + return sup_resp(OMX_REPLY_PLUGIN_HOSTD_PLACEMENT_INVALID_RESP); if (!strcmp(format, PHD_FORMAT_ANY)) { for (f = 0; f < formats_count(); f++) @@ -2282,7 +2282,7 @@ char *sup_pool_config(const char *name, int max) int n; if (!phd_pool_name_valid(name)) - return sup_resp(PHD_ERR_PLACEMENT_INVALID); + return sup_resp(OMX_REPLY_PLUGIN_HOSTD_PLACEMENT_INVALID_RESP); if (max < 1) return sup_resp(ERR_INVALID_OPERATION); for (n = 0; n < g_npools; n++) @@ -2528,19 +2528,19 @@ char *sup_chain(int id, const int *ids, int n) instance_t *i = (ids[k] >= 0 && ids[k] < MAX_INSTANCE) ? g_inst[ids[k]] : NULL; if (!i) - return sup_resp(PHD_ERR_CHAIN_UNKNOWN_INSTANCE); + return sup_resp(OMX_REPLY_PLUGIN_HOSTD_CHAIN_UNKNOWN_INSTANCE_RESP); for (m = 0; m < k; m++) if (ids[m] == ids[k]) - return sup_resp(PHD_ERR_CHAIN_DUPLICATE); + return sup_resp(OMX_REPLY_PLUGIN_HOSTD_CHAIN_DUPLICATE_RESP); if (i->chain && i->chain != c) - return sup_resp(PHD_ERR_CHAIN_INSTANCE_BUSY); + return sup_resp(OMX_REPLY_PLUGIN_HOSTD_CHAIN_INSTANCE_BUSY_RESP); if (!chain_rows_together(i->fmt, g_inst[ids[0]]->fmt)) - return sup_resp(PHD_ERR_CHAIN_MIXED_FORMAT); + return sup_resp(OMX_REPLY_PLUGIN_HOSTD_CHAIN_MIXED_FORMAT_RESP); if (must_run_own(i)) - return sup_resp(PHD_ERR_PLACEMENT_INVALID); + return sup_resp(OMX_REPLY_PLUGIN_HOSTD_PLACEMENT_INVALID_RESP); } if (!chain_world_found(ids, n)) - return sup_resp(PHD_ERR_PLACEMENT_INVALID); + return sup_resp(OMX_REPLY_PLUGIN_HOSTD_PLACEMENT_INVALID_RESP); if (!c) { c = calloc(1, sizeof(chain_t)); @@ -2580,7 +2580,7 @@ char *sup_chain_clear(int id) int k; if (!c) - return sup_resp(PHD_ERR_NO_SUCH_CHAIN); + return sup_resp(OMX_REPLY_PLUGIN_HOSTD_NO_SUCH_CHAIN_RESP); for (k = 0; k < c->n; k++) { instance_t *i = g_inst[c->ids[k]]; @@ -2604,7 +2604,7 @@ char *sup_chain_get(int id) int k, any = 0; if (!c) - return sup_resp(PHD_ERR_NO_SUCH_CHAIN); + return sup_resp(OMX_REPLY_PLUGIN_HOSTD_NO_SUCH_CHAIN_RESP); buf = malloc(cap); if (c->w) put(&buf, &used, &cap, "resp 0 w%d ", c->w->k); @@ -2696,11 +2696,11 @@ static int segment_refusal(const int *ids, int n) for (k = 0; k < n; k++) { if (!chain_rows_together(g_inst[ids[k]]->fmt, g_inst[ids[0]]->fmt)) - return PHD_ERR_CHAIN_MIXED_FORMAT; + return OMX_REPLY_PLUGIN_HOSTD_CHAIN_MIXED_FORMAT_RESP; if (must_run_own(g_inst[ids[k]])) - return PHD_ERR_PLACEMENT_INVALID; + return OMX_REPLY_PLUGIN_HOSTD_PLACEMENT_INVALID_RESP; } - return chain_world_found(ids, n) ? 0 : PHD_ERR_PLACEMENT_INVALID; + return chain_world_found(ids, n) ? 0 : OMX_REPLY_PLUGIN_HOSTD_PLACEMENT_INVALID_RESP; } static void plan_free(plan_t *p) @@ -2905,13 +2905,13 @@ char *sup_plan(int id, const int *ids, int n) instance_t *i = (ids[k] >= 0 && ids[k] < MAX_INSTANCE) ? g_inst[ids[k]] : NULL; if (!i) - return sup_resp(PHD_ERR_CHAIN_UNKNOWN_INSTANCE); + return sup_resp(OMX_REPLY_PLUGIN_HOSTD_CHAIN_UNKNOWN_INSTANCE_RESP); for (j = 0; j < k; j++) if (ids[j] == ids[k]) - return sup_resp(PHD_ERR_CHAIN_DUPLICATE); + return sup_resp(OMX_REPLY_PLUGIN_HOSTD_CHAIN_DUPLICATE_RESP); /* the member of a chain, or of the plan of another chain, is not this plan's to place */ if (i->chain && !(i->chain->planned && i->chain->id == id)) - return sup_resp(PHD_ERR_CHAIN_INSTANCE_BUSY); + return sup_resp(OMX_REPLY_PLUGIN_HOSTD_CHAIN_INSTANCE_BUSY_RESP); } p = plan_run(id, ids, n, &refused); if (refused) @@ -2976,7 +2976,7 @@ char *sup_plan_get(int id) char *buf; if (!p) - return sup_resp(PHD_ERR_NO_SUCH_PLAN); + return sup_resp(OMX_REPLY_PLUGIN_HOSTD_NO_SUCH_PLAN_RESP); buf = malloc(cap); put(&buf, &used, &cap, "resp 0 %s %s", p->segments, p->reasons); return buf; @@ -2988,7 +2988,7 @@ char *sup_plan_clear(int id) int j; if (!p) - return sup_resp(PHD_ERR_NO_SUCH_PLAN); + return sup_resp(OMX_REPLY_PLUGIN_HOSTD_NO_SUCH_PLAN_RESP); while (p->nseg) { chain_t *c = p->seg[p->nseg - 1]; diff --git a/tests/consumer.c b/tests/consumer.c index 7d1f47c..72fd679 100644 --- a/tests/consumer.c +++ b/tests/consumer.c @@ -23,13 +23,13 @@ int main(void) int errors = 0, verbs = 0, events = 0, ints = 0, strings = 0, instance_verbs = 0; char reply[32]; -#define X(id, meaning) errors++; check(PHD_ERR_##id < 0, #id " is a refusal"); +#define X(id, resp, meaning) errors++; check(resp < 0, #id " is a refusal"); PHD_ERRORS(X) #undef X /* each code is the supervisor's own, in its hundred, and no two rows share one: a reply names one refusal */ { static const int codes[] = { -#define X(id, meaning) PHD_ERR_##id, +#define X(id, resp, meaning) resp, PHD_ERRORS(X) #undef X }; @@ -103,7 +103,7 @@ int main(void) longest[PHD_STRING_MAX + 1] = '\0'; check(!phd_string_valid(longest), "a name one byte longer is refused"); } - snprintf(reply, sizeof(reply), "resp %d", PHD_ERR_GAVE_UP); + snprintf(reply, sizeof(reply), "resp %d", OMX_REPLY_PLUGIN_HOSTD_GAVE_UP_RESP); check(!strncmp(reply, "resp -5", 7), "a reply is resp "); if (failures) return 1; diff --git a/tests/daemon_test.py b/tests/daemon_test.py index 479336e..1c97a81 100644 --- a/tests/daemon_test.py +++ b/tests/daemon_test.py @@ -1578,7 +1578,7 @@ def a_binary_swapped_while_its_worker_was_down_is_not_replayed(): d.wait_event("instance_replay_refused 0 %d" % harness.CODE["PIN_BINARY_MISMATCH"], since=mark) log = d.log() check("resp %d, its pin resp %d" % (harness.CODE["REPLAY"], harness.CODE["PIN_BINARY_MISMATCH"]) in log, - "the refusal is written with PHD_ERR_REPLAY, the step and the pin's code: %s" % log[-400:]) + "the refusal is written with OMX_REPLY_PLUGIN_HOSTD_REPLAY_RESP, the step and the pin's code: %s" % log[-400:]) write(p.clap, good) mark = d.mark() os.kill(new, signal.SIGKILL) @@ -1612,7 +1612,7 @@ def a_layout_pinned_again_while_its_worker_was_down_is_refused_by_the_replayed_a "the worker refused the replayed add and got none of its verbs: %s" % p.received()) check(not [e for e in d.events[mark:] if e.startswith("instance_restored 0 ")], "instance 0 is not restored") check("resp %d, its add resp %d" % (harness.CODE["REPLAY"], harness.CODE["PIN_LAYOUT_MISMATCH"]) in d.log(), - "the refusal is written with PHD_ERR_REPLAY, the step and the worker's code: %s" % d.log()[-400:]) + "the refusal is written with OMX_REPLY_PLUGIN_HOSTD_REPLAY_RESP, the step and the worker's code: %s" % d.log()[-400:]) finally: d.close() p.close() diff --git a/tests/fake_host.c b/tests/fake_host.c index d149e55..b7f7a11 100644 --- a/tests/fake_host.c +++ b/tests/fake_host.c @@ -39,7 +39,7 @@ * list_connections "resp 0 > ..." * pin_layout resp 0 , the layout of the instance n (FAKE_NO_PIN_LAYOUT: the verb * is unknown, -902) - * pin_expect the layout pin of the next add of : that add answers PHD_ERR_PIN_LAYOUT_MISMATCH + * pin_expect the layout pin of the next add of : that add answers OMX_REPLY_HOST_PIN_LAYOUT_MISMATCH_RESP * when the fake's own layout differs (FAKE_NO_PIN_EXPECT: the verb is unknown, -902; * FAKE_PIN_EXPECT_HANG: it is never answered) * param_set pages_changed v other than 0 writes "remote_pages_changed " on the feedback port, as a CLAP @@ -59,8 +59,8 @@ * preset_list "resp 2", and preset_get <0|1> one preset each, -902 for any other index * track_info ... "resp 0"; the fake keeps nothing of it (FAKE_LOG shows what it was sent) * note_input "resp 0 midi_in" for an instance whose uri holds "synth", "resp 0 -" for any other - * note_on, note_off, all_notes_off ... "resp 0" for a synth, PHD_ERR_NOTE_QUEUE_FULL for one whose uri holds - * "synth_full", PHD_ERR_NO_NOTE_INPUT for any other; the fake + * note_on, note_off, all_notes_off ... "resp 0" for a synth, OMX_REPLY_HOST_NOTE_QUEUE_FULL_RESP for one whose uri holds + * "synth_full", OMX_REPLY_HOST_NO_NOTE_INPUT_RESP for any other; the fake * plays nothing (FAKE_LOG shows what it was sent) * chain ... "resp 0" when it holds every , -3 when not, -902 with FAKE_REFUSE_CHAIN, as an * omx-clap-host that runs no chain answers it; the fake runs nothing in order (FAKE_LOG @@ -268,11 +268,11 @@ static void receive(msg_t *msg) verb = tok[0]; n = ntok > 1 ? atoi(tok[1]) : -1; - if (verb_is(verb, PHD_VERB_PIN_EXPECT) && getenv("FAKE_NO_PIN_EXPECT")) + if (verb_is(verb, OMX_VERB_PIN_EXPECT) && getenv("FAKE_NO_PIN_EXPECT")) answer(fd, "resp -902"); - else if (verb_is(verb, PHD_VERB_PIN_EXPECT) && getenv("FAKE_PIN_EXPECT_HANG")) + else if (verb_is(verb, OMX_VERB_PIN_EXPECT) && getenv("FAKE_PIN_EXPECT_HANG")) sleep(60); - else if (verb_is(verb, PHD_VERB_PIN_EXPECT) && ntok == 3 && n >= 0 && n < MAX_INST) + else if (verb_is(verb, OMX_VERB_PIN_EXPECT) && ntok == 3 && n >= 0 && n < MAX_INST) { snprintf(g_expect[n], sizeof(g_expect[n]), "%s", tok[2]); answer(fd, "resp 0"); @@ -319,7 +319,7 @@ static void receive(msg_t *msg) else if (id >= 0 && id < MAX_INST && g_expect[id][0] && strcmp(g_expect[id], mine)) { g_expect[id][0] = '\0'; - answer(fd, "resp %d", PHD_ERR_PIN_LAYOUT_MISMATCH); + answer(fd, "resp %d", OMX_REPLY_HOST_PIN_LAYOUT_MISMATCH_RESP); } else if (id < 0 || id >= MAX_INST || g_inst[id].exists) answer(fd, "resp -2"); @@ -501,19 +501,19 @@ static void receive(msg_t *msg) } answer(fd, "resp %d", strcmp(tok[2], "none") ? 1 : 0); } - else if (!strcmp(verb, PHD_VERB_TRACK_INFO)) + else if (!strcmp(verb, OMX_VERB_TRACK_INFO)) answer(fd, "resp 0"); - else if (!strcmp(verb, PHD_VERB_NOTE_INPUT) && ntok == 2) + else if (!strcmp(verb, OMX_VERB_NOTE_INPUT) && ntok == 2) answer(fd, "resp 0 %s", g_inst[n].synth ? "midi_in" : PHD_NO_NOTE_INPUT); - else if (!strcmp(verb, PHD_VERB_NOTE_ON) || !strcmp(verb, PHD_VERB_NOTE_OFF) || !strcmp(verb, PHD_VERB_ALL_NOTES_OFF)) - answer(fd, "resp %d", !g_inst[n].synth ? PHD_ERR_NO_NOTE_INPUT : g_inst[n].full ? PHD_ERR_NOTE_QUEUE_FULL : 0); - else if (!strcmp(verb, PHD_VERB_REMOTE_PAGES) && ntok == 2) + else if (!strcmp(verb, OMX_VERB_NOTE_ON) || !strcmp(verb, OMX_VERB_NOTE_OFF) || !strcmp(verb, OMX_VERB_ALL_NOTES_OFF)) + answer(fd, "resp %d", !g_inst[n].synth ? OMX_REPLY_HOST_NO_NOTE_INPUT_RESP : g_inst[n].full ? OMX_REPLY_HOST_NOTE_QUEUE_FULL_RESP : 0); + else if (!strcmp(verb, OMX_VERB_REMOTE_PAGES) && ntok == 2) answer(fd, "resp 2"); - else if (!strcmp(verb, PHD_VERB_REMOTE_PAGE_GET) && ntok == 3 && !strcmp(tok[2], "0")) + else if (!strcmp(verb, OMX_VERB_REMOTE_PAGE_GET) && ntok == 3 && !strcmp(tok[2], "0")) answer(fd, "resp 0 7 \"Main\" \"Page \\\"A\\\"\" 0 2 - - - - - -"); - else if (!strcmp(verb, PHD_VERB_REMOTE_PAGE_GET) && ntok == 3 && !strcmp(tok[2], "1")) + else if (!strcmp(verb, OMX_VERB_REMOTE_PAGE_GET) && ntok == 3 && !strcmp(tok[2], "1")) answer(fd, "resp 0 8 \"\" \"Two\" 2 - - - - - - -"); - else if (!strcmp(verb, PHD_VERB_REMOTE_PAGE_GET) && ntok == 3) + else if (!strcmp(verb, OMX_VERB_REMOTE_PAGE_GET) && ntok == 3) answer(fd, "resp -902"); else if (!strcmp(verb, OMX_VERB_PRESET_LIST) && ntok == 2) answer(fd, "resp 2"); @@ -523,7 +523,7 @@ static void receive(msg_t *msg) answer(fd, "resp 0 urn:fake:bright \"Bright \\\"B\\\"\""); else if (!strcmp(verb, OMX_VERB_PRESET_GET) && ntok == 3) answer(fd, "resp -902"); - else if (!strcmp(verb, PHD_VERB_PARAM_INFO) && ntok == 3) + else if (!strcmp(verb, OMX_VERB_PARAM_INFO) && ntok == 3) answer(fd, !strcmp(tok[2], "0") ? "resp 0 ms linear 1 2000 350 1 time_ms" : !strcmp(tok[2], "1") ? "resp -511" : "resp -103"); else if (verb_is(verb, EFFECT_PATCH_SET) && ntok == 4) { diff --git a/tests/perturbation.py b/tests/perturbation.py index cd42856..fd1763d 100644 --- a/tests/perturbation.py +++ b/tests/perturbation.py @@ -103,7 +103,6 @@ def make(tree, *args): ("the suspect window default", r"(#define PHD_DEFAULT_SUSPECT_WINDOW_MS )500\b", r"\g<1>731", r"\b500\b"), ("the storm bound default", r"(#define PHD_DEFAULT_STORM_DEATHS +)5\b", r"\g<1>3", None), ("the pool size default", r"(#define PHD_DEFAULT_POOL_MAX +)8\b", r"\g<1>2", None), - ("an error code", r"(#define PHD_ERR_GAVE_UP +)\(-505\)", r"\g<1>(-595)", r"\b505\b"), ("the pool name limit", r"(#define PHD_POOL_NAME_MAX )32\b", r"\g<1>5", None), ("the readiness line", r'(#define PHD_READY_LINE )"plugin-hostd ready!"', r'\g<1>"plugin-hostd is up!"', r"plugin.hostd ready!"), ] @@ -111,6 +110,11 @@ def make(tree, *args): DATA_EDITS = [ ("a verb", r'"instance_info( %i)?"', lambda m: '"instance_where%s"' % (m.group(1) or ""), r"\binstance_info\b"), ] +# a reply code's number is declared in data/verbs.json and rendered as OMX_REPLY__RESP, which the daemon, the README +# and the man page follow: (what, pattern, replacement, old) on that file, one match +CODE_EDITS = [ + ("an error code", r'("resp": )-505\b', r"\g<1>-595", r"\b505\b"), +] # the verb the daemon has after the edit, and the one it has before, which the perturbed daemon must not have VERB_AFTER, VERB_BEFORE = "instance_where", "instance_info" @@ -183,7 +187,7 @@ def main(): verbs = open(declaration).read() # positive control: the greps find the old values where they are declared and documented - for what, pattern, _, old in EDITS + DATA_EDITS: + for what, pattern, _, old in EDITS + DATA_EDITS + CODE_EDITS: if old: found = grep(old, os.path.join(tree, "include"), os.path.join(tree, "README.md"), os.path.join(tree, "doc")) assert found, "control: the grep for the old value of %s finds nothing where it is declared" % what @@ -199,6 +203,9 @@ def main(): for what, pattern, repl, _ in DATA_EDITS: verbs, n = re.subn(pattern, repl, verbs) assert n == 2, "the edit of %s matched %d times, not its word and its format" % (what, n) + for what, pattern, repl, _ in CODE_EDITS: + verbs, n = re.subn(pattern, repl, verbs) + assert n == 1, "the edit of %s matched %d times" % (what, n) open(declaration, "w").write(verbs) # the render names a verb's macro after its word, so a renamed verb renames its C name, which every reader of it # follows; a reader of the old name does not compile @@ -221,7 +228,7 @@ def main(): r = make(tree, target) assert r.returncode == 0, "make %s in the scratch copy: %s%s" % (target, r.stdout, r.stderr) - for what, _, _, old in EDITS + DATA_EDITS: + for what, _, _, old in EDITS + DATA_EDITS + CODE_EDITS: if old: left = grep(old, os.path.join(tree, "src"), os.path.join(tree, "README.md"), os.path.join(tree, "doc")) assert not left, "a copy of the old value of %s remains:\n%s" % (what, "\n".join(left)) diff --git a/tests/planner_test.c b/tests/planner_test.c index 6d199e1..f355f34 100644 --- a/tests/planner_test.c +++ b/tests/planner_test.c @@ -363,7 +363,7 @@ static void a_refused_plan_gives_every_member_the_refusal(void) char text[128]; CHECK(plan(&s, m, 3, &p) == 0, "planned"); - planner_format_reasons(m, &p, PHD_ERR_PLACEMENT_INVALID, text, sizeof(text)); + planner_format_reasons(m, &p, OMX_REPLY_PLUGIN_HOSTD_PLACEMENT_INVALID_RESP, text, sizeof(text)); CHECK(!strcmp(text, "7:plan-refused:-501,8:plan-refused:-501,9:plan-refused:-501"), "the reasons are %s", text); CHECK(!strncmp(text + 2, planner_reason_word(PLANNER_REASON_PLAN_REFUSED), strlen(planner_reason_word(PLANNER_REASON_PLAN_REFUSED))), "and the word is the declared one"); diff --git a/tests/sabotage.py b/tests/sabotage.py index 0e7ce8b..785ecff 100644 --- a/tests/sabotage.py +++ b/tests/sabotage.py @@ -141,7 +141,7 @@ " if (rc == RPC_OK && resp_code(reply) >= 0)\n {\n free(reply);", " if (rc == RPC_OK)\n {\n free(reply);", "a_changed_layout_is_refused_by_the_worker_and_reaches_the_client"), ("a worker that does not answer pin_expect is a failed instantiation", "src/supervisor.c", - " code = PHD_ERR_VERB_DROPPED;\n", "", "a_changed_layout_is_refused_by_the_worker_and_reaches_the_client"), + " code = OMX_REPLY_PLUGIN_HOSTD_VERB_DROPPED_RESP;\n", "", "a_changed_layout_is_refused_by_the_worker_and_reaches_the_client"), ("the pin_expect a worker went with is not named", "src/supervisor.c", " event(PHD_EVENT_VERB_DROPPED_FMT, id, pin_expect_line(id, layout));\n", "", "a_changed_layout_is_refused_by_the_worker_and_reaches_the_client"), @@ -151,7 +151,7 @@ "else if (phd_pin_fd_digest(fd, hex) != 0)", "an_lv2_bundle_is_pinned_by_its_manifest_binary_and_seealso"), ("a pinned LV2 plugin may ask for a pool", "src/supervisor.c", " if (format->pinned_own_only)\n {\n if (placement && !strncmp(placement, PHD_PLACE_POOL_PREFIX, strlen(PHD_PLACE_POOL_PREFIX)))\n" - " return sup_resp(PHD_ERR_PLACEMENT_INVALID);\n", " if (format->pinned_own_only)\n {\n", "a_pinned_lv2_plugin_gets_a_worker_of_its_own"), + " return sup_resp(OMX_REPLY_PLUGIN_HOSTD_PLACEMENT_INVALID_RESP);\n", " if (format->pinned_own_only)\n {\n", "a_pinned_lv2_plugin_gets_a_worker_of_its_own"), ("a pinned LV2 plugin follows a policy into a pool", "src/supervisor.c", " snprintf(place, sizeof(place), PHD_PLACE_OWN);\n }\n /* first-use", " }\n /* first-use", "a_pinned_lv2_plugin_gets_a_worker_of_its_own"), @@ -166,13 +166,13 @@ ("a percent-encoded name is taken as written", "src/lv2.c", " if (strstr(names.name[n], PHD_PIN_PERCENT))\n", " if (0)\n", "what_cannot_be_pinned_is_refused_and_never_pinned_in_part"), - ("a plugin with no pin is not given one", "src/supervisor.c", " if (rc == PHD_ERR_PIN_ABSENT && first_use && !pins_known(fwd))", + ("a plugin with no pin is not given one", "src/supervisor.c", " if (rc == OMX_REPLY_HOST_PIN_ABSENT_RESP && first_use && !pins_known(fwd))", " if (0)", "first_use_pins_an_unpinned_plugin_and_runs_it_isolated"), ("a plugin pinned on first use may share a worker", "src/supervisor.c", " else if (first_use && !pins_in_process(fwd))", " else if (0)", "first_use_pins_an_unpinned_plugin_and_runs_it_isolated"), ("a changed plugin is refused and not announced", "src/supervisor.c", - " if (code == PHD_ERR_PIN_BINARY_MISMATCH)\n event(PHD_EVENT_PIN_CHANGED_FMT, uri, PHD_PIN_CHANGED_FILES);\n", - " if (code == PHD_ERR_PIN_BINARY_MISMATCH)\n ;\n", "a_plugin_changed_after_first_use_is_refused_with_an_event_until_accepted"), + " if (code == OMX_REPLY_PLUGIN_HOSTD_PIN_BINARY_MISMATCH_RESP)\n event(PHD_EVENT_PIN_CHANGED_FMT, uri, PHD_PIN_CHANGED_FILES);\n", + " if (code == OMX_REPLY_PLUGIN_HOSTD_PIN_BINARY_MISMATCH_RESP)\n ;\n", "a_plugin_changed_after_first_use_is_refused_with_an_event_until_accepted"), ("pin_accept takes nothing new", "src/pins.c", " return record(format, uri, search);\n}\n\nint pins_set_layout", " return SUCCESS;\n}\n\nint pins_set_layout", "a_plugin_changed_after_first_use_is_refused_with_an_event_until_accepted"), ("the store is not written", "src/pins.c", " pin.learned = 1;\n pin_put(&pin);\n store_save();\n", @@ -227,8 +227,8 @@ "if (i->track_info && format_at(i->fmt)->native_instance_verbs && replay_line(", "if (i->track_info && replay_line(", "an_lv2_instance_is_answered_by_the_daemon_and_its_worker_never_sees_the_verbs"), ("an LV2 param_info answers -511 for a symbol mod-host does not know", "src/lv2.c", - "code == ERR_HOST_INVALID_PARAM_SYMBOL ? ERR_HOST_INVALID_PARAM_SYMBOL : PHD_ERR_NO_PARAM_CONTRACT", - "PHD_ERR_NO_PARAM_CONTRACT", "an_lv2_instance_is_answered_by_the_daemon_and_its_worker_never_sees_the_verbs"), + "code == ERR_HOST_INVALID_PARAM_SYMBOL ? ERR_HOST_INVALID_PARAM_SYMBOL : OMX_REPLY_HOST_NO_PARAM_CONTRACT_RESP", + "OMX_REPLY_HOST_NO_PARAM_CONTRACT_RESP", "an_lv2_instance_is_answered_by_the_daemon_and_its_worker_never_sees_the_verbs"), ("lv2_worker omx-clap-host does not route to the adapter row", "src/lv2.c", " if (!strcmp(worker, PHD_LV2_WORKER_CLAP_HOST))\n return PHD_FORMAT_LV2_CLAP;\n", "", "lv2_worker_omx_clap_host_runs_the_plugin_in_the_clap_program_on_the_adapter_row"), @@ -252,7 +252,7 @@ " .pin_collect = lv2_pin_collect,\n .binary = lv2_binary,\n .layout_check = 0,", "the_adapter_row_keeps_the_pin_rules_of_the_lv2_row_and_checks_no_layout"), ("the adapter's refusal answers the worker's own error", "src/supervisor.c", - " if (!automatic)\n return sup_resp(PHD_ERR_LV2_ADAPTER_REFUSED);", " if (!automatic)\n return sup_resp(ERR_HOST_INSTANTIATION);", + " if (!automatic)\n return sup_resp(OMX_REPLY_PLUGIN_HOSTD_LV2_ADAPTER_REFUSED_RESP);", " if (!automatic)\n return sup_resp(ERR_HOST_INSTANTIATION);", "a_plugin_the_adapter_refuses_answers_a_named_code_and_the_event_names_the_reason"), ("the adapter's reason is not read from its reply", "src/supervisor.c", " if (refused)\n lv2_refusal_reason(reply, why, sizeof(why));\n", "", @@ -276,7 +276,7 @@ " lv2_adapter_refused(fwd);\n return sup_add(fwd, id, placement, client);", "a_plugin_the_adapter_does_not_find_is_not_found_and_no_refusal"), ("auto does not remember what the adapter refused", "src/supervisor.c", - " lv2_adapter_refused(uri);\n return sup_add(uri, id, placement, client);", " return sup_resp(PHD_ERR_LV2_ADAPTER_REFUSED);", + " lv2_adapter_refused(uri);\n return sup_add(uri, id, placement, client);", " return sup_resp(OMX_REPLY_PLUGIN_HOSTD_LV2_ADAPTER_REFUSED_RESP);", "under_auto_a_plugin_the_adapter_refuses_runs_on_mod_host_and_the_adapter_is_not_asked_again"), ("auto without the adapter's program fails instead of using mod-host", "src/supervisor.c", " if (format_at(fmt)->adapter && !proc_have_binary(bin_of(fmt)) && lv2_worker_is_auto(&g_conf, fwd))", @@ -323,7 +323,7 @@ "&& lv2_refused_under_auto(&g_conf, fmt, fwd))", "&& 0)", "under_auto_a_refused_plugin_that_kills_mod_host_on_add_costs_only_its_own_worker"), ("an add the worker died on is not named by an event", "src/supervisor.c", - " if (code != PHD_ERR_VERB_DROPPED)\n event(PHD_EVENT_VERB_DROPPED_FMT, id, line);\n", "", + " if (code != OMX_REPLY_PLUGIN_HOSTD_VERB_DROPPED_RESP)\n event(PHD_EVENT_VERB_DROPPED_FMT, id, line);\n", "", "under_auto_a_refused_plugin_that_kills_mod_host_on_add_costs_only_its_own_worker"), ("a feedback socket the relay has no memory to follow is left open", "src/relay.c", " fprintf(stderr, \"relay: no memory to follow the feedback of fd %d\\n\", fd);\n close(fd);\n", @@ -347,8 +347,8 @@ ("the generator does not hold a word list to its count", "tools/protocol-gen.c", ' _Static_assert(sizeof(VOCAB_##item) / sizeof(*VOCAB_##item) == OMX_##item##_COUNT, "omx-contract\'s " #item ": not as many words as its count");\n', "\n", "contract", "contract"), - ("two errors share a code", "include/plugin-hostd/protocol.h", "#define PHD_ERR_NOTE_QUEUE_FULL (-517)", - "#define PHD_ERR_NOTE_QUEUE_FULL (-516)", "consumer", "consumer"), + ("two errors share a code", "include/plugin-hostd/omx_clap_core_vocabulary.h", "#define OMX_REPLY_HOST_NOTE_QUEUE_FULL_RESP (-517)", + "#define OMX_REPLY_HOST_NOTE_QUEUE_FULL_RESP (-516)", "consumer", "consumer"), ("a gesture the relay has no memory to hold takes the table with it", "src/relay.c", " if (held == NULL)\n return;\n", "", "alloc_test", "alloc"), ("a refusal the lv2 table has no memory for takes the table with it", "src/lv2.c", @@ -442,11 +442,11 @@ "phd_number_in(word[4], on ? 1 : 0, PHD_NOTE_VELOCITY_MAX)", "phd_number_in(word[4], 0, 1000)", "notes_reach_a_clap_worker_unchanged_and_an_effect_refuses_them"), ("a note on an LV2 instance of mod-host is answered as played", "src/supervisor.c", - " reply = sup_resp(PHD_ERR_NOTES_BY_JACK);", " reply = sup_resp(SUCCESS);", + " reply = sup_resp(OMX_REPLY_HOST_NOTES_BY_JACK_RESP);", " reply = sup_resp(SUCCESS);", "an_lv2_instance_on_mod_host_answers_notes_by_jack_and_mod_host_never_sees_them"), ("a note is kept in the ledger and replayed", "include/plugin-hostd/protocol.h", - 'X(NOTE_ON, PHD_VERB_NOTE_ON, " ", "resp 0", NONE,', - 'X(NOTE_ON, PHD_VERB_NOTE_ON, " ", "resp 0", REPLACE,', + 'X(NOTE_ON, OMX_VERB_NOTE_ON, " ", "resp 0", NONE,', + 'X(NOTE_ON, OMX_VERB_NOTE_ON, " ", "resp 0", REPLACE,', "notes_are_never_replayed"), ("a gesture its worker did not end stays held", "src/relay.c", " gestures_end(&g_src[i]);\n free(g_src[i].buf);", " free(g_src[i].buf);", @@ -458,7 +458,7 @@ " else if (!begin && n < s->nheld)\n", " else if (0)\n", "a_gesture_the_value_it_moved_and_a_suggested_page_reach_the_controller_unchanged_and_in_order"), ("an LV2 instance's preset list goes to mod-host", "src/supervisor.c", - " else if (!strcmp(word[0], OMX_VERB_PRESET_LIST) || !strcmp(word[0], OMX_VERB_PRESET_GET))\n reply = sup_resp(PHD_ERR_NO_PRESET_LIST);", + " else if (!strcmp(word[0], OMX_VERB_PRESET_LIST) || !strcmp(word[0], OMX_VERB_PRESET_GET))\n reply = sup_resp(OMX_REPLY_PLUGIN_HOSTD_NO_PRESET_LIST_RESP);", " else if (!strcmp(word[0], OMX_VERB_PRESET_LIST) || !strcmp(word[0], OMX_VERB_PRESET_GET))\n reply = sup_call(id, line);", "presets_are_listed_by_a_clap_worker_and_an_lv2_instance_on_mod_host_answers_no_list"), ("pin_accept leaves the adapter's refusals in place", "src/supervisor.c", " if (rc == SUCCESS)\n lv2_refusals_forget(NULL);\n return sup_resp(rc);", @@ -623,12 +623,12 @@ ' put(&buf, &used, &cap, "%s%d", any++ ? "," : "", c->ids[k]);', "chain_get_reads_a_chain_back_as_declared_and_as_it_runs"), ('an unknown member of a chain is refused without its named code', "src/supervisor.c", - ' return sup_resp(PHD_ERR_CHAIN_UNKNOWN_INSTANCE);\n for (m = 0; m < k; m++)', + ' return sup_resp(OMX_REPLY_PLUGIN_HOSTD_CHAIN_UNKNOWN_INSTANCE_RESP);\n for (m = 0; m < k; m++)', ' return sup_resp(ERR_INSTANCE_NON_EXISTS);\n for (m = 0; m < k; m++)', "a_chain_is_declared_over_existing_instances_and_each_refusal_is_named"), ('an instance named twice is a chain', "src/supervisor.c", - ' if (ids[m] == ids[k])\n return sup_resp(PHD_ERR_CHAIN_DUPLICATE);', - ' if (0)\n return sup_resp(PHD_ERR_CHAIN_DUPLICATE);', + ' if (ids[m] == ids[k])\n return sup_resp(OMX_REPLY_PLUGIN_HOSTD_CHAIN_DUPLICATE_RESP);', + ' if (0)\n return sup_resp(OMX_REPLY_PLUGIN_HOSTD_CHAIN_DUPLICATE_RESP);', "a_chain_is_declared_over_existing_instances_and_each_refusal_is_named"), ('a member of another chain joins this one', "src/supervisor.c", ' if (i->chain && i->chain != c)\n', @@ -764,8 +764,8 @@ " {\n s = scan_of(format, id, hash);\n return resp_missing(s, SUCCESS);\n", "a_scan_that_runs_answers_pending_and_one_that_fails_answers_its_code_while_the_add_stands"), ("a directory that turns read-only is answered absent", "src/descriptors.c", - " scan_failed(s, PHD_ERR_DIR_NOT_WRITABLE, why);\n return;\n }\n log =", - " scan_failed(s, PHD_ERR_DESCRIPTOR_ABSENT, why);\n return;\n }\n log =", + " scan_failed(s, OMX_REPLY_PLUGIN_HOSTD_DIR_NOT_WRITABLE_RESP, why);\n return;\n }\n log =", + " scan_failed(s, OMX_REPLY_PLUGIN_HOSTD_DESCRIPTOR_ABSENT_RESP, why);\n return;\n }\n log =", "a_directory_that_turns_read_only_makes_the_scan_answer_its_code"), ("the preset schema takes a format version it does not know", "protocol/preset.schema.json", '"enum": ["org.openmixer.preset/1", "org.openmixer.preset/2"]', '"type": "string"', @@ -779,8 +779,9 @@ # the declared verbs (data/verbs.json) against the daemon on its socket, and the sources against the declaration ("a declared format is not the grammar the daemon answers", "data/verbs.json", '"format": "chain_get %i",', '"format": "chain_get %i %i",', "verbs_declared", "verbs"), - ("a declared code is not the one the daemon answers", "data/verbs.json", - '"resp": -522,', '"resp": -101,', "verbs_declared", "verbs"), + ("a rendered code is not the one declared, so not the one the daemon answers", "include/plugin-hostd/plugin_hostd_vocabulary.h", + "#define OMX_REPLY_PLUGIN_HOSTD_NO_SUCH_CHAIN_RESP (-522)", "#define OMX_REPLY_PLUGIN_HOSTD_NO_SUCH_CHAIN_RESP (-101)", + "verbs_declared", "verbs"), ("a number omx-clap-core names is named again by plugin-hostd", "data/verbs.json", ' "codes": {\n "placementInvalid": {', ' "codes": {\n "invalidOperation": {\n "code": "reply.plugin-hostd.invalid-operation",\n' diff --git a/tests/verbs_contract.py b/tests/verbs_contract.py index efd9b1b..a4e2a05 100644 --- a/tests/verbs_contract.py +++ b/tests/verbs_contract.py @@ -122,8 +122,9 @@ def spelled(text, verbs): header = f.read() rows = header[header.index("#define PHD_INSTANCE_VERBS(X)"):] rows = rows[:rows.index("\n\n")] - with open(os.path.join(ROOT, "include", "plugin-hostd", "plugin_hostd_host_verbs.h")) as f: - header += f.read() + for rendered in ("plugin_hostd_host_verbs.h", "omx_clap_core_host_verbs.h"): + with open(os.path.join(ROOT, "include", "plugin-hostd", rendered)) as f: + header += f.read() by_macro = dict(re.findall(r'^#define\s+((?:PHD_(?:VERB|EVENT)|OMX_VERB)_\w+)\s+"(\w+)"$', header, re.M)) instance_info = {by_macro[m] for m in re.findall(r"X\(\w+, ((?:PHD|OMX)_VERB_\w+),", rows)} events = {v for m, v in by_macro.items() if m.startswith("PHD_EVENT_")} diff --git a/tests/verbs_declared.py b/tests/verbs_declared.py index fbf04c1..5220707 100644 --- a/tests/verbs_declared.py +++ b/tests/verbs_declared.py @@ -77,9 +77,27 @@ def check_one_name(own_docs, shared_docs): fail("%d has %d names: %s" % (resp, len(names), ", ".join(names))) with open(os.path.join(ROOT, "include", "plugin-hostd", "protocol.h")) as f: header = f.read() - errors = {int(n) for n in re.findall(r"^#define\s+PHD_ERR_\w+\s+\((-[0-9]+)\)", header, re.M)} + # the numbers PHD_ERRORS answers are the rendered OMX_REPLY_*_RESP macros it names; the header defines none of its own + rendered = {} + for name in ("omx_clap_core_vocabulary.h", "plugin_hostd_vocabulary.h"): + with open(os.path.join(ROOT, "include", "plugin-hostd", name)) as f: + rendered.update({m: int(n) for m, n in re.findall(r"^#define\s+(OMX_REPLY_\w+_RESP)\s+\((-[0-9]+)\)", f.read(), re.M)}) + if re.search(r"^#define\s+PHD_ERR_", header, re.M): + fail("protocol.h defines a PHD_ERR_ number of its own") + block = header[header.index("#define PHD_ERRORS(X)"):header.index("/* ---------------------------------------------------------------- verbs */")] + names = re.findall(r"X\([A-Z0-9_]+, (OMX_REPLY_\w+_RESP), ", block) + absent = [n for n in names if n not in rendered] + if absent: + fail("PHD_ERRORS names %s, which no rendered vocabulary header defines" % absent) + # the daemon is compiled against the rendered numbers: one that is not the declared resp of its code is a stale render + for pkg, docs in (("plugin-hostd", own_docs), ("omx-clap-core", shared_docs)): + for ref, (code, resp) in codes_of(docs).items(): + macro = "OMX_" + re.sub(r"[^A-Za-z0-9]+", "_", code).upper() + "_RESP" + if resp is not None and macro in rendered and rendered[macro] != resp: + fail("%s is %d in the rendered header and %d in %s (%s): render again" % (macro, rendered[macro], resp, pkg, ref)) + errors = {rendered[n] for n in names} if len(errors) < 20: - fail("found only %d PHD_ERR_ numbers in protocol.h" % len(errors)) + fail("found only %d numbers in protocol.h's PHD_ERRORS" % len(errors)) unnamed = sorted(errors - set(named)) if unnamed: fail("protocol.h answers %s, which no code of plugin-hostd or omx-clap-core names" % unnamed) diff --git a/tools/protocol-gen.c b/tools/protocol-gen.c index e6c3acd..386ef08 100644 --- a/tools/protocol-gen.c +++ b/tools/protocol-gen.c @@ -140,8 +140,8 @@ static void json(void) #undef X printf("\n ],\n \"errors\": ["); sep = "\n"; -#define X(id, meaning) \ - printf("%s {\"name\": \"" #id "\", \"macro\": \"PHD_ERR_" #id "\", \"code\": %d, \"meaning\": ", sep, PHD_ERR_##id); \ +#define X(id, resp, meaning) \ + printf("%s {\"name\": \"" #id "\", \"macro\": \"" #resp "\", \"code\": %d, \"meaning\": ", sep, resp); \ jstr(meaning); \ printf("}"); \ sep = ",\n"; @@ -433,9 +433,9 @@ static void region_errors(void) row(" code ", " name ", " meaning ", NULL); printf("|---|---|---|\n"); -#define X(id, meaning) \ - snprintf(code, sizeof(code), " `%d` ", PHD_ERR_##id); \ - row(code, " `PHD_ERR_" #id "` ", " " meaning " ", NULL); +#define X(id, resp, meaning) \ + snprintf(code, sizeof(code), " `%d` ", resp); \ + row(code, " `" #resp "` ", " " meaning " ", NULL); PHD_ERRORS(X) #undef X } @@ -543,7 +543,7 @@ static void region_man_dirs(void) #undef X printf(".PP\nA missing directory is made, mode %04o, with its parents. One that cannot be made or written stops the " "daemon before it is ready: stderr names the key and the path with resp ", PHD_DIR_MODE); - snprintf(buffer, sizeof(buffer), "%d", PHD_ERR_DIR_NOT_WRITABLE); + snprintf(buffer, sizeof(buffer), "%d", OMX_REPLY_PLUGIN_HOSTD_DIR_NOT_WRITABLE_RESP); roff_escape(buffer); printf(".\n.PP\nThe answered\n.B add\nof a plugin whose files have no descriptor yet runs\n.I probe\n.B describe\n" "in a child of its own and files its stdout as\n.IR \""); @@ -551,7 +551,8 @@ static void region_man_dirs(void) printf("\" ,\nwritten once; the add never waits for it.\n.B " OMX_VERB_DESCRIPTOR_GET "\n.I uri\n" "answers the file's path, or "); snprintf(buffer, sizeof(buffer), "%d (none), %d (the scan runs), %d (the scan wrote nothing)", - PHD_ERR_DESCRIPTOR_ABSENT, PHD_ERR_DESCRIPTOR_PENDING, PHD_ERR_DESCRIPTOR_SCAN_FAILED); + OMX_REPLY_PLUGIN_HOSTD_DESCRIPTOR_ABSENT_RESP, OMX_REPLY_PLUGIN_HOSTD_DESCRIPTOR_PENDING_RESP, + OMX_REPLY_PLUGIN_HOSTD_DESCRIPTOR_SCAN_FAILED_RESP); roff_escape(buffer); printf(".\nOnce the descriptor is in place the same scan runs\n.I probe\n.B panel\nand files the plugin's panel as\n" ".IR \"");