#!/usr/bin/env bash set -euo pipefail cd "$(dirname "$0")" cxx=${CXX:-g++} if [[ -z ${CXX:-} ]] && command -v ccache >/dev/null 2>&1; then cxx="ccache $cxx" fi build_jobs=${CNC_SIM_BUILD_JOBS:-8} if ! [[ "$build_jobs" =~ ^[1-9][0-9]*$ ]]; then echo "CNC_SIM_BUILD_JOBS must be a positive integer: $build_jobs" >&2 exit 1 fi build_dir=${CNC_SIM_NATIVE_BUILD_DIR-build/native-test} if [[ -z "$build_dir" ]]; then echo "CNC_SIM_NATIVE_BUILD_DIR must not be empty" >&2 exit 1 fi if [[ "$build_dir" =~ [[:space:]] ]]; then echo "CNC_SIM_NATIVE_BUILD_DIR must not contain whitespace: $build_dir" >&2 exit 1 fi mkdir -p "$build_dir" build_dir=$(cd "$build_dir" && pwd) if [[ "$build_dir" == "/" ]]; then echo "CNC_SIM_NATIVE_BUILD_DIR must not be the filesystem root" >&2 exit 1 fi exec 9>"$build_dir/native-test.lock" flock 9 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-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 grep -F 'tooldata:src/emc/tooldata/tool_watch.cc:LinuxCNC tooldata watcher utility source from tooldata Submakefile' linuxcnc-rs274-source-files.txt >/dev/null grep -F 'header:src/emc/tooldata/tooldata.hh:LinuxCNC tooldata declarations used by RS274 and wasm-safe tooldata shims' linuxcnc-rs274-source-files.txt >/dev/null grep -F 'metadata:src/emc/tooldata/Submakefile:LinuxCNC tooldata build metadata defining mmap and NML backend source selection' linuxcnc-rs274-source-files.txt >/dev/null linuxcnc_root=${LINUXCNC_ROOT:-../linuxcnc} linuxcnc_root=$(cd "$linuxcnc_root" && pwd) tooldata_manifest_entries=$(./list-linuxcnc-source-manifest-sources.sh linuxcnc-rs274-source-files.txt all | grep '^src/emc/tooldata/' | sort) tooldata_source_entries=$(find "$linuxcnc_root/src/emc/tooldata" -maxdepth 1 -type f -printf 'src/emc/tooldata/%f\n' | sort) if ! diff -u <(printf '%s\n' "$tooldata_source_entries") <(printf '%s\n' "$tooldata_manifest_entries") >/dev/null; then echo "native rs274 manifest no longer covers the full LinuxCNC tooldata source directory" >&2 diff -u <(printf '%s\n' "$tooldata_source_entries") <(printf '%s\n' "$tooldata_manifest_entries") >&2 || true exit 1 fi grep -F 'metadata:src/emc/tooldata/tooldata_db.cc:source basis for wasm-safe tooldata runtime export shim' linuxcnc-rs274-wasm-source-files.txt >/dev/null grep -F 'metadata:src/emc/tooldata/tooldata_nml.cc:source basis for wasm-safe tooldata runtime NML export shim' linuxcnc-rs274-wasm-source-files.txt >/dev/null grep -F 'header:src/emc/ini/inifile.h:LinuxCNC C INI reader declarations exported by ini Submakefile' linuxcnc-rs274-wasm-source-files.txt >/dev/null grep -F 'header:src/emc/ini/inifile.hh:LinuxCNC C++ INI reader declarations used by inifile.cc' linuxcnc-rs274-wasm-source-files.txt >/dev/null grep -F 'metadata:src/emc/ini/Submakefile:LinuxCNC ini build metadata defining liblinuxcncini source and exported headers' linuxcnc-rs274-wasm-source-files.txt >/dev/null grep -F 'header:src/emc/nml_intf/emc.hh:LinuxCNC EMC status declarations used by wasm-safe EMC status shim' linuxcnc-rs274-wasm-source-files.txt >/dev/null grep -F 'header:src/emc/nml_intf/emc_nml.hh:LinuxCNC EMC NML aggregate declarations used by wasm-safe EMC status shim' linuxcnc-rs274-wasm-source-files.txt >/dev/null grep -F 'header:src/libnml/nml/nmlmsg.hh:LinuxCNC NML message declarations used by wasm-safe NMLmsg constructor shim' linuxcnc-rs274-wasm-source-files.txt >/dev/null grep -F 'header:src/libnml/nml/stat_msg.hh:LinuxCNC status message declarations used by wasm-safe RCS_STAT_MSG constructor shim' linuxcnc-rs274-wasm-source-files.txt >/dev/null grep -F 'metadata:src/emc/nml_intf/emcops.cc:source basis for native source-link EMC status constructor support object' linuxcnc-rs274-source-files.txt >/dev/null grep -F 'metadata:src/emc/sai/dummyemcstat.cc:source basis for native source-link emcStatus singleton support object' linuxcnc-rs274-source-files.txt >/dev/null grep -F 'metadata:src/emc/sai/Submakefile:LinuxCNC SAI build metadata defining dummyemcstat support object' linuxcnc-rs274-source-files.txt >/dev/null grep -F 'metadata:src/libnml/nml/stat_msg.cc:source basis for native source-link RCS_STAT_MSG support object' linuxcnc-rs274-source-files.txt >/dev/null grep -F 'header:src/emc/nml_intf/emc.hh:LinuxCNC EMC status declarations used by native source-link support objects' linuxcnc-rs274-source-files.txt >/dev/null grep -F 'header:src/emc/nml_intf/emc_nml.hh:LinuxCNC EMC NML aggregate declarations used by native source-link support objects' linuxcnc-rs274-source-files.txt >/dev/null grep -F 'header:src/libnml/nml/nmlmsg.hh:LinuxCNC NML message declarations used by native source-link stat_msg support object' linuxcnc-rs274-source-files.txt >/dev/null grep -F 'header:src/libnml/nml/stat_msg.hh:LinuxCNC status message declarations used by native source-link stat_msg support object' linuxcnc-rs274-source-files.txt >/dev/null grep -F '#include "linuxcnc_switchkins_remap_table.inc"' core/src/cnc_sim_api.cpp >/dev/null grep -F 'switchkins: options.switchkins' web/src/wasm-core.js >/dev/null grep -F 'remap: options.remap' web/src/wasm-core.js >/dev/null grep -F 'machine: options.machine' web/src/wasm-core.js >/dev/null grep -F 'config: options.config' web/src/wasm-core.js >/dev/null grep -F 'configPath: options.configPath' web/src/wasm-core.js >/dev/null grep -F 'configpath: options.configpath' web/src/wasm-core.js >/dev/null grep -F 'config_path: options.config_path' web/src/wasm-core.js >/dev/null grep -F 'ini: options.ini' web/src/wasm-core.js >/dev/null grep -F 'iniFile: options.iniFile' web/src/wasm-core.js >/dev/null grep -F 'inifile: options.inifile' web/src/wasm-core.js >/dev/null grep -F 'iniFileName: options.iniFileName' web/src/wasm-core.js >/dev/null grep -F 'inifilename: options.inifilename' web/src/wasm-core.js >/dev/null grep -F 'ini_file: options.ini_file' web/src/wasm-core.js >/dev/null grep -F 'ini_file_name: options.ini_file_name' web/src/wasm-core.js >/dev/null grep -F 'INI_FILE_NAME: options.INI_FILE_NAME' web/src/wasm-core.js >/dev/null grep -F 'halFile: options.halFile' web/src/wasm-core.js >/dev/null grep -F 'halfile: options.halfile' web/src/wasm-core.js >/dev/null grep -F 'hal_file: options.hal_file' web/src/wasm-core.js >/dev/null grep -F 'HALFILE: options.HALFILE' web/src/wasm-core.js >/dev/null grep -F 'postguiHalFile: options.postguiHalFile' web/src/wasm-core.js >/dev/null grep -F 'postguihalfile: options.postguihalfile' web/src/wasm-core.js >/dev/null grep -F 'postgui_halfile: options.postgui_halfile' web/src/wasm-core.js >/dev/null grep -F 'postgui_hal_file: options.postgui_hal_file' web/src/wasm-core.js >/dev/null grep -F 'POSTGUI_HALFILE: options.POSTGUI_HALFILE' web/src/wasm-core.js >/dev/null grep -F 'subroutinePath: options.subroutinePath' web/src/wasm-core.js >/dev/null grep -F 'subroutinepath: options.subroutinepath' web/src/wasm-core.js >/dev/null grep -F 'subroutine_path: options.subroutine_path' web/src/wasm-core.js >/dev/null grep -F 'SUBROUTINE_PATH: options.SUBROUTINE_PATH' web/src/wasm-core.js >/dev/null grep -F 'kinematics: options.kinematics' web/src/wasm-core.js >/dev/null grep -F 'trt: options.trt' web/src/wasm-core.js >/dev/null grep -F 'pivotLength: options.pivotLength' web/src/wasm-core.js >/dev/null grep -F 'pivot_length: options.pivot_length' web/src/wasm-core.js >/dev/null grep -F 'kinematicsType: options.kinematicsType' web/src/wasm-core.js >/dev/null grep -F 'kinematics_type: options.kinematics_type' web/src/wasm-core.js >/dev/null grep -F 'fiveaxisKinematicsType: options.fiveaxisKinematicsType' web/src/wasm-core.js >/dev/null grep -F 'fiveaxis_kinematics_type: options.fiveaxis_kinematics_type' web/src/wasm-core.js >/dev/null grep -F 'xyzbcTrt: options.xyzbcTrt' web/src/wasm-core.js >/dev/null grep -F 'globalThis.createCncSimModule' web/src/wasm-core.js >/dev/null grep -F 'createModule(moduleOptions)' web/src/wasm-core.js >/dev/null grep -F 'async parseFile(path, dialect = "linuxcnc", options = {})' web/src/wasm-core.js >/dev/null grep -F 'async parseWithParameterFile(program, parameterPath, dialect = "linuxcnc", options = {})' web/src/wasm-core.js >/dev/null grep -F 'async parseFileWithParameterFile(path, parameterPath, dialect = "linuxcnc", options = {})' web/src/wasm-core.js >/dev/null grep -F 'LINUXCNC_DEFAULT_PARAMETER_FILE = "rs274ngc.var"' web/src/wasm-core.js >/dev/null grep -F 'export type CncParseOptions' web/src/index.ts >/dev/null grep -F 'switchkins?: string;' web/src/index.ts >/dev/null grep -F 'remap?: string;' web/src/index.ts >/dev/null grep -F 'machine?: string;' web/src/index.ts >/dev/null grep -F 'config?: string;' web/src/index.ts >/dev/null grep -F 'configPath?: string;' web/src/index.ts >/dev/null grep -F 'configpath?: string;' web/src/index.ts >/dev/null grep -F 'config_path?: string;' web/src/index.ts >/dev/null grep -F 'ini?: string;' web/src/index.ts >/dev/null grep -F 'iniFile?: string;' web/src/index.ts >/dev/null grep -F 'inifile?: string;' web/src/index.ts >/dev/null grep -F 'iniFileName?: string;' web/src/index.ts >/dev/null grep -F 'inifilename?: string;' web/src/index.ts >/dev/null grep -F 'ini_file?: string;' web/src/index.ts >/dev/null grep -F 'ini_file_name?: string;' web/src/index.ts >/dev/null grep -F 'INI_FILE_NAME?: string;' web/src/index.ts >/dev/null grep -F 'halFile?: string;' web/src/index.ts >/dev/null grep -F 'halfile?: string;' web/src/index.ts >/dev/null grep -F 'hal_file?: string;' web/src/index.ts >/dev/null grep -F 'HALFILE?: string;' web/src/index.ts >/dev/null grep -F 'postguiHalFile?: string;' web/src/index.ts >/dev/null grep -F 'postguihalfile?: string;' web/src/index.ts >/dev/null grep -F 'postgui_halfile?: string;' web/src/index.ts >/dev/null grep -F 'postgui_hal_file?: string;' web/src/index.ts >/dev/null grep -F 'POSTGUI_HALFILE?: string;' web/src/index.ts >/dev/null grep -F 'subroutinePath?: string;' web/src/index.ts >/dev/null grep -F 'subroutinepath?: string;' web/src/index.ts >/dev/null grep -F 'subroutine_path?: string;' web/src/index.ts >/dev/null grep -F 'SUBROUTINE_PATH?: string;' web/src/index.ts >/dev/null grep -F 'kinematics?: string;' web/src/index.ts >/dev/null grep -F 'trt?: "xyzbc" | "xyzac" | string;' web/src/index.ts >/dev/null grep -F 'pivotLength?: number;' web/src/index.ts >/dev/null grep -F 'pivot_length?: number;' web/src/index.ts >/dev/null grep -F 'kinematicsType?: number;' web/src/index.ts >/dev/null grep -F 'kinematics_type?: number;' web/src/index.ts >/dev/null grep -F 'fiveaxisKinematicsType?: number;' web/src/index.ts >/dev/null grep -F 'fiveaxis_kinematics_type?: number;' web/src/index.ts >/dev/null grep -F 'xyzbcTrt?: CncXyzbcTrtOptions;' web/src/index.ts >/dev/null grep -F '): CncEvent[];' web/src/index.ts >/dev/null grep -F 'options?: CncParseOptions' web/src/wasm-core.d.ts >/dev/null grep -F 'parseFile(path: string, dialect?: CncDialect, options?: CncParseOptions): Promise;' web/src/wasm-core.d.ts >/dev/null grep -F 'parseWithParameterFile(' web/src/wasm-core.d.ts >/dev/null grep -F 'parseFileWithParameterFile(' web/src/wasm-core.d.ts >/dev/null grep -F 'copyFile(fromPath: string, toPath: string): Promise;' web/src/wasm-core.d.ts >/dev/null grep -F 'moveFile(fromPath: string, toPath: string): Promise;' web/src/wasm-core.d.ts >/dev/null grep -F 'exists(path: string): Promise;' web/src/wasm-core.d.ts >/dev/null grep -F 'stat(path: string): Promise;' web/src/wasm-core.d.ts >/dev/null grep -F 'loadParameterFile(path: string): Promise;' web/src/wasm-core.d.ts >/dev/null grep -F 'async function opfsEntryExists(workspacePath, relativePath)' web/src/wasm-core.js >/dev/null grep -F 'async function statOpfsEntry(workspacePath, relativePath)' web/src/wasm-core.js >/dev/null grep -F 'async function readOpfsDirectoryTree(workspacePath, relativePath, relativeRoot = "")' web/src/wasm-core.js >/dev/null grep -F 'function readWasmDirectoryTree(module, rootPath, relativeRoot = "")' web/src/wasm-core.js >/dev/null grep -F 'function writeWasmFileReplacingPath(module, path, data)' web/src/wasm-core.js >/dev/null grep -F '`${LINUXCNC_DEFAULT_PARAMETER_FILE}.bak`' web/src/wasm-core.js >/dev/null grep -F 'export type WasmModuleOptions' web/src/wasm-core.d.ts >/dev/null grep -F 'printErr?: (text: string) => void;' web/src/wasm-core.d.ts >/dev/null grep -F '"field":"switchkins"' web/public/linuxcnc_switchkins_remap_config_cases.json >/dev/null grep -F '"field":"remap"' web/public/linuxcnc_switchkins_remap_config_cases.json >/dev/null grep -F '"field":"machine"' web/public/linuxcnc_switchkins_remap_config_cases.json >/dev/null grep -F '"field":"kinematics"' web/public/linuxcnc_switchkins_remap_config_cases.json >/dev/null grep -F '"field":"config"' web/public/linuxcnc_switchkins_remap_config_cases.json >/dev/null grep -F '"field":"configPath"' web/public/linuxcnc_switchkins_remap_config_cases.json >/dev/null grep -F '"field":"configpath"' web/public/linuxcnc_switchkins_remap_config_cases.json >/dev/null grep -F '"field":"config_path"' web/public/linuxcnc_switchkins_remap_config_cases.json >/dev/null grep -F '"field":"ini"' web/public/linuxcnc_switchkins_remap_config_cases.json >/dev/null grep -F '"field":"iniFile"' web/public/linuxcnc_switchkins_remap_config_cases.json >/dev/null grep -F '"field":"inifile"' web/public/linuxcnc_switchkins_remap_config_cases.json >/dev/null grep -F '"field":"iniFileName"' web/public/linuxcnc_switchkins_remap_config_cases.json >/dev/null grep -F '"field":"inifilename"' web/public/linuxcnc_switchkins_remap_config_cases.json >/dev/null grep -F '"field":"ini_file"' web/public/linuxcnc_switchkins_remap_config_cases.json >/dev/null grep -F '"field":"ini_file_name"' web/public/linuxcnc_switchkins_remap_config_cases.json >/dev/null grep -F '"field":"INI_FILE_NAME"' web/public/linuxcnc_switchkins_remap_config_cases.json >/dev/null grep -F '"field":"halFile"' web/public/linuxcnc_switchkins_remap_config_cases.json >/dev/null grep -F '"field":"halfile"' web/public/linuxcnc_switchkins_remap_config_cases.json >/dev/null grep -F '"field":"hal_file"' web/public/linuxcnc_switchkins_remap_config_cases.json >/dev/null grep -F '"field":"HALFILE"' web/public/linuxcnc_switchkins_remap_config_cases.json >/dev/null grep -F '"field":"postguiHalFile"' web/public/linuxcnc_switchkins_remap_config_cases.json >/dev/null grep -F '"field":"postguihalfile"' web/public/linuxcnc_switchkins_remap_config_cases.json >/dev/null grep -F '"field":"postgui_halfile"' web/public/linuxcnc_switchkins_remap_config_cases.json >/dev/null grep -F '"field":"postgui_hal_file"' web/public/linuxcnc_switchkins_remap_config_cases.json >/dev/null grep -F '"field":"POSTGUI_HALFILE"' web/public/linuxcnc_switchkins_remap_config_cases.json >/dev/null grep -F '"field":"subroutinePath"' web/public/linuxcnc_switchkins_remap_config_cases.json >/dev/null grep -F '"field":"subroutinepath"' web/public/linuxcnc_switchkins_remap_config_cases.json >/dev/null grep -F '"field":"subroutine_path"' web/public/linuxcnc_switchkins_remap_config_cases.json >/dev/null grep -F '"field":"SUBROUTINE_PATH"' web/public/linuxcnc_switchkins_remap_config_cases.json >/dev/null grep -F '{"switchkins", ' core/tests/linuxcnc_switchkins_remap_config_cases.inc >/dev/null grep -F '{"remap", ' core/tests/linuxcnc_switchkins_remap_config_cases.inc >/dev/null grep -F '{"machine", ' core/tests/linuxcnc_switchkins_remap_config_cases.inc >/dev/null grep -F '{"kinematics", ' core/tests/linuxcnc_switchkins_remap_config_cases.inc >/dev/null grep -F '{"config", ' core/tests/linuxcnc_switchkins_remap_config_cases.inc >/dev/null grep -F '{"configPath", ' core/tests/linuxcnc_switchkins_remap_config_cases.inc >/dev/null grep -F '{"configpath", ' core/tests/linuxcnc_switchkins_remap_config_cases.inc >/dev/null grep -F '{"config_path", ' core/tests/linuxcnc_switchkins_remap_config_cases.inc >/dev/null grep -F '{"ini", ' core/tests/linuxcnc_switchkins_remap_config_cases.inc >/dev/null grep -F '{"iniFile", ' core/tests/linuxcnc_switchkins_remap_config_cases.inc >/dev/null grep -F '{"inifile", ' core/tests/linuxcnc_switchkins_remap_config_cases.inc >/dev/null grep -F '{"iniFileName", ' core/tests/linuxcnc_switchkins_remap_config_cases.inc >/dev/null grep -F '{"inifilename", ' core/tests/linuxcnc_switchkins_remap_config_cases.inc >/dev/null grep -F '{"ini_file", ' core/tests/linuxcnc_switchkins_remap_config_cases.inc >/dev/null grep -F '{"ini_file_name", ' core/tests/linuxcnc_switchkins_remap_config_cases.inc >/dev/null grep -F '{"INI_FILE_NAME", ' core/tests/linuxcnc_switchkins_remap_config_cases.inc >/dev/null grep -F '{"halFile", ' core/tests/linuxcnc_switchkins_remap_config_cases.inc >/dev/null grep -F '{"halfile", ' core/tests/linuxcnc_switchkins_remap_config_cases.inc >/dev/null grep -F '{"hal_file", ' core/tests/linuxcnc_switchkins_remap_config_cases.inc >/dev/null grep -F '{"HALFILE", ' core/tests/linuxcnc_switchkins_remap_config_cases.inc >/dev/null grep -F '{"postguiHalFile", ' core/tests/linuxcnc_switchkins_remap_config_cases.inc >/dev/null grep -F '{"postguihalfile", ' core/tests/linuxcnc_switchkins_remap_config_cases.inc >/dev/null grep -F '{"postgui_halfile", ' core/tests/linuxcnc_switchkins_remap_config_cases.inc >/dev/null grep -F '{"postgui_hal_file", ' core/tests/linuxcnc_switchkins_remap_config_cases.inc >/dev/null grep -F '{"POSTGUI_HALFILE", ' core/tests/linuxcnc_switchkins_remap_config_cases.inc >/dev/null grep -F '{"subroutinePath", ' core/tests/linuxcnc_switchkins_remap_config_cases.inc >/dev/null grep -F '{"subroutinepath", ' core/tests/linuxcnc_switchkins_remap_config_cases.inc >/dev/null grep -F '{"subroutine_path", ' core/tests/linuxcnc_switchkins_remap_config_cases.inc >/dev/null grep -F '{"SUBROUTINE_PATH", ' core/tests/linuxcnc_switchkins_remap_config_cases.inc >/dev/null grep -F '"moduleResolution": "Bundler"' web/tsconfig.json >/dev/null grep -F '"include": ["src/index.ts", "src/**/*.d.ts"]' web/tsconfig.json >/dev/null grep -F 'createWasmSimulator' test-web-wasm-node-smoke.cjs >/dev/null grep -F 'locateFile: (file) => path.join(wasmDir, file)' test-web-wasm-node-smoke.cjs >/dev/null grep -F 'printErr: () => {}' test-web-wasm-node-smoke.cjs >/dev/null grep -F 'expected web wasm-core options to pass LinuxCNC xyzac-trt RTCP config into WASM' test-web-wasm-node-smoke.cjs >/dev/null grep -F 'node test-web-wasm-node-smoke.cjs' test-web-wasm-node-smoke.sh >/dev/null grep -F 'WASM_NODE_SMOKE_MIN_STEPS:-50' test-web-wasm-node-smoke.sh >/dev/null grep -F 'web wasm node smoke passed ([0-9][0-9]* steps)' test-web-wasm-node-smoke.sh >/dev/null grep -F 'createWasmSimulator' web/test-browser-wasm-smoke.html >/dev/null grep -F 'runBrowserWasmSmoke' web/test-browser-wasm-smoke.html >/dev/null grep -F 'runBrowserOpfsWorkspaceSections' web/test-browser-wasm-smoke-sections.js >/dev/null grep -F 'runBrowserOpfsPolicySections' web/test-browser-wasm-smoke-sections.js >/dev/null grep -F 'runBrowserAppOpfsSections' web/test-browser-wasm-smoke-sections.js >/dev/null grep -F 'runLinuxCncBrowserSections' web/test-browser-wasm-smoke-sections.js >/dev/null grep -F 'runBrowserOpfsBasicSections' web/test-browser-wasm-smoke-opfs-workspace-sections.js >/dev/null grep -F 'runBrowserOpfsParameterSections' web/test-browser-wasm-smoke-opfs-workspace-sections.js >/dev/null grep -F 'runBrowserOpfsMirrorSections' web/test-browser-wasm-smoke-opfs-workspace-sections.js >/dev/null grep -F 'runBrowserOpfsDirectorySections' web/test-browser-wasm-smoke-opfs-workspace-sections.js >/dev/null grep -F 'await simulator.parseFile("programs/browser-smoke.ngc", "linuxcnc"' web/test-browser-wasm-smoke-opfs-basic-sections.js >/dev/null grep -F 'await simulator.parseWithParameterFile(' web/test-browser-wasm-smoke-opfs-parameter-sections.js >/dev/null grep -F 'await simulator.parseFileWithParameterFile(' web/test-browser-wasm-smoke-opfs-parameter-sections.js >/dev/null grep -F 'OPFS copyFile did not create the backup file' web/test-browser-wasm-smoke-opfs-mirror-sections.js >/dev/null grep -F 'OPFS copyFile did not update the WASM mirror destination' web/test-browser-wasm-smoke-opfs-mirror-sections.js >/dev/null grep -F 'OPFS moveFile did not replace the destination file' web/test-browser-wasm-smoke-opfs-mirror-sections.js >/dev/null grep -F 'OPFS moveFile left the WASM mirror source behind' web/test-browser-wasm-smoke-opfs-mirror-sections.js >/dev/null grep -F 'OPFS metadata queries polluted the WASM filesystem mirror' web/test-browser-wasm-smoke-opfs-directory-sections.js >/dev/null grep -F 'OPFS persistDirectory did not preserve an empty directory' web/test-browser-wasm-smoke-opfs-directory-sections.js >/dev/null grep -F 'OPFS readDirectory did not mirror an empty directory into WASM FS' web/test-browser-wasm-smoke-opfs-directory-sections.js >/dev/null grep -F 'OPFS readFile did not replace the WASM mirror directory with a file' web/test-browser-wasm-smoke-opfs-directory-sections.js >/dev/null grep -F '"parameters/rs274ngc.var"' web/test-browser-wasm-smoke-opfs-parameter-sections.js >/dev/null grep -F '"parameters/rs274ngc.var.bak"' web/test-browser-wasm-smoke-opfs-parameter-sections.js >/dev/null grep -F 'const opfsOptions = options.opfs ?? (isOpfsAvailable() ? {} : false)' web/src/wasm-core.js >/dev/null grep -F 'OPFS cannot be disabled in browser contexts with OPFS support' web/src/wasm-core.js >/dev/null if grep -R -n -E 'localStorage|sessionStorage|indexedDB|showOpenFilePicker|showSaveFilePicker|webkitRequestFileSystem|FileReader' web/src; then echo "browser app/wasm code must not add filesystem persistence outside OPFS" >&2 exit 1 fi grep -F 'LinuxCNC source basis: rs274ngc_pre.cc restore_parameters() reads the' web/src/wasm-core.js >/dev/null grep -F 'before replacing the main file and managing filename + ".bak".' web/src/wasm-core.js >/dev/null grep -F 'await removeOpfsEntry(workspacePath, `${path}.new`, false);' web/src/wasm-core.js >/dev/null grep -F 'OPFS workspace is required for browser program parsing' web/src/app.js >/dev/null grep -F 'const events = await simulator.parseFileWithParameterFile(programPath, parameterPath, "linuxcnc", parseOptions);' web/src/app.js >/dev/null grep -F 'default browser simulator did not create an OPFS workspace' web/test-browser-wasm-smoke-opfs-policy-sections.js >/dev/null grep -F 'browser simulator allowed OPFS to be disabled' web/test-browser-wasm-smoke-opfs-policy-sections.js >/dev/null grep -F 'app frame did not restore current program from OPFS after reload' web/test-browser-wasm-smoke-app-sections.js >/dev/null grep -F 'app frame did not report OPFS program restore after reload' web/test-browser-wasm-smoke-app-sections.js >/dev/null grep -F 'app frame did not persist LinuxCNC parameter state into OPFS' web/test-browser-wasm-smoke-app-sections.js >/dev/null grep -F 'app frame did not reload LinuxCNC parameter state from OPFS after reload' web/test-browser-wasm-smoke-app-sections.js >/dev/null grep -F '"parameters/missing-main.var.new", "stale temporary without main file' web/test-browser-wasm-smoke-opfs-parameter-sections.js >/dev/null grep -F 'stale LinuxCNC missing-parameter temporary file remained in OPFS' web/test-browser-wasm-smoke-opfs-parameter-sections.js >/dev/null grep -F 'stale LinuxCNC missing-parameter temporary file remained in WASM FS' web/test-browser-wasm-smoke-opfs-parameter-sections.js >/dev/null grep -F 'LinuxCNC out-of-order parameter file remained in WASM FS after restore failure' web/test-browser-wasm-smoke-opfs-parameter-sections.js >/dev/null grep -F 'LinuxCNC out-of-range parameter file remained in WASM FS after restore failure' web/test-browser-wasm-smoke-opfs-parameter-sections.js >/dev/null grep -F 'browser wasm smoke passed' web/test-browser-wasm-smoke-helpers.js >/dev/null grep -F 'browser wasm smoke passed' web/test-browser-wasm-smoke.html >/dev/null grep -F 'chromium chromium-browser google-chrome' test-web-wasm-browser-smoke.sh >/dev/null grep -F 'browser wasm smoke passed' test-web-wasm-browser-smoke.sh >/dev/null grep -F 'BROWSER_SMOKE_MIN_SECTIONS:-50' test-web-wasm-browser-smoke.sh >/dev/null grep -F 'browser wasm smoke passed ([0-9][0-9]* sections)' test-web-wasm-browser-smoke.sh >/dev/null python3 - <<'PY' from pathlib import Path import re import sys node_steps = len(re.findall(r'await\s+runStep\(', Path("test-web-wasm-node-smoke.cjs").read_text(encoding="utf-8"))) browser_sections = sum( len(re.findall(r'await\s+runSection\(', path.read_text(encoding="utf-8"))) for path in Path("web").glob("test-browser-wasm-smoke-*-sections.js") ) total = node_steps + browser_sections if total < 50: print( f"expected Node/browser smoke to keep at least 50 explicit closed-loop steps/sections, got {total}", file=sys.stderr, ) sys.exit(1) html_lines = Path("web/test-browser-wasm-smoke.html").read_text(encoding="utf-8").count("\n") + 1 if html_lines > 80: print( f"expected browser smoke HTML to stay as a small loader, got {html_lines} lines", file=sys.stderr, ) sys.exit(1) for path in sorted(Path("web").glob("test-browser-wasm-smoke-*-sections.js")): line_count = path.read_text(encoding="utf-8").count("\n") + 1 if line_count > 300: print( f"expected browser smoke section module {path} to stay below 300 lines, got {line_count}", file=sys.stderr, ) sys.exit(1) PY kinematics_manifest_sources="$build_dir/linuxcnc_kinematics_manifest_sources.txt" ./list-linuxcnc-kinematics-manifest-sources.sh linuxcnc-kinematics-source-files.txt all > "$kinematics_manifest_sources" grep -Fx "configs/sim/axis/ldelta.ini" "$kinematics_manifest_sources" >/dev/null grep -Fx "configs/sim/axis/ldelta_demo.ini" "$kinematics_manifest_sources" >/dev/null grep -Fx "configs/sim/axis/ldelta_demo.txt" "$kinematics_manifest_sources" >/dev/null grep -Fx "configs/sim/axis/ldelta_demo_es.txt" "$kinematics_manifest_sources" >/dev/null grep -Fx "configs/sim/axis/rdelta.ini" "$kinematics_manifest_sources" >/dev/null grep -Fx "lib/hallib/sim_ldelta.hal" "$kinematics_manifest_sources" >/dev/null grep -Fx "lib/hallib/sim_rdelta.hal" "$kinematics_manifest_sources" >/dev/null grep -F 'manifest does not cover LinuxCNC delta kinematics INI/HAL demo sources as asset sources' check-linuxcnc-inputs.sh >/dev/null grep -Fx "configs/sim/axis/corexy/corexy_by_kins.ini" "$kinematics_manifest_sources" >/dev/null grep -Fx "configs/sim/axis/corexy/corexy_by_hal.ini" "$kinematics_manifest_sources" >/dev/null grep -Fx "configs/sim/axis/corexy/corexy_base.inc" "$kinematics_manifest_sources" >/dev/null grep -Fx "configs/sim/axis/corexy/3joint_xyz.hal" "$kinematics_manifest_sources" >/dev/null grep -Fx "configs/sim/axis/corexy/corexy_by_hal.hal" "$kinematics_manifest_sources" >/dev/null grep -Fx "configs/sim/axis/corexy/corexy.halshow" "$kinematics_manifest_sources" >/dev/null grep -Fx "configs/sim/axis/corexy/README" "$kinematics_manifest_sources" >/dev/null grep -Fx "configs/sim/axis/corexy/corexy_by_kins.txt" "$kinematics_manifest_sources" >/dev/null grep -Fx "configs/sim/axis/corexy/corexy_by_hal.txt" "$kinematics_manifest_sources" >/dev/null grep -Fx "src/hal/components/corexy_by_hal.comp" "$kinematics_manifest_sources" >/dev/null grep -Fx "src/objects/hal/components/corexy_by_hal.c" "$kinematics_manifest_sources" >/dev/null grep -Fx "src/objects/hal/components/corexy_by_hal.mak" "$kinematics_manifest_sources" >/dev/null grep -Fx "src/objects/man/man9/corexy_by_hal.9.adoc" "$kinematics_manifest_sources" >/dev/null grep -F 'manifest does not cover LinuxCNC CoreXY kinematics INI/HAL/demo sources as asset sources' check-linuxcnc-inputs.sh >/dev/null grep -F 'manifest does not cover LinuxCNC CoreXY HAL component source' check-linuxcnc-inputs.sh >/dev/null grep -F 'manifest does not cover LinuxCNC generated CoreXY HAL component source' check-linuxcnc-inputs.sh >/dev/null grep -F 'manifest does not cover LinuxCNC CoreXY HAL component metadata sources' check-linuxcnc-inputs.sh >/dev/null grep -Fx "configs/sim/axis/rose_engine/rose_engine.ini" "$kinematics_manifest_sources" >/dev/null grep -Fx "configs/sim/axis/rose_engine/rose_engine.halshow" "$kinematics_manifest_sources" >/dev/null grep -Fx "configs/sim/axis/rose_engine/rcone.ngc" "$kinematics_manifest_sources" >/dev/null grep -Fx "configs/sim/axis/rose_engine/rcone_demo.ngc" "$kinematics_manifest_sources" >/dev/null grep -Fx "configs/sim/axis/rose_engine/README" "$kinematics_manifest_sources" >/dev/null grep -Fx "docs/src/man/man9/rosekins.9.adoc" "$kinematics_manifest_sources" >/dev/null grep -F 'manifest does not cover LinuxCNC rose engine kinematics INI/NGC/demo sources as asset sources' check-linuxcnc-inputs.sh >/dev/null grep -F 'manifest does not cover LinuxCNC rosekins manpage source' check-linuxcnc-inputs.sh >/dev/null grep -Fx "configs/sim/tklinuxcnc/tripod.ini" "$kinematics_manifest_sources" >/dev/null grep -Fx "lib/hallib/tripodsim.hal" "$kinematics_manifest_sources" >/dev/null grep -Fx "configs/sim/tklinuxcnc/README" "$kinematics_manifest_sources" >/dev/null grep -Fx "docs/man/man9/tripodkins.9" "$kinematics_manifest_sources" >/dev/null grep -F 'manifest does not cover LinuxCNC tripod kinematics INI/HAL sources as asset sources' check-linuxcnc-inputs.sh >/dev/null grep -F 'manifest does not cover LinuxCNC tripodkins manpage source' check-linuxcnc-inputs.sh >/dev/null grep -Fx "configs/sim/tklinuxcnc/trivkins/xz.ini" "$kinematics_manifest_sources" >/dev/null grep -Fx "configs/sim/tklinuxcnc/trivkins/xz_both.ini" "$kinematics_manifest_sources" >/dev/null grep -Fx "configs/sim/tklinuxcnc/trivkins/xzbase.inc" "$kinematics_manifest_sources" >/dev/null grep -Fx "configs/sim/tklinuxcnc/trivkins/xz.tbl" "$kinematics_manifest_sources" >/dev/null grep -Fx "configs/sim/tklinuxcnc/trivkins/README" "$kinematics_manifest_sources" >/dev/null grep -Fx "KINEMATICS = trivkins coordinates=xz" "../linuxcnc/configs/sim/tklinuxcnc/trivkins/xz.ini" >/dev/null grep -Fx "KINEMATICS = trivkins coordinates=xz kinstype=BOTH" "../linuxcnc/configs/sim/tklinuxcnc/trivkins/xz_both.ini" >/dev/null grep -F 'manifest does not cover LinuxCNC TkLinuxCNC trivkins XZ INI/include/tool/demo sources as asset sources' check-linuxcnc-inputs.sh >/dev/null grep -Fx "configs/sim/axis/ja_tests/xz/xz.ini" "$kinematics_manifest_sources" >/dev/null grep -Fx "configs/sim/axis/ja_tests/xz/xz_both.ini" "$kinematics_manifest_sources" >/dev/null grep -Fx "configs/sim/axis/ja_tests/xz/xz_both_auto.ini" "$kinematics_manifest_sources" >/dev/null grep -Fx "configs/sim/axis/ja_tests/xz/xzbase.inc" "$kinematics_manifest_sources" >/dev/null grep -Fx "configs/sim/axis/ja_tests/xz/xz.tbl" "$kinematics_manifest_sources" >/dev/null grep -Fx "configs/sim/axis/ja_tests/xz/README" "$kinematics_manifest_sources" >/dev/null grep -Fx "KINEMATICS = trivkins coordinates=xz" "../linuxcnc/configs/sim/axis/ja_tests/xz/xz.ini" >/dev/null grep -Fx "KINEMATICS = trivkins coordinates=xz kinstype=BOTH" "../linuxcnc/configs/sim/axis/ja_tests/xz/xz_both.ini" >/dev/null grep -Fx "MACHINE = trivkins XZ KINEMATICS_BOTH,AUTO TELEOP" "../linuxcnc/configs/sim/axis/ja_tests/xz/xz_both_auto.ini" >/dev/null grep -F 'manifest does not cover LinuxCNC AXIS joint-axis trivkins XZ INI/include/tool/demo sources as asset sources' check-linuxcnc-inputs.sh >/dev/null grep -Fx "configs/sim/axis/ja_tests/xyzb_locking_indexer/xyzb.ini" "$kinematics_manifest_sources" >/dev/null grep -Fx "configs/sim/axis/ja_tests/xyzb_locking_indexer/xyyzb.ini" "$kinematics_manifest_sources" >/dev/null grep -Fx "configs/sim/axis/ja_tests/xyzb_locking_indexer/xyzb.hal" "$kinematics_manifest_sources" >/dev/null grep -Fx "configs/sim/axis/ja_tests/xyzb_locking_indexer/xyzb.halshow" "$kinematics_manifest_sources" >/dev/null grep -Fx "configs/sim/axis/ja_tests/xyzb_locking_indexer/README" "$kinematics_manifest_sources" >/dev/null grep -Fx "KINEMATICS = trivkins coordinates=xyzb" "../linuxcnc/configs/sim/axis/ja_tests/xyzb_locking_indexer/xyzb.ini" >/dev/null grep -Fx "KINEMATICS = trivkins coordinates=xyyzb kinstype=both" "../linuxcnc/configs/sim/axis/ja_tests/xyzb_locking_indexer/xyyzb.ini" >/dev/null grep -Fx "MACHINE = XYYZB trivkins coordinates=xyyzb KINEMATICS_BOTH" "../linuxcnc/configs/sim/axis/ja_tests/xyzb_locking_indexer/xyyzb.ini" >/dev/null grep -F 'manifest does not cover LinuxCNC AXIS joint-axis trivkins XYZB locking indexer INI/HAL/demo sources as asset sources' check-linuxcnc-inputs.sh >/dev/null grep -Fx "configs/by_machine/scorbot-er-3/scorbot-er-3.ini" "$kinematics_manifest_sources" >/dev/null grep -Fx "configs/by_machine/scorbot-er-3/scorbot-er-3.hal" "$kinematics_manifest_sources" >/dev/null grep -Fx "configs/by_machine/scorbot-er-3/pyvcp.hal" "$kinematics_manifest_sources" >/dev/null grep -Fx "configs/by_machine/scorbot-er-3/gripper.xml" "$kinematics_manifest_sources" >/dev/null grep -Fx "src/hal/user_comps/scorbot-er-3.py" "$kinematics_manifest_sources" >/dev/null grep -Fx "src/hal/user_comps/Submakefile" "$kinematics_manifest_sources" >/dev/null grep -Fx "docs/src/man/man1/scorbot-er-3.1.adoc" "$kinematics_manifest_sources" >/dev/null grep -Fx "KINEMATICS = scorbot-kins" "../linuxcnc/configs/by_machine/scorbot-er-3/scorbot-er-3.ini" >/dev/null grep -Fx "loadusr -W scorbot-er-3" "../linuxcnc/configs/by_machine/scorbot-er-3/scorbot-er-3.hal" >/dev/null grep -F 'manifest does not cover LinuxCNC Scorbot ER-3 kinematics INI/HAL/PYVCP/user component sources as asset sources' check-linuxcnc-inputs.sh >/dev/null grep -F 'manifest does not cover LinuxCNC Scorbot ER-3 user component metadata sources' check-linuxcnc-inputs.sh >/dev/null grep -Fx "configs/sim/axis/gantry/gantry_mm.ini" "$kinematics_manifest_sources" >/dev/null grep -Fx "configs/sim/axis/gantry/gantry_mm.hal" "$kinematics_manifest_sources" >/dev/null grep -Fx "configs/sim/axis/gantry/gantry_mm.tbl" "$kinematics_manifest_sources" >/dev/null grep -Fx "configs/sim/axis/gantry/README" "$kinematics_manifest_sources" >/dev/null grep -Fx "src/hal/components/gantry.comp" "$kinematics_manifest_sources" >/dev/null grep -Fx "src/objects/hal/components/gantry.c" "$kinematics_manifest_sources" >/dev/null grep -Fx "src/objects/hal/components/gantry.mak" "$kinematics_manifest_sources" >/dev/null grep -Fx "src/objects/man/man9/gantry.9.adoc" "$kinematics_manifest_sources" >/dev/null grep -F 'manifest does not cover LinuxCNC gantry metric INI/HAL/tool sources as asset sources' check-linuxcnc-inputs.sh >/dev/null grep -F 'manifest does not cover LinuxCNC gantry HAL component source' check-linuxcnc-inputs.sh >/dev/null grep -F 'manifest does not cover LinuxCNC generated gantry HAL component source' check-linuxcnc-inputs.sh >/dev/null grep -F 'manifest does not cover LinuxCNC gantry HAL component metadata sources' check-linuxcnc-inputs.sh >/dev/null grep -Fx "configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt.ini" "$kinematics_manifest_sources" >/dev/null grep -Fx "configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzbc-trt.ini" "$kinematics_manifest_sources" >/dev/null grep -Fx "configs/sim/axis/vismach/5axis/bridgemill/5axis.ini" "$kinematics_manifest_sources" >/dev/null grep -Fx "configs/sim/axis/vismach/5axis/table-dual-rotary/xyzab-tdr.ini" "$kinematics_manifest_sources" >/dev/null grep -Fx "configs/sim/axis/vismach/5axis/table-rotary_spindle-rotary-nutating/xyzacb-trsrn_twp/xyzacb-trsrn.ini" "$kinematics_manifest_sources" >/dev/null grep -Fx "configs/sim/axis/vismach/5axis/table-rotary_spindle-rotary-nutating/xyzbca-trsrn_twp/xyzbca-trsrn.ini" "$kinematics_manifest_sources" >/dev/null grep -Fx "configs/sim/axis/vismach/hexapod-sim/hexapod.ini" "$kinematics_manifest_sources" >/dev/null grep -Fx "configs/sim/axis/vismach/melfa-sim/melfa.ini" "$kinematics_manifest_sources" >/dev/null grep -Fx "configs/sim/axis/vismach/millturn/millturn.ini" "$kinematics_manifest_sources" >/dev/null grep -Fx "configs/sim/axis/vismach/puma/puma.ini" "$kinematics_manifest_sources" >/dev/null grep -Fx "configs/sim/axis/vismach/puma/puma_cube.ini" "$kinematics_manifest_sources" >/dev/null grep -Fx "configs/sim/axis/vismach/puma/puma560.ini" "$kinematics_manifest_sources" >/dev/null grep -Fx "configs/sim/axis/vismach/puma/puma560_uvw.ini" "$kinematics_manifest_sources" >/dev/null grep -Fx "configs/sim/axis/vismach/scara/scara.ini" "$kinematics_manifest_sources" >/dev/null grep -Fx "configs/sim/qtaxis/non-trivial/scara/scara.ini" "$kinematics_manifest_sources" >/dev/null grep -Fx "configs/sim/qtvcp_screens/non-trivial/scara/scara.ini" "$kinematics_manifest_sources" >/dev/null grep -Fx "configs/sim/axis/vismach/5axis/bridgemill/5axisgui.hal" "$kinematics_manifest_sources" >/dev/null grep -Fx "configs/sim/axis/vismach/hexapod-sim/kinematics.hal" "$kinematics_manifest_sources" >/dev/null grep -Fx "configs/sim/axis/vismach/melfa-sim/melfa_dh.hal" "$kinematics_manifest_sources" >/dev/null grep -Fx "configs/sim/axis/vismach/millturn/millturn.hal" "$kinematics_manifest_sources" >/dev/null grep -Fx "configs/sim/axis/vismach/puma/puma_dh.hal" "$kinematics_manifest_sources" >/dev/null grep -Fx "configs/sim/axis/vismach/puma/puma560_dh.hal" "$kinematics_manifest_sources" >/dev/null grep -Fx "configs/sim/axis/vismach/5axis/bridgemill/5axis_postgui.hal" "$kinematics_manifest_sources" >/dev/null grep -Fx "configs/sim/axis/vismach/5axis/table-rotary-tilting/switchkins_postgui.hal" "$kinematics_manifest_sources" >/dev/null grep -Fx "configs/sim/axis/vismach/5axis/table-rotary_spindle-rotary-nutating/xyzacb-trsrn_twp/xyzacb-trsrn_postgui.hal" "$kinematics_manifest_sources" >/dev/null grep -Fx "configs/sim/axis/vismach/melfa-sim/melfa-postgui.hal" "$kinematics_manifest_sources" >/dev/null grep -Fx "configs/sim/axis/vismach/puma/puma560_postgui.hal" "$kinematics_manifest_sources" >/dev/null if [[ "$(grep -Ec '_postgui\.hal$|-postgui\.hal$' "$kinematics_manifest_sources")" -ne 11 ]]; then echo "expected kinematics manifest to cover all LinuxCNC POSTGUI_HALFILE switchkins sources" >&2 exit 1 fi grep -Fx "configs/sim/axis/vismach/5axis/bridgemill/remap_subs/428remap.ngc" "$kinematics_manifest_sources" >/dev/null grep -Fx "configs/sim/axis/vismach/5axis/table-dual-rotary/remap_subs/428remap.ngc" "$kinematics_manifest_sources" >/dev/null grep -Fx "configs/sim/axis/vismach/5axis/table-rotary-tilting/remap_subs/430remap.ngc" "$kinematics_manifest_sources" >/dev/null grep -Fx "configs/sim/axis/vismach/5axis/table-rotary_spindle-rotary-nutating/remap_subs/429remap.ngc" "$kinematics_manifest_sources" >/dev/null grep -Fx "configs/sim/axis/vismach/hexapod-sim/remap_subs/430remap.ngc" "$kinematics_manifest_sources" >/dev/null grep -Fx "configs/sim/axis/vismach/melfa-sim/remap_subs/429remap.ngc" "$kinematics_manifest_sources" >/dev/null grep -Fx "configs/sim/axis/vismach/millturn/remap_subs/429remap.ngc" "$kinematics_manifest_sources" >/dev/null grep -Fx "configs/sim/axis/vismach/puma/remap_subs/430remap.ngc" "$kinematics_manifest_sources" >/dev/null grep -Fx "configs/sim/axis/vismach/scara/remap_subs/428remap.ngc" "$kinematics_manifest_sources" >/dev/null grep -Fx "configs/sim/qtaxis/non-trivial/scara/remap_subs/429remap.ngc" "$kinematics_manifest_sources" >/dev/null grep -Fx "configs/sim/qtvcp_screens/non-trivial/scara/remap_subs/430remap.ngc" "$kinematics_manifest_sources" >/dev/null if [[ "$(grep -Ec '/remap_subs/(428|429|430)remap\.ngc$' "$kinematics_manifest_sources")" -ne 31 ]]; then echo "expected kinematics manifest to cover all LinuxCNC M428/M429/M430 remap sources" >&2 exit 1 fi grep -Fx "src/hal/components/xyzab_tdr_kins.comp" "$kinematics_manifest_sources" >/dev/null grep -Fx "src/objects/hal/components/xyzab_tdr_kins.c" "$kinematics_manifest_sources" >/dev/null grep -Fx "src/hal/components/xyzacb_trsrn.comp" "$kinematics_manifest_sources" >/dev/null grep -Fx "src/objects/hal/components/xyzacb_trsrn.c" "$kinematics_manifest_sources" >/dev/null grep -Fx "src/hal/components/xyzbca_trsrn.comp" "$kinematics_manifest_sources" >/dev/null grep -Fx "src/objects/hal/components/xyzbca_trsrn.c" "$kinematics_manifest_sources" >/dev/null grep -Fx "src/hal/components/millturn.comp" "$kinematics_manifest_sources" >/dev/null grep -Fx "src/objects/hal/components/millturn.c" "$kinematics_manifest_sources" >/dev/null grep -Fx "src/hal/components/matrixkins.comp" "$kinematics_manifest_sources" >/dev/null grep -Fx "src/objects/hal/components/matrixkins.c" "$kinematics_manifest_sources" >/dev/null grep -Fx "src/hal/components/userkins.comp" "$kinematics_manifest_sources" >/dev/null grep -Fx "src/objects/hal/components/userkins.c" "$kinematics_manifest_sources" >/dev/null grep -Fx "src/objects/hal/components/millturn.mak" "$kinematics_manifest_sources" >/dev/null grep -Fx "src/objects/hal/components/xyzab_tdr_kins.mak" "$kinematics_manifest_sources" >/dev/null grep -Fx "src/objects/hal/components/xyzacb_trsrn.mak" "$kinematics_manifest_sources" >/dev/null grep -Fx "src/objects/hal/components/xyzbca_trsrn.mak" "$kinematics_manifest_sources" >/dev/null grep -Fx "src/objects/hal/components/matrixkins.mak" "$kinematics_manifest_sources" >/dev/null grep -Fx "src/objects/hal/components/userkins.mak" "$kinematics_manifest_sources" >/dev/null if [[ "$(grep -Ec '^src/objects/hal/components/.*\.mak$' "$kinematics_manifest_sources")" -ne 8 ]]; then echo "expected kinematics manifest to cover all generated halcompile make metadata sources" >&2 exit 1 fi grep -Fx "configs/sim/axis/vismach/5axis/bridgemill/5axis.tbl" "$kinematics_manifest_sources" >/dev/null grep -Fx "configs/sim/axis/vismach/5axis/table-dual-rotary/xyzab-tdr.tbl" "$kinematics_manifest_sources" >/dev/null grep -Fx "configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt.tbl" "$kinematics_manifest_sources" >/dev/null grep -Fx "configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzbc-trt.tbl" "$kinematics_manifest_sources" >/dev/null grep -Fx "configs/sim/axis/vismach/5axis/table-rotary_spindle-rotary-nutating/xyzacb-trsrn_twp/xyzacb-trsrn.tbl" "$kinematics_manifest_sources" >/dev/null grep -Fx "configs/sim/axis/vismach/5axis/table-rotary_spindle-rotary-nutating/xyzbca-trsrn_twp/xyzbca-trsrn.tbl" "$kinematics_manifest_sources" >/dev/null grep -Fx "configs/sim/axis/vismach/melfa-sim/melfa.tbl" "$kinematics_manifest_sources" >/dev/null grep -Fx "configs/sim/axis/vismach/millturn/millturn.tbl" "$kinematics_manifest_sources" >/dev/null grep -Fx "configs/sim/axis/vismach/puma/puma.tbl" "$kinematics_manifest_sources" >/dev/null grep -Fx "configs/sim/qtaxis/non-trivial/scara/scara.tbl" "$kinematics_manifest_sources" >/dev/null if [[ "$(./list-linuxcnc-kinematics-manifest-sources.sh linuxcnc-kinematics-source-files.txt tooldata | grep -Ec '\.tbl$')" -ne 10 ]]; then echo "expected kinematics manifest to cover all resolvable LinuxCNC TOOL_TABLE switchkins sources" >&2 exit 1 fi grep -Fx "configs/sim/axis/vismach/5axis/bridgemill/README" "$kinematics_manifest_sources" >/dev/null grep -Fx "configs/sim/axis/vismach/5axis/table-dual-rotary/README" "$kinematics_manifest_sources" >/dev/null grep -Fx "configs/sim/axis/vismach/5axis/table-rotary-tilting/README" "$kinematics_manifest_sources" >/dev/null grep -Fx "configs/sim/axis/vismach/hexapod-sim/README" "$kinematics_manifest_sources" >/dev/null grep -Fx "configs/sim/axis/vismach/melfa-sim/README" "$kinematics_manifest_sources" >/dev/null grep -Fx "configs/sim/axis/vismach/millturn/README" "$kinematics_manifest_sources" >/dev/null grep -Fx "configs/sim/axis/vismach/puma/README" "$kinematics_manifest_sources" >/dev/null grep -Fx "configs/sim/axis/vismach/scara/README" "$kinematics_manifest_sources" >/dev/null if [[ "$(grep -Ec '/README$' "$kinematics_manifest_sources")" -ne 17 ]]; then echo "expected kinematics manifest to cover all tracked LinuxCNC README sources adjacent to kinematics INI files" >&2 exit 1 fi grep -Fx "src/hal/user_comps/vismach/5axisgui.py" "$kinematics_manifest_sources" >/dev/null grep -Fx "src/hal/user_comps/vismach/hexagui.py" "$kinematics_manifest_sources" >/dev/null grep -Fx "src/hal/user_comps/vismach/melfagui.py" "$kinematics_manifest_sources" >/dev/null grep -Fx "src/hal/user_comps/vismach/millturngui.py" "$kinematics_manifest_sources" >/dev/null grep -Fx "src/hal/user_comps/vismach/puma560gui.py" "$kinematics_manifest_sources" >/dev/null grep -Fx "src/hal/user_comps/vismach/pumagui.py" "$kinematics_manifest_sources" >/dev/null grep -Fx "src/hal/user_comps/vismach/scaragui.py" "$kinematics_manifest_sources" >/dev/null grep -Fx "src/hal/user_comps/vismach/xyzab-tdr-gui.py" "$kinematics_manifest_sources" >/dev/null grep -Fx "src/hal/user_comps/vismach/xyzac-trt-gui.py" "$kinematics_manifest_sources" >/dev/null grep -Fx "src/hal/user_comps/vismach/xyzbc-trt-gui.py" "$kinematics_manifest_sources" >/dev/null if [[ "$(grep -Ec '^src/hal/user_comps/vismach/.*gui\.py$|^src/hal/user_comps/vismach/xyz[abc-]+trt-gui\.py$|^src/hal/user_comps/vismach/xyzab-tdr-gui\.py$' "$kinematics_manifest_sources")" -ne 10 ]]; then echo "expected kinematics manifest to cover all LinuxCNC vismach loadusr GUI sources" >&2 exit 1 fi grep -Fx "share/qtvcp/panels/vismach_scara/vismach_scara.ui" "$kinematics_manifest_sources" >/dev/null grep -Fx "share/qtvcp/panels/vismach_scara/vismach_scara_handler.py" "$kinematics_manifest_sources" >/dev/null grep -Fx "lib/python/qtvcp/lib/qt_vismach/README.txt" "$kinematics_manifest_sources" >/dev/null grep -Fx "lib/python/qtvcp/lib/qt_vismach/__init__.py" "$kinematics_manifest_sources" >/dev/null grep -Fx "lib/python/qtvcp/lib/qt_vismach/primitives.py" "$kinematics_manifest_sources" >/dev/null grep -Fx "lib/python/qtvcp/lib/qt_vismach/qt_vismach.py" "$kinematics_manifest_sources" >/dev/null grep -Fx "lib/python/qtvcp/lib/qt_vismach/scara.py" "$kinematics_manifest_sources" >/dev/null if [[ "$(grep -Ec '^(share/qtvcp/panels/vismach_scara/|lib/python/qtvcp/lib/qt_vismach/)' "$kinematics_manifest_sources")" -ne 7 ]]; then echo "expected kinematics manifest to cover all LinuxCNC QtVCP vismach_scara panel sources" >&2 exit 1 fi grep -Fx "src/hal/user_comps/vismach/Submakefile" "$kinematics_manifest_sources" >/dev/null grep -Fx "docs/src/man/man1/5axisgui.1.adoc" "$kinematics_manifest_sources" >/dev/null grep -Fx "docs/src/man/man1/hexagui.1.adoc" "$kinematics_manifest_sources" >/dev/null grep -Fx "docs/src/man/man1/melfagui.1.adoc" "$kinematics_manifest_sources" >/dev/null grep -Fx "docs/src/man/man1/puma560gui.1.adoc" "$kinematics_manifest_sources" >/dev/null grep -Fx "docs/src/man/man1/pumagui.1.adoc" "$kinematics_manifest_sources" >/dev/null grep -Fx "docs/src/man/man1/scaragui.1.adoc" "$kinematics_manifest_sources" >/dev/null grep -Fx "docs/src/man/man1/xyzab-tdr-gui.1.adoc" "$kinematics_manifest_sources" >/dev/null grep -Fx "docs/src/man/man1/xyzac-trt-gui.1.adoc" "$kinematics_manifest_sources" >/dev/null grep -Fx "docs/src/man/man1/xyzbc-trt-gui.1.adoc" "$kinematics_manifest_sources" >/dev/null if [[ "$(grep -Ec '^docs/src/man/man1/(5axisgui|hexagui|melfagui|puma560gui|pumagui|scaragui|xyzab-tdr-gui|xyzac-trt-gui|xyzbc-trt-gui)\.1\.adoc$' "$kinematics_manifest_sources")" -ne 9 ]]; then echo "expected kinematics manifest to cover all LinuxCNC vismach GUI manpage sources" >&2 exit 1 fi grep -Fx "src/emc/kinematics/switchkins.h" "$kinematics_manifest_sources" >/dev/null grep -Fx "src/emc/kinematics/Submakefile" "$kinematics_manifest_sources" >/dev/null grep -Fx "src/emc/kinematics/blend.fig" "$kinematics_manifest_sources" >/dev/null grep -F 'manifest does not group all LinuxCNC kinematics headers as header sources' check-linuxcnc-inputs.sh >/dev/null grep -F 'manifest does not group all LinuxCNC kinematics build metadata as metadata sources' check-linuxcnc-inputs.sh >/dev/null grep -F 'manifest does not group all LinuxCNC kinematics reference assets as asset sources' check-linuxcnc-inputs.sh >/dev/null grep -F 'manifest does not cover all LinuxCNC component sources referenced by M428/M429/M430 INI KINEMATICS entries' check-linuxcnc-inputs.sh >/dev/null grep -F 'manifest does not cover all LinuxCNC generated component sources referenced by M428/M429/M430 INI KINEMATICS entries' check-linuxcnc-inputs.sh >/dev/null grep -F 'manifest does not cover all LinuxCNC generated component make metadata adjacent to generated kinematics sources' check-linuxcnc-inputs.sh >/dev/null grep -F 'manifest does not cover all resolvable LinuxCNC TOOL_TABLE files referenced by M428/M429/M430 INI files as tooldata sources' check-linuxcnc-inputs.sh >/dev/null grep -F 'manifest does not cover LinuxCNC README sources adjacent to M428/M429/M430 INI files as asset sources' check-linuxcnc-inputs.sh >/dev/null grep -F 'manifest does not cover all LinuxCNC vismach user component sources referenced by M428/M429/M430 INI/HAL loadusr commands as asset sources' check-linuxcnc-inputs.sh >/dev/null grep -F 'manifest does not cover LinuxCNC vismach user component build metadata as metadata sources' check-linuxcnc-inputs.sh >/dev/null grep -F 'manifest does not cover LinuxCNC vismach user component manpage sources as metadata sources' check-linuxcnc-inputs.sh >/dev/null grep -F 'manifest does not cover all LinuxCNC QtVCP vismach_scara sources referenced by M428/M429/M430 INI EMBED_TAB_COMMAND entries as asset sources' check-linuxcnc-inputs.sh >/dev/null grep -F 'bad manifest line $manifest_line_number' check-linuxcnc-inputs.sh >/dev/null grep -F 'manifest source must be LinuxCNC-root relative' check-linuxcnc-inputs.sh >/dev/null grep -F 'missing manifest source: $path' check-linuxcnc-inputs.sh >/dev/null core_source_list="$build_dir/cnc_sim_core_sources.txt" ./list-cnc-sim-core-sources.sh --with-smoke > "$core_source_list" mapfile -t core_sources < "$core_source_list" smoke_cxxflags=(-std=c++17 -fpermissive -DCNC_SIM_ENABLE_SMOKE_BACKEND -I core/include -I core/src -I ../linuxcnc/include) native_signature="$build_dir/native-build.signature" native_next_signature="$build_dir/native-build.signature.next" { printf 'CXX=%s\n' "$cxx" printf 'PWD=%s\n' "$PWD" printf 'BUILD_RULE_VERSION=1\n' printf 'SMOKE_CXXFLAGS=' printf ' %s' "${smoke_cxxflags[@]}" printf '\n' printf 'CORE_SOURCES:\n' printf '%s\n' "${core_sources[@]}" } > "$native_next_signature" if [[ ! -f "$native_signature" ]] || ! cmp -s "$native_signature" "$native_next_signature"; then rm -f "$build_dir"/core_*.o \ "$build_dir"/*.d \ "$build_dir"/canon_event_sink_smoke.o \ "$build_dir"/rtcp_kinematics_smoke.o \ "$build_dir"/simulator_gcode_controls_smoke.o \ "$build_dir"/cnc_sim_api_smoke.o \ "$build_dir"/cnc_sim_dump.o \ "$build_dir"/linuxcnc_gees_table_smoke.o \ "$build_dir"/canon_event_sink_smoke \ "$build_dir"/rtcp_kinematics_smoke \ "$build_dir"/linuxcnc_gees_table_smoke \ "$build_dir"/simulator_gcode_controls_smoke \ "$build_dir"/cnc_sim_api_smoke \ "$build_dir"/cnc_sim_dump fi mv "$native_next_signature" "$native_signature" core_objects=() dep_files=() core_index=0 for source in "${core_sources[@]}"; do obj="$build_dir/core_${core_index}.o" core_objects+=("$obj") dep_files+=("$obj.d") core_index=$((core_index + 1)) done for obj in \ "$build_dir/canon_event_sink_smoke.o" \ "$build_dir/rtcp_kinematics_smoke.o" \ "$build_dir/simulator_gcode_controls_smoke.o" \ "$build_dir/cnc_sim_api_smoke.o" \ "$build_dir/cnc_sim_dump.o" \ "$build_dir/linuxcnc_gees_table_smoke.o" do dep_files+=("$obj.d") done native_makefile="$build_dir/native.mk" { printf 'CXX := %s\n' "$cxx" printf 'SMOKE_CXXFLAGS :=' printf ' %s' "${smoke_cxxflags[@]}" printf '\n\n' printf 'CORE_OBJECTS :=' printf ' %s' "${core_objects[@]}" printf '\n\n' printf 'DEP_FILES :=' printf ' %s' "${dep_files[@]}" printf '\n\n' printf '.PHONY: all\n' printf 'all: %s %s %s %s %s %s\n\n' \ "$build_dir/canon_event_sink_smoke" \ "$build_dir/rtcp_kinematics_smoke" \ "$build_dir/linuxcnc_gees_table_smoke" \ "$build_dir/simulator_gcode_controls_smoke" \ "$build_dir/cnc_sim_api_smoke" \ "$build_dir/cnc_sim_dump" core_index=0 for source in "${core_sources[@]}"; do printf '%s: %s\n' "${core_objects[$core_index]}" "$source" printf '\t@$(CXX) $(SMOKE_CXXFLAGS) -MMD -MP -MF %s.d -c %s -o %s\n\n' \ "${core_objects[$core_index]}" "$source" "${core_objects[$core_index]}" core_index=$((core_index + 1)) done printf '%s: core/tests/canon_event_sink_smoke.cpp\n' "$build_dir/canon_event_sink_smoke.o" printf '\t@$(CXX) $(SMOKE_CXXFLAGS) -MMD -MP -MF %s.d -c core/tests/canon_event_sink_smoke.cpp -o %s\n\n' "$build_dir/canon_event_sink_smoke.o" "$build_dir/canon_event_sink_smoke.o" printf '%s: core/tests/rtcp_kinematics_smoke.cpp\n' "$build_dir/rtcp_kinematics_smoke.o" printf '\t@$(CXX) $(SMOKE_CXXFLAGS) -MMD -MP -MF %s.d -c core/tests/rtcp_kinematics_smoke.cpp -o %s\n\n' "$build_dir/rtcp_kinematics_smoke.o" "$build_dir/rtcp_kinematics_smoke.o" printf '%s: core/tests/simulator_gcode_controls_smoke.cpp\n' "$build_dir/simulator_gcode_controls_smoke.o" printf '\t@$(CXX) $(SMOKE_CXXFLAGS) -MMD -MP -MF %s.d -c core/tests/simulator_gcode_controls_smoke.cpp -o %s\n\n' "$build_dir/simulator_gcode_controls_smoke.o" "$build_dir/simulator_gcode_controls_smoke.o" printf '%s: core/tests/cnc_sim_api_smoke.cpp\n' "$build_dir/cnc_sim_api_smoke.o" printf '\t@$(CXX) $(SMOKE_CXXFLAGS) -MMD -MP -MF %s.d -c core/tests/cnc_sim_api_smoke.cpp -o %s\n\n' "$build_dir/cnc_sim_api_smoke.o" "$build_dir/cnc_sim_api_smoke.o" printf '%s: core/tools/cnc_sim_dump.cpp\n' "$build_dir/cnc_sim_dump.o" printf '\t@$(CXX) $(SMOKE_CXXFLAGS) -MMD -MP -MF %s.d -c core/tools/cnc_sim_dump.cpp -o %s\n\n' "$build_dir/cnc_sim_dump.o" "$build_dir/cnc_sim_dump.o" printf '%s: core/tests/linuxcnc_gees_table_smoke.cpp\n' "$build_dir/linuxcnc_gees_table_smoke.o" printf '\t@$(CXX) $(SMOKE_CXXFLAGS) -MMD -MP -MF %s.d -c core/tests/linuxcnc_gees_table_smoke.cpp -o %s\n\n' "$build_dir/linuxcnc_gees_table_smoke.o" "$build_dir/linuxcnc_gees_table_smoke.o" printf '%s: %s\n' "$build_dir/linuxcnc_gees_table_smoke" "$build_dir/linuxcnc_gees_table_smoke.o" printf '\t@$(CXX) $(SMOKE_CXXFLAGS) %s -o %s\n\n' "$build_dir/linuxcnc_gees_table_smoke.o" "$build_dir/linuxcnc_gees_table_smoke" printf '%s: $(CORE_OBJECTS) %s\n' "$build_dir/canon_event_sink_smoke" "$build_dir/canon_event_sink_smoke.o" printf '\t@$(CXX) $(SMOKE_CXXFLAGS) $(CORE_OBJECTS) %s -o %s\n\n' "$build_dir/canon_event_sink_smoke.o" "$build_dir/canon_event_sink_smoke" printf '%s: $(CORE_OBJECTS) %s\n' "$build_dir/rtcp_kinematics_smoke" "$build_dir/rtcp_kinematics_smoke.o" printf '\t@$(CXX) $(SMOKE_CXXFLAGS) $(CORE_OBJECTS) %s -o %s\n\n' "$build_dir/rtcp_kinematics_smoke.o" "$build_dir/rtcp_kinematics_smoke" printf '%s: $(CORE_OBJECTS) %s\n' "$build_dir/simulator_gcode_controls_smoke" "$build_dir/simulator_gcode_controls_smoke.o" printf '\t@$(CXX) $(SMOKE_CXXFLAGS) $(CORE_OBJECTS) %s -o %s\n\n' "$build_dir/simulator_gcode_controls_smoke.o" "$build_dir/simulator_gcode_controls_smoke" printf '%s: $(CORE_OBJECTS) %s\n' "$build_dir/cnc_sim_api_smoke" "$build_dir/cnc_sim_api_smoke.o" printf '\t@$(CXX) $(SMOKE_CXXFLAGS) $(CORE_OBJECTS) %s -o %s\n\n' "$build_dir/cnc_sim_api_smoke.o" "$build_dir/cnc_sim_api_smoke" printf '%s: $(CORE_OBJECTS) %s\n' "$build_dir/cnc_sim_dump" "$build_dir/cnc_sim_dump.o" printf '\t@$(CXX) $(SMOKE_CXXFLAGS) $(CORE_OBJECTS) %s -o %s\n' "$build_dir/cnc_sim_dump.o" "$build_dir/cnc_sim_dump" printf '\n-include $(DEP_FILES)\n' } > "$native_makefile" make --output-sync=target -j"$build_jobs" -f "$native_makefile" "$build_dir/canon_event_sink_smoke" "$build_dir/rtcp_kinematics_smoke" "$build_dir/linuxcnc_gees_table_smoke" "$build_dir/simulator_gcode_controls_smoke" "$build_dir/cnc_sim_api_smoke" ./test-web-wasm-node-smoke.sh ./test-web-wasm-browser-smoke.sh basic_mill_json="$build_dir/cnc_sim_basic_mill.json" incremental_arc_json="$build_dir/cnc_sim_incremental_and_r_arc.json" subprogram_m98_json="$build_dir/cnc_sim_smoke_subprogram_m98.json" oword_subprogram_json="$build_dir/cnc_sim_smoke_oword_subprogram.json" "$build_dir/cnc_sim_dump" tests/gcode/basic_mill.ngc >"$basic_mill_json" "$build_dir/cnc_sim_dump" tests/gcode/incremental_and_r_arc.ngc >"$incremental_arc_json" "$build_dir/cnc_sim_dump" tests/gcode/smoke_subprogram_m98.ngc >"$subprogram_m98_json" "$build_dir/cnc_sim_dump" tests/gcode/smoke_oword_subprogram.ngc >"$oword_subprogram_json" echo "native tests passed" echo "dumped $basic_mill_json" echo "dumped $incremental_arc_json" echo "dumped $subprogram_m98_json" echo "dumped $oword_subprogram_json"