结论:已完成浏览器侧真实加载验证,M428/M429/M430 的配置入口进一步从 LinuxCNC INI/HALFILE/REMAP 来源生成,native 与 source-link 验证通过。
239 lines
6.8 KiB
Bash
Executable File
239 lines
6.8 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
set -euo pipefail
|
|
|
|
cd "$(dirname "$0")"
|
|
|
|
linuxcnc_root=${LINUXCNC_ROOT:-../linuxcnc}
|
|
manifest=${1:-linuxcnc-kinematics-source-files.txt}
|
|
|
|
if [[ ! -d "$linuxcnc_root" ]]; then
|
|
echo "missing LinuxCNC root: $linuxcnc_root" >&2
|
|
exit 1
|
|
fi
|
|
if [[ ! -f "$manifest" ]]; then
|
|
echo "missing kinematics manifest: $manifest" >&2
|
|
exit 1
|
|
fi
|
|
|
|
linuxcnc_root=$(cd "$linuxcnc_root" && pwd)
|
|
|
|
normalize_alias() {
|
|
tr '[:upper:]' '[:lower:]' | tr -d '[:space:]'
|
|
}
|
|
|
|
trim_value() {
|
|
sed 's/[[:space:]]*[#;].*$//; s/^[[:space:]]*//; s/[[:space:]]*$//'
|
|
}
|
|
|
|
ini_value() {
|
|
local file=$1
|
|
local key=$2
|
|
sed -n "s/^[[:space:]]*$key[[:space:]]*=[[:space:]]*//Ip" "$file" | head -n 1 | trim_value
|
|
}
|
|
|
|
ini_values() {
|
|
local file=$1
|
|
local key=$2
|
|
sed -n "s/^[[:space:]]*$key[[:space:]]*=[[:space:]]*//Ip" "$file" | trim_value
|
|
}
|
|
|
|
remap_ngc_name() {
|
|
local file=$1
|
|
local mcode=$2
|
|
sed -n "s/.*REMAP[[:space:]]*=[[:space:]]*M$mcode[[:space:]][^#;]*ngc[[:space:]]*=[[:space:]]*\\([^[:space:]#;]*\\).*/\\1/Ip" "$file" |
|
|
head -n 1
|
|
}
|
|
|
|
resolve_config_path() {
|
|
local config_dir=$1
|
|
local path=$2
|
|
if [[ "$path" = /* ]]; then
|
|
printf '%s\n' "$path"
|
|
else
|
|
printf '%s\n' "$config_dir/$path"
|
|
fi
|
|
}
|
|
|
|
relative_linuxcnc_path() {
|
|
local path=$1
|
|
path=$(cd "$(dirname "$path")" && pwd)/$(basename "$path")
|
|
printf '%s\n' "${path#"$linuxcnc_root/"}"
|
|
}
|
|
|
|
remap_source_for_mcode() {
|
|
local config=$1
|
|
local mcode=$2
|
|
local ngc_name
|
|
ngc_name=$(remap_ngc_name "$config" "$mcode")
|
|
if [[ -z "$ngc_name" ]]; then
|
|
return 1
|
|
fi
|
|
if [[ "$ngc_name" != *.ngc ]]; then
|
|
ngc_name="$ngc_name.ngc"
|
|
fi
|
|
|
|
local config_dir
|
|
config_dir=$(cd "$(dirname "$config")" && pwd)
|
|
local subroutine_paths
|
|
subroutine_paths=$(ini_values "$config" "SUBROUTINE_PATH")
|
|
if [[ -z "$subroutine_paths" ]]; then
|
|
subroutine_paths="."
|
|
fi
|
|
|
|
local subroutine_path
|
|
while IFS= read -r subroutine_path; do
|
|
[[ -n "$subroutine_path" ]] || continue
|
|
local path_part
|
|
IFS=: read -ra path_parts <<<"$subroutine_path"
|
|
for path_part in "${path_parts[@]}"; do
|
|
[[ -n "$path_part" ]] || continue
|
|
local candidate_dir
|
|
candidate_dir=$(resolve_config_path "$config_dir" "$path_part")
|
|
if [[ -f "$candidate_dir/$ngc_name" ]]; then
|
|
relative_linuxcnc_path "$candidate_dir/$ngc_name"
|
|
return 0
|
|
fi
|
|
done
|
|
done <<<"$subroutine_paths"
|
|
|
|
return 1
|
|
}
|
|
|
|
kinstype_for_mcode() {
|
|
local config=$1
|
|
local mcode=$2
|
|
local source
|
|
if ! source=$(remap_source_for_mcode "$config" "$mcode"); then
|
|
printf '%s\n' "-1"
|
|
return 0
|
|
fi
|
|
sed -n 's/^[[:space:]]*#<kinstype>[[:space:]]*=[[:space:]]*\([0-9][0-9]*\).*/\1/p' \
|
|
"$linuxcnc_root/$source" |
|
|
head -n 1
|
|
}
|
|
|
|
json_compact_string() {
|
|
local value=$1
|
|
printf '%s' "$value" | normalize_alias | sed 's/\\/\\\\/g; s/"/\\"/g'
|
|
}
|
|
|
|
declare -A seen_aliases=()
|
|
entries=()
|
|
|
|
add_alias() {
|
|
local alias=$1
|
|
local m428=$2
|
|
local m429=$3
|
|
local m430=$4
|
|
alias=$(json_compact_string "$alias")
|
|
[[ -n "$alias" ]] || return 0
|
|
|
|
local types="$m428,$m429,$m430"
|
|
if [[ -n "${seen_aliases[$alias]:-}" ]]; then
|
|
if [[ "${seen_aliases[$alias]}" != "$types" ]]; then
|
|
echo "ambiguous switchkins alias '$alias': ${seen_aliases[$alias]} and $types" >&2
|
|
exit 1
|
|
fi
|
|
return 0
|
|
fi
|
|
|
|
seen_aliases[$alias]=$types
|
|
entries+=(" {\"$alias\", $m428, $m429, $m430},")
|
|
}
|
|
|
|
add_machine_aliases() {
|
|
local machine=$1
|
|
local m428=$2
|
|
local m429=$3
|
|
local m430=$4
|
|
[[ -n "$machine" ]] || return 0
|
|
add_alias "$machine" "$m428" "$m429" "$m430"
|
|
add_alias "${machine%%(*}" "$m428" "$m429" "$m430"
|
|
}
|
|
|
|
add_kinematics_aliases() {
|
|
local kinematics=$1
|
|
local m428=$2
|
|
local m429=$3
|
|
local m430=$4
|
|
[[ -n "$kinematics" ]] || return 0
|
|
add_alias "$kinematics" "$m428" "$m429" "$m430"
|
|
|
|
local first_word=${kinematics%%[[:space:]]*}
|
|
add_alias "$first_word" "$m428" "$m429" "$m430"
|
|
add_alias "${first_word%_kins}" "$m428" "$m429" "$m430"
|
|
add_alias "${first_word%-kins}" "$m428" "$m429" "$m430"
|
|
add_alias "$(printf '%s' "$first_word" | tr '_' '-')" "$m428" "$m429" "$m430"
|
|
add_alias "$(printf '%s' "${first_word%_kins}" | tr '_' '-')" "$m428" "$m429" "$m430"
|
|
add_alias "$(printf '%s' "${first_word%-kins}" | tr '_' '-')" "$m428" "$m429" "$m430"
|
|
}
|
|
|
|
add_halfile_aliases() {
|
|
local halfile=$1
|
|
local m428=$2
|
|
local m429=$3
|
|
local m430=$4
|
|
[[ -n "$halfile" ]] || return 0
|
|
[[ "$halfile" == LIB:* ]] && return 0
|
|
add_alias "$halfile" "$m428" "$m429" "$m430"
|
|
local hal_base=${halfile##*/}
|
|
add_alias "$hal_base" "$m428" "$m429" "$m430"
|
|
add_alias "${hal_base%.hal}" "$m428" "$m429" "$m430"
|
|
}
|
|
|
|
while IFS=: read -r group path _note; do
|
|
[[ "$group" == "config" && "$path" == *.ini ]] || continue
|
|
|
|
config="$linuxcnc_root/$path"
|
|
[[ -f "$config" ]] || {
|
|
echo "missing LinuxCNC config source: $path" >&2
|
|
exit 1
|
|
}
|
|
if ! grep -Eiq 'REMAP[[:space:]]*=[[:space:]]*M(428|429|430)([^0-9]|$)' "$config"; then
|
|
continue
|
|
fi
|
|
|
|
m428=$(kinstype_for_mcode "$config" 428)
|
|
m429=$(kinstype_for_mcode "$config" 429)
|
|
m430=$(kinstype_for_mcode "$config" 430)
|
|
[[ -n "$m428" ]] || m428=-1
|
|
[[ -n "$m429" ]] || m429=-1
|
|
[[ -n "$m430" ]] || m430=-1
|
|
|
|
machine=$(ini_value "$config" "MACHINE")
|
|
kinematics=$(ini_value "$config" "KINEMATICS")
|
|
halfiles=$(ini_values "$config" "HALFILE")
|
|
config_dir=${path%/*}
|
|
config_base=${path##*/}
|
|
config_stem=${config_base%.ini}
|
|
|
|
add_alias "$path" "$m428" "$m429" "$m430"
|
|
add_alias "$config_dir" "$m428" "$m429" "$m430"
|
|
add_alias "${config_dir##*/}" "$m428" "$m429" "$m430"
|
|
add_alias "$config_stem" "$m428" "$m429" "$m430"
|
|
add_machine_aliases "$machine" "$m428" "$m429" "$m430"
|
|
add_kinematics_aliases "$kinematics" "$m428" "$m429" "$m430"
|
|
while IFS= read -r halfile; do
|
|
add_halfile_aliases "$halfile" "$m428" "$m429" "$m430"
|
|
done <<<"$halfiles"
|
|
|
|
for mcode in 428 429 430; do
|
|
if remap_source=$(remap_source_for_mcode "$config" "$mcode"); then
|
|
remap_dir=${remap_source%/*}
|
|
add_alias "$remap_dir" "$m428" "$m429" "$m430"
|
|
add_alias "${remap_dir%/*}" "$m428" "$m429" "$m430"
|
|
add_alias "${remap_dir%/remap_subs}" "$m428" "$m429" "$m430"
|
|
remap_parent=${remap_dir%/remap_subs}
|
|
add_alias "${remap_parent##*/}" "$m428" "$m429" "$m430"
|
|
fi
|
|
done
|
|
done <"$manifest"
|
|
|
|
cat <<'EOF'
|
|
// Generated by ./generate-linuxcnc-switchkins-remap-table.sh.
|
|
// Source: LinuxCNC INI MACHINE/KINEMATICS/HALFILE/SUBROUTINE_PATH/REMAP entries and
|
|
// adjacent remap_subs/{428,429,430}remap.ngc #<kinstype> assignments.
|
|
EOF
|
|
|
|
printf '%s\n' "${entries[@]}"
|