diff --git a/src/uucore/src/lib/features/format/argument.rs b/src/uucore/src/lib/features/format/argument.rs index 6370c4177e8..db18cf51890 100644 --- a/src/uucore/src/lib/features/format/argument.rs +++ b/src/uucore/src/lib/features/format/argument.rs @@ -1,7 +1,19 @@ +// This file is part of the uutils coreutils package. +// +// For the full copyright and license information, please view the LICENSE +// file that was distributed with this source code. + use os_display::Quotable; use crate::{error::set_exit_code, show_warning}; +/// An argument for formatting +/// +/// Each of these variants is only accepted by their respective directives. For +/// example, [`FormatArgument::Char`] requires a `%c` directive. +/// +/// The [`FormatArgument::Unparsed`] variant contains a string that can be +/// parsed into other types. This is used by the `printf` utility. #[derive(Clone, Debug)] pub enum FormatArgument { Char(char), diff --git a/src/uucore/src/lib/features/format/escape.rs b/src/uucore/src/lib/features/format/escape.rs index 188dd1892b5..d20da3e7e38 100644 --- a/src/uucore/src/lib/features/format/escape.rs +++ b/src/uucore/src/lib/features/format/escape.rs @@ -1,8 +1,19 @@ +// This file is part of the uutils coreutils package. +// +// For the full copyright and license information, please view the LICENSE +// file that was distributed with this source code. + +//! Parsing of escape sequences + #[derive(Debug)] pub enum EscapedChar { + /// A single byte Byte(u8), + /// A unicode character Char(char), + /// A character prefixed with a backslash (i.e. an invalid escape sequence) Backslash(u8), + /// Specifies that the string should stop (`\c`) End, } diff --git a/src/uucore/src/lib/features/format/mod.rs b/src/uucore/src/lib/features/format/mod.rs index 9045b8b90c3..5ce98acdcec 100644 --- a/src/uucore/src/lib/features/format/mod.rs +++ b/src/uucore/src/lib/features/format/mod.rs @@ -1,23 +1,34 @@ -//! Main entry point for our implementation of printf. +// This file is part of the uutils coreutils package. +// +// For the full copyright and license information, please view the LICENSE +// file that was distributed with this source code. + +//! `printf`-style formatting +//! +//! Rust has excellent formatting capabilities, but the coreutils require very +//! specific formatting that needs to work exactly like the GNU utilities. +//! Naturally, the GNU behavior is based on the C `printf` functionality. +//! +//! Additionally, we need support for escape sequences for the `printf` utility. //! -//! The [`printf`] and [`sprintf`] closely match the behavior of the +//! The [`printf`] and [`sprintf`] functions closely match the behavior of the //! corresponding C functions: the former renders a formatted string //! to stdout, the latter renders to a new [`String`] object. //! -//! In addition to the [`printf`] and [`sprintf`] functions, we expose the -//! [`Format`] struct, which represents a parsed format string. This reduces -//! the need for parsing a format string multiple times and assures that no -//! parsing errors occur during writing. -//! //! There are three kinds of parsing that we might want to do: //! -//! 1. Only `printf` specifiers (for e.g. `seq`, `dd`) -//! 2. Only escape sequences (for e.g. `echo`) -//! 3. Both `printf` specifiers and escape sequences (for e.g. `printf`) +//! 1. Parse only `printf` directives (for e.g. `seq`, `dd`) +//! 2. Parse only escape sequences (for e.g. `echo`) +//! 3. Parse both `printf` specifiers and escape sequences (for e.g. `printf`) //! -//! This module aims to combine all three use cases. - -// spell-checker:ignore (vars) charf decf floatf intf scif strf Cninety +//! This module aims to combine all three use cases. An iterator parsing each +//! of these cases is provided by [`parse_escape_only`], [`parse_spec_only`] +//! and [`parse_spec_and_escape`], respectively. +//! +//! There is a special [`Format`] type, which can be used to parse a format +//! string containing exactly one directive and does not use any `*` in that +//! directive. This format can be printed in a type-safe manner without failing +//! (modulo IO errors). mod argument; mod escape; @@ -131,6 +142,7 @@ impl FormatItem { } } +/// Parse a format string containing % directives and escape sequences pub fn parse_spec_and_escape( fmt: &[u8], ) -> impl Iterator, FormatError>> + '_ { @@ -160,7 +172,8 @@ pub fn parse_spec_and_escape( }) } -fn parse_spec_only(fmt: &[u8]) -> impl Iterator, FormatError>> + '_ { +/// Parse a format string containing % directives +pub fn parse_spec_only(fmt: &[u8]) -> impl Iterator, FormatError>> + '_ { let mut current = fmt; std::iter::from_fn(move || match current { [] => None, @@ -183,7 +196,8 @@ fn parse_spec_only(fmt: &[u8]) -> impl Iterator, Fo }) } -fn parse_escape_only(fmt: &[u8]) -> impl Iterator + '_ { +/// Parse a format string containing escape sequences +pub fn parse_escape_only(fmt: &[u8]) -> impl Iterator + '_ { let mut current = fmt; std::iter::from_fn(move || match current { [] => None, diff --git a/src/uucore/src/lib/features/format/num_format.rs b/src/uucore/src/lib/features/format/num_format.rs index c9a2b8c166f..6fd177d1325 100644 --- a/src/uucore/src/lib/features/format/num_format.rs +++ b/src/uucore/src/lib/features/format/num_format.rs @@ -1,3 +1,10 @@ +// This file is part of the uutils coreutils package. +// +// For the full copyright and license information, please view the LICENSE +// file that was distributed with this source code. + +//! Utilities for formatting numbers in various formats + use std::io::Write; use super::{ diff --git a/src/uucore/src/lib/features/format/spec.rs b/src/uucore/src/lib/features/format/spec.rs index e74b6f8660f..7c0d0236764 100644 --- a/src/uucore/src/lib/features/format/spec.rs +++ b/src/uucore/src/lib/features/format/spec.rs @@ -1,4 +1,9 @@ -// spell-checker:ignore (vars) charf decf floatf intf scif strf Cninety intmax ptrdiff +// This file is part of the uutils coreutils package. +// +// For the full copyright and license information, please view the LICENSE +// file that was distributed with this source code. + +// spell-checker:ignore (vars) intmax ptrdiff use crate::quoting_style::{escape_name, QuotingStyle}; @@ -11,6 +16,10 @@ use super::{ }; use std::{fmt::Display, io::Write, ops::ControlFlow}; +/// A parsed specification for formatting a value +/// +/// This might require more than one argument to resolve width or precision +/// values that are given as `*`. #[derive(Debug)] pub enum Spec { Char {