diff --git a/check-linuxcnc-rs274-source-map.sh b/check-linuxcnc-rs274-source-map.sh new file mode 100755 index 0000000..881a3a2 --- /dev/null +++ b/check-linuxcnc-rs274-source-map.sh @@ -0,0 +1,80 @@ +#!/usr/bin/env bash +set -euo pipefail + +cd "$(dirname "$0")" + +# LinuxCNC source basis: this guard keeps the local source map aligned with the +# LinuxCNC-root relative rs274 manifests that drive native and WASM source-link +# probes. It validates documentation/manifest drift only; it does not interpret +# CNC behavior. +python3 - <<'PY' +from pathlib import Path + +source_map = Path("docs/linuxcnc-rs274-source-map.md").read_text(encoding="utf-8") +native_manifest = Path("linuxcnc-rs274-source-files.txt").read_text(encoding="utf-8").splitlines() +wasm_manifest = Path("linuxcnc-rs274-wasm-source-files.txt").read_text(encoding="utf-8").splitlines() + +expected = { + "### Interpreter core": [ + Path(line.split(":", 2)[1]).name + for line in native_manifest + if line.startswith("core:") + ], + "### Python binding modules": [ + Path(line.split(":", 2)[1]).name + for line in native_manifest + if line.startswith("binding:") + ], + "### WASM-safe source core": [ + line.split(":", 2)[1] + for line in wasm_manifest + if line.startswith("core:") + ], + "### WASM-blocked sources": [ + line.split(":", 2)[1] + for line in wasm_manifest + if line.startswith("blocked:") + ], + "### WASM-tracked headers": [ + line.split(":", 2)[1] + for line in wasm_manifest + if line.startswith("header:") + ], + "### WASM-blocked headers": [ + line.split(":", 2)[1] + for line in wasm_manifest + if line.startswith("blocked-header:") + ], + "### WASM metadata sources": [ + line.split(":", 2)[1] + for line in wasm_manifest + if line.startswith("metadata:") + ], +} + +actual = {section: [] for section in expected} +active_section = None +for line in source_map.splitlines(): + if line in expected: + active_section = line + continue + if active_section and line.startswith("### "): + active_section = None + if active_section and line.startswith("- `"): + actual[active_section].append(line.split("`", 2)[1]) + +labels = { + "### Interpreter core": "interpreter core", + "### Python binding modules": "Python binding module", + "### WASM-safe source core": "WASM-safe source core", + "### WASM-blocked sources": "WASM-blocked source", + "### WASM-tracked headers": "WASM-tracked header", + "### WASM-blocked headers": "WASM-blocked header", + "### WASM metadata sources": "WASM metadata source", +} +for section, expected_entries in expected.items(): + if actual[section] != expected_entries: + raise SystemExit( + f"docs/linuxcnc-rs274-source-map.md {labels[section]} list no longer matches source manifest" + ) +PY diff --git a/docs/linuxcnc-rs274-source-map.md b/docs/linuxcnc-rs274-source-map.md index 2199fb0..6a182ed 100644 --- a/docs/linuxcnc-rs274-source-map.md +++ b/docs/linuxcnc-rs274-source-map.md @@ -108,6 +108,66 @@ dependencies are replaced: - `src/emc/rs274ngc/pyinterp1.cc` - `src/emc/rs274ngc/pyparamclass.cc` +### WASM-tracked headers + +These LinuxCNC headers are tracked by the wasm manifest because the +browser-safe source-link probes compile against them or shim their declarations: + +- `src/emc/rs274ngc/array1.hh` +- `src/emc/rs274ngc/interp_array_types.hh` +- `src/emc/rs274ngc/interp_base.hh` +- `src/emc/rs274ngc/interp_fwd.hh` +- `src/emc/rs274ngc/interp_inspection.hh` +- `src/emc/rs274ngc/interp_internal.hh` +- `src/emc/rs274ngc/interp_parameter_def.hh` +- `src/emc/rs274ngc/interp_python.hh` +- `src/emc/rs274ngc/interp_queue.hh` +- `src/emc/rs274ngc/modal_state.hh` +- `src/emc/rs274ngc/paramclass.hh` +- `src/emc/rs274ngc/rs274ngc.hh` +- `src/emc/rs274ngc/rs274ngc_interp.hh` +- `src/emc/rs274ngc/rs274ngc_return.hh` +- `src/emc/rs274ngc/units.h` +- `src/emc/pythonplugin/python_plugin.hh` +- `src/emc/ini/inifile.h` +- `src/emc/ini/inifile.hh` +- `src/emc/nml_intf/emc.hh` +- `src/emc/nml_intf/emc_nml.hh` +- `include/hal.h` +- `src/libnml/nml/nmlmsg.hh` +- `src/libnml/nml/stat_msg.hh` +- `src/libnml/rcs/rcs_print.hh` +- `src/rtapi/rtapi.h` +- `src/rtapi/rtapi_string.h` + +### WASM-blocked headers + +These headers are tracked for source coverage but should not become browser API +surface until their Boost.Python dependency is replaced: + +- `src/emc/rs274ngc/boost_pyenum_macros.hh` + +### WASM metadata sources + +These LinuxCNC source and build metadata files document the source basis for +the browser-safe shims and manifest completeness checks: + +- `src/emc/rs274ngc/Submakefile` +- `src/emc/rs274ngc/meson.build` +- `src/emc/pythonplugin/python_plugin.cc` +- `src/emc/task/emctaskmain.cc` +- `src/emc/task/taskclass.cc` +- `src/emc/task/emccanon.cc` +- `src/emc/sai/dummyemcstat.cc` +- `src/emc/ini/Submakefile` +- `src/libnml/nml/stat_msg.cc` +- `src/libnml/nml/nmlmsg.cc` +- `src/libnml/rcs/rcs_print.cc` +- `src/rtapi/uspace_common.h` +- `src/hal/hal_lib.c` +- `src/emc/tooldata/tooldata_db.cc` +- `src/emc/tooldata/tooldata_nml.cc` + ### Browser-hostile dependencies to replace - Python/Boost.Python remap and named parameter hooks. diff --git a/test-all-native.sh b/test-all-native.sh index 85816f8..3863974 100755 --- a/test-all-native.sh +++ b/test-all-native.sh @@ -141,6 +141,8 @@ grep -F 'CNC_SIM_ALL_NATIVE_GUARDRAILS_ONLY must be 0 or 1: $guardrails_only' te grep -F 'all native guardrail checks passed' test-all-native.sh >/dev/null grep -F 'LinuxCNC source basis: the wasm build preflights and compiles the' build-wasm.sh >/dev/null grep -F 'LinuxCNC source basis: manifest validation checks LinuxCNC-root relative' check-linuxcnc-inputs.sh >/dev/null +grep -F 'LinuxCNC source basis: this guard keeps the local source map aligned' check-linuxcnc-rs274-source-map.sh >/dev/null +grep -F './check-linuxcnc-rs274-source-map.sh' test-native.sh >/dev/null grep -F 'LinuxCNC source basis: the cached input checker keys check-linuxcnc-inputs.sh' check-linuxcnc-inputs-cached.sh >/dev/null grep -F 'LinuxCNC source basis: switchkins/remap table validation derives M428/M429/M430' check-linuxcnc-switchkins-remap-table.sh >/dev/null grep -F 'LINUXCNC_ROOT="$linuxcnc_root" ./check-linuxcnc-inputs-cached.sh "$manifest" --require-kinematics-complete' check-linuxcnc-switchkins-remap-table.sh >/dev/null @@ -853,38 +855,98 @@ wasm_manifest_blocked = [ for line in Path("linuxcnc-rs274-wasm-source-files.txt").read_text(encoding="utf-8").splitlines() if line.startswith("blocked:") ] +wasm_manifest_headers = [ + line.split(":", 2)[1] + for line in Path("linuxcnc-rs274-wasm-source-files.txt").read_text(encoding="utf-8").splitlines() + if line.startswith("header:") +] +wasm_manifest_blocked_headers = [ + line.split(":", 2)[1] + for line in Path("linuxcnc-rs274-wasm-source-files.txt").read_text(encoding="utf-8").splitlines() + if line.startswith("blocked-header:") +] +wasm_manifest_metadata = [ + line.split(":", 2)[1] + for line in Path("linuxcnc-rs274-wasm-source-files.txt").read_text(encoding="utf-8").splitlines() + if line.startswith("metadata:") +] source_map_core = [] source_map_bindings = [] source_map_wasm_core = [] source_map_wasm_blocked = [] +source_map_wasm_headers = [] +source_map_wasm_blocked_headers = [] +source_map_wasm_metadata = [] in_core_section = False in_binding_section = False in_wasm_core_section = False in_wasm_blocked_section = False +in_wasm_header_section = False +in_wasm_blocked_header_section = False +in_wasm_metadata_section = False for line in source_map.splitlines(): if line == "### Interpreter core": in_core_section = True in_binding_section = False in_wasm_core_section = False in_wasm_blocked_section = False + in_wasm_header_section = False + in_wasm_blocked_header_section = False + in_wasm_metadata_section = False continue if line == "### Python binding modules": in_core_section = False in_binding_section = True in_wasm_core_section = False in_wasm_blocked_section = False + in_wasm_header_section = False + in_wasm_blocked_header_section = False + in_wasm_metadata_section = False continue if line == "### WASM-safe source core": in_core_section = False in_binding_section = False in_wasm_core_section = True in_wasm_blocked_section = False + in_wasm_header_section = False + in_wasm_blocked_header_section = False + in_wasm_metadata_section = False continue if line == "### WASM-blocked sources": in_core_section = False in_binding_section = False in_wasm_core_section = False in_wasm_blocked_section = True + in_wasm_header_section = False + in_wasm_blocked_header_section = False + in_wasm_metadata_section = False + continue + if line == "### WASM-tracked headers": + in_core_section = False + in_binding_section = False + in_wasm_core_section = False + in_wasm_blocked_section = False + in_wasm_header_section = True + in_wasm_blocked_header_section = False + in_wasm_metadata_section = False + continue + if line == "### WASM-blocked headers": + in_core_section = False + in_binding_section = False + in_wasm_core_section = False + in_wasm_blocked_section = False + in_wasm_header_section = False + in_wasm_blocked_header_section = True + in_wasm_metadata_section = False + continue + if line == "### WASM metadata sources": + in_core_section = False + in_binding_section = False + in_wasm_core_section = False + in_wasm_blocked_section = False + in_wasm_header_section = False + in_wasm_blocked_header_section = False + in_wasm_metadata_section = True continue if in_core_section and line.startswith("### "): break @@ -894,6 +956,12 @@ for line in source_map.splitlines(): in_wasm_core_section = False if in_wasm_blocked_section and line.startswith("### "): in_wasm_blocked_section = False + if in_wasm_header_section and line.startswith("### "): + in_wasm_header_section = False + if in_wasm_blocked_header_section and line.startswith("### "): + in_wasm_blocked_header_section = False + if in_wasm_metadata_section and line.startswith("### "): + in_wasm_metadata_section = False if in_core_section and line.startswith("- `"): source_map_core.append(line.split("`", 2)[1]) if in_binding_section and line.startswith("- `"): @@ -902,6 +970,12 @@ for line in source_map.splitlines(): source_map_wasm_core.append(line.split("`", 2)[1]) if in_wasm_blocked_section and line.startswith("- `"): source_map_wasm_blocked.append(line.split("`", 2)[1]) + if in_wasm_header_section and line.startswith("- `"): + source_map_wasm_headers.append(line.split("`", 2)[1]) + if in_wasm_blocked_header_section and line.startswith("- `"): + source_map_wasm_blocked_headers.append(line.split("`", 2)[1]) + if in_wasm_metadata_section and line.startswith("- `"): + source_map_wasm_metadata.append(line.split("`", 2)[1]) if source_map_core != manifest_core: raise SystemExit( "docs/linuxcnc-rs274-source-map.md interpreter core list no longer matches linuxcnc-rs274-source-files.txt core manifest" @@ -918,6 +992,18 @@ if source_map_wasm_blocked != wasm_manifest_blocked: raise SystemExit( "docs/linuxcnc-rs274-source-map.md WASM-blocked source list no longer matches linuxcnc-rs274-wasm-source-files.txt blocked manifest" ) +if source_map_wasm_headers != wasm_manifest_headers: + raise SystemExit( + "docs/linuxcnc-rs274-source-map.md WASM-tracked header list no longer matches linuxcnc-rs274-wasm-source-files.txt header manifest" + ) +if source_map_wasm_blocked_headers != wasm_manifest_blocked_headers: + raise SystemExit( + "docs/linuxcnc-rs274-source-map.md WASM-blocked header list no longer matches linuxcnc-rs274-wasm-source-files.txt blocked-header manifest" + ) +if source_map_wasm_metadata != wasm_manifest_metadata: + raise SystemExit( + "docs/linuxcnc-rs274-source-map.md WASM metadata source list no longer matches linuxcnc-rs274-wasm-source-files.txt metadata manifest" + ) PY for script in \ diff --git a/test-native.sh b/test-native.sh index b159c34..acb4823 100755 --- a/test-native.sh +++ b/test-native.sh @@ -34,6 +34,7 @@ preflight_cache_dir="$build_dir/preflight-cache" ./check-linuxcnc-inputs-cached.sh --cache-dir "$preflight_cache_dir" linuxcnc-rs274-source-files.txt --require-rs274-complete ./check-linuxcnc-inputs-cached.sh --cache-dir "$preflight_cache_dir" linuxcnc-rs274-wasm-source-files.txt --require-rs274-complete ./check-linuxcnc-inputs-cached.sh --cache-dir "$preflight_cache_dir" linuxcnc-kinematics-source-files.txt --require-kinematics-complete +./check-linuxcnc-rs274-source-map.sh ./check-linuxcnc-switchkins-remap-table-cached.sh --cache-dir "$preflight_cache_dir" linuxcnc-kinematics-source-files.txt grep -F 'tooldata:src/emc/tooldata/tooldata_nml.cc:NML tool table backend selected by LinuxCNC TOOL_NML_FLAG' linuxcnc-rs274-source-files.txt >/dev/null grep -F 'tooldata:src/emc/tooldata/tool_mmap_read.cc:LinuxCNC tooldata mmap reader utility source from tooldata Submakefile' linuxcnc-rs274-source-files.txt >/dev/null