Add compiler and processor skeleton

This commit is contained in:
Diomidis Spinellis
2025-03-20 20:40:40 +02:00
parent 4a29612ec1
commit 6308ed7b33
6 changed files with 332 additions and 145 deletions
Generated
+143 -134
View File
File diff suppressed because it is too large Load Diff
+1
View File
@@ -15,6 +15,7 @@ categories = ["command-line-utilities"]
[dependencies]
uucore = { workspace = true }
clap = { workspace = true }
regex = { workspace = true }
[lib]
path = "src/sed.rs"
+149
View File
@@ -0,0 +1,149 @@
// Definitions for the compiled code data structures
//
// This file is part of the uutils sed package.
//
// For the full copyright and license information, please view the LICENSE
// file that was distributed with this source code.
// TODO: remove when compile is implemented
#![allow(dead_code)]
use regex::Regex;
use std::collections::HashMap;
use std::fs::File;
use std::path::PathBuf; // For file descriptors and equivalent
// The specification of a script: through a string or a file
#[derive(Debug, PartialEq)]
pub enum ScriptValue {
StringVal(String),
PathVal(PathBuf),
}
/*
* Types of address specifications
*/
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
enum AddressType {
Re, // Line that matches regex
Line, // Specific line
RelLine, // Relative line
Last, // Last line
}
/*
* Format of an address
*/
#[derive(Debug)]
struct Address {
atype: AddressType, // Address type
value: AddressValue, // Line number or regex
}
#[derive(Debug)]
enum AddressValue {
LineNumber(u64),
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
}
/*
* Translate command.
*/
#[derive(Debug)]
struct TranslateCommand {
byte_table: [u8; 256], // Byte translation table
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 '!'
}
#[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
}
/*
* Structure containing things to append before a line is read
*/
#[derive(Debug)]
struct AppendBuffer {
append_type: AppendType,
content: String,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
enum AppendType {
String,
File,
}
/*
* Special flag for space modifications
*/
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
enum SpaceFlag {
Append, // Append to contents
Replace, // Replace contents
}
/*
* 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
}
+14
View File
@@ -0,0 +1,14 @@
// Compile the scripts into the internal representation of commands
//
// This file is part of the uutils sed package.
//
// For the full copyright and license information, please view the LICENSE
// file that was distributed with this source code.
use crate::command::{Command, ScriptValue};
use uucore::error::UResult;
pub fn compile(_scripts: Vec<ScriptValue>) -> UResult<Option<Command>> {
// TODO
Ok(None)
}
+15
View File
@@ -0,0 +1,15 @@
// Process the files with the compiled scripts
//
// This file is part of the uutils sed package.
//
// For the full copyright and license information, please view the LICENSE
// file that was distributed with this source code.
use crate::command::Command;
use std::path::PathBuf;
use uucore::error::UResult;
pub fn process(_code: Option<Command>, _files: Vec<PathBuf>) -> UResult<()> {
// TODO
Ok(())
}
+10 -11
View File
@@ -3,6 +3,13 @@
// For the full copyright and license information, please view the LICENSE
// file that was distributed with this source code.
pub mod command;
pub mod compiler;
pub mod processor;
use crate::command::ScriptValue;
use crate::compiler::compile;
use crate::processor::process;
use clap::{arg, Arg, ArgMatches, Command};
use std::path::PathBuf;
use uucore::error::{UResult, UUsageError};
@@ -11,13 +18,6 @@ use uucore::format_usage;
const ABOUT: &str = "Stream editor for filtering and transforming text";
const USAGE: &str = "sed [OPTION]... [script] [file]...";
// The specification of a script: through a string or a file
#[derive(Debug, PartialEq)]
enum ScriptValue {
StringVal(String),
PathVal(PathBuf),
}
/*
* Iterate through script and file arguments specified in matches and
* return vectors of all scripts and input files in the specified order.
@@ -95,10 +95,9 @@ fn get_scripts_files(matches: &ArgMatches) -> UResult<(Vec<ScriptValue>, Vec<Pat
#[uucore::main]
pub fn uumain(args: impl uucore::Args) -> UResult<()> {
let matches = uu_app().try_get_matches_from(args)?;
let (_scripts, _files) = get_scripts_files(&matches)?;
// TODO apply scripts on files.
let (scripts, files) = get_scripts_files(&matches)?;
let executable = compile(scripts)?;
process(executable, files)?;
Ok(())
}