// ZSHRS — C-TO-RUST PORT COVERAGE REPORT

src/zsh/Src/*.c → src/ported/*.rs · tests/port_purity.rs enforces strict-port purity

>_EXECUTIVE SUMMARY

Large-scale C-to-Rust port of upstream zsh: strict-port code under src/ported/ plus non-port extensions. The core file table below is regenerated from the same indexer as port_report.html (regex C top-level defs + Rust fn names + port-doc mining). Those counts are a mechanical index, not proof that every path is behavior-complete.

Codebase split (NEW): the runtime crate now physically isolates ported code from non-port code so drift is mechanically detectable. src/ported/ is the strict-port directory — every .rs mirrors a real src/zsh/Src/<x>.c file, every top-level fn carries a /// Port of <cname>() from Src/<file>.c:NNNN doc-comment, and the file set is FROZEN (no new files). src/extensions/ is the non-port directory — features zsh C does not have (AOT, daemon coordination, plugin/script/autoload caches, fish-style autosuggest/abbrev/highlight, persistent worker pools, ZWC byte-code helpers). src/recorder/ is feature-gated; deleted by rustc in the default build. Both invariants are enforced by tests/port_purity.rs — a regression of either rule fails CI.

Scope note: this report covers the C-to-Rust port (i.e. src/ported/ only) — what was translated from upstream zsh. It does not cover the new Rust infrastructure layered on top (zshrs-daemon singleton, zshrs-recorder AOP intercept, IPC + HTTP + OpenAPI surface, canonical-state rkyv shards, the z* builtin family, session-persistent supervised jobs with bidirectional ptmx attach, the parser surface in src/ported/parse.rs). That work has no C ancestor and is reported separately in daemon-report.html. See “BEYOND THE C PORT” section below for the cross-link.


#FILE-BY-FILE COVERAGE

Per-file columns: C Fns = symbols whose primary C definition is that file (unique name, heuristic indexer). Same-name Rust fn = a Rust definition with the identical identifier. Other rows = the remainder (doc-only pointers, different Rust names, or not yet indexed). Port-index % = ported / total from gen_port_report.py (ported = any Rust hit or port-doc mention). Rust targets: src/ported/<stem>.rs.

C SourceRust TargetC LinesRust LinesRatioC FnsSame-name Rust fnOther rowsPort-index % 
lex.cported/lex.rs2,2947,739337.4%25250
100.0%
✅
parse.cported/parse.rs4,08012,808313.9%75750
97.3%
⚠️
subst.csrc/ported/subst.rs4,95234,354693.7%24240
100.0%
✅
math.csrc/ported/math.rs1,6857,752460.1%20200
100.0%
✅
exec.csrc/ported/exec.rs6,57815,029228.5%76742
96.1%
⚠️
params.csrc/ported/params.rs6,50123,620363.3%1711683
97.7%
⚠️
pattern.csrc/ported/pattern.rs4,38411,279257.3%40400
90.0%
⚠️
glob.csrc/ported/glob.rs3,9869,934249.2%52520
98.1%
⚠️
jobs.csrc/ported/jobs.rs3,3207,803235.0%57570
98.2%
⚠️
hist.csrc/ported/hist.rs3,9709,186231.4%76760
98.7%
⚠️
utils.csrc/ported/utils.rs7,79217,967230.6%1721720
94.2%
⚠️
prompt.csrc/ported/prompt.rs2,5627,230282.2%32320
100.0%
✅
init.csrc/ported/init.rs2,0013,614180.6%23230
100.0%
✅
signals.csrc/ported/signals.rs1,3393,871289.1%27270
96.3%
⚠️
TOTAL (core)55,444172,186310.6%8708655
96.9%
ℹ️

&RENAMING PATTERNS

C uses free functions with global state. Rust uses struct methods, enum variants, and pattern matching. Every “renamed” C function maps to a Rust equivalent under an idiomatic name. This section explains the mapping patterns.

params.c → ParamTable

60+ GSU callback pointers (randomgetfn, uidsetfn, ifsgetfn, homegetfn, termsetfn, etc.) become match arms in ParamTable::get_special_value() and handle_special_set(). Internal helpers (getparamnode, assigngetset, scanparamvals, paramvalarr, getvaluearr) become get_param(), set_scalar(), scan_match(). Env functions (zputenv, addenv, mkenvstr, delenv, copyenvstr) use std::env::set_var/remove_var. Nameref (resolve_nameref_rec, setscope, upscope) becomes resolve_nameref_name(). Uniq array (simple_arrayuniq, newuniqtable, arrayuniq) becomes uniq_array().

parse.c → ShellParser + AST

C’s recursive-descent functions (par_for, par_case, par_if, par_while, par_repeat, par_subsh, par_funcdef, par_time, par_dinbrack, par_simple, par_redir, par_wordlist, par_cond*) become parse_for(), parse_case(), parse_if(), etc. Bytecode system (ecadd, ecdel, ecstrcode, bld_eprog, ecgetstr, ecgetlist, ecgetredirs, init_eprog) replaced by typed AST: ShellCommand enum with Simple, Pipeline, Compound, FunctionDef. ZWC dump/load (dump_find_func, bin_zcompile, load_dump_header, write_dump, build_dump, try_dump_file) moves to zwc.rs.

exec.c → ShellExecutor

execlist→execute_list(), execpline→execute_pipeline(), execsimple→execute_simple(), execode→execute_command(). Function: execshfunc/runshfunc→call_function(), execautofn→autoload_function(). Pipes: spawnpipes/getpipe inline in pipeline execution. Fd: fixfds/closemn/closemnodes inline.

glob.c → Qualifier enum

15 qualifier test functions (qualdev, qualnlink, qualuid, qualgid, qualisdev, qualisblk, qualischr, qualisdir, qualisfifo, qualislnk, qualisreg, qualissock, qualflags, qualmodeflags, qualnonemptydir) become enum variants + GlobMatch::from_path(). Match internals (igetmatch, matchpat, parsecomplist, parsepat, insert_glob_match) in getmatch(), pattern_match(), GlobEngine::glob().

init.c → init_main()

zsh_main→init_main(). Subsystem inits (init_signals, init_misc, init_bltinmods, init_shout, setupshin) fold into ShellExecutor::new() and init_main(). Stubs (noop_function, noop_function_int, zleentry, fallback_compctlread) not needed. parseopts_insert/printhelp/getmypath/tccap_get_name handled inline.

lex.c → Lexer struct

lexinit/initlextabs→Lexer::new(). lex_context_save/restore→save_state()/restore_state(). checkalias/exalias inline in next_token(). skipcomm→lex_comment(). Raw buffer ops (zshlex_raw_add/back/mark/back_to_mark) unnecessary — Rust String handles buffer ops natively.

math.c → MathEvaluator

lexconstant part of number parser. callmathfunc→call_math_func(). setmathvar→set_variable(). getmathparam→get_variable(). mathevall→evaluate(). checkunary/notzero/getcvar inline in eval loop.

jobs.c builtins

bin_fg, bin_kill and bin_suspend keep their C names in src/ported/jobs.rs, the same file as the job internals, as in C, and are registered in BUILTINS (src/ported/builtin.rs).

subst.c

wcpadwidth/subst_parse_str inline in SubstState methods. All 22 other functions matched by name.


$KEY FEATURES PORTED

params.c — Full Parameter System

All 80+ special params with dynamic get/set:

  • $?, $$, $!, $#, $*, $@, $0, $_, $-
  • RANDOM (LCG PRNG, seedable), SECONDS (int + float modes)
  • ERRNO, UID/EUID/GID/EGID (with setuid on assign)
  • COLUMNS/LINES (ioctl), SHLVL, FUNCNEST, OPTIND/OPTARG
  • IFS, HOME, TERM, WORDCHARS, HISTCHARS
  • PS1-PS4, RPS1/2, RPROMPT/2, SPROMPT, POSTEDIT
  • PATH/path, CDPATH/cdpath, FPATH/fpath tied pairs
  • pipestatus, argv, HISTSIZE/SAVEHIST
  • Namerefs with loop detection, scope push/pop with save/restore
  • typeset -p re-executable output, += augmented assignment

pattern.c — Complete Pattern Engine

Bytecode-compiled pattern matcher:

  • Wildcards: *, ?, [...], [!...], [^...]
  • Extended glob: # (0+), ## (1+), ^ (negation), ~ (exclusion)
  • KSH globs: ?(pat), *(pat), +(pat), !(pat), @(pat)
  • Numeric ranges: <n-m>, <n->, <-m>
  • Backreferences with () capture groups (9 max)
  • Case-insensitive: (#i), lowercase-match-upper: (#l)
  • POSIX classes: [:alpha:], [:digit:], [:space:], etc.
  • Glob flags: (#b) backrefs, (#m) match refs, (#s)/(#e) anchors
  • Pattern scope management for completion system

Builtins — Ported + Extensions

Every ported zsh builtin (BUILTINS, src/ported/builtin.rs), plus the extension builtins, including the in-process coreutils:

  • Variables: typeset/local/declare/export/readonly/integer/float
  • I/O: print/printf/echo/read/getln/pushln
  • History: fc/history/r
  • Control: eval/source/exec/command/builtin/noglob
  • Jobs: bg/fg/jobs/kill/wait/disown/suspend
  • Dir: cd/pushd/popd/dirs/pwd
  • Options: set/setopt/unsetopt/emulate
  • Traps: trap/kill
  • Completion: compgen/complete/compdef/compadd/compset
  • ZLE: bindkey/zle/vared
  • Modules: zmodload/autoload/functions
  • Files: mkdir/rmdir/rm/cp/mv/ln/chmod/chown
  • Coreutils (anti-fork): cat/head/tail/wc/sort/find/uniq/cut/tr/seq/rev/tee/sleep/date/mktemp/hostname/uname/whoami/id/basename/dirname/touch/realpath
  • Misc: getopts/zparseopts/zstyle/sched/zformat/coproc

glob.c — Full Globbing

Complete file globbing engine:

  • Recursive scanning with **/ support
  • Brace expansion: {a,b,c}, {1..10}, {a..z}
  • 20+ glob qualifiers: (.) regular, (/) dir, (@) symlink, (=) socket, (p) fifo, (%b) block, (%c) char
  • Permission qualifiers: (r)/(w)/(x), (R)/(W)/(X), (s) setuid
  • Ownership: (u:name:), (U) owned by EUID
  • Size/time/links: (L+n), (m-n), (l+n)
  • Sorting: (on) name, (oL) size, (om) mtime
  • Match/replace: ${var/pat/repl}, ${var//pat/repl}
  • Tokenization: tokenize(), shtokenize(), zshtokenize()

hist.c — Full History

Complete history expansion and management:

  • Event designators: !!, !n, !-n, !string, !?string?
  • Word designators: !:0, !:^, !:$, !:*, !:n-m
  • Quick substitution: ^old^new
  • Modifiers: :h head, :t tail, :r root, :e ext, :l/:u case, :s/o/n/ subst, :& repeat, :q/:Q quote, :x words, :a abs path
  • File I/O with locking, extended format timestamps
  • Deduplication, blank reduction, word splitting
  • History stack for nested parsing contexts
  • Search: prefix (hcomsearch) and substring (hconsearch)

jobs.c — Full Job Control

Complete job lifecycle management:

  • Job table with add/remove/reap/expand/shrink
  • Process tracking: update_process, update_job, update_bg_job
  • Wait: waitforpid, waitjob, waitjobs, waitonejob
  • Control: fg_job, bg_job, disown_job, killjob
  • Process groups: acquire_pgrp, release_pgrp
  • Pipestats tracking with PIPEFAIL support
  • Background status: addbgstatus/getbgstatus
  • Superjob/subjob hierarchy
  • Time reporting: format_time with %E/%U/%S/%P/%J
  • Signal name/number conversion: all 31 standard signals

utils.c — utility surface

Complete utility library:

  • Error/warning: zerr, zerrnam, zwarn, zerrmsg
  • Quoting: quotestring (7 modes), quotedzputs, dquotedztrdup
  • String ops: sepsplit, spacesplit, sepjoin, zjoin, colonsplit
  • Path ops: expand_tilde, findpwd, lchdir, xsymlink, slashsplit
  • Named dirs: finddir, adduserdir, getnameddir, substnamedir
  • Terminal: get_term_width/height, adjustwinsize, gettyinfo/settyinfo
  • Fd: movefd, redup, zclose, read_loop/write_loop
  • Escape parsing: getkeystring (\n \t \xNN \uNNNN \UNNNNNNNN \0NNN \cX)
  • Spelling correction: spdist, spckword, spname, mindist
  • Time: ztrftime, monotonic_time_ns, zsleep

prompt.c + signals.c + init.c

Complete prompt, signal, and init systems:

  • All % escapes: dir (%~/%//%c), user (%n/%m/%M), status (%?/%#), time (%D/%T/%*), history (%h), jobs (%j), psvar (%v)
  • Formatting: %B/%U/%S bold/underline/standout, %F{color}/%K{color}
  • Conditionals: %(?.true.false), truncation, right prompt
  • True color detection, named colors, highlight parsing
  • 28 signal handlers: block/unblock, queue, trap scope management
  • Startup sequence: zshenv, zprofile, zshrc, zlogin, zlogout
  • Emulation modes: zsh, sh, ksh, csh

@PER-SYMBOL PORT INDEX

Hand-maintained per-function tables previously claimed a fixed “859” row total and drifted (wrong Rust paths, inflated coverage). Those rows are removed. The port_report.html file produced by python3 scripts/gen_port_report.py lists every C symbol the indexer extracts from src/zsh/Src/**/*.c (heuristic: top-level ident( with a following {) together with Rust placement and port-doc pointers — regenerate after upstream or port changes.

The core file table above (between PORT_REPORT:CORETABLE markers) is rewritten by the same script from live tree counts; it is not manually curated.


!TEST RESULTS

Pass/fail counts are intentionally not pinned in this HTML snapshot (they drift with feature flags and cargo version). The static surface is the #[test] hook total in the engineering overview below. For a local matrix run cargo test with the same features you ship; when triaging ordering-sensitive cases, --test-threads=1 remains the tie-breaker.


~ARCHITECTURE: WHY RUST IS DIFFERENT

C wordcode vs Rust AST port

C zsh lowers shell to wordcode (ecadd, ecstrcode, bld_eprog) executed from Src/exec.c. The zshrs parser port surfaces a typed AST instead (ShellCommand::Pipeline(Vec<ShellCommand>, bool), etc.), so many wordcode helpers disappear behind enum variants and structured lowering.

Methods Instead of Function Pointers

C’s parameter system uses GSU (get/set/unset) function pointer structs — 60+ callback functions like randomgetfn, uidsetfn, ifsgetfn. Rust dispatches by parameter name in two central match expressions: get_special_value() and handle_special_set(). Same functionality, ~130 fewer function definitions.

Native UTF-8 vs Meta Encoding

C’s zsh uses a custom “meta” encoding for strings containing special characters (20+ functions: metafy, unmetafy, metalen, unmeta, metacharinc, mb_metacharlenconv, etc.). Rust’s String is natively UTF-8. Most meta functions become identity operations or char iteration.

RAII vs Manual Memory

C requires explicit freearray(), freeparamnode(), freeeprog(), freerepldata(), freestr(), deleteparamtable(). Rust’s ownership system handles all of these automatically via Drop. These functions are provided as no-ops for API completeness.


%ENGINEERING OVERVIEW

Workspace-wide cargo workspace layout (zshrs root crate — compsys folded in — plus zshrs-daemon, znative, and vendored crates). Size figures are not typed here; regenerate them with git ls-files '*.rs' | xargs wc -l when needed.


ΔMAY 2026 — RECENT PORT WORK

Three themes closed out across May 2026: (1) every // Deferred / // FAKE / // stub marker in builtin.rs turned into a real C-faithful body, (2) the try_with_executor dispatch path — a Rust-only abstraction that bypassed paramtab — was removed from src/ported/ in May (40 → 0 call sites; later work reintroduced calls, see below), and (3) all 30 module files (clone/cap/example/datetime/socket/tcp/stat/zftp/zprof/zselect/watch/zpty/termcap/terminfo/attr/system/zutil/ksh93/db_gdbm/pcre/param_private/mathfunc/langinfo/hlgroup/mapfile/parameter/nearcolor/random/regex/files) were migrated from per-module featuresarray/handlefeatures/getfeatureenables/setfeatureenables stub copies to the canonical crate::ported::module::* impls — 4 stubs × 30 modules = 120 duplicate fake fns deleted, replaced with slice-based module::Features { bn_list, cd_list, mf_list, pd_list } arrays populated with the real BUILTIN/CONDDEF/MATHFUNC/PARAMDEF entries.

Other major de-faking in May: fake structs in hashtable.rs deleted (CmdName / Alias / Reswd / DirCache / SuffixAliasTable / ReswdToken / ShFunc impl block — all replaced with canonical lowercase C-named structs from zsh_h.rs), jobs.rs deleted (JobEntry / BgStatus / PipeStats / CommandTimer / JobPointers fake aggregates; JobState/JobInfo/JobTable moved out to exec_jobs.rs), input.rs deleted (StringInput convenience wrapper, InputBuffer aggregate, INP_* drift constants), glob.rs deleted (GlobOptions / GlobSort / SortOrder / SortSpec / TimeUnit / SizeUnit / RangeOp / impl GlobMatch), cond.rs deleted (CondType / CondResult / CondEval fake enums), module.rs deleted (Wrapper struct + addwrapper/deletewrapper), options.rs deleted (ShellOption enum, with opt_state_get("name") globally swapped to isset(OPT_CONST)).

AreaWhat landedC sourceRust location
builtin.rsloadautofn — real $fpath walk + file read + PM_UNDEFINED clear (was return-0 stub)exec.c:5050ported/builtin.rs:883
builtin.rsbin_functions -c autoload-trampoline now invokes loadautofnbuiltin.c:3414ported/builtin.rs:1593
builtin.rsscanmatchshfunc wired (replaces stale “funcs.rs” comment that referenced a non-existent file)builtin.c:3682ported/hashtable.rs
builtin.rsbin_functions -M / +M / -m+M — full add/list/remove/match paths into the new MATHFUNCS globalbuiltin.c:3478–3611ported/module.rs:31
builtin.rsbin_return POSIX-trap promotion to TRAP_STATE_FORCE_RETURNbuiltin.c:5845–5854exec.rs::TRAP_STATE/TRAP_RETURN
builtin.rsbin_enable toggles for Builtin / Shfunc / Reswd via real disable/enable; new BUILTINS_DISABLED setbuiltin.c:541–547ported/builtin.rs
builtin.rsinit_builtins — real reswdtab.disable("repeat") when not EMULATE_ZSHbuiltin.c:212ported/builtin.rs:361
signals.rsSIGPIPE / SIGHUP / SIGINT / SIGWINCH / SIGALRM real bodies (zexit, errflag, stopmsg, adjustwinsize, TMOUT)signals.c:429–498ported/signals.rs:670
signals.rsPOSIXTRAPS option lookup for SIGEXIT sticky-tag bypasssignals.c:746ported/signals.rs
jobs.rskill %jobspec dispatch: real getjob + killjb + SIGCONT-after-stop loopjobs.c:2989–3010ported/jobs.rs:2635
params.rsgetsparam/getiparam/getnparam rewritten to C-faithful single-arg paramtab read (was a drift wrapper around HashMap)params.c:3076ported/params.rs:1726
params.rsnumeric-prefix detection (blanks / minus / 0x / base#) for PM_RIGHT_Z paddingparams.c:2446–2466ported/params.rs:975
params.rsfetchvalue real bracket-subscript dispatch into getindex + KSHARRAYS implicit [0]params.c:2289–2296ported/params.rs
params.rsnew DELUNSET atomic file-global; deleteparamtable save/restore; freeparamnode unsetfn dispatchparams.c:610 / 5986ported/params.rs
module.rsnew HOOKTAB global (mirror of Hookdef hooktab) + addhookfunc/deletehookfunc wrappersmodule.c:843ported/module.rs
module.rsnew MATHFUNCS global — user math fn chain for functions -Mmodule.c:1258ported/module.rs:31
zle/zle_main.rsnew WATCH_FDS global — bin_zle -F registration storezle_main.c:204ported/zle/zle_main.rs
zle/zle_refresh.rsnew TCOUT_FUNC_NAME global — bin_zle -T tc redisplay transformzle_refresh.c:246ported/zle/zle_refresh.rs
zle/zle_vi.rsVIRANGEFLAG / WORDFLAG / VILINERANGE / VICHGFLAG / VIINREPEAT / VIINSBEGIN atomic file-globals (replaces ViState aggregate)zle_vi.c:36–78ported/zle/zle_vi.rs
prompt.rssync_from_executor → sync_from_globals: reads paramtab / LASTVAL / curhist / JOBTAB / scriptname directlyprompt.c:56ported/prompt.rs
utils.rsprintprompt4 reads isset(XTRACE) + getsparam("PS4") + opt_state save/restoreutils.c:1720–1730ported/utils.rs:5025
utils.rscallhookfunc walks shfunctab + paramtab <name>_functions arrayutils.c:1494–1514ported/utils.rs

try_with_executor in src/ported/: the May 2026 migration took it from 40 call sites to 0; live calls have since returned in exec.rs, builtin.rs and subst.rs (list them with grep -rn 'try_with_executor(' src/ported | grep -v //).


*MODULE BREAKDOWN BY SUBSYSTEM

Every tracked .rs file under src/ported/ assigned to exactly one subsystem; lines from git ls-files 'src/ported/*.rs' | xargs wc -l (106 files), 2026-10-18.

SubsystemModulesLines%Coverage BarDescription
Core Enginelex, parse, exec, subst, loop, cond, builtin, builtins/*103,46623.0%
Lexer, parser, executor (pipelines, redirects), substitution, loops and conditionals, the builtin table
ZLE Line Editorzle/* (28 files)125,18527.8%
Keymaps, widgets, vi mode, completion, refresh, history navigation, text objects, complete/complist/compctl/compmatch/compcore
Loadable Modulesmodules/* (33 modules + mod.rs, tcp_h.rs)69,56215.4%
33 module ports: networking, files, PCRE, curses, profiling, pseudo-tty, parameter introspection, math functions, db_gdbm, etc.
Utilitiesutils, compat, sort, string, input, linklist, mem28,5086.3%
String ops, quoting, escape parsing, path resolution, spelling correction
Parametersparams23,6205.2%
Special params, namerefs, scoping, tied pairs, typeset, GSU dispatch (param_private and parameter are counted under Loadable Modules)
Pattern / Globpattern, glob21,2134.7%
Compiled pattern engine, glob qualifiers, brace expansion, match/replace
Jobs / Signalsjobs, signals, signals_h13,1322.9%
Process lifecycle, pipestats, trap scopes, signal queuing, fg/bg/disown
Mathmath7,7521.7%
Arithmetic evaluator (mathfunc is counted under Loadable Modules)
Prompt / Textprompt, text9,6852.1%
% escape expansion, colors, truncation, right prompt, AST deparsing
Historyhist9,1862.0%
Expansion (!!/!$/^old^new), modifiers (:h:t:r:e:s), file I/O, word splitting
Options / Initoptions, init, context8,0831.8%
Shell options, startup files, emulation modes (sh/ksh/csh/zsh)
Otherhashtable, hashtable_h, hashnameddir, module, modentry, zsh_h, zsh_system_h, ztype_h, config_h, prototypes_h, patchlevel, openssh_bsd_setres_id, mod31,2886.9%
Hash tables, module loader, header ports (zsh.h, system.h, ztype.h, config.h, prototypes.h)
TOTAL (src/ported/)450,680100%

+33 LOADABLE MODULE PORTS

Each C module from src/zsh/Src/Modules/ has a corresponding strict-port Rust implementation in src/ported/modules/. Module file set is included in the file freeze on src/ported/; every module now routes its features_ / enables_ / cleanup_ hooks through the canonical module::featuresarray / handlefeatures / setfeatureenables impls instead of per-module Rust-only stub copies.

zsh/attr

zgetattr, zsetattr, zdelattr, zlistattr — extended attributes (xattr)

zsh/cap

cap, getcap, setcap — POSIX capabilities (gated on Linux and a libcap cargo feature that Cargo.toml does not declare, so absent from current builds)

zsh/clone

clone builtin — fork shell to new tty

zsh/curses

zcurses — ncurses windows, colors, attributes, input

zsh/datetime

strftime builtin, $EPOCHSECONDS/$EPOCHREALTIME/$epochtime

zsh/db/gdbm

ztie, zuntie, zgdbmpath — GDBM tied associative arrays

zsh/example

Demonstration module — builtins / conddefs / mathfuncs / paramdefs

zsh/files

chgrp, chmod, chown, ln, mkdir, mv, rm, rmdir, sync + zf_ aliases (18 entries)

zsh/hlgroup

$.zle.esc, $.zle.sgr — highlighting group helper

zsh/ksh93

nameref + .sh.* param family (edchar, edmode, file, lineno, match, name, subscript, subshell, version)

zsh/langinfo

$langinfo — nl_langinfo(3) queries (CODESET, D_FMT, etc.)

zsh/mapfile

$mapfile assoc array — memory-mapped file access

zsh/mathfunc

48 math functions (sin/cos/log/sqrt/atan/copysign/hypot/ilogb/nextafter/scalb/...)

zsh/nearcolor

Hook into get_color_attr for nearest-truecolor remap

zsh/newuser

First-login wizard hook (~/.zshrc seeding)

zsh/param/private

private builtin — local-only param scope override

zsh/parameter

33 magic assoc params: $parameters, $functions, $aliases, $commands, $options, $history, $modules, etc.

zsh/pcre

pcre_compile, pcre_match, pcre_study, =~ condition — Perl-compatible regex

zsh/random

$SRANDOM, zrand_float, zrand_int — /dev/urandom backed

zsh/random/real

Real-valued random number generation (extras for math expressions)

zsh/regex

POSIX regex-match condition — [[ x =~ pat ]]

zsh/net/socket

zsocket builtin — Unix domain sockets

zsh/stat

zstat, stat builtins — stat fields, formatting, array output

zsh/system

syserror, sysread, syswrite, sysopen, sysseek, zsystem flock, systell math fn, $errnos/$sysparams

zsh/net/tcp

ztcp builtin — TCP client/server connections

zsh/termcap

echotc + $termcap assoc — termcap capability database

zsh/terminfo

echoti + $terminfo assoc — terminfo capability database

zsh/watch

log builtin, $WATCH/$watch arrays — login/logout watching, utmp parsing

zsh/zftp

zftp builtin — full FTP client (open / get / put / ls / cd / mkdir / ...)

zsh/zprof

zprof builtin — function profiler (gprof-style call/arc graph)

zsh/zpty

zpty builtin — pseudo-terminal process management

zsh/zselect

zselect builtin — poll/select on file descriptors

zsh/zutil

zformat, zparseopts, zregexparse, zstyle — completion-system utilities


^ZLE LINE EDITOR — 28 FILES, 125,185 LINES

The Zsh Line Editor (ZLE) is a complete terminal-based input system with vi and emacs keybinding modes, programmable widgets, and inline completion. Ported from src/zsh/Src/Zle/*.c. Files mirror the C source 1:1 with the canonical zsh prefix (zle_* / comp* / termquery / deltochar).

FileLinesResponsibility
computil.rs11,626Completion utility functions used by _arguments etc.
zle_refresh.rs10,025Screen refresh, cursor positioning, line wrapping, TCOUT_FUNC_NAME
compcore.rs9,598Completion core: shared matcher state, group ordering
complist.rs9,093Menu selection (Tab cycling, arrow nav, mouse)
compctl.rs8,606Legacy compctl system (pre-compsys, kept for back-compat)
compmatch.rs7,566Match patterns, anchor matching, case-insensitive matchers
zle_tricky.rs7,103Completion: prefix matching, menu selection, listing
compresult.rs6,212Match result presentation, prefix/suffix sharing
zle_main.rs5,594ZLE main loop, key reading, widget dispatch, initialization, WATCH_FDS
complete.rs5,039Completion engine: compadd, compset, _arguments dispatch
zle_keymap.rs4,911Keymap management, key binding, bindkey builtin
zle_misc.rs4,874Miscellaneous widgets: transpose, case change, undo, named-cmd lookup
zle_hist.rs4,168History widgets: up/down, search, accept-line
zle_utils.rs3,769ZLE utility functions, character classification, prompt expansion
zle_thingy.rs3,365Thingy (widget reference) management, zle -A / zle -N
zle_params.rs3,049ZLE special parameters: $BUFFER, $CURSOR, $LBUFFER, $RBUFFER, $REGION_ACTIVE, etc.
zle_vi.rs2,903Vi mode: motions, operators, text objects, registers; VIRANGEFLAG / WORDFLAG / VILINERANGE / VICHGFLAG / VIINREPEAT / VIINSBEGIN atomics
termquery.rs2,616Terminal capability queries (tigetstr / tparm)
zle_word.rs2,574Word detection, WORDCHARS handling, shell-word vs vi-word
zle_move.rs2,466Cursor movement: word, line, char, matching bracket
zle_h.rs2,003Header port — keymap / widget / keystruct types
comp_h.rs1,971Header port — Cmatcher / Cmgroup / Cmlist types
zle_bindings.rs1,802Default emacs/vi keymap tables
zleparameter.rs1,450$widgets, $keymaps, $builtins intro params for zle/parameter module
compctl_h.rs1,305Header port for compctl
textobjects.rs1,040Vi text objects: iw, aw, i", a(, i{, etc.
deltochar.rs353Delete-to-char widget (Vi f/t/F/T family)
mod.rs104Module declarations and re-exports
TOTAL ZLE125,185

;PORTED SHELL BUILTINS

The ported builtin table is BUILTINS in src/ported/builtin.rs; each BUILTIN(...) row names its bin_* handler, defined in src/ported/builtin.rs or in the port file that owns it (src/ported/modules/*.rs, src/ported/zle/*.rs, jobs.rs, options.rs, builtins/rlimits.rs, …). The table holds BUILTIN( rows (fg, kill and suspend are each registered twice) and BIN_PREFIX( precommand modifiers; every distinct BUILTIN name is listed below. compat_builtin_names() (src/extensions/ext_builtins.rs), which feeds the reference’s Compat Builtin Index and zbanner, dedups the table. The zshrs extension builtins (EXT_BUILTIN_NAMES: coreutils, parallel primitives, compgen/complete, …) are a separate table and are not listed here.

Variable Declaration (12)

typeset local declare export readonly integer float set unset shift private nameref

I/O (6)

echo print printf read getln pushln

Flow Control & Exit (9)

. source eval break continue return exit bye logout

Job Control & Traps (8)

bg fg jobs kill wait disown suspend trap

Directory (6)

cd chdir pushd popd dirs pwd

History (3)

fc history r

Options & Emulation (5)

setopt unsetopt emulate enable disable

Alias, Function & Hash (8)

alias unalias functions autoload unfunction hash unhash rehash

Lookup (4)

type whence where which

Test & Arithmetic (6)

test [ let true false :

Modules, Compilation & Option Parsing (4)

zmodload zcompile getopts zparseopts

Completion (compctl / computil / complete) (12)

compadd comparguments compcall compctl compdescribe compfiles compgroups compquote compset comptags comptry compvalues

ZLE (3)

bindkey zle vared

File Operations (zsh/files) (18)

chgrp chmod chown ln mkdir mv rm rmdir sync zf_chgrp zf_chmod zf_chown zf_ln zf_mkdir zf_mv zf_rm zf_rmdir zf_sync

stat & xattr (zsh/stat, zsh/attr) (6)

stat zstat zgetattr zsetattr zdelattr zlistattr

System (zsh/system) (6)

syserror sysopen sysread sysseek syswrite zsystem

Limits, Timing & Scheduling (6)

ulimit limit unlimit umask times sched

Networking (3)

ztcp zsocket zftp

Terminal (6)

echotc echoti ttyctl zcurses zpty zselect

zsh/zutil (3)

zformat zstyle zregexparse

Other Modules (14)

strftime clone log cap getcap setcap example zprof ztie zuntie zgdbmpath pcre_compile pcre_match pcre_study

Debug-Build Builtins (zsh: ZSH_HASH_DEBUG / ZSH_MEM_DEBUG / ZSH_PAT_DEBUG) (3)

hashinfo mem patdebug

zshrs-native (no C counterpart) (1)

__rust_compile

Precommand modifiers (BIN_PREFIX, not counted above) (5)

- builtin command exec noglob


&DEPENDENCY ARCHITECTURE

Line counts are wc -l on the named files under src/ported/ (directories: sum of their tracked .rs files), 2026-10-18.

               ┌─────────────────────────────────────┐
               │          exec.rs (15,029)           │
               │         builtin.rs (25,612)         │
               └──────────────────┬──────────────────┘
                                  │
      ┌───────────────────────────┼───────────────────────────┐
┌─────▼─────┐               ┌─────▼─────┐               ┌─────▼─────┐
│ parse.rs  │               │  lex.rs   │               │ subst.rs  │
│ (12,808)  │               │  (7,739)  │               │ (34,354)  │
└─────┬─────┘               └───────────┘               └─────┬─────┘
      │                                                       │
      ├─────────────┬─────────────┬─────────────┬─────────────┼─────────────┐
┌─────▼─────┐ ┌─────▼─────┐ ┌─────▼─────┐ ┌─────▼─────┐ ┌─────▼─────┐ ┌─────▼─────┐
│  params   │ │  pattern  │ │   glob    │ │   hist    │ │   math    │ │   text    │
│ (23,620)  │ │ (11,279)  │ │  (9,934)  │ │  (9,186)  │ │  (7,752)  │ │  (2,455)  │
└─────┬─────┘ └───────────┘ └───────────┘ └─────┬─────┘ └───────────┘ └───────────┘
      │                                         │
┌─────▼─────┐ ┌───────────┐ ┌───────────┐ ┌─────▼─────┐ ┌───────────┐ ┌───────────┐
│   utils   │ │   jobs    │ │  signals  │ │  prompt   │ │   init    │ │  options  │
│ (17,967)  │ │  (7,803)  │ │  (3,871)  │ │  (7,230)  │ │  (3,614)  │ │  (3,630)  │
└───────────┘ └─────┬─────┘ └───────────┘ └───────────┘ └───────────┘ └───────────┘
                    │
      ┌─────────────┼─────────────┬─────────────┐
┌─────▼─────┐ ┌─────▼─────┐ ┌─────▼─────┐ ┌─────▼─────┐
│   zle/    │ │   cond    │ │   loop    │ │ modules/  │
│ (125,185) │ │  (2,220)  │ │  (1,300)  │ │ (69,562)  │
└───────────┘ └───────────┘ └───────────┘ └───────────┘

◆COMPSYS — ZSH COMPLETION SYSTEM IN RUST

zsh’s compsys — the programmable completion system — inside the runtime crate under src/compsys/ (the former standalone crate was folded in). Runtime files plus engine ports under src/compsys/ported/, which sit beside the upstream Completion/ files copied verbatim.

ModuleLinesDescription
ported/ (250 files)76,916Engine functions ported to Rust, one .rs per upstream function, each citing its shell source; per-directory breakdown below.
cache.rs2,149SQLite mirror tables for compsys. Mirror only — the authoritative completion cache is the rkyv-mmap’d shard set (zero-copy hot path); this file backs dbview / SQL inspection.
router.rs1,012Backend router between the Rust ports under ported/ and the upstream shell functions.
in_editor.rs837In-editor entry point: drives _main_complete outside an interactive shell so the LSP gets the match list a Tab press would produce.
zpwr_colors.rs804ZPWR zstyle color configuration parser.
mod.rs342Module root.
TOTAL COMPSYS82,060255 files

// 250 ENGINE PORTS BY UPSTREAM DIRECTORY

DirectoryFilesLines
Unix/Type7019,130
Base/Utility2611,268
(top level: compinit, compdump, compaudit, shared, mod)59,546
Base/Core116,564
Zsh/Type286,050
Base/Completer165,188
X/Type193,423
Zsh/Context163,297
Base/Widget122,685
BSD/Type111,934
Linux/Type81,557
Debian/Type51,322
Zsh/Function71,278
Darwin/Type31,129
Zsh/Command3781
Solaris/Type3760
AIX/Type4504
X/Utility2469
Unix/Command131
TOTAL PORTED25076,916

⬢FUSEVM + LEX / PARSE (src/ported/)

Runtime bytecode targets the crates.io fusevm crate (pinned in workspace Cargo.toml). Lexing and parsing live in src/ported/lex.rs and src/ported/parse.rs in the runtime crate (the standalone parse package was absorbed back). Stryke / strykelang is a separate repository — it is not part of this workspace; the former Perl-interpreter block here was erroneous pasted content.

// LEX + PARSER (IN-CRATE PORTS)

FileLinesRole
src/ported/lex.rs7,739Lexer port of Src/lex.c — tokens, contexts, alias fusion
src/ported/parse.rs12,808Parser port of Src/parse.c — lists, compounds, redirections
LEX + PARSE20,547two files in src/ported/ (no separate parse crate)

// EXECUTION PIPELINE (ZSHRS)

  Source / REPL input (zsh script)
       │
       ▼
  ┌─────────────────┐     ┌──────────────────┐
  │  Lexer          │────▶│  Parser          │
  │  (lex.rs)       │     │  (parse.rs)      │
  │  token stream   │     │  AST / commands  │
  └────────┬────────┘     └────────┬─────────┘
           │                       │
           └───────────┬───────────┘
                       ▼
              ┌────────────────────┐
              │ compile_zsh (+AOT) │  ──▶  fusevm bytecode (workspace crate)
              │ extensions/        │
              └─────────┬──────────┘
                        ▼
              ┌────────────────────┐
              │ ShellExecutor / VM │  ──▶  builtins, jobs, redirects, zle
              └────────────────────┘

●BEYOND THE C PORT — RUNTIME INFRASTRUCTURE

The C-to-Rust port covered above lives under src/ported/ against upstream src/zsh/Src/**/*.c. The numbers below count what zshrs adds — new Rust code with no C ancestor. This is the layer that takes zshrs from “zsh in Rust” to “the first JIT-compiled Unix shell with a session-persistent daemon, AOP-intercept recorder, and bidirectional ptmx-attach job supervisor.” Non-port runtime code lives in src/extensions/ — mechanically isolated from src/ported/ by tests/port_purity.rs.

Crate / LayerFilesLinesPub FnsTestsPurpose
src/extensions/ 135 148,648 945 1,417 The non-port directory. Features zsh C demonstrably does not have: AOT compile (aot.rs, compile_zsh.rs), autoload / plugin / script caches (autoload_cache.rs, plugin_cache.rs, script_cache.rs), fish-style features (fish_features.rs), persistent worker pool (worker.rs), arith JIT compiler (arith_compiler.rs), AST s-exp dump (ast_sexp.rs), ZWC byte-code helpers (zwc.rs, zwc_decode.rs), recorder hooks (recorder.rs), daemon presence (daemon_presence.rs), structured logging (log.rs), ext builtins (ext_builtins.rs), regex module (regex_mod.rs), config (config.rs), overlay snapshot + canonical apply (overlay_snapshot.rs, canonical_apply.rs), fds / hist (fds.rs, history.rs), stringsort (stringsort.rs), completion shim (completion.rs). Mounted at the crate root by #[path = "extensions/…"] module declarations in src/lib.rs, so call sites resolve to crate::aot::*, etc.
daemon/ 43 29,687 239 142 Singleton daemon: IPC server, HTTP listener (auto-derived OpenAPI 3.1), canonical-state engine, fsnotify, schedule, supervisor (jobs + bidirectional ptmx attach), pub/sub bus, named locks, ask-inbox, snapshots, artifacts, cache. Hosts every z* builtin.
src/recorder/ (feature-gated) 1 2,134 56 2 AOP intercept: every state-mutating dispatcher fires a record event with (kind, name, value, file, line, fn_chain). #[cfg(feature = "recorder")]-gated — deleted by rustc in the default zshrs build, compiled into the separate zshrs-recorder binary. Replaces the static-walker approach every other shell uses for completion/fpath scanning.
vendor/fish/ 157 88,088 1,244 175 Fish-style reader, syntax highlighter, autosuggestions, abbreviations, env dispatch, history backend, process control, event system. Largest non-port surface in the workspace.
src/compsys/ 255 82,060 501 1,032 Completion system inside the runtime crate: SQL mirror, backend router, in-editor entry point, and 250 engine ports of upstream Completion/ shell functions. No C ancestor (zsh's compsys is shell-script, not C).
NEW INFRASTRUCTURE (rows above)591350,6172,9852,768
Sums cover the five layers in this table only. Workspace-wide Rust LOC additionally includes src/ported/, the top-level src/*.rs glue, tests/, examples/, bins/, build.rs, znative/ and runtime/.

Architectural moves with no zsh equivalent: the 90/10 daemon/shell work split (singleton daemon owns every mutation; thin shell clients are stateless and forkable); the recorder-owns-rebuild stance (no in-daemon walker; zshrs-recorder is the sole producer of recorder-managed canonical subsystems); the single ~/.zshrs/ directory rule (every config + log + sqlite + rkyv shard + socket under one root, configurable via $ZSHRS_HOME); the z* builtin family (zcache / zls / zsend / znotify / zsubscribe / zjob / zsync / zask / zlock / zpublish / zwhere / zd); session-persistent supervised jobs with bidirectional ptmx attach (replaces nohup + screen + pueue + disown); the auto-derived OpenAPI 3.1 surface at GET /openapi from the daemon op registry; the flat zsh-extended-history text file + sibling FTS5 sqlite index; zsh grammar introspection to stdout (lexer token stream, Eprog wordcode layout, parser AST S-expression) via zshrs --dump-* and zshrs_dump (dumptokens, dumpwordcode) in formats byte-diffable against parity harnesses — not shipped as a trio by stock zsh. Op-by-op detail in daemon-report.html.


≡GRAND TOTAL — FULL WORKSPACE

Four Rust packages in one Cargo workspace (zshrs + zshrs-daemon + znative + zshrs-runtime, the 16-line crate that emits the zsh staticlib for AOT linking; compsys was folded into zshrs). Size figures are not typed here; regenerate them with git ls-files '*.rs' | xargs wc -l.

CrateDescription
zshrs (root, lib zsh) Runtime: src/ (ported + extensions + compsys + exec bridge), bins/, tests/, examples/, build.rs. Lines/tests include integration suites.
vendor/ (vendored crates) Vendored third-party crates carried in-tree so a clone builds offline — includes vendor/fish/. (compsys is no longer a separate package — it was folded into the root crate.)
zshrs-daemon Singleton daemon: IPC + HTTP/OpenAPI, canonical shards, jobs, fsnotify, pub/sub.
znative Published plugin ABI SDK: third parties cargo add znative, ship a cdylib, load it via zmodload -R.
zshrs-runtime Emits libzsh.a for AOT linking so cargo install zshrs does not build it (runtime/src/lib.rs).