1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
//! csh/tcsh source → zsh source translator for `zshrs --csh`.
//!
//! zshrs-original — no zsh C counterpart. csh syntax is not zsh syntax
//! (`set x = 5`, `setenv`, `@ n = 1 + 2`, `if (...) then`/`endif`,
//! `foreach`/`end`, `switch`/`endsw`, `$#x`, `$x[2]`, `>&`, `|&`), so a
//! `--csh` input is rewritten here into zsh text with the same meaning and
//! run by the ordinary engine. The reference is /bin/tcsh (macOS `/bin/csh`
//! is tcsh); every rule here is checked against it.
//!
//! Pure `std`; no crate dependencies, so the tree compiles standalone with
//! `rustc --edition 2021 --test mod.rs`.
//!
//! Layering (each file owns one concern):
//! * [`lex`] — logical lines, quote-aware splitting (shared helpers)
//! * [`words`] — one csh word → zsh word (`$x[2]`, `$#x`, `$?x`, `:h`, …)
//! * [`expr`] — csh expressions (`if`/`while`/`@`) → zsh conditions/arith
//! * [`cmds`] — one command line (lists, pipes, redirections, builtins)
//! * [`ctl`] — control structures with block nesting
/// zsh-side helpers the translated output relies on (`cd`/`pushd`/`popd`
/// with tcsh's error text, `printenv`, the command-not-found handler).
/// Installed once, ahead of the first translated input.
pub const PREAMBLE: &str = include_str!;
/// Translate a whole csh script (a file, a `-c` string) to zsh, with tcsh's
/// end-of-input behaviour: a block left open still runs its body, and an
/// error is raised only where tcsh has to skip over the missing closer.
/// Errors carry the csh-side message text real tcsh prints
/// (`if: Expression Syntax.`, `Too many ('s`, …).
/// Translate input that may still be arriving (a prompt, stdin). A block
/// left open is an `Err` whose text ends in `not found.`, which the caller
/// treats as "keep reading lines".