From d69b536d1d12b6219647c5e3bbbcbc28174b8764 Mon Sep 17 00:00:00 2001 From: CNC Local Date: Fri, 22 May 2026 05:11:11 +0800 Subject: [PATCH] Preserve LinuxCNC comment event line numbers --- README.zh-CN.md | 2 ++ core/src/linuxcnc_canon_bridge.cpp | 1 + core/tests/cnc_sim_api_linuxcnc_rs274_smoke.cpp | 16 ++++++++++++++++ core/tests/linuxcnc_canon_bridge_smoke.cpp | 6 ++++++ test-linuxcnc-rs274-native.sh | 6 ++++++ tests/gcode/linuxcnc_comments.ngc | 4 ++++ 6 files changed, 35 insertions(+) create mode 100644 tests/gcode/linuxcnc_comments.ngc diff --git a/README.zh-CN.md b/README.zh-CN.md index 8af1724..c8d2473 100644 --- a/README.zh-CN.md +++ b/README.zh-CN.md @@ -60,6 +60,7 @@ The first useful target is: - 已有坐标系事件回归语料,覆盖 `G10 L2`、`G10 L20` 的 G5X/XY 旋转事件和 `G92.1` 清零事件。 - 已有探针事件回归语料,LinuxCNC `G38.3` 会输出独立 `probe` 事件,不再混作普通直线进给。 - 已有主轴方向状态回归语料,`M3/M4/M5` 会通过 `set-spindle.reserved` 输出 `1=顺时针`、`2=逆时针`、`0=停止`。 +- 已有注释事件行号回归语料,LinuxCNC `COMMENT` 事件会保留当前 G-code 行号。 - LinuxCNC Canon bridge 会把当前解释行号补到没有自带 `lineno` 的回调事件上,方便 Web 端诊断和源码高亮。 - 下一步是继续替换源码级链接中残留的 Python、INI/HAL、文件系统和动态加载依赖,并把 RTCP 内核接入 canon 事件流和机型配置。 @@ -80,6 +81,7 @@ The first useful target is: - LinuxCNC RS274 源码级链接 smoke - 五轴 RTCP 几何内核 smoke - `M3` / `M4` / `M5` 主轴方向事件回归 +- LinuxCNC 注释事件行号回归 - `G10 L2` / `G10 L20` / `G92.1` 坐标系事件回归 - `G38.3` 探针事件回归 diff --git a/core/src/linuxcnc_canon_bridge.cpp b/core/src/linuxcnc_canon_bridge.cpp index 8cb33df..b9674ce 100644 --- a/core/src/linuxcnc_canon_bridge.cpp +++ b/core/src/linuxcnc_canon_bridge.cpp @@ -414,6 +414,7 @@ void COMMENT(const char *) { CncSimEvent event{}; event.version = 1; event.type = CNC_SIM_EVENT_COMMENT; + event.line = event_line(); active_sink->emit_raw(event); } } diff --git a/core/tests/cnc_sim_api_linuxcnc_rs274_smoke.cpp b/core/tests/cnc_sim_api_linuxcnc_rs274_smoke.cpp index 1ddf53a..1bd6b08 100644 --- a/core/tests/cnc_sim_api_linuxcnc_rs274_smoke.cpp +++ b/core/tests/cnc_sim_api_linuxcnc_rs274_smoke.cpp @@ -76,6 +76,7 @@ int main() { bool saw_spindle_cw = false; bool saw_spindle_ccw = false; bool saw_spindle_stop = false; + bool saw_comment_line = false; for (const auto &event : events) { saw_tool = saw_tool || event.type == CNC_SIM_EVENT_TOOL_CHANGE; saw_rapid = saw_rapid || event.type == CNC_SIM_EVENT_RAPID; @@ -154,6 +155,21 @@ int main() { ok &= expect(saw_spindle_ccw, "expected LinuxCNC M4 counterclockwise spindle state"); ok &= expect(saw_spindle_stop, "expected LinuxCNC M5 stopped spindle state"); + const char comment_program[] = + "G21 G90 G17\n" + "(operator note)\n" + "G0 X0 Y0 Z1\n" + "M30\n"; + events.clear(); + ok &= expect(cnc_sim_parse_program(sim, comment_program, sizeof(comment_program) - 1) == 0, + cnc_sim_last_error(sim)); + for (const auto &event : events) { + saw_comment_line = saw_comment_line || + (event.type == CNC_SIM_EVENT_COMMENT && + event.line == 2); + } + ok &= expect(saw_comment_line, "expected LinuxCNC comment event line number"); + const char probe_program[] = "G21 G90 G17\n" "G0 X0 Y0 Z5\n" diff --git a/core/tests/linuxcnc_canon_bridge_smoke.cpp b/core/tests/linuxcnc_canon_bridge_smoke.cpp index ccf16f9..f8e7365 100644 --- a/core/tests/linuxcnc_canon_bridge_smoke.cpp +++ b/core/tests/linuxcnc_canon_bridge_smoke.cpp @@ -47,6 +47,8 @@ int main() { SET_G5X_OFFSET(1, 10.0, 20.0, 30.0, 1.0, 2.0, 3.0, 0.0, 0.0, 0.0); SET_G92_OFFSET(1.0, 2.0, 3.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0); SET_XY_ROTATION(15.0); + cnc_sim_linuxcnc_set_current_line(20); + COMMENT("bridge comment"); PROGRAM_END(); bool ok = true; @@ -65,6 +67,7 @@ int main() { bool saw_g5x = false; bool saw_g92 = false; bool saw_rotation = false; + bool saw_comment = false; bool saw_end = false; for (const auto &event : events) { saw_tool = saw_tool || (event.type == CNC_SIM_EVENT_TOOL_CHANGE && event.tool == 7); @@ -102,6 +105,8 @@ int main() { event.start.z == 3.0); saw_rotation = saw_rotation || (event.type == CNC_SIM_EVENT_SET_XY_ROTATION && event.feed == 15.0); + saw_comment = saw_comment || (event.type == CNC_SIM_EVENT_COMMENT && + event.line == 20); saw_end = saw_end || event.type == CNC_SIM_EVENT_PROGRAM_END; } @@ -116,6 +121,7 @@ int main() { ok &= expect(saw_g5x, "expected G5X offset event"); ok &= expect(saw_g92, "expected G92 offset event"); ok &= expect(saw_rotation, "expected XY rotation event"); + ok &= expect(saw_comment, "expected comment event line"); ok &= expect(saw_end, "expected program end"); cnc_sim_linuxcnc_set_canon_sink(nullptr); diff --git a/test-linuxcnc-rs274-native.sh b/test-linuxcnc-rs274-native.sh index 7663283..9c59d81 100755 --- a/test-linuxcnc-rs274-native.sh +++ b/test-linuxcnc-rs274-native.sh @@ -39,6 +39,7 @@ CNC_SIM_RS274_VAR="$var_file" "$build_dir/linuxcnc_rs274_dump" tests/gcode/basic CNC_SIM_RS274_VAR="$var_file" "$build_dir/linuxcnc_rs274_dump" tests/gcode/linuxcnc_rtcp_controls.ngc >/tmp/cnc_sim_linuxcnc_rtcp_controls.json CNC_SIM_RS274_VAR="$var_file" "$build_dir/linuxcnc_rs274_dump" tests/gcode/linuxcnc_spindle_direction.ngc >/tmp/cnc_sim_linuxcnc_spindle_direction.json CNC_SIM_RS274_VAR="$var_file" "$build_dir/linuxcnc_rs274_dump" tests/gcode/linuxcnc_canned_cycle.ngc >/tmp/cnc_sim_linuxcnc_canned_cycle.json +CNC_SIM_RS274_VAR="$var_file" "$build_dir/linuxcnc_rs274_dump" tests/gcode/linuxcnc_comments.ngc >/tmp/cnc_sim_linuxcnc_comments.json CNC_SIM_RS274_VAR="$var_file" "$build_dir/linuxcnc_rs274_dump" tests/gcode/linuxcnc_probe_no_error.ngc >/tmp/cnc_sim_linuxcnc_probe_no_error.json cp "$base_var_file" "$var_file" CNC_SIM_RS274_VAR="$var_file" "$build_dir/linuxcnc_rs274_dump" tests/gcode/linuxcnc_coordinate_offsets.ngc >/tmp/cnc_sim_linuxcnc_coordinate_offsets.json @@ -97,6 +98,10 @@ actual_cycle = [(event["type"], event["end"]["x"], event["end"]["y"], event["end if actual_cycle != expected_cycle: raise SystemExit(f"unexpected G81/G80 expansion: {actual_cycle!r}") +comments = json.loads(Path("/tmp/cnc_sim_linuxcnc_comments.json").read_text()) +if not any(event["type"] == "comment" and event["line"] == 2 for event in comments): + raise SystemExit("missing LinuxCNC comment line event") + probe = json.loads(Path("/tmp/cnc_sim_linuxcnc_probe_no_error.json").read_text()) if not any( event["type"] == "probe" and @@ -157,6 +162,7 @@ echo "dumped /tmp/cnc_sim_linuxcnc_basic_mill.json" echo "dumped /tmp/cnc_sim_linuxcnc_rtcp_controls.json" echo "dumped /tmp/cnc_sim_linuxcnc_spindle_direction.json" echo "dumped /tmp/cnc_sim_linuxcnc_canned_cycle.json" +echo "dumped /tmp/cnc_sim_linuxcnc_comments.json" echo "dumped /tmp/cnc_sim_linuxcnc_probe_no_error.json" echo "dumped /tmp/cnc_sim_linuxcnc_coordinate_offsets.json" echo "dumped /tmp/cnc_sim_linuxcnc_coordinate_l20.json" diff --git a/tests/gcode/linuxcnc_comments.ngc b/tests/gcode/linuxcnc_comments.ngc new file mode 100644 index 0000000..d62fd2d --- /dev/null +++ b/tests/gcode/linuxcnc_comments.ngc @@ -0,0 +1,4 @@ +G21 G90 G17 +(operator note) +G0 X0 Y0 Z1 +M30