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] | [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| { | ||||||
|  |                         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)); |                             eprint!("{}", a.get().with_info(i)); | ||||||
|                         _ = std::io::stderr().lock().flush(); |                             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| { | ||||||
|  |                         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)); |                             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| { | ||||||
|  |                         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)); |                             print!("{}", a.get().with_info(i)); | ||||||
|                         _ = std::io::stdout().lock().flush(); |                             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| { | ||||||
|  |                         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)); |                             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…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user
	 Mark
						Mark