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