mirror of
https://github.com/RGBCube/uutils-coreutils
synced 2025-07-29 12:07:46 +00:00
Merge pull request #2777 from jfinkels/uucore-printf
uucore: move printf::memo module to uucore
This commit is contained in:
commit
5932937952
26 changed files with 60 additions and 54 deletions
1
Cargo.lock
generated
1
Cargo.lock
generated
|
@ -3250,6 +3250,7 @@ dependencies = [
|
||||||
"data-encoding-macro",
|
"data-encoding-macro",
|
||||||
"dns-lookup",
|
"dns-lookup",
|
||||||
"dunce",
|
"dunce",
|
||||||
|
"itertools 0.8.2",
|
||||||
"lazy_static",
|
"lazy_static",
|
||||||
"libc",
|
"libc",
|
||||||
"nix 0.23.1",
|
"nix 0.23.1",
|
||||||
|
|
|
@ -20,7 +20,7 @@ path = "src/printf.rs"
|
||||||
[dependencies]
|
[dependencies]
|
||||||
clap = { version = "3.0", features = ["wrap_help", "cargo"] }
|
clap = { version = "3.0", features = ["wrap_help", "cargo"] }
|
||||||
itertools = "0.8.0"
|
itertools = "0.8.0"
|
||||||
uucore = { version=">=0.0.11", package="uucore", path="../../uucore" }
|
uucore = { version=">=0.0.11", package="uucore", path="../../uucore", features=["memo"] }
|
||||||
uucore_procs = { version=">=0.0.8", package="uucore_procs", path="../../uucore_procs" }
|
uucore_procs = { version=">=0.0.8", package="uucore_procs", path="../../uucore_procs" }
|
||||||
|
|
||||||
[[bin]]
|
[[bin]]
|
||||||
|
|
|
@ -1,23 +0,0 @@
|
||||||
//! stdio convenience fns
|
|
||||||
|
|
||||||
// spell-checker:ignore (ToDO) bslice
|
|
||||||
|
|
||||||
use std::io::{stdout, Write};
|
|
||||||
|
|
||||||
pub const EXIT_OK: i32 = 0;
|
|
||||||
pub const EXIT_ERR: i32 = 1;
|
|
||||||
|
|
||||||
// by default stdout only flushes
|
|
||||||
// to console when a newline is passed.
|
|
||||||
pub fn flush_char(c: char) {
|
|
||||||
print!("{}", c);
|
|
||||||
let _ = stdout().flush();
|
|
||||||
}
|
|
||||||
pub fn flush_str(s: &str) {
|
|
||||||
print!("{}", s);
|
|
||||||
let _ = stdout().flush();
|
|
||||||
}
|
|
||||||
pub fn flush_bytes(bslice: &[u8]) {
|
|
||||||
let _ = stdout().write(bslice);
|
|
||||||
let _ = stdout().flush();
|
|
||||||
}
|
|
|
@ -1,3 +1 @@
|
||||||
mod cli;
|
mod cli;
|
||||||
mod memo;
|
|
||||||
mod tokenize;
|
|
||||||
|
|
|
@ -4,12 +4,9 @@
|
||||||
|
|
||||||
use clap::{crate_version, App, Arg};
|
use clap::{crate_version, App, Arg};
|
||||||
use uucore::error::{UResult, UUsageError};
|
use uucore::error::{UResult, UUsageError};
|
||||||
|
use uucore::memo;
|
||||||
use uucore::InvalidEncodingHandling;
|
use uucore::InvalidEncodingHandling;
|
||||||
|
|
||||||
mod cli;
|
|
||||||
mod memo;
|
|
||||||
mod tokenize;
|
|
||||||
|
|
||||||
const VERSION: &str = "version";
|
const VERSION: &str = "version";
|
||||||
const HELP: &str = "help";
|
const HELP: &str = "help";
|
||||||
static LONGHELP_LEAD: &str = "printf
|
static LONGHELP_LEAD: &str = "printf
|
||||||
|
|
|
@ -21,6 +21,7 @@ dns-lookup = { version="1.0.5", optional=true }
|
||||||
dunce = "1.0.0"
|
dunce = "1.0.0"
|
||||||
wild = "2.0"
|
wild = "2.0"
|
||||||
# * optional
|
# * optional
|
||||||
|
itertools = { version="0.8", optional=true }
|
||||||
thiserror = { version="1.0", optional=true }
|
thiserror = { version="1.0", optional=true }
|
||||||
time = { version="<= 0.1.43", optional=true }
|
time = { version="<= 0.1.43", optional=true }
|
||||||
# * "problem" dependencies (pinned)
|
# * "problem" dependencies (pinned)
|
||||||
|
@ -53,6 +54,7 @@ encoding = ["data-encoding", "data-encoding-macro", "z85", "thiserror"]
|
||||||
entries = ["libc"]
|
entries = ["libc"]
|
||||||
fs = ["libc", "nix", "winapi-util"]
|
fs = ["libc", "nix", "winapi-util"]
|
||||||
fsext = ["libc", "time"]
|
fsext = ["libc", "time"]
|
||||||
|
memo = ["itertools"]
|
||||||
mode = ["libc"]
|
mode = ["libc"]
|
||||||
perms = ["libc", "walkdir"]
|
perms = ["libc", "walkdir"]
|
||||||
process = ["libc"]
|
process = ["libc"]
|
||||||
|
|
|
@ -6,8 +6,12 @@ pub mod encoding;
|
||||||
pub mod fs;
|
pub mod fs;
|
||||||
#[cfg(feature = "fsext")]
|
#[cfg(feature = "fsext")]
|
||||||
pub mod fsext;
|
pub mod fsext;
|
||||||
|
#[cfg(feature = "memo")]
|
||||||
|
pub mod memo;
|
||||||
#[cfg(feature = "ringbuffer")]
|
#[cfg(feature = "ringbuffer")]
|
||||||
pub mod ringbuffer;
|
pub mod ringbuffer;
|
||||||
|
#[cfg(feature = "memo")]
|
||||||
|
mod tokenize;
|
||||||
|
|
||||||
// * (platform-specific) feature-gated modules
|
// * (platform-specific) feature-gated modules
|
||||||
// ** non-windows (i.e. Unix + Fuchsia)
|
// ** non-windows (i.e. Unix + Fuchsia)
|
||||||
|
|
|
@ -5,15 +5,14 @@
|
||||||
//! 2. feeds remaining arguments into function
|
//! 2. feeds remaining arguments into function
|
||||||
//! that prints tokens.
|
//! that prints tokens.
|
||||||
|
|
||||||
|
use crate::display::Quotable;
|
||||||
|
use crate::features::tokenize::sub::Sub;
|
||||||
|
use crate::features::tokenize::token::{Token, Tokenizer};
|
||||||
|
use crate::features::tokenize::unescaped_text::UnescapedText;
|
||||||
|
use crate::show_warning;
|
||||||
use itertools::put_back_n;
|
use itertools::put_back_n;
|
||||||
use std::iter::Peekable;
|
use std::iter::Peekable;
|
||||||
use std::slice::Iter;
|
use std::slice::Iter;
|
||||||
use uucore::display::Quotable;
|
|
||||||
use uucore::show_warning;
|
|
||||||
|
|
||||||
use crate::tokenize::sub::Sub;
|
|
||||||
use crate::tokenize::token::{Token, Tokenizer};
|
|
||||||
use crate::tokenize::unescaped_text::UnescapedText;
|
|
||||||
|
|
||||||
pub struct Memo {
|
pub struct Memo {
|
||||||
tokens: Vec<Box<dyn Token>>,
|
tokens: Vec<Box<dyn Token>>,
|
|
@ -1,9 +1,9 @@
|
||||||
//! Primitives used by num_format and sub_modules.
|
//! Primitives used by num_format and sub_modules.
|
||||||
//! never dealt with above (e.g. Sub Tokenizer never uses these)
|
//! never dealt with above (e.g. Sub Tokenizer never uses these)
|
||||||
|
|
||||||
|
use crate::{display::Quotable, show_error};
|
||||||
use itertools::{put_back_n, PutBackN};
|
use itertools::{put_back_n, PutBackN};
|
||||||
use std::str::Chars;
|
use std::str::Chars;
|
||||||
use uucore::{display::Quotable, show_error};
|
|
||||||
|
|
||||||
use super::format_field::FormatField;
|
use super::format_field::FormatField;
|
||||||
|
|
|
@ -32,17 +32,20 @@ pub fn arrnum_int_mult(arr_num: &[u8], basenum: u8, base_ten_int_fact: u8) -> Ve
|
||||||
ret
|
ret
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[allow(dead_code)]
|
||||||
pub struct Remainder<'a> {
|
pub struct Remainder<'a> {
|
||||||
pub position: usize,
|
pub position: usize,
|
||||||
pub replace: Vec<u8>,
|
pub replace: Vec<u8>,
|
||||||
pub arr_num: &'a Vec<u8>,
|
pub arr_num: &'a Vec<u8>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[allow(dead_code)]
|
||||||
pub struct DivOut<'a> {
|
pub struct DivOut<'a> {
|
||||||
pub quotient: u8,
|
pub quotient: u8,
|
||||||
pub remainder: Remainder<'a>,
|
pub remainder: Remainder<'a>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[allow(dead_code)]
|
||||||
pub fn arrnum_int_div_step(
|
pub fn arrnum_int_div_step(
|
||||||
rem_in: Remainder,
|
rem_in: Remainder,
|
||||||
radix_in: u8,
|
radix_in: u8,
|
||||||
|
@ -141,6 +144,7 @@ pub fn base_conv_vec(src: &[u8], radix_src: u8, radix_dest: u8) -> Vec<u8> {
|
||||||
result
|
result
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[allow(dead_code)]
|
||||||
pub fn unsigned_to_arrnum(src: u16) -> Vec<u8> {
|
pub fn unsigned_to_arrnum(src: u16) -> Vec<u8> {
|
||||||
let mut result: Vec<u8> = Vec::new();
|
let mut result: Vec<u8> = Vec::new();
|
||||||
let mut src_tmp: u16 = src;
|
let mut src_tmp: u16 = src;
|
|
@ -9,6 +9,7 @@ use super::base_conv::RadixDef;
|
||||||
use super::float_common::{primitive_to_str_common, FloatAnalysis};
|
use super::float_common::{primitive_to_str_common, FloatAnalysis};
|
||||||
|
|
||||||
pub struct CninetyNineHexFloatf {
|
pub struct CninetyNineHexFloatf {
|
||||||
|
#[allow(dead_code)]
|
||||||
as_num: f64,
|
as_num: f64,
|
||||||
}
|
}
|
||||||
impl CninetyNineHexFloatf {
|
impl CninetyNineHexFloatf {
|
||||||
|
@ -91,6 +92,7 @@ fn get_primitive_hex(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[allow(dead_code)]
|
||||||
fn to_hex(src: &str, before_decimal: bool) -> String {
|
fn to_hex(src: &str, before_decimal: bool) -> String {
|
||||||
let radix_ten = base_conv::RadixTen;
|
let radix_ten = base_conv::RadixTen;
|
||||||
let radix_hex = base_conv::RadixHex;
|
let radix_hex = base_conv::RadixHex;
|
|
@ -7,8 +7,8 @@
|
||||||
use std::env;
|
use std::env;
|
||||||
use std::vec::Vec;
|
use std::vec::Vec;
|
||||||
|
|
||||||
use uucore::display::Quotable;
|
use crate::display::Quotable;
|
||||||
use uucore::{show_error, show_warning};
|
use crate::{show_error, show_warning};
|
||||||
|
|
||||||
use super::format_field::{FieldType, FormatField};
|
use super::format_field::{FieldType, FormatField};
|
||||||
use super::formatter::{Base, FormatPrimitive, Formatter, InitialPrefix};
|
use super::formatter::{Base, FormatPrimitive, Formatter, InitialPrefix};
|
|
@ -5,23 +5,24 @@
|
||||||
//! it is created by Sub's implementation of the Tokenizer trait
|
//! it is created by Sub's implementation of the Tokenizer trait
|
||||||
//! Subs which have numeric field chars make use of the num_format
|
//! Subs which have numeric field chars make use of the num_format
|
||||||
//! submodule
|
//! submodule
|
||||||
|
use crate::show_error;
|
||||||
use itertools::{put_back_n, PutBackN};
|
use itertools::{put_back_n, PutBackN};
|
||||||
use std::iter::Peekable;
|
use std::iter::Peekable;
|
||||||
use std::process::exit;
|
use std::process::exit;
|
||||||
use std::slice::Iter;
|
use std::slice::Iter;
|
||||||
use std::str::Chars;
|
use std::str::Chars;
|
||||||
use uucore::show_error;
|
|
||||||
// use std::collections::HashSet;
|
// use std::collections::HashSet;
|
||||||
|
|
||||||
use super::num_format::format_field::{FieldType, FormatField};
|
use super::num_format::format_field::{FieldType, FormatField};
|
||||||
use super::num_format::num_format;
|
use super::num_format::num_format;
|
||||||
use super::token;
|
use super::token;
|
||||||
use super::unescaped_text::UnescapedText;
|
use super::unescaped_text::UnescapedText;
|
||||||
use crate::cli;
|
|
||||||
|
const EXIT_ERR: i32 = 1;
|
||||||
|
|
||||||
fn err_conv(sofar: &str) {
|
fn err_conv(sofar: &str) {
|
||||||
show_error!("%{}: invalid conversion specification", sofar);
|
show_error!("%{}: invalid conversion specification", sofar);
|
||||||
exit(cli::EXIT_ERR);
|
exit(EXIT_ERR);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn convert_asterisk_arg_int(asterisk_arg: &str) -> isize {
|
fn convert_asterisk_arg_int(asterisk_arg: &str) -> isize {
|
||||||
|
@ -80,7 +81,7 @@ impl Sub {
|
||||||
_ => {
|
_ => {
|
||||||
// should be unreachable.
|
// should be unreachable.
|
||||||
println!("Invalid field type");
|
println!("Invalid field type");
|
||||||
exit(cli::EXIT_ERR);
|
exit(EXIT_ERR);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
Sub {
|
Sub {
|
|
@ -3,10 +3,11 @@
|
||||||
//! and escaped character literals (of allowed escapes),
|
//! and escaped character literals (of allowed escapes),
|
||||||
//! into an unescaped text byte array
|
//! into an unescaped text byte array
|
||||||
|
|
||||||
// spell-checker:ignore (ToDO) retval hexchars octals printf's bvec vals coreutil addchar eval bytecode
|
// spell-checker:ignore (ToDO) retval hexchars octals printf's bvec vals coreutil addchar eval bytecode bslice
|
||||||
|
|
||||||
use itertools::PutBackN;
|
use itertools::PutBackN;
|
||||||
use std::char::from_u32;
|
use std::char::from_u32;
|
||||||
|
use std::io::{stdout, Write};
|
||||||
use std::iter::Peekable;
|
use std::iter::Peekable;
|
||||||
use std::process::exit;
|
use std::process::exit;
|
||||||
use std::slice::Iter;
|
use std::slice::Iter;
|
||||||
|
@ -14,7 +15,25 @@ use std::str::Chars;
|
||||||
|
|
||||||
use super::token;
|
use super::token;
|
||||||
|
|
||||||
use crate::cli;
|
const EXIT_OK: i32 = 0;
|
||||||
|
const EXIT_ERR: i32 = 1;
|
||||||
|
|
||||||
|
// by default stdout only flushes
|
||||||
|
// to console when a newline is passed.
|
||||||
|
fn flush_char(c: char) {
|
||||||
|
print!("{}", c);
|
||||||
|
let _ = stdout().flush();
|
||||||
|
}
|
||||||
|
|
||||||
|
fn flush_str(s: &str) {
|
||||||
|
print!("{}", s);
|
||||||
|
let _ = stdout().flush();
|
||||||
|
}
|
||||||
|
|
||||||
|
fn flush_bytes(bslice: &[u8]) {
|
||||||
|
let _ = stdout().write(bslice);
|
||||||
|
let _ = stdout().flush();
|
||||||
|
}
|
||||||
|
|
||||||
pub struct UnescapedText(Vec<u8>);
|
pub struct UnescapedText(Vec<u8>);
|
||||||
impl UnescapedText {
|
impl UnescapedText {
|
||||||
|
@ -53,7 +72,7 @@ impl UnescapedText {
|
||||||
if found < min_chars {
|
if found < min_chars {
|
||||||
// only ever expected for hex
|
// only ever expected for hex
|
||||||
println!("missing hexadecimal number in escape"); //todo stderr
|
println!("missing hexadecimal number in escape"); //todo stderr
|
||||||
exit(cli::EXIT_ERR);
|
exit(EXIT_ERR);
|
||||||
}
|
}
|
||||||
retval
|
retval
|
||||||
}
|
}
|
||||||
|
@ -76,7 +95,7 @@ impl UnescapedText {
|
||||||
);
|
);
|
||||||
if (val < 159 && (val != 36 && val != 64 && val != 96)) || (val > 55296 && val < 57343) {
|
if (val < 159 && (val != 36 && val != 64 && val != 96)) || (val > 55296 && val < 57343) {
|
||||||
println!("{}", err_msg); //todo stderr
|
println!("{}", err_msg); //todo stderr
|
||||||
exit(cli::EXIT_ERR);
|
exit(EXIT_ERR);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// pass an iterator that succeeds an '/',
|
// pass an iterator that succeeds an '/',
|
||||||
|
@ -117,7 +136,7 @@ impl UnescapedText {
|
||||||
let val = (UnescapedText::base_to_u32(min_len, max_len, base, it) % 256) as u8;
|
let val = (UnescapedText::base_to_u32(min_len, max_len, base, it) % 256) as u8;
|
||||||
byte_vec.push(val);
|
byte_vec.push(val);
|
||||||
let bvec = [val];
|
let bvec = [val];
|
||||||
cli::flush_bytes(&bvec);
|
flush_bytes(&bvec);
|
||||||
} else {
|
} else {
|
||||||
byte_vec.push(ch as u8);
|
byte_vec.push(ch as u8);
|
||||||
}
|
}
|
||||||
|
@ -145,7 +164,7 @@ impl UnescapedText {
|
||||||
'f' => '\x0C',
|
'f' => '\x0C',
|
||||||
// escape character
|
// escape character
|
||||||
'e' => '\x1B',
|
'e' => '\x1B',
|
||||||
'c' => exit(cli::EXIT_OK),
|
'c' => exit(EXIT_OK),
|
||||||
'u' | 'U' => {
|
'u' | 'U' => {
|
||||||
let len = match e {
|
let len = match e {
|
||||||
'u' => 4,
|
'u' => 4,
|
||||||
|
@ -165,7 +184,7 @@ impl UnescapedText {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
s.push(ch);
|
s.push(ch);
|
||||||
cli::flush_str(&s);
|
flush_str(&s);
|
||||||
byte_vec.extend(s.bytes());
|
byte_vec.extend(s.bytes());
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -193,7 +212,7 @@ impl UnescapedText {
|
||||||
// lazy branch eval
|
// lazy branch eval
|
||||||
// remember this fn could be called
|
// remember this fn could be called
|
||||||
// many times in a single exec through %b
|
// many times in a single exec through %b
|
||||||
cli::flush_char(ch);
|
flush_char(ch);
|
||||||
tmp_str.push(ch);
|
tmp_str.push(ch);
|
||||||
}
|
}
|
||||||
'\\' => {
|
'\\' => {
|
||||||
|
@ -213,7 +232,7 @@ impl UnescapedText {
|
||||||
x if x == '%' && !subs_mode => {
|
x if x == '%' && !subs_mode => {
|
||||||
if let Some(follow) = it.next() {
|
if let Some(follow) = it.next() {
|
||||||
if follow == '%' {
|
if follow == '%' {
|
||||||
cli::flush_char(ch);
|
flush_char(ch);
|
||||||
tmp_str.push(ch);
|
tmp_str.push(ch);
|
||||||
} else {
|
} else {
|
||||||
it.put_back(follow);
|
it.put_back(follow);
|
||||||
|
@ -226,7 +245,7 @@ impl UnescapedText {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
cli::flush_char(ch);
|
flush_char(ch);
|
||||||
tmp_str.push(ch);
|
tmp_str.push(ch);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -252,6 +271,6 @@ impl token::Tokenizer for UnescapedText {
|
||||||
}
|
}
|
||||||
impl token::Token for UnescapedText {
|
impl token::Token for UnescapedText {
|
||||||
fn print(&self, _: &mut Peekable<Iter<String>>) {
|
fn print(&self, _: &mut Peekable<Iter<String>>) {
|
||||||
cli::flush_bytes(&self.0[..]);
|
flush_bytes(&self.0[..]);
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -36,6 +36,8 @@ pub use crate::features::encoding;
|
||||||
pub use crate::features::fs;
|
pub use crate::features::fs;
|
||||||
#[cfg(feature = "fsext")]
|
#[cfg(feature = "fsext")]
|
||||||
pub use crate::features::fsext;
|
pub use crate::features::fsext;
|
||||||
|
#[cfg(feature = "memo")]
|
||||||
|
pub use crate::features::memo;
|
||||||
#[cfg(feature = "ringbuffer")]
|
#[cfg(feature = "ringbuffer")]
|
||||||
pub use crate::features::ringbuffer;
|
pub use crate::features::ringbuffer;
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue