From 2d66c84413fc950ffc76d0fb3eb161414deaf807 Mon Sep 17 00:00:00 2001 From: Jeffrey Finkelstein Date: Thu, 16 Dec 2021 20:44:05 -0500 Subject: [PATCH 1/2] printf: remove cli module Remove the cli module from the printf crate and move its functions into the module tokenize::unescaped_text module, the only place they are used. --- src/uu/printf/src/cli.rs | 23 ------------ src/uu/printf/src/printf.rs | 1 - src/uu/printf/src/tokenize/sub.rs | 7 ++-- src/uu/printf/src/tokenize/unescaped_text.rs | 39 +++++++++++++++----- 4 files changed, 33 insertions(+), 37 deletions(-) delete mode 100644 src/uu/printf/src/cli.rs diff --git a/src/uu/printf/src/cli.rs b/src/uu/printf/src/cli.rs deleted file mode 100644 index fa2fda1d2..000000000 --- a/src/uu/printf/src/cli.rs +++ /dev/null @@ -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(); -} diff --git a/src/uu/printf/src/printf.rs b/src/uu/printf/src/printf.rs index b49057522..e825fea86 100644 --- a/src/uu/printf/src/printf.rs +++ b/src/uu/printf/src/printf.rs @@ -6,7 +6,6 @@ use clap::{crate_version, App, Arg}; use uucore::error::{UResult, UUsageError}; use uucore::InvalidEncodingHandling; -mod cli; mod memo; mod tokenize; diff --git a/src/uu/printf/src/tokenize/sub.rs b/src/uu/printf/src/tokenize/sub.rs index 48d854fab..3a2165bb3 100644 --- a/src/uu/printf/src/tokenize/sub.rs +++ b/src/uu/printf/src/tokenize/sub.rs @@ -17,11 +17,12 @@ use super::num_format::format_field::{FieldType, FormatField}; use super::num_format::num_format; use super::token; use super::unescaped_text::UnescapedText; -use crate::cli; + +const EXIT_ERR: i32 = 1; fn err_conv(sofar: &str) { show_error!("%{}: invalid conversion specification", sofar); - exit(cli::EXIT_ERR); + exit(EXIT_ERR); } fn convert_asterisk_arg_int(asterisk_arg: &str) -> isize { @@ -80,7 +81,7 @@ impl Sub { _ => { // should be unreachable. println!("Invalid field type"); - exit(cli::EXIT_ERR); + exit(EXIT_ERR); } }; Sub { diff --git a/src/uu/printf/src/tokenize/unescaped_text.rs b/src/uu/printf/src/tokenize/unescaped_text.rs index 084014ae9..d70ad853c 100644 --- a/src/uu/printf/src/tokenize/unescaped_text.rs +++ b/src/uu/printf/src/tokenize/unescaped_text.rs @@ -7,6 +7,7 @@ use itertools::PutBackN; use std::char::from_u32; +use std::io::{stdout, Write}; use std::iter::Peekable; use std::process::exit; use std::slice::Iter; @@ -14,7 +15,25 @@ use std::str::Chars; 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); impl UnescapedText { @@ -53,7 +72,7 @@ impl UnescapedText { if found < min_chars { // only ever expected for hex println!("missing hexadecimal number in escape"); //todo stderr - exit(cli::EXIT_ERR); + exit(EXIT_ERR); } retval } @@ -76,7 +95,7 @@ impl UnescapedText { ); if (val < 159 && (val != 36 && val != 64 && val != 96)) || (val > 55296 && val < 57343) { println!("{}", err_msg); //todo stderr - exit(cli::EXIT_ERR); + exit(EXIT_ERR); } } // 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; byte_vec.push(val); let bvec = [val]; - cli::flush_bytes(&bvec); + flush_bytes(&bvec); } else { byte_vec.push(ch as u8); } @@ -145,7 +164,7 @@ impl UnescapedText { 'f' => '\x0C', // escape character 'e' => '\x1B', - 'c' => exit(cli::EXIT_OK), + 'c' => exit(EXIT_OK), 'u' | 'U' => { let len = match e { 'u' => 4, @@ -165,7 +184,7 @@ impl UnescapedText { } }; s.push(ch); - cli::flush_str(&s); + flush_str(&s); byte_vec.extend(s.bytes()); } }; @@ -193,7 +212,7 @@ impl UnescapedText { // lazy branch eval // remember this fn could be called // many times in a single exec through %b - cli::flush_char(ch); + flush_char(ch); tmp_str.push(ch); } '\\' => { @@ -213,7 +232,7 @@ impl UnescapedText { x if x == '%' && !subs_mode => { if let Some(follow) = it.next() { if follow == '%' { - cli::flush_char(ch); + flush_char(ch); tmp_str.push(ch); } else { it.put_back(follow); @@ -226,7 +245,7 @@ impl UnescapedText { } } _ => { - cli::flush_char(ch); + flush_char(ch); tmp_str.push(ch); } } @@ -252,6 +271,6 @@ impl token::Tokenizer for UnescapedText { } impl token::Token for UnescapedText { fn print(&self, _: &mut Peekable>) { - cli::flush_bytes(&self.0[..]); + flush_bytes(&self.0[..]); } } From d9afdf0527b3ad925a2c7f47f58527605aeab325 Mon Sep 17 00:00:00 2001 From: Jeffrey Finkelstein Date: Mon, 29 Nov 2021 20:17:27 -0500 Subject: [PATCH 2/2] uucore: move printf::memo module to uucore Move the `printf::memo` module to `uucore` so that it can be used by other programs, not just `printf`. For example, the `-f` option to `seq` requires parsing and formatting numbers according to the same logic as `printf`. --- Cargo.lock | 1 + src/uu/printf/Cargo.toml | 2 +- src/uu/printf/src/mod.rs | 2 -- src/uu/printf/src/printf.rs | 4 +--- src/uucore/Cargo.toml | 2 ++ src/uucore/src/lib/features.rs | 4 ++++ .../printf/src => uucore/src/lib/features}/memo.rs | 11 +++++------ .../src => uucore/src/lib/features}/tokenize/mod.rs | 0 .../lib/features}/tokenize/num_format/format_field.rs | 0 .../lib/features}/tokenize/num_format/formatter.rs | 2 +- .../tokenize/num_format/formatters/base_conv/mod.rs | 4 ++++ .../tokenize/num_format/formatters/base_conv/tests.rs | 0 .../num_format/formatters/cninetyninehexfloatf.rs | 2 ++ .../features}/tokenize/num_format/formatters/decf.rs | 0 .../tokenize/num_format/formatters/float_common.rs | 0 .../tokenize/num_format/formatters/floatf.rs | 0 .../features}/tokenize/num_format/formatters/intf.rs | 0 .../features}/tokenize/num_format/formatters/mod.rs | 0 .../features}/tokenize/num_format/formatters/scif.rs | 0 .../src/lib/features}/tokenize/num_format/mod.rs | 0 .../lib/features}/tokenize/num_format/num_format.rs | 4 ++-- .../src => uucore/src/lib/features}/tokenize/sub.rs | 2 +- .../src => uucore/src/lib/features}/tokenize/token.rs | 0 .../src/lib/features}/tokenize/unescaped_text.rs | 2 +- src/uucore/src/lib/lib.rs | 2 ++ 25 files changed, 27 insertions(+), 17 deletions(-) rename src/{uu/printf/src => uucore/src/lib/features}/memo.rs (91%) rename src/{uu/printf/src => uucore/src/lib/features}/tokenize/mod.rs (100%) rename src/{uu/printf/src => uucore/src/lib/features}/tokenize/num_format/format_field.rs (100%) rename src/{uu/printf/src => uucore/src/lib/features}/tokenize/num_format/formatter.rs (97%) rename src/{uu/printf/src => uucore/src/lib/features}/tokenize/num_format/formatters/base_conv/mod.rs (98%) rename src/{uu/printf/src => uucore/src/lib/features}/tokenize/num_format/formatters/base_conv/tests.rs (100%) rename src/{uu/printf/src => uucore/src/lib/features}/tokenize/num_format/formatters/cninetyninehexfloatf.rs (98%) rename src/{uu/printf/src => uucore/src/lib/features}/tokenize/num_format/formatters/decf.rs (100%) rename src/{uu/printf/src => uucore/src/lib/features}/tokenize/num_format/formatters/float_common.rs (100%) rename src/{uu/printf/src => uucore/src/lib/features}/tokenize/num_format/formatters/floatf.rs (100%) rename src/{uu/printf/src => uucore/src/lib/features}/tokenize/num_format/formatters/intf.rs (100%) rename src/{uu/printf/src => uucore/src/lib/features}/tokenize/num_format/formatters/mod.rs (100%) rename src/{uu/printf/src => uucore/src/lib/features}/tokenize/num_format/formatters/scif.rs (100%) rename src/{uu/printf/src => uucore/src/lib/features}/tokenize/num_format/mod.rs (100%) rename src/{uu/printf/src => uucore/src/lib/features}/tokenize/num_format/num_format.rs (99%) rename src/{uu/printf/src => uucore/src/lib/features}/tokenize/sub.rs (99%) rename src/{uu/printf/src => uucore/src/lib/features}/tokenize/token.rs (100%) rename src/{uu/printf/src => uucore/src/lib/features}/tokenize/unescaped_text.rs (99%) diff --git a/Cargo.lock b/Cargo.lock index 5323fe628..d520b6458 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3212,6 +3212,7 @@ dependencies = [ "data-encoding-macro", "dns-lookup", "dunce", + "itertools 0.8.2", "lazy_static", "libc", "nix 0.23.1", diff --git a/src/uu/printf/Cargo.toml b/src/uu/printf/Cargo.toml index 09a5640a8..cfe9aff6f 100644 --- a/src/uu/printf/Cargo.toml +++ b/src/uu/printf/Cargo.toml @@ -20,7 +20,7 @@ path = "src/printf.rs" [dependencies] clap = { version = "2.33", features = ["wrap_help"] } 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" } [[bin]] diff --git a/src/uu/printf/src/mod.rs b/src/uu/printf/src/mod.rs index 5ed2ecea8..26710c101 100644 --- a/src/uu/printf/src/mod.rs +++ b/src/uu/printf/src/mod.rs @@ -1,3 +1 @@ mod cli; -mod memo; -mod tokenize; diff --git a/src/uu/printf/src/printf.rs b/src/uu/printf/src/printf.rs index e825fea86..2fb23276a 100644 --- a/src/uu/printf/src/printf.rs +++ b/src/uu/printf/src/printf.rs @@ -4,11 +4,9 @@ use clap::{crate_version, App, Arg}; use uucore::error::{UResult, UUsageError}; +use uucore::memo; use uucore::InvalidEncodingHandling; -mod memo; -mod tokenize; - const VERSION: &str = "version"; const HELP: &str = "help"; static LONGHELP_LEAD: &str = "printf diff --git a/src/uucore/Cargo.toml b/src/uucore/Cargo.toml index ff064e5fc..555dd60aa 100644 --- a/src/uucore/Cargo.toml +++ b/src/uucore/Cargo.toml @@ -21,6 +21,7 @@ dns-lookup = { version="1.0.5", optional=true } dunce = "1.0.0" wild = "2.0" # * optional +itertools = { version="0.8", optional=true } thiserror = { version="1.0", optional=true } time = { version="<= 0.1.43", optional=true } # * "problem" dependencies (pinned) @@ -53,6 +54,7 @@ encoding = ["data-encoding", "data-encoding-macro", "z85", "thiserror"] entries = ["libc"] fs = ["libc", "nix", "winapi-util"] fsext = ["libc", "time"] +memo = ["itertools"] mode = ["libc"] perms = ["libc", "walkdir"] process = ["libc"] diff --git a/src/uucore/src/lib/features.rs b/src/uucore/src/lib/features.rs index 546cbea87..999d8af6c 100644 --- a/src/uucore/src/lib/features.rs +++ b/src/uucore/src/lib/features.rs @@ -6,8 +6,12 @@ pub mod encoding; pub mod fs; #[cfg(feature = "fsext")] pub mod fsext; +#[cfg(feature = "memo")] +pub mod memo; #[cfg(feature = "ringbuffer")] pub mod ringbuffer; +#[cfg(feature = "memo")] +mod tokenize; // * (platform-specific) feature-gated modules // ** non-windows (i.e. Unix + Fuchsia) diff --git a/src/uu/printf/src/memo.rs b/src/uucore/src/lib/features/memo.rs similarity index 91% rename from src/uu/printf/src/memo.rs rename to src/uucore/src/lib/features/memo.rs index a87d4fa89..232ead2ae 100644 --- a/src/uu/printf/src/memo.rs +++ b/src/uucore/src/lib/features/memo.rs @@ -5,15 +5,14 @@ //! 2. feeds remaining arguments into function //! 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 std::iter::Peekable; 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 { tokens: Vec>, diff --git a/src/uu/printf/src/tokenize/mod.rs b/src/uucore/src/lib/features/tokenize/mod.rs similarity index 100% rename from src/uu/printf/src/tokenize/mod.rs rename to src/uucore/src/lib/features/tokenize/mod.rs diff --git a/src/uu/printf/src/tokenize/num_format/format_field.rs b/src/uucore/src/lib/features/tokenize/num_format/format_field.rs similarity index 100% rename from src/uu/printf/src/tokenize/num_format/format_field.rs rename to src/uucore/src/lib/features/tokenize/num_format/format_field.rs diff --git a/src/uu/printf/src/tokenize/num_format/formatter.rs b/src/uucore/src/lib/features/tokenize/num_format/formatter.rs similarity index 97% rename from src/uu/printf/src/tokenize/num_format/formatter.rs rename to src/uucore/src/lib/features/tokenize/num_format/formatter.rs index 790c338ae..801e05eb8 100644 --- a/src/uu/printf/src/tokenize/num_format/formatter.rs +++ b/src/uucore/src/lib/features/tokenize/num_format/formatter.rs @@ -1,9 +1,9 @@ //! Primitives used by num_format and sub_modules. //! never dealt with above (e.g. Sub Tokenizer never uses these) +use crate::{display::Quotable, show_error}; use itertools::{put_back_n, PutBackN}; use std::str::Chars; -use uucore::{display::Quotable, show_error}; use super::format_field::FormatField; diff --git a/src/uu/printf/src/tokenize/num_format/formatters/base_conv/mod.rs b/src/uucore/src/lib/features/tokenize/num_format/formatters/base_conv/mod.rs similarity index 98% rename from src/uu/printf/src/tokenize/num_format/formatters/base_conv/mod.rs rename to src/uucore/src/lib/features/tokenize/num_format/formatters/base_conv/mod.rs index a20f03a95..076731f3f 100644 --- a/src/uu/printf/src/tokenize/num_format/formatters/base_conv/mod.rs +++ b/src/uucore/src/lib/features/tokenize/num_format/formatters/base_conv/mod.rs @@ -32,17 +32,20 @@ pub fn arrnum_int_mult(arr_num: &[u8], basenum: u8, base_ten_int_fact: u8) -> Ve ret } +#[allow(dead_code)] pub struct Remainder<'a> { pub position: usize, pub replace: Vec, pub arr_num: &'a Vec, } +#[allow(dead_code)] pub struct DivOut<'a> { pub quotient: u8, pub remainder: Remainder<'a>, } +#[allow(dead_code)] pub fn arrnum_int_div_step( rem_in: Remainder, radix_in: u8, @@ -141,6 +144,7 @@ pub fn base_conv_vec(src: &[u8], radix_src: u8, radix_dest: u8) -> Vec { result } +#[allow(dead_code)] pub fn unsigned_to_arrnum(src: u16) -> Vec { let mut result: Vec = Vec::new(); let mut src_tmp: u16 = src; diff --git a/src/uu/printf/src/tokenize/num_format/formatters/base_conv/tests.rs b/src/uucore/src/lib/features/tokenize/num_format/formatters/base_conv/tests.rs similarity index 100% rename from src/uu/printf/src/tokenize/num_format/formatters/base_conv/tests.rs rename to src/uucore/src/lib/features/tokenize/num_format/formatters/base_conv/tests.rs diff --git a/src/uu/printf/src/tokenize/num_format/formatters/cninetyninehexfloatf.rs b/src/uucore/src/lib/features/tokenize/num_format/formatters/cninetyninehexfloatf.rs similarity index 98% rename from src/uu/printf/src/tokenize/num_format/formatters/cninetyninehexfloatf.rs rename to src/uucore/src/lib/features/tokenize/num_format/formatters/cninetyninehexfloatf.rs index 0ca993680..68b35c3c1 100644 --- a/src/uu/printf/src/tokenize/num_format/formatters/cninetyninehexfloatf.rs +++ b/src/uucore/src/lib/features/tokenize/num_format/formatters/cninetyninehexfloatf.rs @@ -9,6 +9,7 @@ use super::base_conv::RadixDef; use super::float_common::{primitive_to_str_common, FloatAnalysis}; pub struct CninetyNineHexFloatf { + #[allow(dead_code)] as_num: f64, } impl CninetyNineHexFloatf { @@ -91,6 +92,7 @@ fn get_primitive_hex( } } +#[allow(dead_code)] fn to_hex(src: &str, before_decimal: bool) -> String { let radix_ten = base_conv::RadixTen; let radix_hex = base_conv::RadixHex; diff --git a/src/uu/printf/src/tokenize/num_format/formatters/decf.rs b/src/uucore/src/lib/features/tokenize/num_format/formatters/decf.rs similarity index 100% rename from src/uu/printf/src/tokenize/num_format/formatters/decf.rs rename to src/uucore/src/lib/features/tokenize/num_format/formatters/decf.rs diff --git a/src/uu/printf/src/tokenize/num_format/formatters/float_common.rs b/src/uucore/src/lib/features/tokenize/num_format/formatters/float_common.rs similarity index 100% rename from src/uu/printf/src/tokenize/num_format/formatters/float_common.rs rename to src/uucore/src/lib/features/tokenize/num_format/formatters/float_common.rs diff --git a/src/uu/printf/src/tokenize/num_format/formatters/floatf.rs b/src/uucore/src/lib/features/tokenize/num_format/formatters/floatf.rs similarity index 100% rename from src/uu/printf/src/tokenize/num_format/formatters/floatf.rs rename to src/uucore/src/lib/features/tokenize/num_format/formatters/floatf.rs diff --git a/src/uu/printf/src/tokenize/num_format/formatters/intf.rs b/src/uucore/src/lib/features/tokenize/num_format/formatters/intf.rs similarity index 100% rename from src/uu/printf/src/tokenize/num_format/formatters/intf.rs rename to src/uucore/src/lib/features/tokenize/num_format/formatters/intf.rs diff --git a/src/uu/printf/src/tokenize/num_format/formatters/mod.rs b/src/uucore/src/lib/features/tokenize/num_format/formatters/mod.rs similarity index 100% rename from src/uu/printf/src/tokenize/num_format/formatters/mod.rs rename to src/uucore/src/lib/features/tokenize/num_format/formatters/mod.rs diff --git a/src/uu/printf/src/tokenize/num_format/formatters/scif.rs b/src/uucore/src/lib/features/tokenize/num_format/formatters/scif.rs similarity index 100% rename from src/uu/printf/src/tokenize/num_format/formatters/scif.rs rename to src/uucore/src/lib/features/tokenize/num_format/formatters/scif.rs diff --git a/src/uu/printf/src/tokenize/num_format/mod.rs b/src/uucore/src/lib/features/tokenize/num_format/mod.rs similarity index 100% rename from src/uu/printf/src/tokenize/num_format/mod.rs rename to src/uucore/src/lib/features/tokenize/num_format/mod.rs diff --git a/src/uu/printf/src/tokenize/num_format/num_format.rs b/src/uucore/src/lib/features/tokenize/num_format/num_format.rs similarity index 99% rename from src/uu/printf/src/tokenize/num_format/num_format.rs rename to src/uucore/src/lib/features/tokenize/num_format/num_format.rs index a9fee58e1..0e184fb6f 100644 --- a/src/uu/printf/src/tokenize/num_format/num_format.rs +++ b/src/uucore/src/lib/features/tokenize/num_format/num_format.rs @@ -7,8 +7,8 @@ use std::env; use std::vec::Vec; -use uucore::display::Quotable; -use uucore::{show_error, show_warning}; +use crate::display::Quotable; +use crate::{show_error, show_warning}; use super::format_field::{FieldType, FormatField}; use super::formatter::{Base, FormatPrimitive, Formatter, InitialPrefix}; diff --git a/src/uu/printf/src/tokenize/sub.rs b/src/uucore/src/lib/features/tokenize/sub.rs similarity index 99% rename from src/uu/printf/src/tokenize/sub.rs rename to src/uucore/src/lib/features/tokenize/sub.rs index 3a2165bb3..c869a3564 100644 --- a/src/uu/printf/src/tokenize/sub.rs +++ b/src/uucore/src/lib/features/tokenize/sub.rs @@ -5,12 +5,12 @@ //! it is created by Sub's implementation of the Tokenizer trait //! Subs which have numeric field chars make use of the num_format //! submodule +use crate::show_error; use itertools::{put_back_n, PutBackN}; use std::iter::Peekable; use std::process::exit; use std::slice::Iter; use std::str::Chars; -use uucore::show_error; // use std::collections::HashSet; use super::num_format::format_field::{FieldType, FormatField}; diff --git a/src/uu/printf/src/tokenize/token.rs b/src/uucore/src/lib/features/tokenize/token.rs similarity index 100% rename from src/uu/printf/src/tokenize/token.rs rename to src/uucore/src/lib/features/tokenize/token.rs diff --git a/src/uu/printf/src/tokenize/unescaped_text.rs b/src/uucore/src/lib/features/tokenize/unescaped_text.rs similarity index 99% rename from src/uu/printf/src/tokenize/unescaped_text.rs rename to src/uucore/src/lib/features/tokenize/unescaped_text.rs index d70ad853c..ffbcd4afe 100644 --- a/src/uu/printf/src/tokenize/unescaped_text.rs +++ b/src/uucore/src/lib/features/tokenize/unescaped_text.rs @@ -3,7 +3,7 @@ //! and escaped character literals (of allowed escapes), //! 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 std::char::from_u32; diff --git a/src/uucore/src/lib/lib.rs b/src/uucore/src/lib/lib.rs index 2f8ccce13..7a5ca66cb 100644 --- a/src/uucore/src/lib/lib.rs +++ b/src/uucore/src/lib/lib.rs @@ -36,6 +36,8 @@ pub use crate::features::encoding; pub use crate::features::fs; #[cfg(feature = "fsext")] pub use crate::features::fsext; +#[cfg(feature = "memo")] +pub use crate::features::memo; #[cfg(feature = "ringbuffer")] pub use crate::features::ringbuffer;