forked from Rust-related/RustPython
Merge pull request #1797 from RustPython/coolreader18/stdlib-msvcrt
Add the msvcrt stdlib module
This commit is contained in:
@@ -248,7 +248,7 @@ fn create_settings(matches: &ArgMatches) -> PySettings {
|
||||
.chain(cmd.skip(1).map(ToOwned::to_owned))
|
||||
.collect()
|
||||
} else {
|
||||
vec![]
|
||||
vec!["".to_owned()]
|
||||
};
|
||||
|
||||
settings.argv = argv;
|
||||
|
||||
@@ -1,3 +1,7 @@
|
||||
use crate::pyobject::PyObjectRef;
|
||||
use crate::vm::VirtualMachine;
|
||||
use std::collections::HashMap;
|
||||
|
||||
pub mod array;
|
||||
#[cfg(feature = "rustpython-parser")]
|
||||
pub(crate) mod ast;
|
||||
@@ -33,15 +37,17 @@ mod tokenize;
|
||||
mod unicodedata;
|
||||
mod warnings;
|
||||
mod weakref;
|
||||
use std::collections::HashMap;
|
||||
|
||||
use crate::vm::VirtualMachine;
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
#[macro_use]
|
||||
mod os;
|
||||
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
mod faulthandler;
|
||||
#[cfg(windows)]
|
||||
mod msvcrt;
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
mod multiprocessing;
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
mod os;
|
||||
#[cfg(all(unix, not(any(target_os = "android", target_os = "redox"))))]
|
||||
mod pwd;
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
@@ -57,8 +63,6 @@ mod winreg;
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
mod zlib;
|
||||
|
||||
use crate::pyobject::PyObjectRef;
|
||||
|
||||
pub type StdlibInitFunc = Box<dyn Fn(&VirtualMachine) -> PyObjectRef>;
|
||||
|
||||
pub fn get_module_inits() -> HashMap<String, StdlibInitFunc> {
|
||||
@@ -136,6 +140,7 @@ pub fn get_module_inits() -> HashMap<String, StdlibInitFunc> {
|
||||
// Windows-only
|
||||
#[cfg(windows)]
|
||||
{
|
||||
modules.insert("msvcrt".to_owned(), Box::new(msvcrt::make_module));
|
||||
modules.insert("_winapi".to_owned(), Box::new(winapi::make_module));
|
||||
modules.insert("winreg".to_owned(), Box::new(winreg::make_module));
|
||||
}
|
||||
|
||||
58
vm/src/stdlib/msvcrt.rs
Normal file
58
vm/src/stdlib/msvcrt.rs
Normal file
@@ -0,0 +1,58 @@
|
||||
use crate::obj::objbytes::PyBytesRef;
|
||||
use crate::obj::objstr::PyStringRef;
|
||||
use crate::pyobject::{PyObjectRef, PyResult};
|
||||
use crate::VirtualMachine;
|
||||
|
||||
use itertools::Itertools;
|
||||
|
||||
extern "C" {
|
||||
fn _getch() -> i32;
|
||||
fn _getwch() -> u32;
|
||||
fn _getche() -> i32;
|
||||
fn _getwche() -> u32;
|
||||
fn _putch(c: u32) -> i32;
|
||||
fn _putwch(c: u16) -> u32;
|
||||
}
|
||||
|
||||
fn msvcrt_getch() -> Vec<u8> {
|
||||
let c = unsafe { _getch() };
|
||||
vec![c as u8]
|
||||
}
|
||||
fn msvcrt_getwch() -> String {
|
||||
let c = unsafe { _getwch() };
|
||||
std::char::from_u32(c).unwrap().to_string()
|
||||
}
|
||||
fn msvcrt_getche() -> Vec<u8> {
|
||||
let c = unsafe { _getche() };
|
||||
vec![c as u8]
|
||||
}
|
||||
fn msvcrt_getwche() -> String {
|
||||
let c = unsafe { _getwche() };
|
||||
std::char::from_u32(c).unwrap().to_string()
|
||||
}
|
||||
fn msvcrt_putch(b: PyBytesRef, vm: &VirtualMachine) -> PyResult<()> {
|
||||
let &c = b.get_value().iter().exactly_one().map_err(|_| {
|
||||
vm.new_type_error("putch() argument must be a byte string of length 1".to_owned())
|
||||
})?;
|
||||
unsafe { suppress_iph!(_putch(c.into())) };
|
||||
Ok(())
|
||||
}
|
||||
fn msvcrt_putwch(s: PyStringRef, vm: &VirtualMachine) -> PyResult<()> {
|
||||
let c = s.as_str().chars().exactly_one().map_err(|_| {
|
||||
vm.new_type_error("putch() argument must be a string of length 1".to_owned())
|
||||
})?;
|
||||
unsafe { suppress_iph!(_putwch(c as u16)) };
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn make_module(vm: &VirtualMachine) -> PyObjectRef {
|
||||
let ctx = &vm.ctx;
|
||||
py_module!(vm, "_msvcrt", {
|
||||
"getch" => ctx.new_function(msvcrt_getch),
|
||||
"getwch" => ctx.new_function(msvcrt_getwch),
|
||||
"getche" => ctx.new_function(msvcrt_getche),
|
||||
"getwche" => ctx.new_function(msvcrt_getwche),
|
||||
"putch" => ctx.new_function(msvcrt_putch),
|
||||
"putwch" => ctx.new_function(msvcrt_putwch),
|
||||
})
|
||||
}
|
||||
@@ -1211,13 +1211,15 @@ type InvalidParamHandler = extern "C" fn(
|
||||
);
|
||||
#[cfg(windows)]
|
||||
extern "C" {
|
||||
fn _set_thread_local_invalid_parameter_handler(
|
||||
#[doc(hidden)]
|
||||
pub fn _set_thread_local_invalid_parameter_handler(
|
||||
pNew: InvalidParamHandler,
|
||||
) -> InvalidParamHandler;
|
||||
}
|
||||
|
||||
#[cfg(windows)]
|
||||
extern "C" fn silent_iph_handler(
|
||||
#[doc(hidden)]
|
||||
pub extern "C" fn silent_iph_handler(
|
||||
_: *const libc::wchar_t,
|
||||
_: *const libc::wchar_t,
|
||||
_: *const libc::wchar_t,
|
||||
@@ -1226,13 +1228,16 @@ extern "C" fn silent_iph_handler(
|
||||
) {
|
||||
}
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! suppress_iph {
|
||||
($e:expr) => {{
|
||||
#[cfg(windows)]
|
||||
{
|
||||
let old = _set_thread_local_invalid_parameter_handler(silent_iph_handler);
|
||||
let old = $crate::stdlib::os::_set_thread_local_invalid_parameter_handler(
|
||||
$crate::stdlib::os::silent_iph_handler,
|
||||
);
|
||||
let ret = $e;
|
||||
_set_thread_local_invalid_parameter_handler(old);
|
||||
$crate::stdlib::os::_set_thread_local_invalid_parameter_handler(old);
|
||||
ret
|
||||
}
|
||||
#[cfg(not(windows))]
|
||||
|
||||
Reference in New Issue
Block a user