From b4d0bfae46fb89addff278bfebbe3e57e689655a Mon Sep 17 00:00:00 2001 From: cnc Date: Tue, 2 Jun 2026 16:10:03 +0800 Subject: [PATCH] =?UTF-8?q?=E7=BB=A7=E7=BB=AD=E6=8C=89=20align-linuxcnc=20?= =?UTF-8?q?=E7=BA=A6=E6=9D=9F=EF=BC=9A=E8=A1=A5=E9=BD=90=20read=5Foperatio?= =?UTF-8?q?n=20=E6=BA=90=E7=A0=81=E9=94=99=E8=AF=AF=E8=A6=86=E7=9B=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 结论:覆盖 LinuxCNC interp_read.cc read_operation() 的未知二元操作名前缀、未知操作字符和未闭合表达式错误;未扩展 smoke。 验证:./test-native.sh;./test-linuxcnc-source-link.sh。 --- docs/linuxcnc-porting.md | 2 +- test-linuxcnc-source-link.sh | 27 +++++++++++++++++++ ...uxcnc_binary_unknown_a_operation_error.ngc | 2 ++ ...uxcnc_binary_unknown_e_operation_error.ngc | 2 ++ ...uxcnc_binary_unknown_g_operation_error.ngc | 2 ++ ...uxcnc_binary_unknown_l_operation_error.ngc | 2 ++ ...uxcnc_binary_unknown_m_operation_error.ngc | 2 ++ ...uxcnc_binary_unknown_n_operation_error.ngc | 2 ++ ...uxcnc_binary_unknown_o_operation_error.ngc | 2 ++ ...inuxcnc_binary_unknown_operation_error.ngc | 2 ++ ...uxcnc_binary_unknown_x_operation_error.ngc | 2 ++ .../linuxcnc_unclosed_expression_error.ngc | 2 ++ 12 files changed, 48 insertions(+), 1 deletion(-) create mode 100644 tests/gcode/linuxcnc_binary_unknown_a_operation_error.ngc create mode 100644 tests/gcode/linuxcnc_binary_unknown_e_operation_error.ngc create mode 100644 tests/gcode/linuxcnc_binary_unknown_g_operation_error.ngc create mode 100644 tests/gcode/linuxcnc_binary_unknown_l_operation_error.ngc create mode 100644 tests/gcode/linuxcnc_binary_unknown_m_operation_error.ngc create mode 100644 tests/gcode/linuxcnc_binary_unknown_n_operation_error.ngc create mode 100644 tests/gcode/linuxcnc_binary_unknown_o_operation_error.ngc create mode 100644 tests/gcode/linuxcnc_binary_unknown_operation_error.ngc create mode 100644 tests/gcode/linuxcnc_binary_unknown_x_operation_error.ngc create mode 100644 tests/gcode/linuxcnc_unclosed_expression_error.ngc diff --git a/docs/linuxcnc-porting.md b/docs/linuxcnc-porting.md index d99bdfe..5febe22 100644 --- a/docs/linuxcnc-porting.md +++ b/docs/linuxcnc-porting.md @@ -212,6 +212,6 @@ This matrix tracks LinuxCNC feature coverage for the web/WASM simulator. A featu | Cutter compensation | covered for tool-table `G41/G42 D...` and explicit-radius `G41.1/G42.1/G40` through LinuxCNC native/source backends | `tests/gcode/linuxcnc_cutter_comp.ngc` | | Probe moves `G38.2/G38.3/G38.4/G38.5` | covered as distinct probe events with LinuxCNC `probe_type` preserved through smoke, native, and source-linked paths | `tests/gcode/linuxcnc_probe_no_error.ngc` | | O-word subroutines, calls, and control flow | covered for numeric and named `O... sub/call/return/endsub` plus `if`/`elseif`/`else`, `while`, `repeat`, `do`/`while`, `break`, and `continue` through LinuxCNC file mode; smoke parser also covers named `O` sub/call/return/endsub and loop-control forms | `tests/gcode/smoke_oword_subprogram.ngc`, `tests/gcode/linuxcnc_named_oword_subprogram.ngc`, `tests/gcode/linuxcnc_oword_control_flow.ngc` | -| Parameter expressions and operators | covered for parameter references, source-linked `mod`, `**`, logical, and relational operator precedence, plus LinuxCNC divide-by-zero, negative-power, malformed `ATAN[]/[]`, and unary operation error paths from `interp_read.cc`/`interp_execute.cc` | `tests/gcode/linuxcnc_parameter_expression_assignment.ngc`, `tests/gcode/linuxcnc_expression_operators.ngc`, `tests/gcode/linuxcnc_divide_by_zero_error.ngc`, `tests/gcode/linuxcnc_negative_power_error.ngc`, `tests/gcode/linuxcnc_atan_missing_slash_error.ngc`, `tests/gcode/linuxcnc_atan_missing_bracket_error.ngc`, `tests/gcode/linuxcnc_unary_missing_bracket_error.ngc`, `tests/gcode/linuxcnc_unary_unknown_word_error.ngc` | +| Parameter expressions and operators | covered for parameter references, source-linked `mod`, `**`, logical, and relational operator precedence, plus LinuxCNC divide-by-zero, negative-power, malformed `ATAN[]/[]`, unary operation, `read_operation()` binary-operation prefix, unknown operation, and unclosed-expression error paths from `interp_read.cc`/`interp_execute.cc` | `tests/gcode/linuxcnc_parameter_expression_assignment.ngc`, `tests/gcode/linuxcnc_expression_operators.ngc`, `tests/gcode/linuxcnc_divide_by_zero_error.ngc`, `tests/gcode/linuxcnc_negative_power_error.ngc`, `tests/gcode/linuxcnc_atan_missing_slash_error.ngc`, `tests/gcode/linuxcnc_atan_missing_bracket_error.ngc`, `tests/gcode/linuxcnc_unary_missing_bracket_error.ngc`, `tests/gcode/linuxcnc_unary_unknown_word_error.ngc`, `tests/gcode/linuxcnc_binary_unknown_a_operation_error.ngc`, `tests/gcode/linuxcnc_binary_unknown_e_operation_error.ngc`, `tests/gcode/linuxcnc_binary_unknown_g_operation_error.ngc`, `tests/gcode/linuxcnc_binary_unknown_l_operation_error.ngc`, `tests/gcode/linuxcnc_binary_unknown_m_operation_error.ngc`, `tests/gcode/linuxcnc_binary_unknown_n_operation_error.ngc`, `tests/gcode/linuxcnc_binary_unknown_o_operation_error.ngc`, `tests/gcode/linuxcnc_binary_unknown_x_operation_error.ngc`, `tests/gcode/linuxcnc_binary_unknown_operation_error.ngc`, `tests/gcode/linuxcnc_unclosed_expression_error.ngc` | | Broader canned cycles `G73`, `G74`, `G82`-`G89` | partially covered: `G73`, `G74`, `G82`, `G83`, `G84`, `G85`, `G86`, `G87`, `G88`, `G89`; smoke parser maps supported cycles across `G17/G18/G19`, including LinuxCNC's special non-XY `G74/G84` tapping argument order and `G87` plane-specific `I/J/K` mapping; native/source regressions now check non-XY `G74/G84/G86/G87/G88` sequences | `tests/gcode/linuxcnc_canned_cycles_extended.ngc`, `tests/gcode/linuxcnc_canned_cycle_planes.ngc`, smoke API regression | | Full source-level wasm build | covered for the current wasm-safe RS274 source set, with remaining work focused on broadening browser-hostile dependency replacement and feature coverage | `./build-wasm.sh`, `test-linuxcnc-wasm-runtime-link.sh`, `test-web-wasm-node-smoke.sh`, `test-web-wasm-browser-smoke.sh` | diff --git a/test-linuxcnc-source-link.sh b/test-linuxcnc-source-link.sh index a1dcfa8..ae8718b 100755 --- a/test-linuxcnc-source-link.sh +++ b/test-linuxcnc-source-link.sh @@ -627,6 +627,33 @@ if CNC_SIM_RS274_FILE_MODE=1 CNC_SIM_RS274_VAR="$var_file" \ fi grep -q "Unknown word starting with a" \ "$output_dir/cnc_sim_linuxcnc_source_unary_unknown_word_error.err" +# Source basis: LinuxCNC src/emc/rs274ngc/interp_read.cc +# read_operation() rejects unknown binary operation names by prefix, +# unknown operation characters, and expressions that reach end-of-line +# before a right bracket. +binary_operation_error_cases=( + "linuxcnc_binary_unknown_a_operation_error|Unknown operation name starting with a" + "linuxcnc_binary_unknown_e_operation_error|Unknown operation name starting with e" + "linuxcnc_binary_unknown_g_operation_error|Unknown operation name starting with g" + "linuxcnc_binary_unknown_l_operation_error|Unknown operation name starting with l" + "linuxcnc_binary_unknown_m_operation_error|Unknown operation name starting with m" + "linuxcnc_binary_unknown_n_operation_error|Unknown operation name starting with n" + "linuxcnc_binary_unknown_o_operation_error|Unknown operation name starting with o" + "linuxcnc_binary_unknown_x_operation_error|Unknown operation name starting with x" + "linuxcnc_binary_unknown_operation_error|Unknown operation" + "linuxcnc_unclosed_expression_error|Unclosed expression" +) +for case in "${binary_operation_error_cases[@]}"; do + fixture=${case%%|*} + expected=${case#*|} + if CNC_SIM_RS274_FILE_MODE=1 CNC_SIM_RS274_VAR="$var_file" \ + "$build_dir/linuxcnc_rs274_source_dump" "tests/gcode/$fixture.ngc" \ + >"$output_dir/cnc_sim_linuxcnc_source_$fixture.json" 2>"$output_dir/cnc_sim_linuxcnc_source_$fixture.err"; then + echo "expected $fixture.ngc to fail" >&2 + exit 1 + fi + grep -q "$expected" "$output_dir/cnc_sim_linuxcnc_source_$fixture.err" +done CNC_SIM_RS274_FILE_MODE=1 CNC_SIM_RS274_VAR="$var_file" \ "$build_dir/linuxcnc_rs274_source_dump" tests/gcode/linuxcnc_value_returned.ngc \ >"$output_dir/cnc_sim_linuxcnc_source_value_returned.json" diff --git a/tests/gcode/linuxcnc_binary_unknown_a_operation_error.ngc b/tests/gcode/linuxcnc_binary_unknown_a_operation_error.ngc new file mode 100644 index 0000000..f58512b --- /dev/null +++ b/tests/gcode/linuxcnc_binary_unknown_a_operation_error.ngc @@ -0,0 +1,2 @@ +#1 = [1 aaz 2] +G1 X#1 F100 diff --git a/tests/gcode/linuxcnc_binary_unknown_e_operation_error.ngc b/tests/gcode/linuxcnc_binary_unknown_e_operation_error.ngc new file mode 100644 index 0000000..813a3c1 --- /dev/null +++ b/tests/gcode/linuxcnc_binary_unknown_e_operation_error.ngc @@ -0,0 +1,2 @@ +#1 = [1 ez 2] +G1 X#1 F100 diff --git a/tests/gcode/linuxcnc_binary_unknown_g_operation_error.ngc b/tests/gcode/linuxcnc_binary_unknown_g_operation_error.ngc new file mode 100644 index 0000000..1229b07 --- /dev/null +++ b/tests/gcode/linuxcnc_binary_unknown_g_operation_error.ngc @@ -0,0 +1,2 @@ +#1 = [1 gz 2] +G1 X#1 F100 diff --git a/tests/gcode/linuxcnc_binary_unknown_l_operation_error.ngc b/tests/gcode/linuxcnc_binary_unknown_l_operation_error.ngc new file mode 100644 index 0000000..3a79bf8 --- /dev/null +++ b/tests/gcode/linuxcnc_binary_unknown_l_operation_error.ngc @@ -0,0 +1,2 @@ +#1 = [1 lz 2] +G1 X#1 F100 diff --git a/tests/gcode/linuxcnc_binary_unknown_m_operation_error.ngc b/tests/gcode/linuxcnc_binary_unknown_m_operation_error.ngc new file mode 100644 index 0000000..55804f0 --- /dev/null +++ b/tests/gcode/linuxcnc_binary_unknown_m_operation_error.ngc @@ -0,0 +1,2 @@ +#1 = [1 moz 2] +G1 X#1 F100 diff --git a/tests/gcode/linuxcnc_binary_unknown_n_operation_error.ngc b/tests/gcode/linuxcnc_binary_unknown_n_operation_error.ngc new file mode 100644 index 0000000..3da9b88 --- /dev/null +++ b/tests/gcode/linuxcnc_binary_unknown_n_operation_error.ngc @@ -0,0 +1,2 @@ +#1 = [1 nz 2] +G1 X#1 F100 diff --git a/tests/gcode/linuxcnc_binary_unknown_o_operation_error.ngc b/tests/gcode/linuxcnc_binary_unknown_o_operation_error.ngc new file mode 100644 index 0000000..d5559e2 --- /dev/null +++ b/tests/gcode/linuxcnc_binary_unknown_o_operation_error.ngc @@ -0,0 +1,2 @@ +#1 = [1 oz 2] +G1 X#1 F100 diff --git a/tests/gcode/linuxcnc_binary_unknown_operation_error.ngc b/tests/gcode/linuxcnc_binary_unknown_operation_error.ngc new file mode 100644 index 0000000..0a5c14f --- /dev/null +++ b/tests/gcode/linuxcnc_binary_unknown_operation_error.ngc @@ -0,0 +1,2 @@ +#1 = [1 @ 2] +G1 X#1 F100 diff --git a/tests/gcode/linuxcnc_binary_unknown_x_operation_error.ngc b/tests/gcode/linuxcnc_binary_unknown_x_operation_error.ngc new file mode 100644 index 0000000..e549f00 --- /dev/null +++ b/tests/gcode/linuxcnc_binary_unknown_x_operation_error.ngc @@ -0,0 +1,2 @@ +#1 = [1 xaz 2] +G1 X#1 F100 diff --git a/tests/gcode/linuxcnc_unclosed_expression_error.ngc b/tests/gcode/linuxcnc_unclosed_expression_error.ngc new file mode 100644 index 0000000..adf7cce --- /dev/null +++ b/tests/gcode/linuxcnc_unclosed_expression_error.ngc @@ -0,0 +1,2 @@ +#1 = [1 + 2 +G1 X#1 F100