Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ clap_mangen = "0.2"
regex = "1.10.4"
sysinfo = "0.34"
libc = "0.2.153"
once_cell = "1.21"
phf = "0.11.2"
phf_codegen = "0.11.2"
textwrap = { version = "0.16.1", features = ["terminal_size"] }
Expand Down
2 changes: 1 addition & 1 deletion LICENSE
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
MIT License

Copyright (c) 2024 uutils
Copyright (c) 2025 Diomidis Spinellis

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
Expand Down
4 changes: 3 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,9 @@

# sed

Rust reimplementation of the [sed utility](https://pubs.opengroup.org/onlinepubs/9799919799/utilities/sed.html).
Rust reimplementation of the [sed utility](https://pubs.opengroup.org/onlinepubs/9799919799/utilities/sed.html)
with some [GNU sed](https://www.gnu.org/software/sed/manual/sed.html)
and [FreeBSD sed](https://man.freebsd.org/cgi/man.cgi?sed(1)) extensions.

## Installation

Expand Down
2 changes: 2 additions & 0 deletions src/uu/sed/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,9 @@ categories = ["command-line-utilities"]
[dependencies]
uucore = { workspace = true }
clap = { workspace = true }
once_cell = { workspace = true }
regex = { workspace = true }
tempfile = { workspace = true }

[lib]
path = "src/sed.rs"
Expand Down
129 changes: 66 additions & 63 deletions src/uu/sed/src/command.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
// Definitions for the compiled code data structures
//
// This file is part of the uutils sed package.
// SPDX-License-Identifier: MIT
// Copyright (c) 2025 Diomidis Spinellis
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We, in uutils, usually don't add names in the copyright in the files.

I feel that it isn't bring much in general.
The author can be easily found in git {log, blame} and it gives the impression for new comers that the file is "owned" by someone and increases the contribution bar.

However, it isn't a big deal, so, feel free to let it as it.

//
// This file is part of the uutils sed package.
// It is licensed under the MIT License.
// For the full copyright and license information, please view the LICENSE
// file that was distributed with this source code.

Expand All @@ -13,6 +16,26 @@ use std::collections::HashMap;
use std::fs::File;
use std::path::PathBuf; // For file descriptors and equivalent

// Compilation and processing options provided mostly through the
// command-line interface
#[derive(Debug)]
pub struct CliOptions {
// Command-line flags with corresponding names
pub all_output_files: bool,
pub debug: bool,
pub regexp_extended: bool,
pub follow_symlinks: bool,
pub in_place: bool,
pub in_place_suffix: Option<String>,
pub length: usize,
pub quiet: bool,
pub posix: bool,
pub separate: bool,
pub sandbox: bool,
pub unbuffered: bool,
pub null_data: bool,
}

// The specification of a script: through a string or a file
#[derive(Debug, PartialEq)]
pub enum ScriptValue {
Expand All @@ -24,7 +47,7 @@ pub enum ScriptValue {
* Types of address specifications
*/
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
enum AddressType {
pub enum AddressType {
Re, // Line that matches regex
Line, // Specific line
RelLine, // Relative line
Expand All @@ -35,95 +58,75 @@ enum AddressType {
* Format of an address
*/
#[derive(Debug)]
struct Address {
atype: AddressType, // Address type
value: AddressValue, // Line number or regex
pub struct Address {
pub atype: AddressType, // Address type
pub value: AddressValue, // Line number or regex
}

#[derive(Debug)]
enum AddressValue {
LineNumber(u64),
pub enum AddressValue {
LineNumber(usize),
Regex(Regex),
}

/*
* Substitution command
*/
#[derive(Debug)]
struct Substitution {
occurrence: usize, // Which occurrence to substitute
print_flag: bool, // True if 'p' flag
ignore_case: bool, // True if 'I' flag
write_file: Option<PathBuf>, // Path to file if 'w' flag is used
file_descriptor: Option<File>, // Cached file descriptor
regex: Regex, // Regular expression
max_backref: u32, // Largest backreference
line_number: u64, // Line number
replacement: String, // Replacement text
pub struct Substitution {
pub occurrence: usize, // Which occurrence to substitute
pub print_flag: bool, // True if 'p' flag
pub ignore_case: bool, // True if 'I' flag
pub write_file: Option<PathBuf>, // Path to file if 'w' flag is used
pub file_descriptor: Option<File>, // Cached file descriptor
pub regex: Regex, // Regular expression
pub max_backref: u32, // Largest backreference
pub line_number: usize, // Line number
pub replacement: String, // Replacement text
}

/*
* Translate command.
*/
// Transliteration command (y)
#[derive(Debug)]
struct TranslateCommand {
byte_table: [u8; 256], // Byte translation table
multi_map: HashMap<char, char>, // Direct mapping from one char to another
pub struct Transliteration {
pub byte_table: [u8; 256], // Byte translation table
pub multi_map: HashMap<char, char>, // Direct mapping from one char to another
}

/*
* An internally compiled command.
*/
#[derive(Debug)]
pub struct Command {
next: Option<Box<Command>>, // Pointer to next command
addr1: Option<Address>, // Start address
addr2: Option<Address>, // End address
start_line: Option<u64>, // Start line number (or None)
text: Option<String>, // Text for ':', 'a', 'c', 'i', 'r', 'w'
data: CommandData, // Union equivalent
code: char, // Command code
non_select: bool, // True if '!'
pub code: char, // Command code
pub addr1: Option<Address>, // Start address
pub addr2: Option<Address>, // End address
pub non_select: bool, // True if '!'
pub start_line: Option<usize>, // Start line number (or None)
pub text: Option<String>, // Text for ':', 'a', 'c', 'i', 'r', 'w'
pub data: CommandData, // Command-specific data
pub next: Option<Box<Command>>, // Pointer to next command
}

#[derive(Debug)]
enum CommandData {
SubCommands(Vec<Command>), // Commands for 'b', 't', '{'
Substitution(Box<Substitution>), // Substitute command
Translate(Box<TranslateCommand>), // Replace command array
WriteFileDescriptor(File), // File descriptor for 'w'
}

/*
* Types of command arguments recognized by the parser
*/
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
enum CommandArgs {
Empty, // d D g G h H l n N p P q x = \0
Text, // a c i
NonSelect, // !
Group, // {
EndGroup, // }
Comment, // #
Branch, // b t
Label, // :
ReadFile, // r
WriteFile, // w
Substitute, // s
Translate, // y
pub enum CommandData {
None,
SubCommands(Vec<Command>), // Commands for 'b', 't', '{'
Substitution(Box<Substitution>), // Substitute command 's'
Transliteration(Box<Transliteration>), // Transliteration command 'y'
WriteFileDescriptor(File), // File descriptor for 'w'
}

/*
* Structure containing things to append before a line is read
*/
#[derive(Debug)]
struct AppendBuffer {
pub struct AppendBuffer {
append_type: AppendType,
content: String,
}

#[derive(Debug, Clone, Copy, PartialEq, Eq)]
enum AppendType {
pub enum AppendType {
String,
File,
}
Expand All @@ -132,7 +135,7 @@ enum AppendType {
* Special flag for space modifications
*/
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
enum SpaceFlag {
pub enum SpaceFlag {
Append, // Append to contents
Replace, // Replace contents
}
Expand All @@ -141,9 +144,9 @@ enum SpaceFlag {
* Structure for a processing space (process, hold, otherwise).
*/
#[derive(Debug)]
struct Space {
current: String, // Current space content
deleted: bool, // Whether content was deleted
append_newline: bool, // Whether originally terminated by \n
backup: String, // Backing memory
pub struct Space {
pub current: String, // Current space content
pub deleted: bool, // Whether content was deleted
pub append_newline: bool, // Whether originally terminated by \n
pub backup: String, // Backing memory
}
Loading
Loading