diff --git a/wasm-port/docs/porting-steps-standalone.md b/wasm-port/docs/porting-steps-standalone.md index ae2c29a..4492279 100644 --- a/wasm-port/docs/porting-steps-standalone.md +++ b/wasm-port/docs/porting-steps-standalone.md @@ -365,6 +365,11 @@ Current verified progress: current-position parameter visibility for `#5420`, `#5421`, and `#5422`. The parameter source basis is LinuxCNC `interp_parameter_def.hh` and `interp_namedparams.cc`. +- `tests/fixtures/gcode_errors/g1_zero_feed.ngc` and + `tests/fixtures/canon_errors/g1_zero_feed.expected` pin the negative + `G1` zero-feed case. The source basis is LinuxCNC + `interp_convert.cc::convert_straight()` and + `rs274ngc_return.hh::NCE_CANNOT_DO_G1_WITH_ZERO_FEED_RATE`. - This proves the current extracted interpreter slice can parse and execute a simple traverse and feed move through a standalone canonical event sink. @@ -667,7 +672,7 @@ traverse path: 1. replace the temporary minimal `convert_g()` implementation with thin wrappers around more vendored interpreter conversion code, -2. add a negative fixture for `G1` without feed rate to start pinning error - semantics, +2. add `_x`/`_y`/`_z` named parameter fixture coverage and align it with + `#5420`/`#5421`/`#5422`, 3. keep all source changes inside `wasm-port/` and leave `../linuxcnc/` read-only. diff --git a/wasm-port/runtime/core/linuxcnc_wrap/linuxcnc_interp_minimal_runtime.cpp b/wasm-port/runtime/core/linuxcnc_wrap/linuxcnc_interp_minimal_runtime.cpp index 161673f..5f38c7a 100644 --- a/wasm-port/runtime/core/linuxcnc_wrap/linuxcnc_interp_minimal_runtime.cpp +++ b/wasm-port/runtime/core/linuxcnc_wrap/linuxcnc_interp_minimal_runtime.cpp @@ -10,6 +10,7 @@ #include "emc/rs274ngc/rs274ngc_interp.hh" #undef private +#include "emc/rs274ngc/rs274ngc_return.hh" #include "canon_event_sink.hh" PythonPlugin *python_plugin = nullptr; @@ -381,6 +382,13 @@ int Interp::convert_g(block_pointer block, setup_pointer settings) SET_FEED_RATE(block->f_number); } + if ((block->motion_to_be == G_1) && + (settings->feed_mode == FEED_MODE::UNITS_PER_MINUTE) && + (settings->feed_rate == 0.0)) { + setError("%s", NCE_CANNOT_DO_G1_WITH_ZERO_FEED_RATE); + return INTERP_ERROR; + } + const bool incremental = settings->distance_mode == DISTANCE_MODE::INCREMENTAL; if (block->x_flag) { settings->current_x = incremental ? settings->current_x + block->x_number diff --git a/wasm-port/tests/fixtures/canon_errors/g1_zero_feed.expected b/wasm-port/tests/fixtures/canon_errors/g1_zero_feed.expected new file mode 100644 index 0000000..2efceb3 --- /dev/null +++ b/wasm-port/tests/fixtures/canon_errors/g1_zero_feed.expected @@ -0,0 +1,9 @@ +execute_line_1=5 +error_text=Cannot do g1 with zero feed rate +setup.current_x=0 +setup.current_y=0 +setup.current_z=0 +setup.parameter_5420=0 +setup.parameter_5421=0 +setup.parameter_5422=0 +absent=canon_event=STRAIGHT_FEED diff --git a/wasm-port/tests/fixtures/gcode_errors/g1_zero_feed.ngc b/wasm-port/tests/fixtures/gcode_errors/g1_zero_feed.ngc new file mode 100644 index 0000000..b3e98be --- /dev/null +++ b/wasm-port/tests/fixtures/gcode_errors/g1_zero_feed.ngc @@ -0,0 +1 @@ +G1 X1.0 diff --git a/wasm-port/tests/native/verify_native_probes.sh b/wasm-port/tests/native/verify_native_probes.sh index b7dda83..14a0e50 100755 --- a/wasm-port/tests/native/verify_native_probes.sh +++ b/wasm-port/tests/native/verify_native_probes.sh @@ -5,6 +5,8 @@ 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" "$ROOT_DIR/tools/build_native_probes.sh" @@ -77,4 +79,34 @@ for fixture in "$GCODE_FIXTURE_DIR"/*.ngc; do check_fixture_output "$fixture" "$expected" "$stdout_file" 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" + "$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#error_text=}" "$stderr_file" + else + grep -Fq "$expected_line" "$stdout_file" + fi + done < "$expected" +done + echo "native probe validation complete"