In patch-rexx/src/eval.rs: #23
No reviewers
Labels
No labels
bug
dependencies
documentation
duplicate
enhancement
good first issue
help wanted
invalid
question
rust
wontfix
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
navicore/patch-rexx!23
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "set-cmd"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
It's fully backward-compatible — without calling set_command_handler, behavior is identical to 0.9.2. All 556 existing tests pass.
PR Review - Custom Command Handler
I've reviewed PR #23 which adds a custom command handler mechanism to the REXX evaluator. Overall, the implementation is solid and backward-compatible. I identified one potential correctness issue and have some observations:
Critical Issue
Potential panic in custom handler (src/eval.rs:492-497)
The custom command handler is called without any panic catching or error handling:
If the custom handler panics, it will unwind through the evaluator. REXX semantics require that the interpreter should be resilient to errors - malformed input should never crash the interpreter. Consider either:
std::panic::catch_unwindto convert panics into a FAILURE conditionResult<Option<i32>, Box<dyn Error>>The choice depends on the intended use case. For embedding scenarios (like XEDIT mentioned in the docs), option 1 with clear documentation is probably sufficient since the embedding application controls the handler.
Observations (not issues, but worth noting)
Handler state and reentrancy (src/eval.rs:189)
The handler is
Box<dyn FnMut>, which allows stateful handlers. However:Send, so it can't be shared across threads, which is correct for this single-threaded evaluatorCondition handling is preserved correctly (src/eval.rs:522-534)
The ERROR condition is correctly triggered for non-zero return codes from both custom handlers and shell execution. The trap removal (
self.traps.remove(&Condition::Error)) follows REXX semantics where a trap fires once and is then disabled.FAILURE trap helper extraction (src/eval.rs:537-550)
The
fire_failure_traprefactoring is clean and improves readability. The early return pattern is correct - if there's no FAILURE trap installed, execution continues normally with RC=-1.Correctness Verified
✓ ADDRESS environment is correctly passed to the handler (the environment is switched before calling the handler for temporary commands, which is correct REXX semantics)
✓ RC is set before condition traps fire (correct order per ANSI X3.274-1996)
✓ Fall-through behavior preserves existing shell execution
✓ Backward compatibility - all 556 tests pass
Recommendation
Document the panic behavior of the custom handler in the function's documentation comment (src/eval.rs:912-922). Suggest adding something like:
Otherwise, LGTM! The implementation is clean, follows REXX semantics correctly, and the refactoring improves code organization.
Code Review
I reviewed PR #23 for the custom command handler feature. The implementation is mostly solid, but I found one critical issue that needs to be fixed:
Critical Issue: Documentation Corruption
src/eval.rs:187 and src/eval.rs:911 - The documentation comments are corrupted with garbled text:
Should be:
This appears in two places:
What I Verified ✓
Correctness:
Some(rc)- this is correct behaviorREXX Semantics:
Error Handling:
status.code()returning None (uses -1) ✓Safety & Design:
FnMutallows stateful handlers ✓ref mutborrow prevents move ✓fire_failure_trapextraction is clean refactoring ✓Minor Observations (not blocking)
#[allow(clippy::type_complexity)]is appropriate hereAction Required: Fix the documentation corruption at lines 187 and 911 before merging.
Code Review - PR #23: Custom Command Handler
I've reviewed this PR for correctness, REXX semantics compliance, and safety. The implementation is clean and backward-compatible. I found one issue that must be fixed before merging.
CRITICAL: Documentation Corruption
src/eval.rs:187 and src/eval.rs:912 - Doc comments are corrupted with garbled backticks:
Should be something like:
This appears in two locations:
Evaluatorstructset_command_handler()Impact: Rustdoc output will be malformed. This affects users trying to understand the API.
Correctness Analysis ✓
ERROR/FAILURE semantics (lines 491-548):
rc != 0from either custom handler or shell (lines 520-531) ✓Some(rc)bypasses shell execution - correct design ✓RC variable handling:
Refactoring quality:
fire_failure_trap()extraction improves readability ✓Safety Analysis ✓
No panics on malformed input:
status.code()returns None is handled withunwrap_or(-1)(line 511) ✓Type safety:
Box<dyn FnMut(&str, &str) -> Option<i32>>signature is appropriate ✓ref mutprevents moving the handler ✓#[allow(clippy::type_complexity)]is justified here ✓REXX Semantics Compliance ✓
Per ANSI X3.274-1996 and test suite analysis:
Test coverage from
tests/phase8.rsconfirms all behaviors are preserved.Design Notes (not issues)
Custom handler semantics: Handler returns
Some(rc)to handle command,Noneto fall through to shell. Clean design that avoids breaking changes.Reentrancy: Handler is
FnMut, allowing state. Documentation doesn't address reentrancy (e.g., if handler triggers INTERPRET that calls another command). This is probably fine for initial use case.FAILURE from custom handler: If a custom handler wants to signal "I couldn't execute this", it has no way to trigger FAILURE condition. Returning
Some(-1)triggers ERROR, not FAILURE. This is probably correct - the handler either handles the command or doesn't; spawn failures are shell-specific.Summary
Must fix: Documentation corruption at lines 187 and 912.
Otherwise: LGTM! The implementation correctly preserves REXX semantics, handles all error conditions properly, maintains backward compatibility, and provides a clean API for embedding applications.
File references:
Code Review: Custom Command Handler for ADDRESS Environments
I've reviewed PR #23 which adds a custom command handler mechanism for ADDRESS environments. The implementation is generally solid and maintains backward compatibility. All 556 tests pass. Here are my findings:
✅ Correct Implementation
Option<CommandHandler>field with defaultNoneensures zero impact on existing code⚠️ Potential Issue: FAILURE Condition for Custom Handlers
Location:
src/eval.rs:502-543The current implementation only fires the FAILURE trap when shell execution fails (lines 526-528). However, there's an ambiguity in the contract for custom command handlers:
Current behavior:
Some(rc)→ sets RC, fires ERROR trap if rc ≠ 0None→ falls through to shellMissing case:
What if the custom handler itself experiences an execution failure (not just a non-zero return code, but an inability to execute the command at all)?
In REXX semantics per ANSI X3.274-1996:
The custom handler API uses
Option<i32>where:Some(rc)means "I handled it, here's the return code"Nonemeans "I don't handle this environment"There's no way for a custom handler to signal "I should handle this but execution failed." The handler must choose between:
Some(-1)(fires ERROR trap)Recommendation:
Consider whether the
CommandHandlertype should be:Where:
Ok(Some(rc))= handled successfully with return code rcOk(None)= don't handle this environmentErr(())= attempted to handle but execution failed (fire FAILURE)This would allow custom handlers to properly distinguish between "command failed" (ERROR) and "couldn't execute command" (FAILURE).
Alternatively, document explicitly in the handler contract that handlers must return
Some(-1)for execution failures and accept that FAILURE traps won't fire for custom handler execution failures. This is a reasonable design choice if custom handlers are expected to be well-behaved.📝 Minor Observations
Line 505:
self.env.address().to_string()- unavoidable allocation, but custom handlers that don't use the address parameter will pay this cost. Consider if the address should be passed by reference.Documentation clarity: The panic warning at lines 172-176 is good, but consider adding a note about FAILURE vs ERROR semantics and when handlers should return which codes.
🔍 Safety Check
ref mut handlerfor FnMutVerdict
The implementation is functionally correct for the stated use case (allowing embedding applications to intercept commands). The FAILURE condition ambiguity is a design question rather than a bug - it depends on whether custom handlers need the ability to signal execution failures separately from non-zero return codes.
If the current design is intentional (handlers always "succeed" in executing, even if they return non-zero codes), then this is good to merge as-is. Otherwise, consider the API refinement suggested above.
Recommendation: Merge as-is if custom handlers are trusted to handle failures internally, or refine the API to support FAILURE condition for handler execution failures.