From 9a9b931982349a5034f45e71bc90daa95bad36bf Mon Sep 17 00:00:00 2001 From: cnc Date: Tue, 2 Jun 2026 17:20:42 +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=E5=8F=82=E6=95=B0=E8=AF=BB?= =?UTF-8?q?=E5=8F=96=E9=94=99=E8=AF=AF=E6=BA=90=E7=A0=81=E8=A6=86=E7=9B=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 结论:新增参数索引、命名参数终止和实数读取错误 fixture,全部绑定 LinuxCNC interp_read.cc 的 source-link 断言;未扩展 smoke。 --- docs/linuxcnc-porting.md | 2 +- test-linuxcnc-source-link.sh | 23 +++++++++++++++++++ .../linuxcnc_bad_number_format_error.ngc | 1 + ...c_named_parameter_not_terminated_error.ngc | 1 + tests/gcode/linuxcnc_no_real_value_error.ngc | 1 + ...xcnc_non_integer_parameter_index_error.ngc | 1 + ...nc_parameter_number_out_of_range_error.ngc | 1 + ...parameter_reference_out_of_range_error.ngc | 1 + 8 files changed, 30 insertions(+), 1 deletion(-) create mode 100644 tests/gcode/linuxcnc_bad_number_format_error.ngc create mode 100644 tests/gcode/linuxcnc_named_parameter_not_terminated_error.ngc create mode 100644 tests/gcode/linuxcnc_no_real_value_error.ngc create mode 100644 tests/gcode/linuxcnc_non_integer_parameter_index_error.ngc create mode 100644 tests/gcode/linuxcnc_parameter_number_out_of_range_error.ngc create mode 100644 tests/gcode/linuxcnc_parameter_reference_out_of_range_error.ngc diff --git a/docs/linuxcnc-porting.md b/docs/linuxcnc-porting.md index 05ab1b4..feb498a 100644 --- a/docs/linuxcnc-porting.md +++ b/docs/linuxcnc-porting.md @@ -212,7 +212,7 @@ 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 parameter-setting syntax, divide-by-zero, negative-power, malformed `ATAN[]/[]`, unary operation syntax, `read_operation_unary()` unknown-word branches, `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_parameter_missing_equal_error.ngc`, `tests/gcode/linuxcnc_parameter_missing_value_error.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_unary_unknown_c_word_error.ngc`, `tests/gcode/linuxcnc_unary_unknown_e_word_error.ngc`, `tests/gcode/linuxcnc_unary_unknown_f_word_error.ngc`, `tests/gcode/linuxcnc_unary_unknown_l_word_error.ngc`, `tests/gcode/linuxcnc_unary_unknown_r_word_error.ngc`, `tests/gcode/linuxcnc_unary_unknown_s_word_error.ngc`, `tests/gcode/linuxcnc_unary_unknown_t_word_error.ngc`, `tests/gcode/linuxcnc_unary_unknown_default_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` | +| Parameter expressions and operators | covered for parameter references, source-linked `mod`, `**`, logical, and relational operator precedence, plus LinuxCNC parameter-setting syntax, parameter index validation, named-parameter termination, real-number parsing, divide-by-zero, negative sqrt/power, infinity rejection, malformed `ATAN[]/[]`, unary operation syntax, `read_operation_unary()` unknown-word branches, `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_parameter_missing_equal_error.ngc`, `tests/gcode/linuxcnc_parameter_missing_value_error.ngc`, `tests/gcode/linuxcnc_parameter_number_out_of_range_error.ngc`, `tests/gcode/linuxcnc_parameter_reference_out_of_range_error.ngc`, `tests/gcode/linuxcnc_non_integer_parameter_index_error.ngc`, `tests/gcode/linuxcnc_named_parameter_not_terminated_error.ngc`, `tests/gcode/linuxcnc_no_real_value_error.ngc`, `tests/gcode/linuxcnc_bad_number_format_error.ngc`, `tests/gcode/linuxcnc_expression_operators.ngc`, `tests/gcode/linuxcnc_negative_sqrt_error.ngc`, `tests/gcode/linuxcnc_divide_by_zero_error.ngc`, `tests/gcode/linuxcnc_negative_power_error.ngc`, `tests/gcode/linuxcnc_infinite_expression_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_unary_unknown_c_word_error.ngc`, `tests/gcode/linuxcnc_unary_unknown_e_word_error.ngc`, `tests/gcode/linuxcnc_unary_unknown_f_word_error.ngc`, `tests/gcode/linuxcnc_unary_unknown_l_word_error.ngc`, `tests/gcode/linuxcnc_unary_unknown_r_word_error.ngc`, `tests/gcode/linuxcnc_unary_unknown_s_word_error.ngc`, `tests/gcode/linuxcnc_unary_unknown_t_word_error.ngc`, `tests/gcode/linuxcnc_unary_unknown_default_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` | | Word reader validation | source-linked LinuxCNC reader errors covered for negative `F/G/H/L/M/S/T` values and repeated `A/B/C/D/E/F/H/I/J/K/L/P/Q/R/S/T/U/V/W/X/Y/Z` words from `interp_read.cc` | `tests/gcode/linuxcnc_negative_f_word_error.ngc`, `tests/gcode/linuxcnc_negative_g_code_error.ngc`, `tests/gcode/linuxcnc_negative_h_word_error.ngc`, `tests/gcode/linuxcnc_negative_l_word_error.ngc`, `tests/gcode/linuxcnc_negative_m_code_error.ngc`, `tests/gcode/linuxcnc_negative_s_word_error.ngc`, `tests/gcode/linuxcnc_negative_t_word_error.ngc`, `tests/gcode/linuxcnc_multiple_a_words_error.ngc`, `tests/gcode/linuxcnc_multiple_b_words_error.ngc`, `tests/gcode/linuxcnc_multiple_c_words_error.ngc`, `tests/gcode/linuxcnc_multiple_d_words_error.ngc`, `tests/gcode/linuxcnc_multiple_e_words_error.ngc`, `tests/gcode/linuxcnc_multiple_f_words_error.ngc`, `tests/gcode/linuxcnc_multiple_h_words_error.ngc`, `tests/gcode/linuxcnc_multiple_i_words_error.ngc`, `tests/gcode/linuxcnc_multiple_j_words_error.ngc`, `tests/gcode/linuxcnc_multiple_k_words_error.ngc`, `tests/gcode/linuxcnc_multiple_l_words_error.ngc`, `tests/gcode/linuxcnc_multiple_p_words_error.ngc`, `tests/gcode/linuxcnc_multiple_q_words_error.ngc`, `tests/gcode/linuxcnc_multiple_r_words_error.ngc`, `tests/gcode/linuxcnc_multiple_s_words_error.ngc`, `tests/gcode/linuxcnc_multiple_t_words_error.ngc`, `tests/gcode/linuxcnc_multiple_u_words_error.ngc`, `tests/gcode/linuxcnc_multiple_v_words_error.ngc`, `tests/gcode/linuxcnc_multiple_w_words_error.ngc`, `tests/gcode/linuxcnc_multiple_x_words_error.ngc`, `tests/gcode/linuxcnc_multiple_y_words_error.ngc`, `tests/gcode/linuxcnc_multiple_z_words_error.ngc` | | G/M reader validation | source-linked LinuxCNC `read_g()`/`read_m()` errors covered for range checks, unknown code tables, and same-modal-group conflicts from `interp_read.cc` and `interp_array.cc` | `tests/gcode/linuxcnc_g_code_out_of_range_error.ngc`, `tests/gcode/linuxcnc_unknown_g_code_error.ngc`, `tests/gcode/linuxcnc_two_g_codes_same_modal_group_error.ngc`, `tests/gcode/linuxcnc_m_code_greater_199_error.ngc`, `tests/gcode/linuxcnc_unknown_m_code_error.ngc`, `tests/gcode/linuxcnc_two_m_codes_same_modal_group_error.ngc` | | Block/item reader validation | source-linked LinuxCNC block reader errors covered for repeated `$`, bad item-start characters, middle-of-line `N` words, and too many M-codes from `interp_read.cc`, `interp_array.cc`, and `interp_check.cc` | `tests/gcode/linuxcnc_multiple_spindle_choice_words_error.ngc`, `tests/gcode/linuxcnc_bad_character_bang_error.ngc`, `tests/gcode/linuxcnc_bad_character_middle_n_word_error.ngc`, `tests/gcode/linuxcnc_too_many_m_codes_error.ngc` | diff --git a/test-linuxcnc-source-link.sh b/test-linuxcnc-source-link.sh index c383092..2794907 100755 --- a/test-linuxcnc-source-link.sh +++ b/test-linuxcnc-source-link.sh @@ -577,6 +577,29 @@ for case in "${parameter_setting_error_cases[@]}"; do fi grep -q "$expected" "$output_dir/cnc_sim_linuxcnc_source_$fixture.err" done +# Source basis: LinuxCNC src/emc/rs274ngc/interp_read.cc +# read_parameter(), read_parameter_setting(), read_integer_value(), +# read_name(), and read_real_value() reject malformed parameter indices, +# unterminated named parameters, and missing or malformed real values. +parameter_reader_error_cases=( + "linuxcnc_parameter_number_out_of_range_error|Parameter number out of range" + "linuxcnc_parameter_reference_out_of_range_error|Parameter number out of range" + "linuxcnc_non_integer_parameter_index_error|Non integer value for integer" + "linuxcnc_named_parameter_not_terminated_error|Named parameter not terminated" + "linuxcnc_no_real_value_error|No characters found in reading real value" + "linuxcnc_bad_number_format_error|bad number format (conversion failed) parsing '+'" +) +for case in "${parameter_reader_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 if CNC_SIM_RS274_FILE_MODE=1 CNC_SIM_RS274_VAR="$var_file" \ "$build_dir/linuxcnc_rs274_source_dump" tests/gcode/linuxcnc_negative_sqrt_error.ngc \ >"$output_dir/cnc_sim_linuxcnc_source_negative_sqrt_error.json" 2>"$output_dir/cnc_sim_linuxcnc_source_negative_sqrt_error.err"; then diff --git a/tests/gcode/linuxcnc_bad_number_format_error.ngc b/tests/gcode/linuxcnc_bad_number_format_error.ngc new file mode 100644 index 0000000..8649dc9 --- /dev/null +++ b/tests/gcode/linuxcnc_bad_number_format_error.ngc @@ -0,0 +1 @@ +G1 X+ diff --git a/tests/gcode/linuxcnc_named_parameter_not_terminated_error.ngc b/tests/gcode/linuxcnc_named_parameter_not_terminated_error.ngc new file mode 100644 index 0000000..350f7b0 --- /dev/null +++ b/tests/gcode/linuxcnc_named_parameter_not_terminated_error.ngc @@ -0,0 +1 @@ +G1 X#