#!/usr/bin/env bash set -euo pipefail cd "$(dirname "$0")" linuxcnc_root=${LINUXCNC_ROOT:-../linuxcnc} manifest=${1:-} require_complete=${2:-} if [[ "$manifest" == "--root-only" ]]; then manifest= fi if [[ "$manifest" == "--require-rs274-complete" || "$manifest" == "--require-kinematics-complete" ]]; then echo "usage: $0 [manifest] [--require-rs274-complete|--require-kinematics-complete]" >&2 exit 1 fi case "$require_complete" in ""|--require-rs274-complete|--require-kinematics-complete) ;; *) echo "unknown check-linuxcnc-inputs option: $require_complete" >&2 exit 1 ;; esac if [[ -n "$manifest" && ! -f "$manifest" ]]; then echo "missing manifest: $manifest" >&2 exit 1 fi if [[ ! -d "$linuxcnc_root" ]]; then echo "missing LinuxCNC root: $linuxcnc_root" >&2 exit 1 fi if [[ -n "$manifest" && "$require_complete" == "--require-rs274-complete" ]]; then rs274_dir="$linuxcnc_root/src/emc/rs274ngc" if [[ ! -d "$rs274_dir" ]]; then echo "missing LinuxCNC rs274ngc source directory: $rs274_dir" >&2 exit 1 fi mapfile -t rs274_sources < <( find "$rs274_dir" -maxdepth 1 -type f \ | sed "s#^$linuxcnc_root/##" \ | sort ) mapfile -t manifest_rs274_sources < <( awk -F: ' $1 !~ /^($|#)/ && $2 ~ /^src\/emc\/rs274ngc\// { print $2 } ' "$manifest" | sort -u ) missing_rs274_sources=() for source in "${rs274_sources[@]}"; do if ! printf '%s\n' "${manifest_rs274_sources[@]}" | grep -Fx -- "$source" >/dev/null; then missing_rs274_sources+=("$source") fi done if ((${#missing_rs274_sources[@]} > 0)); then echo "manifest does not cover all LinuxCNC rs274ngc sources: $manifest" >&2 printf 'missing rs274ngc source: %s\n' "${missing_rs274_sources[@]}" >&2 exit 1 fi fi if [[ -n "$manifest" && "$require_complete" == "--require-kinematics-complete" ]]; then kinematics_dir="$linuxcnc_root/src/emc/kinematics" if [[ ! -d "$kinematics_dir" ]]; then echo "missing LinuxCNC kinematics source directory: $kinematics_dir" >&2 exit 1 fi mapfile -t kinematics_sources < <( find "$kinematics_dir" -maxdepth 1 -type f \ | sed "s#^$linuxcnc_root/##" \ | sort ) mapfile -t manifest_kinematics_sources < <( awk -F: ' $1 !~ /^($|#)/ && $2 ~ /^src\/emc\/kinematics\// { print $2 } ' "$manifest" | sort -u ) missing_kinematics_sources=() for source in "${kinematics_sources[@]}"; do if ! printf '%s\n' "${manifest_kinematics_sources[@]}" | grep -Fx -- "$source" >/dev/null; then missing_kinematics_sources+=("$source") fi done if ((${#missing_kinematics_sources[@]} > 0)); then echo "manifest does not cover all LinuxCNC kinematics sources: $manifest" >&2 printf 'missing kinematics source: %s\n' "${missing_kinematics_sources[@]}" >&2 exit 1 fi mapfile -t m428_m430_remap_sources < <( find "$linuxcnc_root/configs" -path '*/remap_subs/*' -type f \ \( -name '428remap.ngc' -o -name '429remap.ngc' -o -name '430remap.ngc' \) \ | sed "s#^$linuxcnc_root/##" \ | sort ) mapfile -t manifest_m428_m430_remap_sources < <( awk -F: ' $1 !~ /^($|#)/ && $2 ~ /\/remap_subs\/(428|429|430)remap\.ngc$/ { print $2 } ' "$manifest" | sort -u ) missing_m428_m430_remap_sources=() for source in "${m428_m430_remap_sources[@]}"; do if ! printf '%s\n' "${manifest_m428_m430_remap_sources[@]}" | grep -Fx -- "$source" >/dev/null; then missing_m428_m430_remap_sources+=("$source") fi done if ((${#missing_m428_m430_remap_sources[@]} > 0)); then echo "manifest does not cover all LinuxCNC M428/M429/M430 remap sources: $manifest" >&2 printf 'missing M428/M429/M430 remap source: %s\n' "${missing_m428_m430_remap_sources[@]}" >&2 exit 1 fi mismatched_m428_m430_remap_notes=() for source in "${m428_m430_remap_sources[@]}"; do kinstype=$(sed -n 's/^[[:space:]]*#[[:space:]]*=[[:space:]]*\([0-9][0-9]*\).*/\1/p' "$linuxcnc_root/$source" | head -n 1) manifest_note=$(awk -F: -v path="$source" ' $1 !~ /^($|#)/ && $2 == path { print $3; exit } ' "$manifest") if [[ -z "$kinstype" || "$manifest_note" != *"kinstype $kinstype"* ]]; then mismatched_m428_m430_remap_notes+=("$source") fi done if ((${#mismatched_m428_m430_remap_notes[@]} > 0)); then echo "manifest M428/M429/M430 remap notes do not match LinuxCNC # assignments: $manifest" >&2 printf 'mismatched M428/M429/M430 remap note: %s\n' "${mismatched_m428_m430_remap_notes[@]}" >&2 exit 1 fi mapfile -t m428_m430_ini_sources < <( find "$linuxcnc_root/configs" -name '*.ini' -type f -print0 \ | while IFS= read -r -d '' source; do if grep -Eiq 'REMAP[[:space:]]*=[[:space:]]*M(428|429|430)([^0-9]|$)' "$source"; then printf '%s\n' "${source#"$linuxcnc_root/"}" fi done \ | sort ) mapfile -t manifest_m428_m430_ini_sources < <( awk -F: ' $1 !~ /^($|#)/ && $1 == "config" && $2 ~ /\.ini$/ { print $2 } ' "$manifest" | sort -u ) missing_m428_m430_ini_sources=() for source in "${m428_m430_ini_sources[@]}"; do if ! printf '%s\n' "${manifest_m428_m430_ini_sources[@]}" | grep -Fx -- "$source" >/dev/null; then missing_m428_m430_ini_sources+=("$source") fi done if ((${#missing_m428_m430_ini_sources[@]} > 0)); then echo "manifest does not cover all LinuxCNC INI files that declare M428/M429/M430 remaps: $manifest" >&2 printf 'missing M428/M429/M430 INI source: %s\n' "${missing_m428_m430_ini_sources[@]}" >&2 exit 1 fi fi