#[allow(unused_imports)]
#[allow(unused_imports)]
use crate::ported::zle::zle_main::*;
#[allow(unused_imports)]
use crate::ported::zle::zle_misc::*;
#[allow(unused_imports)]
use crate::ported::zle::zle_hist::*;
#[allow(unused_imports)]
use crate::ported::zle::zle_move::*;
#[allow(unused_imports)]
use crate::ported::zle::zle_word::*;
#[allow(unused_imports)]
use crate::ported::zle::zle_params::*;
#[allow(unused_imports)]
use crate::ported::zle::zle_vi::*;
#[allow(unused_imports)]
use crate::ported::zle::zle_utils::*;
#[allow(unused_imports)]
use crate::ported::zle::zle_refresh::*;
#[allow(unused_imports)]
use crate::ported::zle::zle_tricky::*;
#[allow(unused_imports)]
use crate::ported::zle::textobjects::*;
#[allow(unused_imports)]
use crate::ported::zle::deltochar::*;
pub const CCT_UNUSED: i32 = 0; pub const CCT_POS: i32 = 1; pub const CCT_CURSTR: i32 = 2; pub const CCT_CURPAT: i32 = 3; pub const CCT_WORDSTR: i32 = 4; pub const CCT_WORDPAT: i32 = 5; pub const CCT_CURSUF: i32 = 6; pub const CCT_CURPRE: i32 = 7; pub const CCT_CURSUB: i32 = 8; pub const CCT_CURSUBC: i32 = 9; pub const CCT_NUMWORDS: i32 = 10; pub const CCT_RANGESTR: i32 = 11; pub const CCT_RANGEPAT: i32 = 12; pub const CCT_QUOTE: i32 = 13;
pub const CC_FILES: u64 = 1 << 0; pub const CC_COMMPATH: u64 = 1 << 1; pub const CC_REMOVE: u64 = 1 << 2; pub const CC_OPTIONS: u64 = 1 << 3; pub const CC_VARS: u64 = 1 << 4; pub const CC_BINDINGS: u64 = 1 << 5; pub const CC_ARRAYS: u64 = 1 << 6; pub const CC_INTVARS: u64 = 1 << 7; pub const CC_SHFUNCS: u64 = 1 << 8; pub const CC_PARAMS: u64 = 1 << 9; pub const CC_ENVVARS: u64 = 1 << 10; pub const CC_JOBS: u64 = 1 << 11; pub const CC_RUNNING: u64 = 1 << 12; pub const CC_STOPPED: u64 = 1 << 13; pub const CC_BUILTINS: u64 = 1 << 14; pub const CC_ALREG: u64 = 1 << 15; pub const CC_ALGLOB: u64 = 1 << 16; pub const CC_USERS: u64 = 1 << 17; pub const CC_DISCMDS: u64 = 1 << 18; pub const CC_EXCMDS: u64 = 1 << 19; pub const CC_SCALARS: u64 = 1 << 20; pub const CC_READONLYS: u64 = 1 << 21; pub const CC_SPECIALS: u64 = 1 << 22; pub const CC_DELETE: u64 = 1 << 23; pub const CC_NAMED: u64 = 1 << 24; pub const CC_QUOTEFLAG: u64 = 1 << 25; pub const CC_EXTCMDS: u64 = 1 << 26; pub const CC_RESWDS: u64 = 1 << 27; pub const CC_DIRS: u64 = 1 << 28; pub const CC_EXPANDEXPL: u64 = 1 << 30; pub const CC_RESERVED: u64 = 1 << 31;
pub const CC_NOSORT: u64 = 1 << 0; pub const CC_XORCONT: u64 = 1 << 1; pub const CC_CCCONT: u64 = 1 << 2; pub const CC_PATCONT: u64 = 1 << 3; pub const CC_DEFCONT: u64 = 1 << 4; pub const CC_UNIQCON: u64 = 1 << 5; pub const CC_UNIQALL: u64 = 1 << 6;
#[derive(Debug, Clone)]
#[allow(non_camel_case_types)]
pub struct Compctlp { pub cc: std::sync::Arc<Compctl>, }
#[derive(Debug, Clone)]
#[allow(non_camel_case_types)]
pub struct Patcomp { pub next: Option<Box<Patcomp>>, pub pat: String, pub cc: std::sync::Arc<Compctl>, }
#[derive(Debug, Clone, Default)]
#[allow(non_camel_case_types)]
pub struct Compcond { pub and: Option<Box<Compcond>>, pub or: Option<Box<Compcond>>, pub typ: i32, pub n: i32, pub u: CompcondData, }
#[derive(Debug, Clone, Default)]
#[allow(non_camel_case_types)]
pub enum CompcondData { R { a: Vec<i32>, b: Vec<i32> },
S { p: Vec<i32>, s: Vec<String> },
L { a: Vec<String>, b: Vec<String> },
#[default]
Unused,
}
#[derive(Debug, Clone, Default)]
#[allow(non_camel_case_types)]
pub struct Compctl { pub refc: i32, pub next: Option<std::sync::Arc<Compctl>>, pub mask: u64, pub mask2: u64, pub keyvar: Option<String>, pub glob: Option<String>, pub str: Option<String>, pub func: Option<String>, pub explain: Option<String>, pub ylist: Option<String>, pub prefix: Option<String>, pub suffix: Option<String>, pub subcmd: Option<String>, pub substr: Option<String>, pub withd: Option<String>, pub hpat: Option<String>, pub hnum: i32, pub gname: Option<String>, pub ext: Option<std::sync::Arc<Compctl>>, pub cond: Option<Box<Compcond>>, pub xor: Option<std::sync::Arc<Compctl>>, pub matcher: Option<Box<crate::ported::zle::comp_h::Cmatcher>>, pub mstr: Option<String>, }
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn cct_constants_correct() {
let _g = crate::ported::zle::zle_main::zle_test_setup();
assert_eq!(CCT_UNUSED, 0);
assert_eq!(CCT_POS, 1);
assert_eq!(CCT_CURSTR, 2);
assert_eq!(CCT_QUOTE, 13);
}
#[test]
fn cc_primary_mask_bits_distinct() {
let _g = crate::ported::zle::zle_main::zle_test_setup();
let all = CC_FILES | CC_COMMPATH | CC_REMOVE | CC_OPTIONS
| CC_VARS | CC_BINDINGS | CC_ARRAYS | CC_INTVARS
| CC_SHFUNCS | CC_PARAMS | CC_ENVVARS | CC_JOBS
| CC_RUNNING | CC_STOPPED | CC_BUILTINS | CC_ALREG
| CC_ALGLOB | CC_USERS | CC_DISCMDS | CC_EXCMDS
| CC_SCALARS | CC_READONLYS | CC_SPECIALS | CC_DELETE
| CC_NAMED | CC_QUOTEFLAG | CC_EXTCMDS | CC_RESWDS
| CC_DIRS | CC_EXPANDEXPL | CC_RESERVED;
assert_eq!(all.count_ones(), 31); }
#[test]
fn cc_secondary_mask_values() {
let _g = crate::ported::zle::zle_main::zle_test_setup();
assert_eq!(CC_NOSORT, 1);
assert_eq!(CC_XORCONT, 2);
assert_eq!(CC_UNIQALL, 1 << 6);
}
#[test]
fn compctl_default_zeros_fields() {
let _g = crate::ported::zle::zle_main::zle_test_setup();
let cc = Compctl::default();
assert_eq!(cc.refc, 0);
assert!(cc.next.is_none());
assert_eq!(cc.mask, 0);
assert_eq!(cc.mask2, 0);
assert!(cc.keyvar.is_none());
assert!(cc.cond.is_none());
assert!(cc.xor.is_none());
assert_eq!(cc.hnum, 0);
}
#[test]
fn compcond_default_is_unused() {
let _g = crate::ported::zle::zle_main::zle_test_setup();
let c = Compcond::default();
assert_eq!(c.typ, CCT_UNUSED);
assert!(matches!(c.u, CompcondData::Unused));
}
#[test]
fn compcond_data_variants() {
let _g = crate::ported::zle::zle_main::zle_test_setup();
let r = CompcondData::R { a: vec![0, 1], b: vec![2, 3] };
if let CompcondData::R { a, b } = r {
assert_eq!(a, vec![0, 1]);
assert_eq!(b, vec![2, 3]);
} else {
panic!("expected R variant");
}
let s = CompcondData::S { p: vec![1], s: vec!["x".into()] };
assert!(matches!(s, CompcondData::S { .. }));
let l = CompcondData::L { a: vec!["lo".into()], b: vec!["hi".into()] };
assert!(matches!(l, CompcondData::L { .. }));
}
#[test]
fn cct_constants_are_unique() {
let _g = crate::ported::zle::zle_main::zle_test_setup();
let all = [
CCT_UNUSED, CCT_POS, CCT_CURSTR, CCT_CURPAT,
CCT_WORDSTR, CCT_WORDPAT, CCT_CURSUF, CCT_CURPRE,
CCT_CURSUB, CCT_CURSUBC, CCT_NUMWORDS,
CCT_RANGESTR, CCT_RANGEPAT, CCT_QUOTE,
];
let unique: std::collections::HashSet<_> = all.iter().copied().collect();
assert_eq!(unique.len(), all.len(),
"duplicate CCT_* constant detected");
for &v in &all {
assert!(v >= 0, "CCT_* constants must be non-negative");
}
}
#[test]
fn cct_unused_is_zero() {
assert_eq!(CCT_UNUSED, 0, "CCT_UNUSED must be the zero-init sentinel");
}
#[test]
fn cc_primary_mask_bits_are_distinct_singletons() {
let primary = [
CC_FILES, CC_COMMPATH, CC_REMOVE, CC_OPTIONS,
CC_VARS, CC_BINDINGS, CC_ARRAYS, CC_INTVARS,
CC_SHFUNCS, CC_PARAMS, CC_ENVVARS,
];
for &m in &primary {
assert_eq!(m.count_ones(), 1, "primary CC_ mask {} has {} bits set",
m, m.count_ones());
}
let mut all: u64 = 0;
for &m in &primary {
assert_eq!(all & m, 0, "primary CC_ mask {} overlaps", m);
all |= m;
}
}
#[test]
fn compctl_default_partial_population_doesnt_clobber_other_fields() {
let _g = crate::ported::zle::zle_main::zle_test_setup();
let mut cc = Compctl::default();
cc.mask = CC_FILES;
assert_eq!(cc.mask, CC_FILES);
assert_eq!(cc.refc, 0);
assert!(cc.next.is_none());
assert_eq!(cc.mask2, 0);
assert!(cc.keyvar.is_none());
assert!(cc.cond.is_none());
assert_eq!(cc.hnum, 0);
}
#[test]
fn compcond_default_typ_and_data_are_consistent() {
let _g = crate::ported::zle::zle_main::zle_test_setup();
let c = Compcond::default();
assert_eq!(c.typ, CCT_UNUSED, "tag must be UNUSED");
assert!(matches!(c.u, CompcondData::Unused),
"data must be CompcondData::Unused");
}
#[test]
fn cc_primary_mask_full_sweep_no_overlap() {
let primary = [
CC_FILES, CC_COMMPATH, CC_REMOVE, CC_OPTIONS, CC_VARS,
CC_BINDINGS, CC_ARRAYS, CC_INTVARS, CC_SHFUNCS, CC_PARAMS,
CC_ENVVARS, CC_STOPPED, CC_BUILTINS, CC_ALREG, CC_ALGLOB,
CC_USERS, CC_DISCMDS, CC_EXCMDS, CC_SCALARS, CC_READONLYS,
CC_SPECIALS, CC_DELETE, CC_NAMED, CC_QUOTEFLAG, CC_EXTCMDS,
CC_RESWDS, CC_DIRS, CC_EXPANDEXPL, CC_RESERVED,
];
for &m in &primary {
assert_eq!(m.count_ones(), 1,
"primary CC_ mask {:#x} must be single bit", m);
}
let mut all: u64 = 0;
for &m in &primary {
assert_eq!(all & m, 0,
"CC_ mask {:#x} overlaps with previous flags", m);
all |= m;
}
}
#[test]
fn cc_expandexpl_at_bit_30_skips_bit_29() {
assert_eq!(CC_EXPANDEXPL, 1 << 30,
"c:148 — CC_EXPANDEXPL must be at bit 30 (bit 29 is the gap)");
let all_primary = [
CC_FILES, CC_COMMPATH, CC_REMOVE, CC_OPTIONS, CC_VARS,
CC_BINDINGS, CC_ARRAYS, CC_INTVARS, CC_SHFUNCS, CC_PARAMS,
CC_ENVVARS, CC_STOPPED, CC_BUILTINS, CC_ALREG, CC_ALGLOB,
CC_USERS, CC_DISCMDS, CC_EXCMDS, CC_SCALARS, CC_READONLYS,
CC_SPECIALS, CC_DELETE, CC_NAMED, CC_QUOTEFLAG, CC_EXTCMDS,
CC_RESWDS, CC_DIRS, CC_EXPANDEXPL, CC_RESERVED,
];
let bit_29: u64 = 1 << 29;
for &m in &all_primary {
assert_ne!(m, bit_29,
"no primary mask should occupy bit 29 (the documented gap)");
}
}
#[test]
fn cc_reserved_is_bit_31() {
assert_eq!(CC_RESERVED, 1u64 << 31);
}
#[test]
fn secondary_mask_collides_with_primary_by_design() {
assert_eq!(CC_NOSORT, CC_FILES,
"collision is intentional — different mask fields");
assert_eq!(CC_XORCONT, CC_COMMPATH);
let secondary = [
CC_NOSORT, CC_XORCONT, CC_CCCONT, CC_PATCONT,
CC_DEFCONT, CC_UNIQCON, CC_UNIQALL,
];
let mut all: u64 = 0;
for &m in &secondary {
assert_eq!(m.count_ones(), 1,
"secondary CC_ mask {:#x} must be single bit", m);
assert_eq!(all & m, 0,
"secondary {:#x} overlaps within mask2 namespace", m);
all |= m;
}
}
#[test]
fn cct_values_are_sequential_zero_through_thirteen() {
let in_order = [
CCT_UNUSED, CCT_POS, CCT_CURSTR, CCT_CURPAT, CCT_WORDSTR,
CCT_WORDPAT, CCT_CURSUF, CCT_CURPRE, CCT_CURSUB, CCT_CURSUBC,
CCT_NUMWORDS, CCT_RANGESTR, CCT_RANGEPAT, CCT_QUOTE,
];
for (i, &v) in in_order.iter().enumerate() {
assert_eq!(v, i as i32,
"CCT_ at position {} must be {}, got {}", i, i, v);
}
}
}