mirror of
https://github.com/Dummi26/mers.git
synced 2025-03-10 05:43:53 +01:00
allow using other stdin/stdout/stderr via RunInfo
This commit is contained in:
parent
4e73ec0201
commit
8e07f240cc
@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "mers_lib"
|
name = "mers_lib"
|
||||||
version = "0.9.10"
|
version = "0.9.11"
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
license = "MIT OR Apache-2.0"
|
license = "MIT OR Apache-2.0"
|
||||||
description = "library to use the mers language in other projects"
|
description = "library to use the mers language in other projects"
|
||||||
|
@ -4,19 +4,14 @@ use std::{
|
|||||||
};
|
};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
data::{
|
data::{self, bool::bool_type, int::INT_MAX, Data, MersTypeWInfo, Type},
|
||||||
self,
|
|
||||||
bool::bool_type,
|
|
||||||
int::{INT_MAX, INT_MIN},
|
|
||||||
Data, MersTypeWInfo, Type,
|
|
||||||
},
|
|
||||||
errors::CheckError,
|
errors::CheckError,
|
||||||
program::run::{CheckInfo, Info},
|
program::run::{CheckInfo, Info},
|
||||||
};
|
};
|
||||||
|
|
||||||
use super::{
|
use super::{
|
||||||
gen::{
|
gen::{
|
||||||
function::{func, func_end, func_err},
|
function::{func, func_err},
|
||||||
IntR, OneOf,
|
IntR, OneOf,
|
||||||
},
|
},
|
||||||
Config,
|
Config,
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
use std::{
|
use std::{
|
||||||
io::Write,
|
io::{BufRead, Write},
|
||||||
sync::{Arc, Mutex},
|
sync::{Arc, Mutex},
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -66,8 +66,13 @@ impl Config {
|
|||||||
)
|
)
|
||||||
.add_var(
|
.add_var(
|
||||||
"read_line",
|
"read_line",
|
||||||
func(|_: (), _| {
|
func(|_: (), i| {
|
||||||
Ok(if let Some(Ok(line)) = std::io::stdin().lines().next() {
|
let next_line = if let Some(stdin) = &mut *i.global.stdin.lock().unwrap() {
|
||||||
|
std::io::BufReader::new(stdin).lines().next()
|
||||||
|
} else {
|
||||||
|
std::io::stdin().lines().next()
|
||||||
|
};
|
||||||
|
Ok(if let Some(Ok(line)) = next_line {
|
||||||
OneOrNone(Some(line))
|
OneOrNone(Some(line))
|
||||||
} else {
|
} else {
|
||||||
OneOrNone(None)
|
OneOrNone(None)
|
||||||
@ -82,7 +87,15 @@ impl Config {
|
|||||||
out: Ok(Arc::new(|a, _i| Ok(a.clone()))),
|
out: Ok(Arc::new(|a, _i| Ok(a.clone()))),
|
||||||
run: Arc::new(|a, i| {
|
run: Arc::new(|a, i| {
|
||||||
let a2 = a.get();
|
let a2 = a.get();
|
||||||
eprintln!("{} :: {}", a2.as_type().with_info(i), a2.with_info(i));
|
let ty = a2.as_type();
|
||||||
|
let ty = ty.with_info(i);
|
||||||
|
let v = a2.with_info(i);
|
||||||
|
if let Some((_, stderr)) = &mut *i.global.stdout.lock().unwrap() {
|
||||||
|
let _ = write!(stderr, "{ty} :: {v}");
|
||||||
|
let _ = stderr.flush();
|
||||||
|
} else {
|
||||||
|
eprintln!("{ty} :: {v}");
|
||||||
|
}
|
||||||
drop(a2);
|
drop(a2);
|
||||||
Ok(a)
|
Ok(a)
|
||||||
}),
|
}),
|
||||||
@ -96,8 +109,13 @@ impl Config {
|
|||||||
info_check: Arc::new(Mutex::new(CheckInfo::neverused())),
|
info_check: Arc::new(Mutex::new(CheckInfo::neverused())),
|
||||||
out: Ok(Arc::new(|_a, _i| Ok(Type::empty_tuple()))),
|
out: Ok(Arc::new(|_a, _i| Ok(Type::empty_tuple()))),
|
||||||
run: Arc::new(|a, i| {
|
run: Arc::new(|a, i| {
|
||||||
eprint!("{}", a.get().with_info(i));
|
if let Some((_, stderr)) = &mut *i.global.stdout.lock().unwrap() {
|
||||||
_ = std::io::stderr().lock().flush();
|
let _ = write!(stderr, "{}", a.get().with_info(i));
|
||||||
|
let _ = stderr.flush();
|
||||||
|
} else {
|
||||||
|
eprint!("{}", a.get().with_info(i));
|
||||||
|
let _ = std::io::stderr().lock().flush();
|
||||||
|
}
|
||||||
Ok(Data::empty_tuple())
|
Ok(Data::empty_tuple())
|
||||||
}),
|
}),
|
||||||
inner_statements: None,
|
inner_statements: None,
|
||||||
@ -110,7 +128,12 @@ impl Config {
|
|||||||
info_check: Arc::new(Mutex::new(CheckInfo::neverused())),
|
info_check: Arc::new(Mutex::new(CheckInfo::neverused())),
|
||||||
out: Ok(Arc::new(|_a, _i| Ok(Type::empty_tuple()))),
|
out: Ok(Arc::new(|_a, _i| Ok(Type::empty_tuple()))),
|
||||||
run: Arc::new(|a, i| {
|
run: Arc::new(|a, i| {
|
||||||
eprintln!("{}", a.get().with_info(i));
|
if let Some((_, stderr)) = &mut *i.global.stdout.lock().unwrap() {
|
||||||
|
let _ = writeln!(stderr, "{}", a.get().with_info(i));
|
||||||
|
let _ = stderr.flush();
|
||||||
|
} else {
|
||||||
|
eprintln!("{}", a.get().with_info(i));
|
||||||
|
}
|
||||||
Ok(Data::empty_tuple())
|
Ok(Data::empty_tuple())
|
||||||
}),
|
}),
|
||||||
inner_statements: None,
|
inner_statements: None,
|
||||||
@ -123,8 +146,13 @@ impl Config {
|
|||||||
info_check: Arc::new(Mutex::new(CheckInfo::neverused())),
|
info_check: Arc::new(Mutex::new(CheckInfo::neverused())),
|
||||||
out: Ok(Arc::new(|_a, _i| Ok(Type::empty_tuple()))),
|
out: Ok(Arc::new(|_a, _i| Ok(Type::empty_tuple()))),
|
||||||
run: Arc::new(|a, i| {
|
run: Arc::new(|a, i| {
|
||||||
print!("{}", a.get().with_info(i));
|
if let Some((stdout, _)) = &mut *i.global.stdout.lock().unwrap() {
|
||||||
_ = std::io::stdout().lock().flush();
|
let _ = write!(stdout, "{}", a.get().with_info(i));
|
||||||
|
let _ = stdout.flush();
|
||||||
|
} else {
|
||||||
|
print!("{}", a.get().with_info(i));
|
||||||
|
let _ = std::io::stdout().lock().flush();
|
||||||
|
}
|
||||||
Ok(Data::empty_tuple())
|
Ok(Data::empty_tuple())
|
||||||
}),
|
}),
|
||||||
inner_statements: None,
|
inner_statements: None,
|
||||||
@ -137,7 +165,12 @@ impl Config {
|
|||||||
info_check: Arc::new(Mutex::new(CheckInfo::neverused())),
|
info_check: Arc::new(Mutex::new(CheckInfo::neverused())),
|
||||||
out: Ok(Arc::new(|_a, _i| Ok(Type::empty_tuple()))),
|
out: Ok(Arc::new(|_a, _i| Ok(Type::empty_tuple()))),
|
||||||
run: Arc::new(|a, i| {
|
run: Arc::new(|a, i| {
|
||||||
println!("{}", a.get().with_info(i));
|
if let Some((stdout, _)) = &mut *i.global.stdout.lock().unwrap() {
|
||||||
|
let _ = writeln!(stdout, "{}", a.get().with_info(i));
|
||||||
|
let _ = stdout.flush();
|
||||||
|
} else {
|
||||||
|
println!("{}", a.get().with_info(i));
|
||||||
|
}
|
||||||
Ok(Data::empty_tuple())
|
Ok(Data::empty_tuple())
|
||||||
}),
|
}),
|
||||||
inner_statements: None,
|
inner_statements: None,
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
use std::{
|
use std::{
|
||||||
collections::HashMap,
|
collections::HashMap,
|
||||||
fmt::Debug,
|
fmt::Debug,
|
||||||
|
io::{Read, Write},
|
||||||
sync::{Arc, Mutex, RwLock},
|
sync::{Arc, Mutex, RwLock},
|
||||||
time::Instant,
|
time::Instant,
|
||||||
};
|
};
|
||||||
@ -126,12 +127,38 @@ pub type CheckInfo = info::Info<CheckLocal>;
|
|||||||
pub struct RunLocal {
|
pub struct RunLocal {
|
||||||
pub vars: Vec<Arc<RwLock<Data>>>,
|
pub vars: Vec<Arc<RwLock<Data>>>,
|
||||||
}
|
}
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone)]
|
||||||
pub struct RunLocalGlobalInfo {
|
pub struct RunLocalGlobalInfo {
|
||||||
/// if set, if `Instant::now()` is equal to or after the set `Instant`, stop the program with an error.
|
/// if set, if `Instant::now()` is equal to or after the set `Instant`, stop the program with an error.
|
||||||
pub limit_runtime: Option<Instant>,
|
pub limit_runtime: Option<Instant>,
|
||||||
pub object_fields: Arc<Mutex<HashMap<String, usize>>>,
|
pub object_fields: Arc<Mutex<HashMap<String, usize>>>,
|
||||||
pub object_fields_rev: Arc<Mutex<Vec<String>>>,
|
pub object_fields_rev: Arc<Mutex<Vec<String>>>,
|
||||||
|
pub stdin: Arc<Mutex<Option<Box<dyn Read + Send + Sync>>>>,
|
||||||
|
pub stdout: Arc<Mutex<Option<(Box<dyn Write + Send + Sync>, Box<dyn Write + Send + Sync>)>>>,
|
||||||
|
}
|
||||||
|
#[derive(Debug)]
|
||||||
|
#[allow(unused)]
|
||||||
|
struct RunLocalGlobalInfoDebug<'a> {
|
||||||
|
pub limit_runtime: &'a Option<Instant>,
|
||||||
|
pub object_fields: &'a Arc<Mutex<HashMap<String, usize>>>,
|
||||||
|
pub object_fields_rev: &'a Arc<Mutex<Vec<String>>>,
|
||||||
|
pub stdin: bool,
|
||||||
|
pub stdout: bool,
|
||||||
|
}
|
||||||
|
impl Debug for RunLocalGlobalInfo {
|
||||||
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||||
|
write!(
|
||||||
|
f,
|
||||||
|
"{:?}",
|
||||||
|
RunLocalGlobalInfoDebug {
|
||||||
|
limit_runtime: &self.limit_runtime,
|
||||||
|
object_fields: &self.object_fields,
|
||||||
|
object_fields_rev: &self.object_fields_rev,
|
||||||
|
stdin: self.stdin.lock().unwrap().is_some(),
|
||||||
|
stdout: self.stdout.lock().unwrap().is_some()
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
impl RunLocalGlobalInfo {
|
impl RunLocalGlobalInfo {
|
||||||
pub fn new(object_fields: Arc<Mutex<HashMap<String, usize>>>) -> Self {
|
pub fn new(object_fields: Arc<Mutex<HashMap<String, usize>>>) -> Self {
|
||||||
@ -139,6 +166,8 @@ impl RunLocalGlobalInfo {
|
|||||||
limit_runtime: None,
|
limit_runtime: None,
|
||||||
object_fields,
|
object_fields,
|
||||||
object_fields_rev: Default::default(),
|
object_fields_rev: Default::default(),
|
||||||
|
stdin: Arc::new(Mutex::new(None)),
|
||||||
|
stdout: Arc::new(Mutex::new(None)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -216,6 +245,8 @@ impl info::Local for RunLocal {
|
|||||||
limit_runtime: None,
|
limit_runtime: None,
|
||||||
object_fields: Default::default(),
|
object_fields: Default::default(),
|
||||||
object_fields_rev: Default::default(),
|
object_fields_rev: Default::default(),
|
||||||
|
stdin: Default::default(),
|
||||||
|
stdout: Default::default(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fn init_var(&mut self, id: Self::VariableIdentifier, value: Self::VariableData) {
|
fn init_var(&mut self, id: Self::VariableIdentifier, value: Self::VariableData) {
|
||||||
|
Loading…
Reference in New Issue
Block a user