#!/usr/bin/env bash set -euo pipefail ROOT_DIR="$(cd "$(dirname "$0")/.." && pwd)" TMP_FILE="$(mktemp)" VIOLATION_FILE="$(mktemp)" trap 'rm -f "$TMP_FILE" "$VIOLATION_FILE"' EXIT find \ "$ROOT_DIR/runtime" \ "$ROOT_DIR/tests" \ "$ROOT_DIR/tools" \ -type f \ \( -name '*.c' -o -name '*.cc' -o -name '*.cpp' -o -name '*.h' -o -name '*.hh' -o -name '*.hpp' -o -name '*.js' -o -name '*.ts' \) \ ! -path "$ROOT_DIR/vendor/*" \ ! -path "$ROOT_DIR/runtime/ui/ini-panel/linuxcnc_ini.js" \ -print0 | xargs -0 grep -nE '^[[:space:]]*([A-Za-z_][A-Za-z0-9_:<>~*&[:space:]]+[[:space:]]+)?Interp::[A-Za-z_~][A-Za-z0-9_]*[[:space:]]*\(' > "$TMP_FILE" || true ALLOWED_STUB_FILE="$ROOT_DIR/runtime/core/linuxcnc_wrap/linuxcnc_interp_edge_stubs.cpp" ALLOWED_PYTHON_STUB_FILE="$ROOT_DIR/runtime/core/linuxcnc_wrap/linuxcnc_interp_python_edge_stubs.cpp" is_allowed_interp_stub() { local line="$1" case "$line" in "$ALLOWED_STUB_FILE":*Interp::is_pycallable\(* | \ "$ALLOWED_STUB_FILE":*Interp::is_user_defined_g_code\(* | \ "$ALLOWED_STUB_FILE":*Interp::is_any_m_code_remapped\(* | \ "$ALLOWED_STUB_FILE":*Interp::is_user_defined_m_code\(* | \ "$ALLOWED_STUB_FILE":*Interp::is_m_code_remappable\(* | \ "$ALLOWED_STUB_FILE":*Interp::is_g_code_remappable\(* | \ "$ALLOWED_STUB_FILE":*Interp::remap_in_progress\(* | \ "$ALLOWED_STUB_FILE":*Interp::remapping\(* | \ "$ALLOWED_STUB_FILE":*Interp::parse_remap\(* | \ "$ALLOWED_STUB_FILE":*Interp::convert_remapped_code\(* | \ "$ALLOWED_STUB_FILE":*Interp::add_parameters\(* | \ "$ALLOWED_STUB_FILE":*Interp::pycall\(* | \ "$ALLOWED_STUB_FILE":*Interp::py_execute\(* | \ "$ALLOWED_STUB_FILE":*Interp::py_reload\(* | \ "$ALLOWED_PYTHON_STUB_FILE":*Interp::is_pycallable\(* | \ "$ALLOWED_PYTHON_STUB_FILE":*Interp::pycall\(* | \ "$ALLOWED_PYTHON_STUB_FILE":*Interp::py_execute\(* | \ "$ALLOWED_PYTHON_STUB_FILE":*Interp::py_reload\(*) return 0 ;; esac return 1 } while IFS= read -r line; do if ! is_allowed_interp_stub "$line"; then printf '%s\n' "$line" >> "$VIOLATION_FILE" fi done < "$TMP_FILE" if [[ -s "$VIOLATION_FILE" ]]; then echo "standalone Interp member definitions are not allowed outside documented runtime-edge stubs:" >&2 cat "$VIOLATION_FILE" >&2 exit 1 fi echo "standalone CNC semantics guard complete"