#!/usr/bin/env bash set -euo pipefail ROOT_DIR="$(cd "$(dirname "$0")/../.." && pwd)" BUILD_DIR="$ROOT_DIR/build/native" GCODE_FIXTURE_DIR="$ROOT_DIR/tests/fixtures/gcode" CANON_FIXTURE_DIR="$ROOT_DIR/tests/fixtures/canon" GCODE_ERROR_FIXTURE_DIR="$ROOT_DIR/tests/fixtures/gcode_errors" CANON_ERROR_FIXTURE_DIR="$ROOT_DIR/tests/fixtures/canon_errors" NAMEDPARAM_INI_FIXTURE="$ROOT_DIR/tests/fixtures/ini/namedparams.ini" "$ROOT_DIR/tools/verify_upstream_baseline.sh" "$ROOT_DIR/tools/verify_vendor_sync.sh" "$ROOT_DIR/tools/verify_no_standalone_cnc_semantics.sh" "$ROOT_DIR/tools/verify_native_linuxcnc_fixture_baseline.sh" "$ROOT_DIR/tools/build_native_probes.sh" check_source_probe_coverage() { local manifest_sources="$BUILD_DIR/source-manifest-sources.sorted" local probe_sources="$BUILD_DIR/source-probe-sources.sorted" local duplicate_probe_sources="$BUILD_DIR/source-probe-sources.duplicates" awk ' /^[[:space:]]*($|#)/ { next } /\.(c|cc)$/ { print } ' "$ROOT_DIR/tools/source-manifest.txt" | sort > "$manifest_sources" if [[ ! -f "$BUILD_DIR/source-probes.tsv" ]]; then echo "missing source probe map: $BUILD_DIR/source-probes.tsv" >&2 exit 1 fi cut -f1 "$BUILD_DIR/source-probes.tsv" | sort > "$probe_sources" uniq -d "$probe_sources" > "$duplicate_probe_sources" if [[ -s "$duplicate_probe_sources" ]]; then echo "duplicate source probe entries:" >&2 cat "$duplicate_probe_sources" >&2 exit 1 fi local missing_sources missing_sources="$(comm -23 "$manifest_sources" "$probe_sources")" if [[ -n "$missing_sources" ]]; then echo "manifest source files without source probes:" >&2 printf '%s\n' "$missing_sources" >&2 exit 1 fi local extra_sources extra_sources="$(comm -13 "$manifest_sources" "$probe_sources")" if [[ -n "$extra_sources" ]]; then echo "source probes not listed in manifest:" >&2 printf '%s\n' "$extra_sources" >&2 exit 1 fi } check_exitcode() { local name="$1" local file="$BUILD_DIR/$name.exitcode" if [[ ! -f "$file" ]]; then echo "missing exitcode: $file" >&2 exit 1 fi local rc rc="$(tr -d '[:space:]' < "$file")" if [[ "$rc" != "0" ]]; then echo "$name failed with exit code $rc" >&2 if [[ -f "$BUILD_DIR/$name.stderr.log" ]]; then sed -n '1,160p' "$BUILD_DIR/$name.stderr.log" >&2 fi exit 1 fi } check_source_probe_coverage check_exitcode linuxcnc_interp_state_probe check_exitcode linuxcnc_inifile_source_probe check_exitcode linuxcnc_tp_api_probe check_exitcode linuxcnc_tp_api_probe.run check_exitcode linuxcnc_kinematics_probe check_exitcode linuxcnc_kinematics_probe.run check_exitcode linuxcnc_5axis_kinematics_probe check_exitcode linuxcnc_5axis_kinematics_probe.run check_exitcode linuxcnc_xyzac_trt_kinematics_probe check_exitcode linuxcnc_xyzac_trt_kinematics_probe.run check_exitcode linuxcnc_xyzbc_trt_kinematics_probe check_exitcode linuxcnc_xyzbc_trt_kinematics_probe.run check_exitcode linuxcnc_corexy_kinematics_probe check_exitcode linuxcnc_corexy_kinematics_probe.run check_exitcode linuxcnc_rotate_kinematics_probe check_exitcode linuxcnc_rotate_kinematics_probe.run check_exitcode linuxcnc_rose_kinematics_probe check_exitcode linuxcnc_rose_kinematics_probe.run check_exitcode linuxcnc_max_kinematics_probe check_exitcode linuxcnc_max_kinematics_probe.run check_exitcode linuxcnc_lineardelta_kinematics_probe check_exitcode linuxcnc_lineardelta_kinematics_probe.run check_exitcode linuxcnc_rotarydelta_kinematics_probe check_exitcode linuxcnc_rotarydelta_kinematics_probe.run check_exitcode linuxcnc_scorbot_kinematics_probe check_exitcode linuxcnc_scorbot_kinematics_probe.run check_exitcode linuxcnc_tripod_kinematics_probe check_exitcode linuxcnc_tripod_kinematics_probe.run check_exitcode linuxcnc_scara_kinematics_probe check_exitcode linuxcnc_scara_kinematics_probe.run check_exitcode linuxcnc_puma_kinematics_probe check_exitcode linuxcnc_puma_kinematics_probe.run check_exitcode linuxcnc_genser_kinematics_probe check_exitcode linuxcnc_genser_kinematics_probe.run check_exitcode linuxcnc_genhex_kinematics_probe check_exitcode linuxcnc_genhex_kinematics_probe.run check_exitcode linuxcnc_pentakins_kinematics_probe check_exitcode linuxcnc_pentakins_kinematics_probe.run for name in \ linuxcnc_tp_tp_source_probe \ linuxcnc_tp_tc_source_probe \ linuxcnc_tp_tcq_source_probe \ linuxcnc_tp_spherical_arc_source_probe \ linuxcnc_tp_blendmath_source_probe \ linuxcnc_tp_sp_scurve_source_probe \ linuxcnc_tp_ruckig_wrapper_source_probe \ linuxcnc_cruckig_block_source_probe \ linuxcnc_cruckig_brake_source_probe \ linuxcnc_cruckig_calculator_source_probe \ linuxcnc_cruckig_cruckig_source_probe \ linuxcnc_cruckig_input_parameter_source_probe \ linuxcnc_cruckig_output_parameter_source_probe \ linuxcnc_cruckig_profile_source_probe \ linuxcnc_cruckig_roots_source_probe \ linuxcnc_cruckig_trajectory_source_probe \ linuxcnc_cruckig_position_first_step1_source_probe \ linuxcnc_cruckig_position_first_step2_source_probe \ linuxcnc_cruckig_position_second_step1_source_probe \ linuxcnc_cruckig_position_second_step2_source_probe \ linuxcnc_cruckig_position_third_step1_source_probe \ linuxcnc_cruckig_position_third_step2_source_probe \ linuxcnc_cruckig_velocity_second_step1_source_probe \ linuxcnc_cruckig_velocity_second_step2_source_probe \ linuxcnc_cruckig_velocity_third_step1_source_probe \ linuxcnc_cruckig_velocity_third_step2_source_probe \ linuxcnc_emcpose_source_probe \ linuxcnc_posemath_source_probe \ linuxcnc_posemath_c_source_probe \ linuxcnc_sincos_source_probe; do check_exitcode "$name" done check_exitcode linuxcnc_namedparam_harness check_exitcode linuxcnc_namedparam_harness.run check_exitcode linuxcnc_interp_minimal_harness check_exitcode linuxcnc_interp_minimal_harness.run check_exitcode linuxcnc_parameter_file_harness check_exitcode linuxcnc_parameter_file_harness.run check_exitcode linuxcnc_interp_init_harness check_exitcode linuxcnc_interp_init_harness.run check_exitcode linuxcnc_indexer_harness check_exitcode linuxcnc_indexer_harness.run check_exitcode linuxcnc_rs274_compile_probe check_exitcode linuxcnc_kins_util_source_probe check_exitcode linuxcnc_cubic_source_probe check_exitcode linuxcnc_trivkins_source_probe check_exitcode linuxcnc_switchkins_source_probe check_exitcode linuxcnc_userkfuncs_source_probe check_exitcode linuxcnc_5axiskins_source_probe check_exitcode linuxcnc_trtfuncs_source_probe check_exitcode linuxcnc_xyzac_trt_kins_source_probe check_exitcode linuxcnc_xyzbc_trt_kins_source_probe check_exitcode linuxcnc_corexykins_source_probe check_exitcode linuxcnc_rotatekins_source_probe check_exitcode linuxcnc_rosekins_source_probe check_exitcode linuxcnc_maxkins_source_probe check_exitcode linuxcnc_lineardeltakins_source_probe check_exitcode linuxcnc_rotarydeltakins_source_probe check_exitcode linuxcnc_scorbot_kins_source_probe check_exitcode linuxcnc_tripodkins_source_probe check_exitcode linuxcnc_scarakins_source_probe check_exitcode linuxcnc_pumakins_source_probe check_exitcode linuxcnc_genhexkins_source_probe check_exitcode linuxcnc_genserfuncs_source_probe check_exitcode linuxcnc_genserkins_source_probe check_exitcode linuxcnc_ugenserkins_source_probe check_exitcode linuxcnc_pentakins_source_probe check_exitcode linuxcnc_interp_convert_source_probe check_exitcode linuxcnc_interp_read_source_probe check_exitcode linuxcnc_interp_check_source_probe check_exitcode linuxcnc_interp_execute_source_probe check_exitcode linuxcnc_modal_state_source_probe check_exitcode linuxcnc_interp_array_source_probe check_exitcode linuxcnc_interp_internal_source_probe check_exitcode linuxcnc_interp_arc_source_probe check_exitcode linuxcnc_interp_inverse_source_probe check_exitcode linuxcnc_interp_cycles_source_probe check_exitcode linuxcnc_interp_g7x_source_probe check_exitcode linuxcnc_interp_queue_source_probe check_exitcode linuxcnc_interp_find_source_probe check_exitcode linuxcnc_interp_namedparams_source_probe check_exitcode linuxcnc_interp_write_source_probe check_exitcode linuxcnc_interp_o_word_source_probe check_exitcode linuxcnc_rs274ngc_pre_source_probe check_exitcode linuxcnc_interp_base_source_probe check_exitcode linuxcnc_gomath_source_probe NAMEDPARAM_STDOUT="$BUILD_DIR/linuxcnc_namedparam_harness.run.stdout.log" grep -Fq "init_named_parameters=0" "$NAMEDPARAM_STDOUT" grep -Fq "global_named_count=57" "$NAMEDPARAM_STDOUT" grep -Fq "_metric_machine: rc=0 found=1 value=1" "$NAMEDPARAM_STDOUT" grep -Fq "_motion_mode: rc=0 found=1 value=10" "$NAMEDPARAM_STDOUT" grep -Fq "_metric: rc=0 found=1 value=1" "$NAMEDPARAM_STDOUT" grep -Fq "_feed: rc=0 found=1 value=123.45" "$NAMEDPARAM_STDOUT" grep -Fq "_rpm: rc=0 found=1 value=678.9" "$NAMEDPARAM_STDOUT" grep -Fq "_x: rc=0 found=1 value=1.25" "$NAMEDPARAM_STDOUT" grep -Fq "_current_tool: rc=0 found=1 value=12" "$NAMEDPARAM_STDOUT" grep -Fq "_ini[traj]max_linear_velocity: rc=0 found=1 value=35" "$NAMEDPARAM_STDOUT" grep -Fq "_hal[standalone.pin-bit]: rc=0 found=1 value=1" "$NAMEDPARAM_STDOUT" grep -Fq "_hal[standalone.signal-float]: rc=0 found=1 value=98.25" "$NAMEDPARAM_STDOUT" grep -Fq "_hal[standalone.param-s32]: rc=0 found=1 value=-17" "$NAMEDPARAM_STDOUT" grep -Fq "_hal[standalone.pin-u32]: rc=0 found=1 value=1.23457e+08" "$NAMEDPARAM_STDOUT" grep -Fq "_hal[standalone.signal-s64]: rc=0 found=1 value=-9e+09" "$NAMEDPARAM_STDOUT" grep -Fq "_hal[standalone.param-u64]: rc=0 found=1 value=9e+09" "$NAMEDPARAM_STDOUT" grep -Fq "_hal[standalone.disconnected-float]: rc=0 found=1 value=12.5" "$NAMEDPARAM_STDOUT" grep -Fq "_hal[standalone.missing]: rc=0 found=0 value=0" "$NAMEDPARAM_STDOUT" PARAMETER_FILE_STDOUT="$BUILD_DIR/linuxcnc_parameter_file_harness.run.stdout.log" grep -Fq "restore_existing=0" "$PARAMETER_FILE_STDOUT" grep -Fq "parameter_5161=10.5" "$PARAMETER_FILE_STDOUT" grep -Fq "parameter_5162=20.25" "$PARAMETER_FILE_STDOUT" grep -Fq "parameter_5220=1" "$PARAMETER_FILE_STDOUT" grep -Fq "parameter_5221=2.25" "$PARAMETER_FILE_STDOUT" grep -Fq "parameter_5399=44" "$PARAMETER_FILE_STDOUT" grep -Fq "restore_missing_file=0" "$PARAMETER_FILE_STDOUT" grep -Fq "restore_out_of_order=5" "$PARAMETER_FILE_STDOUT" grep -Fq "restore_out_of_order_error=Parameter file out of order" "$PARAMETER_FILE_STDOUT" grep -Fq "restore_missing_required=0" "$PARAMETER_FILE_STDOUT" grep -Fq "missing_required_5161=3.5" "$PARAMETER_FILE_STDOUT" grep -Fq "missing_required_5162=0" "$PARAMETER_FILE_STDOUT" grep -Fq "save_parameters=0" "$PARAMETER_FILE_STDOUT" grep -Fq "saved_has_5161=1" "$PARAMETER_FILE_STDOUT" grep -Fq "saved_has_5162=1" "$PARAMETER_FILE_STDOUT" grep -Fq "saved_has_5221=1" "$PARAMETER_FILE_STDOUT" grep -Fq "saved_has_5399=1" "$PARAMETER_FILE_STDOUT" grep -Fq "saved_has_named_param=0" "$PARAMETER_FILE_STDOUT" grep -Fq "backup_has_original_5161=1" "$PARAMETER_FILE_STDOUT" INIT_HARNESS_STDOUT="$BUILD_DIR/linuxcnc_interp_init_harness.run.stdout.log" grep -Fq "init=0" "$INIT_HARNESS_STDOUT" grep -Fq "setup.length_units=2" "$INIT_HARNESS_STDOUT" grep -Fq "setup.origin_index=1" "$INIT_HARNESS_STDOUT" grep -Fq "setup.distance_mode=0" "$INIT_HARNESS_STDOUT" grep -Fq "setup.feed_mode=0" "$INIT_HARNESS_STDOUT" grep -Fq "setup.motion_mode=800" "$INIT_HARNESS_STDOUT" grep -Fq "canon_event=INIT_CANON" "$INIT_HARNESS_STDOUT" grep -Fq "canon_event=USE_LENGTH_UNITS units=2" "$INIT_HARNESS_STDOUT" grep -Fq "canon_event=SET_G5X_OFFSET index=1" "$INIT_HARNESS_STDOUT" grep -Fq "canon_event=SET_G92_OFFSET x=0 y=0 z=0" "$INIT_HARNESS_STDOUT" grep -Fq "canon_event=SET_XY_ROTATION rotation=0" "$INIT_HARNESS_STDOUT" grep -Fq "canon_event=SET_FEED_REFERENCE reference=2" "$INIT_HARNESS_STDOUT" INDEXER_HARNESS_STDOUT="$BUILD_DIR/linuxcnc_indexer_harness.run.stdout.log" grep -Fq "execute=0" "$INDEXER_HARNESS_STDOUT" grep -Fq "post_a=90" "$INDEXER_HARNESS_STDOUT" grep -Fq "canon_event=SET_MOTION_CONTROL_MODE mode=2 tolerance=0" "$INDEXER_HARNESS_STDOUT" grep -Fq "canon_event=UNLOCK_ROTARY line=1 joint=0" "$INDEXER_HARNESS_STDOUT" grep -Fq "canon_event=STRAIGHT_TRAVERSE line=1 x=0 y=0 z=0 a=90 b=0 c=0 u=0 v=0 w=0" "$INDEXER_HARNESS_STDOUT" grep -Fq "canon_event=LOCK_ROTARY line=1 joint=0" "$INDEXER_HARNESS_STDOUT" grep -Fq "canon_event=SET_MOTION_CONTROL_MODE mode=1 tolerance=0" "$INDEXER_HARNESS_STDOUT" grep -Fq "canon_event=SET_NAIVECAM_TOLERANCE tolerance=0" "$INDEXER_HARNESS_STDOUT" grep -Fq "canon_event=UPDATE_TAG line=1" "$INDEXER_HARNESS_STDOUT" TP_API_STDOUT="$BUILD_DIR/linuxcnc_tp_api_probe.run.stdout.log" grep -Fq "tp_default_queue_size=32" "$TP_API_STDOUT" grep -Fq "tp_err_ok=0" "$TP_API_STDOUT" grep -Fq "tc_linear=1" "$TP_API_STDOUT" grep -Fq "tc_circular=2" "$TP_API_STDOUT" grep -Fq "pose_xyz=1,2,3" "$TP_API_STDOUT" grep -Fq "tp_create=0" "$TP_API_STDOUT" grep -Fq "tp_set_cycle_time=0" "$TP_API_STDOUT" grep -Fq "tp_add_line=0" "$TP_API_STDOUT" grep -Fq "tp_done_after_line=1" "$TP_API_STDOUT" grep -Fq "tp_final_pos=1,0,0" "$TP_API_STDOUT" grep -Fq "tp_add_circle=0" "$TP_API_STDOUT" grep -Fq "tp_done_after_arc=1" "$TP_API_STDOUT" grep -Fq "tp_arc_final_pos_near_end=1" "$TP_API_STDOUT" grep -Fq "tp_queue_add_line1=0" "$TP_API_STDOUT" grep -Fq "tp_queue_depth_after_line1=1" "$TP_API_STDOUT" grep -Fq "tp_queue_add_line2=0" "$TP_API_STDOUT" grep -Fq "tp_queue_depth_after_line2=2" "$TP_API_STDOUT" grep -Fq "tp_done_after_queued_lines=1" "$TP_API_STDOUT" grep -Fq "tp_queue_final_depth=0" "$TP_API_STDOUT" grep -Fq "tp_queue_final_pos_near_end=1" "$TP_API_STDOUT" KINEMATICS_STDOUT="$BUILD_DIR/linuxcnc_kinematics_probe.run.stdout.log" grep -Fq "kinematics_init=0" "$KINEMATICS_STDOUT" grep -Fq "kinematics_type=1" "$KINEMATICS_STDOUT" grep -Fq "kinematics_switchable=0" "$KINEMATICS_STDOUT" grep -Fq "kinematics_switch=0" "$KINEMATICS_STDOUT" grep -Fq "kinematics_forward=0" "$KINEMATICS_STDOUT" grep -Fq "kinematics_forward_xyz=1,2,3" "$KINEMATICS_STDOUT" grep -Fq "kinematics_forward_abcuvw=4,5,6,7,8,9" "$KINEMATICS_STDOUT" grep -Fq "kinematics_inverse=0" "$KINEMATICS_STDOUT" grep -Fq "kinematics_inverse_xyz=10,20,30" "$KINEMATICS_STDOUT" grep -Fq "kinematics_inverse_abcuvw=40,50,60,70,80,90" "$KINEMATICS_STDOUT" FIVEAXIS_KINEMATICS_STDOUT="$BUILD_DIR/linuxcnc_5axis_kinematics_probe.run.stdout.log" grep -Fq "fiveaxis_init=0" "$FIVEAXIS_KINEMATICS_STDOUT" grep -Fq "fiveaxis_type=4" "$FIVEAXIS_KINEMATICS_STDOUT" grep -Fq "fiveaxis_switchable=1" "$FIVEAXIS_KINEMATICS_STDOUT" grep -Fq "fiveaxis_forward=0" "$FIVEAXIS_KINEMATICS_STDOUT" grep -Fq "fiveaxis_inverse=0" "$FIVEAXIS_KINEMATICS_STDOUT" grep -Fq "fiveaxis_roundtrip_joints=1" "$FIVEAXIS_KINEMATICS_STDOUT" grep -Fq "fiveaxis_switch_identity=0" "$FIVEAXIS_KINEMATICS_STDOUT" grep -Fq "fiveaxis_identity_forward=0" "$FIVEAXIS_KINEMATICS_STDOUT" grep -Fq "fiveaxis_identity_near=1" "$FIVEAXIS_KINEMATICS_STDOUT" XYZAC_TRT_KINEMATICS_STDOUT="$BUILD_DIR/linuxcnc_xyzac_trt_kinematics_probe.run.stdout.log" grep -Fq "xyzac_trt_init=0" "$XYZAC_TRT_KINEMATICS_STDOUT" grep -Fq "xyzac_trt_type=4" "$XYZAC_TRT_KINEMATICS_STDOUT" grep -Fq "xyzac_trt_switchable=1" "$XYZAC_TRT_KINEMATICS_STDOUT" grep -Fq "xyzac_trt_forward=0" "$XYZAC_TRT_KINEMATICS_STDOUT" grep -Fq "xyzac_trt_inverse=0" "$XYZAC_TRT_KINEMATICS_STDOUT" grep -Fq "xyzac_trt_roundtrip_joints=1" "$XYZAC_TRT_KINEMATICS_STDOUT" grep -Fq "xyzac_trt_switch_identity=0" "$XYZAC_TRT_KINEMATICS_STDOUT" grep -Fq "xyzac_trt_identity_forward=0" "$XYZAC_TRT_KINEMATICS_STDOUT" grep -Fq "xyzac_trt_identity_near=1" "$XYZAC_TRT_KINEMATICS_STDOUT" XYZBC_TRT_KINEMATICS_STDOUT="$BUILD_DIR/linuxcnc_xyzbc_trt_kinematics_probe.run.stdout.log" grep -Fq "xyzbc_trt_init=0" "$XYZBC_TRT_KINEMATICS_STDOUT" grep -Fq "xyzbc_trt_type=4" "$XYZBC_TRT_KINEMATICS_STDOUT" grep -Fq "xyzbc_trt_switchable=1" "$XYZBC_TRT_KINEMATICS_STDOUT" grep -Fq "xyzbc_trt_forward=0" "$XYZBC_TRT_KINEMATICS_STDOUT" grep -Fq "xyzbc_trt_inverse=0" "$XYZBC_TRT_KINEMATICS_STDOUT" grep -Fq "xyzbc_trt_roundtrip_joints=1" "$XYZBC_TRT_KINEMATICS_STDOUT" grep -Fq "xyzbc_trt_switch_identity=0" "$XYZBC_TRT_KINEMATICS_STDOUT" grep -Fq "xyzbc_trt_identity_forward=0" "$XYZBC_TRT_KINEMATICS_STDOUT" grep -Fq "xyzbc_trt_identity_near=1" "$XYZBC_TRT_KINEMATICS_STDOUT" COREXY_KINEMATICS_STDOUT="$BUILD_DIR/linuxcnc_corexy_kinematics_probe.run.stdout.log" grep -Fq "corexy_init=0" "$COREXY_KINEMATICS_STDOUT" grep -Fq "corexy_type=4" "$COREXY_KINEMATICS_STDOUT" grep -Fq "corexy_switchable=0" "$COREXY_KINEMATICS_STDOUT" grep -Fq "corexy_forward=0" "$COREXY_KINEMATICS_STDOUT" grep -Fq "corexy_inverse=0" "$COREXY_KINEMATICS_STDOUT" grep -Fq "corexy_roundtrip_joints=1" "$COREXY_KINEMATICS_STDOUT" ROTATE_KINEMATICS_STDOUT="$BUILD_DIR/linuxcnc_rotate_kinematics_probe.run.stdout.log" grep -Fq "rotate_init=0" "$ROTATE_KINEMATICS_STDOUT" grep -Fq "rotate_type=4" "$ROTATE_KINEMATICS_STDOUT" grep -Fq "rotate_switchable=0" "$ROTATE_KINEMATICS_STDOUT" grep -Fq "rotate_forward=0" "$ROTATE_KINEMATICS_STDOUT" grep -Fq "rotate_inverse=0" "$ROTATE_KINEMATICS_STDOUT" grep -Fq "rotate_roundtrip_joints=1" "$ROTATE_KINEMATICS_STDOUT" ROSE_KINEMATICS_STDOUT="$BUILD_DIR/linuxcnc_rose_kinematics_probe.run.stdout.log" grep -Fq "rose_init=0" "$ROSE_KINEMATICS_STDOUT" grep -Fq "rose_type=4" "$ROSE_KINEMATICS_STDOUT" grep -Fq "rose_switchable=0" "$ROSE_KINEMATICS_STDOUT" grep -Fq "rose_forward=0" "$ROSE_KINEMATICS_STDOUT" grep -Fq "rose_inverse=0" "$ROSE_KINEMATICS_STDOUT" grep -Fq "rose_roundtrip_joints=1" "$ROSE_KINEMATICS_STDOUT" MAX_KINEMATICS_STDOUT="$BUILD_DIR/linuxcnc_max_kinematics_probe.run.stdout.log" grep -Fq "max_init=0" "$MAX_KINEMATICS_STDOUT" grep -Fq "max_type=4" "$MAX_KINEMATICS_STDOUT" grep -Fq "max_switchable=0" "$MAX_KINEMATICS_STDOUT" grep -Fq "max_forward=0" "$MAX_KINEMATICS_STDOUT" grep -Fq "max_inverse=0" "$MAX_KINEMATICS_STDOUT" grep -Fq "max_roundtrip_joints=1" "$MAX_KINEMATICS_STDOUT" LINEARDELTA_KINEMATICS_STDOUT="$BUILD_DIR/linuxcnc_lineardelta_kinematics_probe.run.stdout.log" grep -Fq "lineardelta_init=0" "$LINEARDELTA_KINEMATICS_STDOUT" grep -Fq "lineardelta_type=4" "$LINEARDELTA_KINEMATICS_STDOUT" grep -Fq "lineardelta_switchable=0" "$LINEARDELTA_KINEMATICS_STDOUT" grep -Fq "lineardelta_inverse=0" "$LINEARDELTA_KINEMATICS_STDOUT" grep -Fq "lineardelta_forward=0" "$LINEARDELTA_KINEMATICS_STDOUT" grep -Fq "lineardelta_roundtrip_pose=1" "$LINEARDELTA_KINEMATICS_STDOUT" ROTARYDELTA_KINEMATICS_STDOUT="$BUILD_DIR/linuxcnc_rotarydelta_kinematics_probe.run.stdout.log" grep -Fq "rotarydelta_init=0" "$ROTARYDELTA_KINEMATICS_STDOUT" grep -Fq "rotarydelta_type=4" "$ROTARYDELTA_KINEMATICS_STDOUT" grep -Fq "rotarydelta_switchable=0" "$ROTARYDELTA_KINEMATICS_STDOUT" grep -Fq "rotarydelta_inverse=0" "$ROTARYDELTA_KINEMATICS_STDOUT" grep -Fq "rotarydelta_forward=0" "$ROTARYDELTA_KINEMATICS_STDOUT" grep -Fq "rotarydelta_roundtrip_pose=1" "$ROTARYDELTA_KINEMATICS_STDOUT" SCORBOT_KINEMATICS_STDOUT="$BUILD_DIR/linuxcnc_scorbot_kinematics_probe.run.stdout.log" grep -Fq "scorbot_init=0" "$SCORBOT_KINEMATICS_STDOUT" grep -Fq "scorbot_type=4" "$SCORBOT_KINEMATICS_STDOUT" grep -Fq "scorbot_switchable=0" "$SCORBOT_KINEMATICS_STDOUT" grep -Fq "scorbot_forward=0" "$SCORBOT_KINEMATICS_STDOUT" grep -Fq "scorbot_inverse=0" "$SCORBOT_KINEMATICS_STDOUT" grep -Fq "scorbot_roundtrip_forward=0" "$SCORBOT_KINEMATICS_STDOUT" grep -Fq "scorbot_roundtrip_pose=1" "$SCORBOT_KINEMATICS_STDOUT" TRIPOD_KINEMATICS_STDOUT="$BUILD_DIR/linuxcnc_tripod_kinematics_probe.run.stdout.log" grep -Fq "tripod_init=0" "$TRIPOD_KINEMATICS_STDOUT" grep -Fq "tripod_type=4" "$TRIPOD_KINEMATICS_STDOUT" grep -Fq "tripod_switchable=0" "$TRIPOD_KINEMATICS_STDOUT" grep -Fq "tripod_inverse=0" "$TRIPOD_KINEMATICS_STDOUT" grep -Fq "tripod_inverse_flags=0" "$TRIPOD_KINEMATICS_STDOUT" grep -Fq "tripod_forward=0" "$TRIPOD_KINEMATICS_STDOUT" grep -Fq "tripod_roundtrip_xyz=1" "$TRIPOD_KINEMATICS_STDOUT" grep -Fq "tripod_inverse_below=0" "$TRIPOD_KINEMATICS_STDOUT" grep -Fq "tripod_inverse_below_flags=1" "$TRIPOD_KINEMATICS_STDOUT" grep -Fq "tripod_forward_below=0" "$TRIPOD_KINEMATICS_STDOUT" grep -Fq "tripod_roundtrip_below_xyz=1" "$TRIPOD_KINEMATICS_STDOUT" SCARA_KINEMATICS_STDOUT="$BUILD_DIR/linuxcnc_scara_kinematics_probe.run.stdout.log" grep -Fq "scara_init=0" "$SCARA_KINEMATICS_STDOUT" grep -Fq "scara_type=4" "$SCARA_KINEMATICS_STDOUT" grep -Fq "scara_switchable=1" "$SCARA_KINEMATICS_STDOUT" grep -Fq "scara_forward=0" "$SCARA_KINEMATICS_STDOUT" grep -Fq "scara_forward_iflags=0" "$SCARA_KINEMATICS_STDOUT" grep -Fq "scara_inverse=0" "$SCARA_KINEMATICS_STDOUT" grep -Fq "scara_roundtrip_joints=1" "$SCARA_KINEMATICS_STDOUT" grep -Fq "scara_switch_identity=0" "$SCARA_KINEMATICS_STDOUT" grep -Fq "scara_identity_forward=0" "$SCARA_KINEMATICS_STDOUT" grep -Fq "scara_identity_near=1" "$SCARA_KINEMATICS_STDOUT" PUMA_KINEMATICS_STDOUT="$BUILD_DIR/linuxcnc_puma_kinematics_probe.run.stdout.log" grep -Fq "puma_init=0" "$PUMA_KINEMATICS_STDOUT" grep -Fq "puma_type=4" "$PUMA_KINEMATICS_STDOUT" grep -Fq "puma_switchable=1" "$PUMA_KINEMATICS_STDOUT" grep -Fq "puma_forward=0" "$PUMA_KINEMATICS_STDOUT" grep -Fq "puma_inverse=0" "$PUMA_KINEMATICS_STDOUT" grep -Fq "puma_roundtrip_forward=0" "$PUMA_KINEMATICS_STDOUT" grep -Fq "puma_roundtrip_pose=1" "$PUMA_KINEMATICS_STDOUT" grep -Fq "puma_switch_identity=0" "$PUMA_KINEMATICS_STDOUT" grep -Fq "puma_identity_forward=0" "$PUMA_KINEMATICS_STDOUT" grep -Fq "puma_identity_near=1" "$PUMA_KINEMATICS_STDOUT" GENSER_KINEMATICS_STDOUT="$BUILD_DIR/linuxcnc_genser_kinematics_probe.run.stdout.log" grep -Fq "genser_init=0" "$GENSER_KINEMATICS_STDOUT" grep -Fq "genser_type=4" "$GENSER_KINEMATICS_STDOUT" grep -Fq "genser_switchable=1" "$GENSER_KINEMATICS_STDOUT" grep -Fq "genser_forward=0" "$GENSER_KINEMATICS_STDOUT" grep -Fq "genser_inverse=0" "$GENSER_KINEMATICS_STDOUT" grep -Fq "genser_roundtrip_joints=1" "$GENSER_KINEMATICS_STDOUT" grep -Fq "genser_roundtrip_uvw=1" "$GENSER_KINEMATICS_STDOUT" grep -Fq "genser_switch_identity=0" "$GENSER_KINEMATICS_STDOUT" grep -Fq "genser_identity_forward=0" "$GENSER_KINEMATICS_STDOUT" grep -Fq "genser_identity_near=1" "$GENSER_KINEMATICS_STDOUT" GENHEX_KINEMATICS_STDOUT="$BUILD_DIR/linuxcnc_genhex_kinematics_probe.run.stdout.log" grep -Fq "genhex_init=0" "$GENHEX_KINEMATICS_STDOUT" grep -Fq "genhex_type=4" "$GENHEX_KINEMATICS_STDOUT" grep -Fq "genhex_switchable=1" "$GENHEX_KINEMATICS_STDOUT" grep -Fq "genhex_inverse=0" "$GENHEX_KINEMATICS_STDOUT" grep -Fq "genhex_forward_warmup=-1" "$GENHEX_KINEMATICS_STDOUT" grep -Fq "genhex_forward=0" "$GENHEX_KINEMATICS_STDOUT" grep -Fq "genhex_roundtrip_pose=1" "$GENHEX_KINEMATICS_STDOUT" grep -Fq "genhex_switch_identity=0" "$GENHEX_KINEMATICS_STDOUT" grep -Fq "genhex_identity_forward=0" "$GENHEX_KINEMATICS_STDOUT" grep -Fq "genhex_identity_near=1" "$GENHEX_KINEMATICS_STDOUT" PENTAKINS_KINEMATICS_STDOUT="$BUILD_DIR/linuxcnc_pentakins_kinematics_probe.run.stdout.log" grep -Fq "pentakins_init=0" "$PENTAKINS_KINEMATICS_STDOUT" grep -Fq "pentakins_type=4" "$PENTAKINS_KINEMATICS_STDOUT" grep -Fq "pentakins_switchable=0" "$PENTAKINS_KINEMATICS_STDOUT" grep -Fq "pentakins_inverse=0" "$PENTAKINS_KINEMATICS_STDOUT" grep -Fq "pentakins_positive_struts=1" "$PENTAKINS_KINEMATICS_STDOUT" grep -Fq "pentakins_forward=0" "$PENTAKINS_KINEMATICS_STDOUT" grep -Fq "pentakins_roundtrip_pose=1" "$PENTAKINS_KINEMATICS_STDOUT" check_fixture_output() { local fixture="$1" local expected="$2" local stdout_file="$3" local require_mdi="${4:-1}" if [[ "$require_mdi" == "1" ]]; then grep -Fq "read=0" "$stdout_file" grep -Fq "parse_line=0" "$stdout_file" local line_count line_count="$(grep -cv '^[[:space:]]*$' "$fixture")" local line_number for ((line_number = 1; line_number <= line_count; line_number += 1)); do if ! grep -Fq "execute_line_${line_number}=0" "$stdout_file" && ! grep -Fq "execute_line_${line_number}=1" "$stdout_file" && ! grep -Fq "execute_line_${line_number}=2" "$stdout_file"; then echo "missing successful execute status for line $line_number in $stdout_file" >&2 exit 1 fi done else grep -Fq "file_open=0" "$stdout_file" grep -Fq "file_execute_1=0" "$stdout_file" fi while IFS= read -r expected_event; do [[ -z "$expected_event" ]] && continue grep -Fq "$expected_event" "$stdout_file" done < "$expected" } RUN_STDOUT="$BUILD_DIR/linuxcnc_interp_minimal_harness.run.stdout.log" check_fixture_output \ "$GCODE_FIXTURE_DIR/minimal_linear.ngc" \ "$CANON_FIXTURE_DIR/minimal_linear.events" \ "$RUN_STDOUT" for fixture in "$GCODE_FIXTURE_DIR"/*.ngc; do name="$(basename "$fixture" .ngc)" expected="$CANON_FIXTURE_DIR/$name.events" if [[ ! -f "$expected" ]]; then echo "missing expected canon fixture: $expected" >&2 exit 1 fi stdout_file="$BUILD_DIR/linuxcnc_interp_minimal_harness.$name.stdout.log" stderr_file="$BUILD_DIR/linuxcnc_interp_minimal_harness.$name.stderr.log" INI_FILE_NAME="$NAMEDPARAM_INI_FIXTURE" "$BUILD_DIR/linuxcnc_interp_minimal_harness" "$fixture" \ >"$stdout_file" \ 2>"$stderr_file" require_mdi=1 if [[ "$name" == "oword_subroutine" || "$name" == "percent_file_finish" ]]; then require_mdi=0 fi check_fixture_output "$fixture" "$expected" "$stdout_file" "$require_mdi" done for fixture in "$GCODE_ERROR_FIXTURE_DIR"/*.ngc; do name="$(basename "$fixture" .ngc)" expected="$CANON_ERROR_FIXTURE_DIR/$name.expected" if [[ ! -f "$expected" ]]; then echo "missing expected error fixture: $expected" >&2 exit 1 fi stdout_file="$BUILD_DIR/linuxcnc_interp_minimal_harness.$name.stdout.log" stderr_file="$BUILD_DIR/linuxcnc_interp_minimal_harness.$name.stderr.log" INI_FILE_NAME="$NAMEDPARAM_INI_FIXTURE" "$BUILD_DIR/linuxcnc_interp_minimal_harness" "$fixture" \ >"$stdout_file" \ 2>"$stderr_file" while IFS= read -r expected_line; do [[ -z "$expected_line" ]] && continue if [[ "$expected_line" == absent=* ]]; then forbidden="${expected_line#absent=}" if grep -Fq "$forbidden" "$stdout_file"; then echo "unexpected output in $stdout_file: $forbidden" >&2 exit 1 fi elif [[ "$expected_line" == error_text=* ]]; then grep -Fq "$expected_line" "$stdout_file" else grep -Fq "$expected_line" "$stdout_file" fi done < "$expected" done echo "native probe validation complete"