#!/usr/bin/env bash set -euo pipefail cd "$(dirname "$0")" # LinuxCNC source basis: this guard ties the documented wasm-safe shim map to # the linuxcnc_wasm_safe_probe_shims CMake set, the RS274/WASM source manifest, # and the LinuxCNC sources each shim cites. It validates source coverage only; # it does not add CNC behavior or expand smoke parsing. linuxcnc_root=${LINUXCNC_ROOT:-../linuxcnc} manifest=${1:-linuxcnc-rs274-wasm-source-files.txt} LINUXCNC_ROOT="$linuxcnc_root" ./check-linuxcnc-inputs-cached.sh "$manifest" linuxcnc_root=$(cd "$linuxcnc_root" && pwd) grep -F 'LinuxCNC source basis: wasm-safe shim probe sources are limited to the' \ list-linuxcnc-wasm-safe-shims.sh >/dev/null grep -F 'set(linuxcnc_wasm_safe_probe_shims' core/CMakeLists.txt >/dev/null grep -F 'LinuxCNC source basis: this guard ties the documented WASM blocker map' \ check-linuxcnc-wasm-blockers-source-map.sh >/dev/null grep -F 'dlopen' "$linuxcnc_root/src/emc/rs274ngc/interp_base.cc" >/dev/null grep -F '#define _(s) gettext(s)' "$linuxcnc_root/src/emc/rs274ngc/interp_internal.hh" >/dev/null grep -F 'int _task = 0;' "$linuxcnc_root/src/emc/rs274ngc/gcodemodule.cc" >/dev/null grep -F 'int _task = 1;' "$linuxcnc_root/src/emc/task/emctaskmain.cc" >/dev/null grep -F 'struct _inittab builtin_modules[]' "$linuxcnc_root/src/emc/task/taskclass.cc" >/dev/null grep -F 'int Interp::fetch_hal_param(' "$linuxcnc_root/src/emc/rs274ngc/interp_namedparams.cc" >/dev/null grep -F 'wordexp(basename, &exp_result, 0);' "$linuxcnc_root/src/emc/rs274ngc/rs274ngc_pre.cc" >/dev/null grep -F 'EMC_STAT *emcStatus = new EMC_STAT;' "$linuxcnc_root/src/emc/sai/dummyemcstat.cc" >/dev/null grep -F 'NMLmsg::NMLmsg' "$linuxcnc_root/src/libnml/nml/nmlmsg.cc" >/dev/null grep -F 'RCS_STAT_MSG::RCS_STAT_MSG' "$linuxcnc_root/src/libnml/nml/stat_msg.cc" >/dev/null grep -F 'print_rcs_error_new' "$linuxcnc_root/src/libnml/rcs/rcs_print.cc" >/dev/null grep -F 'rtapi_snprintf' "$linuxcnc_root/src/rtapi/uspace_common.h" >/dev/null grep -F 'class PythonPlugin' "$linuxcnc_root/src/emc/pythonplugin/python_plugin.hh" >/dev/null grep -F 'PythonPlugin::instantiate' "$linuxcnc_root/src/emc/pythonplugin/python_plugin.cc" >/dev/null grep -F '#define TOOL_MMAP_FILENAME ".tool.mmap"' "$linuxcnc_root/src/emc/tooldata/tooldata_mmap.cc" >/dev/null grep -F 'int tool_nml_register(CANON_TOOL_TABLE *tblptr)' "$linuxcnc_root/src/emc/tooldata/tooldata_nml.cc" >/dev/null grep -F 'int tooldata_db_init(char progname_plus_args[]' "$linuxcnc_root/src/emc/tooldata/tooldata_db.cc" >/dev/null python3 - "$manifest" <<'PY' from pathlib import Path import re import subprocess import sys manifest = Path(sys.argv[1]) source_map = Path("docs/linuxcnc-wasm-shims-source-map.md").read_text(encoding="utf-8") manifest_text = manifest.read_text(encoding="utf-8") shim_paths = [ line for line in subprocess.check_output(["./list-linuxcnc-wasm-safe-shims.sh"], text=True).splitlines() if line ] if len(shim_paths) != 11: raise SystemExit(f"expected 11 wasm-safe CMake shim sources, found {len(shim_paths)}") if f"| CMake `linuxcnc_wasm_safe_probe_shims` sources | {len(shim_paths)} |" not in source_map: raise SystemExit("docs/linuxcnc-wasm-shims-source-map.md shim count mismatch") expected_shims = { "core/wasm_shims/dlfcn.cc": ["src/emc/rs274ngc/interp_base.cc"], "core/wasm_shims/emc_status_shim.cc": ["src/emc/sai/dummyemcstat.cc"], "core/wasm_shims/gettext_shim.cc": ["src/emc/rs274ngc/interp_internal.hh"], "core/wasm_shims/linuxcnc_runtime_shim.cc": [ "src/emc/rs274ngc/gcodemodule.cc", "src/emc/task/emctaskmain.cc", "src/emc/task/taskclass.cc", "src/emc/rs274ngc/interp_namedparams.cc", "src/hal/hal_lib.c", "src/emc/rs274ngc/rs274ngc_pre.cc", ], "core/wasm_shims/nml_status_shim.cc": [ "src/libnml/nml/nmlmsg.cc", "src/libnml/nml/stat_msg.cc", ], "core/wasm_shims/python_c_api_shim.cc": [ "src/emc/rs274ngc/interp_python.cc", "src/emc/rs274ngc/interp_namedparams.cc", "src/emc/rs274ngc/gcodemodule.cc", "src/emc/pythonplugin/python_plugin.cc", ], "core/wasm_shims/rcs_print_shim.cc": ["src/libnml/rcs/rcs_print.cc"], "core/wasm_shims/rtapi_compat.cc": [ "src/rtapi/uspace_common.h", "src/rtapi/rtapi.h", ], "core/wasm_shims/tooldata/tooldata_mmap_backend.cc": [ "src/emc/tooldata/tooldata_mmap.cc", ], "core/wasm_shims/tooldata/tooldata_runtime_stubs.cc": [ "src/emc/tooldata/tooldata_nml.cc", "src/emc/tooldata/tooldata_db.cc", ], "core/wasm_shims/pythonplugin/python_plugin.cc": [ "src/emc/pythonplugin/python_plugin.cc", "src/emc/pythonplugin/python_plugin.hh", ], } if shim_paths != list(expected_shims): raise SystemExit("wasm-safe shim CMake order no longer matches docs/linuxcnc-wasm-shims-source-map.md") for shim_path, linuxcnc_sources in expected_shims.items(): shim_text = Path(shim_path).read_text(encoding="utf-8") if "LinuxCNC source basis:" not in shim_text: raise SystemExit(f"{shim_path} is missing a LinuxCNC source basis comment") if f"| `{shim_path}` |" not in source_map: raise SystemExit(f"docs/linuxcnc-wasm-shims-source-map.md missing shim row: {shim_path}") for source in linuxcnc_sources: if source not in source_map: raise SystemExit(f"docs/linuxcnc-wasm-shims-source-map.md missing source {source} for {shim_path}") if source not in manifest_text: raise SystemExit(f"{source} is not tracked in {manifest}") for phrase in [ "must not add CNC behavior", "must not expand the temporary smoke parser", "CMake `linuxcnc_wasm_safe_probe_shims` set", "RS274/WASM manifest", "browser-safe LinuxCNC adaptations", ]: if phrase not in source_map: raise SystemExit(f"docs/linuxcnc-wasm-shims-source-map.md missing boundary phrase: {phrase}") cmake_text = Path("core/CMakeLists.txt").read_text(encoding="utf-8") for shim_path in shim_paths: cmake_suffix = shim_path.removeprefix("core/") if cmake_suffix not in cmake_text: raise SystemExit(f"{shim_path} is not listed in linuxcnc_wasm_safe_probe_shims") blocker_map = Path("docs/linuxcnc-wasm-blockers-source-map.md").read_text(encoding="utf-8") for shim_path in [ "core/wasm_shims/linuxcnc_runtime_shim.cc", "core/wasm_shims/python_c_api_shim.cc", "core/wasm_shims/tooldata/tooldata_mmap_backend.cc", ]: if shim_path not in blocker_map: raise SystemExit(f"docs/linuxcnc-wasm-blockers-source-map.md no longer references {shim_path}") PY