use crate::ported::zle::comp_h::{Aminfo, Cexpl, Cmatch, Cmatcher, Cmgroup};
use crate::ported::zle::compcore::{allccs, expls, fmatches, matches};
use std::sync::atomic::Ordering::Relaxed;
use std::sync::{Arc, Mutex};
pub fn matches_arc() -> Arc<Mutex<Vec<Cmatch>>> {
Arc::clone(&matches.get_or_init(default_match_handle).lock().unwrap())
}
pub fn fmatches_arc() -> Arc<Mutex<Vec<Cmatch>>> {
Arc::clone(&fmatches.get_or_init(default_match_handle).lock().unwrap())
}
pub fn expls_arc() -> Arc<Mutex<Vec<Cexpl>>> {
Arc::clone(&expls.get_or_init(default_expl_handle).lock().unwrap())
}
pub fn allccs_arc() -> Arc<Mutex<Vec<String>>> {
Arc::clone(&allccs.get_or_init(default_ccs_handle).lock().unwrap())
}
#[allow(clippy::type_complexity)]
pub fn rebind_current(
lmatches: &Arc<Mutex<Vec<Cmatch>>>,
lfmatches: &Arc<Mutex<Vec<Cmatch>>>,
lexpls: &Arc<Mutex<Vec<Cexpl>>>,
lallccs: &Arc<Mutex<Vec<String>>>,
) {
*matches.get_or_init(default_match_handle).lock().unwrap() = Arc::clone(lmatches);
*fmatches.get_or_init(default_match_handle).lock().unwrap() = Arc::clone(lfmatches);
*expls.get_or_init(default_expl_handle).lock().unwrap() = Arc::clone(lexpls);
*allccs.get_or_init(default_ccs_handle).lock().unwrap() = Arc::clone(lallccs);
}
fn default_match_handle() -> Mutex<Arc<Mutex<Vec<Cmatch>>>> {
Mutex::new(Arc::new(Mutex::new(Vec::new())))
}
fn default_expl_handle() -> Mutex<Arc<Mutex<Vec<Cexpl>>>> {
Mutex::new(Arc::new(Mutex::new(Vec::new())))
}
fn default_ccs_handle() -> Mutex<Arc<Mutex<Vec<String>>>> {
Mutex::new(Arc::new(Mutex::new(Vec::new())))
}
pub struct CompArenaSnapshot {
matches_h: Arc<Mutex<Vec<Cmatch>>>,
matches_v: Vec<Cmatch>,
fmatches_h: Arc<Mutex<Vec<Cmatch>>>,
fmatches_v: Vec<Cmatch>,
expls_h: Arc<Mutex<Vec<Cexpl>>>,
expls_v: Vec<Cexpl>,
allccs_h: Arc<Mutex<Vec<String>>>,
allccs_v: Vec<String>,
amatches: Vec<Cmgroup>,
pmatches: Vec<Cmgroup>,
lastmatches: Vec<Cmgroup>,
lmatches: Option<Cmgroup>,
lastlmatches: Option<Cmgroup>,
mgroup: Option<Cmgroup>,
ainfo: Option<Aminfo>,
fainfo: Option<Aminfo>,
curexpl: Option<Cexpl>,
matchers: Vec<Box<Cmatcher>>,
counters: Vec<i32>,
compignored: i64,
}
fn arena_counters() -> [&'static std::sync::atomic::AtomicI32; 24] {
use crate::ported::zle::compcore as cc;
[
&cc::mnum, &cc::nmatches, &cc::smatches, &cc::diffmatches, &cc::nmessages, &cc::onlyexpl, &cc::newmatches, &cc::hasmatched, &cc::hasunmatched, &cc::hasallmatch, &cc::haspattern, &cc::ispattern, &cc::maxmlen, &cc::minmlen, &cc::unambig_mnum, &cc::useexact, &cc::lenchanged, &cc::dolastprompt, &cc::hasoldlist, &cc::hasperm, &cc::permmnum, &cc::permgnum, &cc::lastpermmnum, &cc::lastpermgnum, ]
}
pub fn comp_arena_save() -> CompArenaSnapshot {
use crate::ported::zle::compcore as cc;
let matches_h = matches_arc();
let fmatches_h = fmatches_arc();
let expls_h = expls_arc();
let allccs_h = allccs_arc();
let matches_v = matches_h.lock().map(|v| v.clone()).unwrap_or_default();
let fmatches_v = fmatches_h.lock().map(|v| v.clone()).unwrap_or_default();
let expls_v = expls_h.lock().map(|v| v.clone()).unwrap_or_default();
let allccs_v = allccs_h.lock().map(|v| v.clone()).unwrap_or_default();
CompArenaSnapshot {
matches_h,
matches_v,
fmatches_h,
fmatches_v,
expls_h,
expls_v,
allccs_h,
allccs_v,
amatches: cc::amatches
.get_or_init(|| Mutex::new(Vec::new()))
.lock()
.map(|g| g.clone())
.unwrap_or_default(),
pmatches: cc::pmatches
.get_or_init(|| Mutex::new(Vec::new()))
.lock()
.map(|g| g.clone())
.unwrap_or_default(),
lastmatches: cc::lastmatches
.get_or_init(|| Mutex::new(Vec::new()))
.lock()
.map(|g| g.clone())
.unwrap_or_default(),
lmatches: cc::lmatches
.get_or_init(|| Mutex::new(None))
.lock()
.map(|g| g.clone())
.unwrap_or_default(),
lastlmatches: cc::lastlmatches
.get_or_init(|| Mutex::new(None))
.lock()
.map(|g| g.clone())
.unwrap_or_default(),
mgroup: cc::mgroup
.get_or_init(|| Mutex::new(None))
.lock()
.map(|g| g.clone())
.unwrap_or_default(),
ainfo: cc::ainfo
.get_or_init(|| Mutex::new(None))
.lock()
.map(|g| g.clone())
.unwrap_or_default(),
fainfo: cc::fainfo
.get_or_init(|| Mutex::new(None))
.lock()
.map(|g| g.clone())
.unwrap_or_default(),
curexpl: cc::curexpl
.get_or_init(|| Mutex::new(None))
.lock()
.map(|g| g.clone())
.unwrap_or_default(),
matchers: cc::matchers
.get_or_init(|| Mutex::new(Vec::new()))
.lock()
.map(|g| g.clone())
.unwrap_or_default(),
counters: arena_counters().iter().map(|a| a.load(Relaxed)).collect(),
compignored: crate::ported::zle::complete::COMPIGNORED.load(Relaxed),
}
}
pub fn comp_arena_restore(snap: CompArenaSnapshot) {
use crate::ported::zle::compcore as cc;
rebind_current(
&snap.matches_h,
&snap.fmatches_h,
&snap.expls_h,
&snap.allccs_h,
);
if let Ok(mut v) = snap.matches_h.lock() {
*v = snap.matches_v;
}
if let Ok(mut v) = snap.fmatches_h.lock() {
*v = snap.fmatches_v;
}
if let Ok(mut v) = snap.expls_h.lock() {
*v = snap.expls_v;
}
if let Ok(mut v) = snap.allccs_h.lock() {
*v = snap.allccs_v;
}
if let Ok(mut g) = cc::amatches.get_or_init(|| Mutex::new(Vec::new())).lock() {
*g = snap.amatches;
}
if let Ok(mut g) = cc::pmatches.get_or_init(|| Mutex::new(Vec::new())).lock() {
*g = snap.pmatches;
}
if let Ok(mut g) = cc::lastmatches
.get_or_init(|| Mutex::new(Vec::new()))
.lock()
{
*g = snap.lastmatches;
}
if let Ok(mut g) = cc::lmatches.get_or_init(|| Mutex::new(None)).lock() {
*g = snap.lmatches;
}
if let Ok(mut g) = cc::lastlmatches.get_or_init(|| Mutex::new(None)).lock() {
*g = snap.lastlmatches;
}
if let Ok(mut g) = cc::mgroup.get_or_init(|| Mutex::new(None)).lock() {
*g = snap.mgroup;
}
if let Ok(mut g) = cc::ainfo.get_or_init(|| Mutex::new(None)).lock() {
*g = snap.ainfo;
}
if let Ok(mut g) = cc::fainfo.get_or_init(|| Mutex::new(None)).lock() {
*g = snap.fainfo;
}
if let Ok(mut g) = cc::curexpl.get_or_init(|| Mutex::new(None)).lock() {
*g = snap.curexpl;
}
if let Ok(mut g) = cc::matchers.get_or_init(|| Mutex::new(Vec::new())).lock() {
*g = snap.matchers;
}
for (a, v) in arena_counters().iter().zip(snap.counters.iter()) {
a.store(*v, Relaxed);
}
crate::ported::zle::complete::COMPIGNORED.store(snap.compignored, Relaxed);
}