initial commit
This commit is contained in:
165
src/entry/args.rs
Normal file
165
src/entry/args.rs
Normal file
@@ -0,0 +1,165 @@
|
||||
/*
|
||||
* Copyright (c) 2023 Emma Tebibyte <emma@tebibyte.media>
|
||||
* SPDX-License-Identifier: LGPL-3.0-or-later
|
||||
*
|
||||
* This file is part of SPD.
|
||||
*
|
||||
* SPD is free software: you can redistribute it and/or modify it under the
|
||||
* terms of the GNU Lesser General Public License as published by the Free
|
||||
* Software Foundation, either version 3 of the License, or (at your option) any
|
||||
* later version.
|
||||
*
|
||||
* SPD is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
* FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
|
||||
* details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with SPD. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* This file incorporates work covered by the following copyright and permission
|
||||
* notice:
|
||||
*
|
||||
* Copyright 2023 Douman
|
||||
*
|
||||
* Boost Software License - Version 1.0 - August 17th, 2003
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person or
|
||||
* organization obtaining a copy of the software and accompanying
|
||||
* documentation covered by this license (the "Software") to use, reproduce,
|
||||
* display, distribute, execute, and transmit the Software, and to prepare
|
||||
* derivative works of the Software, and to permit third-parties to whom the
|
||||
* Software is furnished to do so, all subject to the following:
|
||||
*
|
||||
* The copyright notices in the Software and this entire statement,
|
||||
* including the above license grant, this restriction and the following
|
||||
* disclaimer, must be included in all copies of the Software, in whole or
|
||||
* in part, and all derivative works of the Software, unless such copies or
|
||||
* derivative works are solely in the form of machine-executable object code
|
||||
* generated by a source language processor.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND
|
||||
* NON-INFRINGEMENT. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR ANYONE
|
||||
* DISTRIBUTING THE SOFTWARE BE LIABLE FOR ANY DAMAGES OR OTHER LIABILITY,
|
||||
* WHETHER IN CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
//! C style arguments wrapper
|
||||
|
||||
use super::{
|
||||
c_str_to_rust,
|
||||
c_str_to_rust_unchecked,
|
||||
};
|
||||
|
||||
#[derive(Copy, Clone, Debug)]
|
||||
///Wrapper over C-style arguments
|
||||
pub struct Args {
|
||||
argc: usize,
|
||||
argv: *const *const u8,
|
||||
}
|
||||
|
||||
impl Args {
|
||||
///Creates new instance, but verifies that each string inside are UTF-8.
|
||||
///
|
||||
///On error returns pair: `(string index, Utf8Error)`
|
||||
///
|
||||
///The function is safe as long as you pass C style main function arguments.
|
||||
pub unsafe fn new(argc: isize, argv: *const *const u8) -> Result<Self, (usize, core::str::Utf8Error)> {
|
||||
assert!(argc > 0);
|
||||
assert!(!argv.is_null());
|
||||
|
||||
let this = Args {
|
||||
argc: argc as usize,
|
||||
argv,
|
||||
};
|
||||
|
||||
let args = this.as_slice();
|
||||
for idx in 0..this.argc {
|
||||
let arg = *args.get_unchecked(idx);
|
||||
if let Err(error) = c_str_to_rust(arg) {
|
||||
return Err((idx, error));
|
||||
}
|
||||
}
|
||||
|
||||
Ok(this)
|
||||
}
|
||||
#[inline(always)]
|
||||
///Unchecked version of `Args::new`
|
||||
///
|
||||
///Do it on your own risk
|
||||
pub unsafe fn new_unchecked(argc: isize, argv: *const *const u8) -> Self {
|
||||
Args {
|
||||
argc: argc as usize,
|
||||
argv,
|
||||
}
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
///Returns slice of raw C strings
|
||||
pub fn as_slice(&self) -> &[*const u8] {
|
||||
unsafe {
|
||||
core::slice::from_raw_parts(self.argv, self.argc)
|
||||
}
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
///Retrieves string by index.
|
||||
///
|
||||
///No checks, 100% unsafe.
|
||||
pub unsafe fn get_str_by_index(&self, index: usize) -> &str {
|
||||
let elem = *self.as_slice().get_unchecked(index);
|
||||
c_str_to_rust_unchecked(elem)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> IntoIterator for &'a Args {
|
||||
type Item = &'a str;
|
||||
type IntoIter = IntoIter<'a>;
|
||||
|
||||
#[inline(always)]
|
||||
fn into_iter(self) -> Self::IntoIter {
|
||||
Self::IntoIter {
|
||||
inner: self,
|
||||
index: 0,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
///Iterator over [Args](struct.Args.html)
|
||||
///
|
||||
///Comparing to normal iterators can be iterated back and forth.
|
||||
pub struct IntoIter<'a> {
|
||||
inner: &'a Args,
|
||||
index: usize,
|
||||
}
|
||||
|
||||
impl<'a> Iterator for IntoIter<'a> {
|
||||
type Item = &'a str;
|
||||
|
||||
fn next(&mut self) -> Option<Self::Item> {
|
||||
if self.index >= self.inner.argc {
|
||||
return None;
|
||||
}
|
||||
|
||||
let elem = unsafe {
|
||||
self.inner.get_str_by_index(self.index)
|
||||
};
|
||||
self.index += 1;
|
||||
Some(elem)
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn size_hint(&self) -> (usize, Option<usize>) {
|
||||
let count = self.inner.argc - self.index;
|
||||
(count, Some(count))
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn count(self) -> usize {
|
||||
self.inner.argc - self.index
|
||||
}
|
||||
}
|
||||
109
src/entry/mod.rs
Normal file
109
src/entry/mod.rs
Normal file
@@ -0,0 +1,109 @@
|
||||
/*
|
||||
* Copyright (c) 2023 Emma Tebibyte <emma@tebibyte.media>
|
||||
* SPDX-License-Identifier: LGPL-3.0-or-later
|
||||
*
|
||||
* This file is part of SPD.
|
||||
*
|
||||
* SPD is free software: you can redistribute it and/or modify it under the
|
||||
* terms of the GNU Lesser General Public License as published by the Free
|
||||
* Software Foundation, either version 3 of the License, or (at your option) any
|
||||
* later version.
|
||||
*
|
||||
* SPD is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
* FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
|
||||
* details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with SPD. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* This file incorporates work covered by the following copyright and permission
|
||||
* notice:
|
||||
*
|
||||
* Copyright 2023 Douman
|
||||
*
|
||||
* Boost Software License - Version 1.0 - August 17th, 2003
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person or
|
||||
* organization obtaining a copy of the software and accompanying
|
||||
* documentation covered by this license (the "Software") to use, reproduce,
|
||||
* display, distribute, execute, and transmit the Software, and to prepare
|
||||
* derivative works of the Software, and to permit third-parties to whom the
|
||||
* Software is furnished to do so, all subject to the following:
|
||||
*
|
||||
* The copyright notices in the Software and this entire statement,
|
||||
* including the above license grant, this restriction and the following
|
||||
* disclaimer, must be included in all copies of the Software, in whole or
|
||||
* in part, and all derivative works of the Software, unless such copies or
|
||||
* derivative works are solely in the form of machine-executable object code
|
||||
* generated by a source language processor.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND
|
||||
* NON-INFRINGEMENT. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR ANYONE
|
||||
* DISTRIBUTING THE SOFTWARE BE LIABLE FOR ANY DAMAGES OR OTHER LIABILITY,
|
||||
* WHETHER IN CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
//! C main entry point with nice wrapper for arguments.
|
||||
//!
|
||||
//!```rust
|
||||
//!#![no_main]
|
||||
//!
|
||||
//!#[no_mangle]
|
||||
//!pub fn rust_main(args: c_main::Args) -> isize {
|
||||
//! for arg in args.into_iter().skip(1) {
|
||||
//! println!("arg={:?}", arg);
|
||||
//! }
|
||||
//! 0
|
||||
//!}
|
||||
//!```
|
||||
|
||||
#![cfg_attr(feature = "cargo-clippy", allow(clippy::style))]
|
||||
#![cfg_attr(rustfmt, rustfmt_skip)]
|
||||
|
||||
mod args;
|
||||
use args::*;
|
||||
|
||||
#[allow(unused)]
|
||||
#[cold]
|
||||
#[inline(never)]
|
||||
unsafe fn invalid_cli_args_error() -> libc::c_int {
|
||||
libc::printf("Unable to parse C argv as utf-8 string\n\0".as_ptr() as _);
|
||||
255
|
||||
}
|
||||
|
||||
///Converts C string to Rust's, verifying it is UTF-8
|
||||
///
|
||||
///It is UB to pass non-C string as it requires \0
|
||||
pub unsafe fn c_str_to_rust(ptr: *const u8) -> Result<&'static str, core::str::Utf8Error> {
|
||||
let len = libc::strlen(ptr as *const i8);
|
||||
let parts = core::slice::from_raw_parts(ptr, len);
|
||||
core::str::from_utf8(parts)
|
||||
}
|
||||
|
||||
///Converts C string to Rust's one assuming it is UTF-8
|
||||
///
|
||||
///It is UB to pass non-C string as it requires \0
|
||||
pub unsafe fn c_str_to_rust_unchecked(ptr: *const u8) -> &'static str {
|
||||
let len = libc::strlen(ptr as *const i8);
|
||||
let parts = core::slice::from_raw_parts(ptr, len);
|
||||
core::str::from_utf8_unchecked(parts)
|
||||
}
|
||||
|
||||
extern "Rust" {
|
||||
fn rust_main(args: Args) -> isize;
|
||||
}
|
||||
|
||||
#[doc(hidden)]
|
||||
#[cfg(not(test))]
|
||||
#[no_mangle]
|
||||
pub unsafe extern fn main(argc: libc::c_int, argv: *const *const u8) -> libc::c_int {
|
||||
match Args::new(argc as isize, argv) {
|
||||
Ok(args) => rust_main(args) as _,
|
||||
Err(_) => invalid_cli_args_error(),
|
||||
}
|
||||
}
|
||||
64
src/lib.rs
Normal file
64
src/lib.rs
Normal file
@@ -0,0 +1,64 @@
|
||||
/*
|
||||
* Copyright (c) 2023 Emma Tebibyte <emma@tebibyte.media>
|
||||
* SPDX-License-Identifier: LGPL-3.0-or-later
|
||||
*
|
||||
* This file is part of SPD.
|
||||
*
|
||||
* SPD is free software: you can redistribute it and/or modify it under the
|
||||
* terms of the GNU Lesser General Public License as published by the Free
|
||||
* Software Foundation, either version 3 of the License, or (at your option) any
|
||||
* later version.
|
||||
*
|
||||
* SPD is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
* FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
|
||||
* details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with SPD. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* This file incorporates work covered by the following copyright and permission
|
||||
* notice:
|
||||
*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2023 Matt Mastracci and contributors
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included
|
||||
* in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
|
||||
* NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
|
||||
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
|
||||
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
|
||||
* USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#![no_std]
|
||||
|
||||
pub mod entry;
|
||||
// pub mod env;
|
||||
mod macros;
|
||||
pub mod process;
|
||||
|
||||
pub use macros::*;
|
||||
|
||||
pub use libc_dbg as dbg;
|
||||
pub use libc_eprint as eprint;
|
||||
pub use libc_eprintln as eprintln;
|
||||
pub use libc_ewriteln as ewriteln;
|
||||
pub use libc_print as print;
|
||||
pub use libc_println as println;
|
||||
pub use libc_writeln as writeln;
|
||||
|
||||
pub const SOURCE: &str = "https://git.tebibyte.media/emma/spd.git";
|
||||
370
src/macros.rs
Normal file
370
src/macros.rs
Normal file
@@ -0,0 +1,370 @@
|
||||
/*
|
||||
* Copyright (c) 2023 Emma Tebibyte <emma@tebibyte.media>
|
||||
* SPDX-License-Identifier: LGPL-3.0-or-later
|
||||
*
|
||||
* This file is part of SPD.
|
||||
*
|
||||
* SPD is free software: you can redistribute it and/or modify it under the
|
||||
* terms of the GNU Lesser General Public License as published by the Free
|
||||
* Software Foundation, either version 3 of the License, or (at your option) any
|
||||
* later version.
|
||||
*
|
||||
* SPD is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
* FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
|
||||
* details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with SPD. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* This file incorporates work covered by the following copyright and permission
|
||||
* notice:
|
||||
*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2023 Matt Mastracci and contributors
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included
|
||||
* in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
|
||||
* NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
|
||||
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
|
||||
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
|
||||
* USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
//! Implements `println!`, `eprintln!` and `dbg!` on top of the `libc `crate without requiring
|
||||
//! the use of an allocator.
|
||||
//!
|
||||
//! Allows you to use these macros in a #!\[no_std\] context, or in a situation where the
|
||||
//! traditional Rust streams might not be available (ie: at process shutdown time).
|
||||
//!
|
||||
//! [`libc_writeln`] and [`libc_ewriteln`] are provided for cases where you may not wish
|
||||
//! to pull in the overhead of the formatter code and simply wish to print C-style strings.
|
||||
//!
|
||||
//! ## Usage
|
||||
//!
|
||||
//! Exactly as you'd use `println!`, `eprintln!` and `dbg!`.
|
||||
//!
|
||||
//! ```rust
|
||||
//! # use libc_print::*;
|
||||
//! // Use the default `libc_`-prefixed macros:
|
||||
//! # fn test1()
|
||||
//! # {
|
||||
//! libc_println!("Hello {}!", "stdout");
|
||||
//! libc_eprintln!("Hello {}!", "stderr");
|
||||
//! let a = 2;
|
||||
//! let b = libc_dbg!(a * 2) + 1;
|
||||
//! assert_eq!(b, 5);
|
||||
//! # }
|
||||
//! ```
|
||||
//!
|
||||
//! Or you can import aliases to `std` names:
|
||||
//!
|
||||
//! ```rust
|
||||
//! use libc_print::std_name::{println, eprintln, dbg};
|
||||
//!
|
||||
//! # fn test2()
|
||||
//! # {
|
||||
//! println!("Hello {}!", "stdout");
|
||||
//! eprintln!("Hello {}!", "stderr");
|
||||
//! let a = 2;
|
||||
//! let b = dbg!(a * 2) + 1;
|
||||
//! assert_eq!(b, 5);
|
||||
//! # }
|
||||
//! ```
|
||||
|
||||
#![no_std]
|
||||
#![allow(dead_code)]
|
||||
#![allow(unused)]
|
||||
#![warn(unsafe_op_in_unsafe_fn)]
|
||||
|
||||
use core::{convert::TryFrom, file, line, stringify};
|
||||
|
||||
/// This forces a "C" library linkage
|
||||
#[cfg(not(windows))]
|
||||
#[link(name = "c")]
|
||||
mod c {
|
||||
extern "C" {}
|
||||
}
|
||||
|
||||
// These constants are used by the macros but we don't want to expose
|
||||
// them to library users.
|
||||
#[doc(hidden)]
|
||||
pub const __LIBC_NEWLINE: &str = "\n";
|
||||
#[doc(hidden)]
|
||||
pub const __LIBC_STDOUT: i32 = 1;
|
||||
#[doc(hidden)]
|
||||
pub const __LIBC_STDERR: i32 = 2;
|
||||
|
||||
#[doc(hidden)]
|
||||
pub struct __LibCWriter(i32);
|
||||
|
||||
impl core::fmt::Write for __LibCWriter {
|
||||
#[inline]
|
||||
fn write_str(&mut self, s: &str) -> core::fmt::Result {
|
||||
__libc_println(self.0, s)
|
||||
}
|
||||
}
|
||||
|
||||
impl __LibCWriter {
|
||||
#[inline]
|
||||
pub fn new(handle: i32) -> __LibCWriter {
|
||||
__LibCWriter(handle)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn write_fmt(&mut self, args: core::fmt::Arguments) -> core::fmt::Result {
|
||||
core::fmt::Write::write_fmt(self, args)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn write_str(&mut self, s: &str) -> core::fmt::Result {
|
||||
__libc_println(self.0, s)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn write_nl(&mut self) -> core::fmt::Result {
|
||||
__libc_println(self.0, __LIBC_NEWLINE)
|
||||
}
|
||||
}
|
||||
|
||||
#[doc(hidden)]
|
||||
#[inline]
|
||||
pub fn __libc_println(handle: i32, msg: &str) -> core::fmt::Result {
|
||||
let msg = msg.as_bytes();
|
||||
|
||||
let mut written = 0;
|
||||
while written < msg.len() {
|
||||
match unsafe { libc_write(handle, &msg[written..]) } {
|
||||
// Ignore errors
|
||||
None | Some(0) => break,
|
||||
Some(res) => written += res,
|
||||
}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[cfg(not(windows))]
|
||||
unsafe fn libc_write(handle: i32, bytes: &[u8]) -> Option<usize> {
|
||||
usize::try_from(unsafe {
|
||||
libc::write(
|
||||
handle,
|
||||
bytes.as_ptr().cast::<core::ffi::c_void>(),
|
||||
bytes.len(),
|
||||
)
|
||||
})
|
||||
.ok()
|
||||
}
|
||||
|
||||
#[cfg(windows)]
|
||||
unsafe fn libc_write(handle: i32, bytes: &[u8]) -> Option<usize> {
|
||||
usize::try_from(unsafe {
|
||||
libc::write(
|
||||
handle,
|
||||
bytes.as_ptr().cast::<core::ffi::c_void>(),
|
||||
libc::c_uint::try_from(bytes.len()).unwrap_or(libc::c_uint::MAX),
|
||||
)
|
||||
})
|
||||
.ok()
|
||||
}
|
||||
|
||||
/// Macro for printing to the standard output, with a newline.
|
||||
///
|
||||
/// Does not panic on failure to write - instead silently ignores errors.
|
||||
///
|
||||
/// See [`println!`](https://doc.rust-lang.org/std/macro.println.html) for
|
||||
/// full documentation.
|
||||
///
|
||||
/// You may wish to `use libc_print::std_name::*` to use a replacement
|
||||
/// `println!` macro instead of this longer name.
|
||||
#[macro_export]
|
||||
macro_rules! libc_println {
|
||||
() => { $crate::libc_println!("") };
|
||||
($($arg:tt)*) => {
|
||||
{
|
||||
#[allow(unused_must_use)]
|
||||
{
|
||||
let mut stm = $crate::__LibCWriter::new($crate::__LIBC_STDOUT);
|
||||
stm.write_fmt(format_args!($($arg)*));
|
||||
stm.write_nl();
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/// Macro for printing to the standard output.
|
||||
///
|
||||
/// Does not panic on failure to write - instead silently ignores errors.
|
||||
///
|
||||
/// See [`print!`](https://doc.rust-lang.org/std/macro.print.html) for
|
||||
/// full documentation.
|
||||
///
|
||||
/// You may wish to `use libc_print::std_name::*` to use a replacement
|
||||
/// `print!` macro instead of this longer name.
|
||||
#[macro_export]
|
||||
macro_rules! libc_print {
|
||||
($($arg:tt)*) => {
|
||||
{
|
||||
#[allow(unused_must_use)]
|
||||
{
|
||||
let mut stm = $crate::__LibCWriter::new($crate::__LIBC_STDOUT);
|
||||
stm.write_fmt(format_args!($($arg)*));
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/// Macro for printing to the standard error, with a newline.
|
||||
///
|
||||
/// Does not panic on failure to write - instead silently ignores errors.
|
||||
///
|
||||
/// See [`eprintln!`](https://doc.rust-lang.org/std/macro.eprintln.html) for
|
||||
/// full documentation.
|
||||
///
|
||||
/// You may wish to `use libc_print::std_name::*` to use a replacement
|
||||
/// `eprintln!` macro instead of this longer name.
|
||||
#[macro_export]
|
||||
macro_rules! libc_eprintln {
|
||||
() => { $crate::libc_eprintln!("") };
|
||||
($($arg:tt)*) => {
|
||||
{
|
||||
#[allow(unused_must_use)]
|
||||
{
|
||||
let mut stm = $crate::__LibCWriter::new($crate::__LIBC_STDERR);
|
||||
stm.write_fmt(format_args!($($arg)*));
|
||||
stm.write_nl();
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/// Macro for printing to the standard error.
|
||||
///
|
||||
/// Does not panic on failure to write - instead silently ignores errors.
|
||||
///
|
||||
/// See [`eprint!`](https://doc.rust-lang.org/std/macro.eprint.html) for
|
||||
/// full documentation.
|
||||
///
|
||||
/// You may wish to `use libc_print::std_name::*` to use a replacement
|
||||
/// `eprint!` macro instead of this longer name.
|
||||
#[macro_export]
|
||||
macro_rules! libc_eprint {
|
||||
($($arg:tt)*) => {
|
||||
{
|
||||
#[allow(unused_must_use)]
|
||||
{
|
||||
let mut stm = $crate::__LibCWriter::new($crate::__LIBC_STDERR);
|
||||
stm.write_fmt(format_args!($($arg)*));
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/// Macro for printing a static string to the standard output.
|
||||
///
|
||||
/// Does not panic on failure to write - instead silently ignores errors.
|
||||
#[macro_export]
|
||||
macro_rules! libc_write {
|
||||
($arg:expr) => {
|
||||
#[allow(unused_must_use)]
|
||||
{
|
||||
let mut stm = $crate::__LibCWriter::new($crate::__LIBC_STDOUT);
|
||||
stm.write_str($arg);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/// Macro for printing a static string to the standard error.
|
||||
///
|
||||
/// Does not panic on failure to write - instead silently ignores errors.
|
||||
#[macro_export]
|
||||
macro_rules! libc_ewrite {
|
||||
($arg:expr) => {
|
||||
{
|
||||
#[allow(unused_must_use)]
|
||||
{
|
||||
let mut stm = $crate::__LibCWriter::new($crate::__LIBC_STDERR);
|
||||
stm.write_str($arg);
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/// Macro for printing a static string to the standard output, with a newline.
|
||||
///
|
||||
/// Does not panic on failure to write - instead silently ignores errors.
|
||||
#[macro_export]
|
||||
macro_rules! libc_writeln {
|
||||
($arg:expr) => {
|
||||
#[allow(unused_must_use)]
|
||||
{
|
||||
let mut stm = $crate::__LibCWriter::new($crate::__LIBC_STDOUT);
|
||||
stm.write_str($arg);
|
||||
stm.write_nl();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/// Macro for printing a static string to the standard error, with a newline.
|
||||
///
|
||||
/// Does not panic on failure to write - instead silently ignores errors.
|
||||
#[macro_export]
|
||||
macro_rules! libc_ewriteln {
|
||||
($arg:expr) => {
|
||||
{
|
||||
#[allow(unused_must_use)]
|
||||
{
|
||||
let mut stm = $crate::__LibCWriter::new($crate::__LIBC_STDERR);
|
||||
stm.write_str($arg);
|
||||
stm.write_nl();
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/// Prints and returns the value of a given expression for quick and dirty
|
||||
/// debugging.
|
||||
///
|
||||
/// An example:
|
||||
///
|
||||
/// ```rust
|
||||
/// let a = 2;
|
||||
/// let b = dbg!(a * 2) + 1;
|
||||
/// // ^-- prints: [src/main.rs:2] a * 2 = 4
|
||||
/// assert_eq!(b, 5);
|
||||
/// ```
|
||||
///
|
||||
/// See [dbg!](https://doc.rust-lang.org/std/macro.dbg.html) for full documentation.
|
||||
///
|
||||
/// You may wish to `use libc_print::std_name::*` to use a replacement
|
||||
/// `dbg!` macro instead of this longer name.
|
||||
#[macro_export]
|
||||
macro_rules! libc_dbg {
|
||||
() => {
|
||||
$crate::libc_eprintln!("[{}:{}]", $file!(), $line!())
|
||||
};
|
||||
($val:expr $(,)?) => {
|
||||
match $val {
|
||||
tmp => {
|
||||
$crate::libc_eprintln!("[{}:{}] {} = {:#?}", file!(), line!(), stringify!($val), &tmp);
|
||||
tmp
|
||||
}
|
||||
}
|
||||
};
|
||||
($($val:expr),+ $(,)?) => {
|
||||
($($crate::libc_dbg!($val)),+,)
|
||||
};
|
||||
}
|
||||
42
src/process.rs
Normal file
42
src/process.rs
Normal file
@@ -0,0 +1,42 @@
|
||||
/*
|
||||
* Copyright (c) 2023 Emma Tebibyte <emma@tebibyte.media>
|
||||
* SPDX-License-Identifier: LGPL-3.0-or-later
|
||||
*
|
||||
* This file is part of SPD.
|
||||
*
|
||||
* SPD is free software: you can redistribute it and/or modify it under the
|
||||
* terms of the GNU Lesser General Public License as published by the Free
|
||||
* Software Foundation, either version 3 of the License, or (at your option) any
|
||||
* later version.
|
||||
*
|
||||
* SPD is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
* FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
|
||||
* details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with SPD. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* This file incorporates work covered by the following copyright and permission
|
||||
* notice:
|
||||
*
|
||||
* Copyright (c) 2023 YAC
|
||||
* SPDX-License-Identifier: FSFAP
|
||||
*
|
||||
* Copying and distribution of this file, with or without modification, are
|
||||
* permitted in any medium without royalty provided the copyright notice and
|
||||
* this notice are preserved. This file is offered as-is, without any
|
||||
* warranty.
|
||||
*/
|
||||
|
||||
#![allow(non_upper_case_globals)]
|
||||
#![allow(non_camel_case_types)]
|
||||
#![allow(non_snake_case)]
|
||||
|
||||
include!(concat!(env!("OUT_DIR"), "/bindings.rs"));
|
||||
|
||||
extern crate core;
|
||||
|
||||
pub fn exit(code: u32) -> ! {
|
||||
unsafe { libc::exit(code as i32 as libc::c_int); }
|
||||
}
|
||||
Reference in New Issue
Block a user