1
Fork 0
mirror of https://github.com/RGBCube/uutils-coreutils synced 2025-08-02 05:57:46 +00:00

uucore/format: fix license headers and improve docs

This commit is contained in:
Terts Diepraam 2023-11-22 12:38:10 +01:00
parent 4b9fca8def
commit e95add7940
5 changed files with 71 additions and 16 deletions

View file

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

View file

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

View file

@ -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
//!
//! The [`printf`] and [`sprintf`] closely match the behavior of the
//! 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`] 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<C: FormatChar> FormatItem<C> {
}
}
/// Parse a format string containing % directives and escape sequences
pub fn parse_spec_and_escape(
fmt: &[u8],
) -> impl Iterator<Item = Result<FormatItem<EscapedChar>, FormatError>> + '_ {
@ -160,7 +172,10 @@ pub fn parse_spec_and_escape(
})
}
fn parse_spec_only(fmt: &[u8]) -> impl Iterator<Item = Result<FormatItem<u8>, FormatError>> + '_ {
/// Parse a format string containing % directives
pub fn parse_spec_only(
fmt: &[u8],
) -> impl Iterator<Item = Result<FormatItem<u8>, FormatError>> + '_ {
let mut current = fmt;
std::iter::from_fn(move || match current {
[] => None,
@ -183,7 +198,8 @@ fn parse_spec_only(fmt: &[u8]) -> impl Iterator<Item = Result<FormatItem<u8>, Fo
})
}
fn parse_escape_only(fmt: &[u8]) -> impl Iterator<Item = EscapedChar> + '_ {
/// Parse a format string containing escape sequences
pub fn parse_escape_only(fmt: &[u8]) -> impl Iterator<Item = EscapedChar> + '_ {
let mut current = fmt;
std::iter::from_fn(move || match current {
[] => None,

View file

@ -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::{

View file

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