Merge pull request #1797 from RustPython/coolreader18/stdlib-msvcrt

Add the msvcrt stdlib module
This commit is contained in:
Aviv Palivoda
2020-03-13 12:44:29 +02:00
committed by GitHub
4 changed files with 79 additions and 11 deletions

View File

@@ -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;

View File

@@ -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
View 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),
})
}

View File

@@ -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))]