added comments and cleaned code
This commit is contained in:
parent
37702c02e3
commit
c0171c0986
@ -1,3 +1,5 @@
|
||||
//! Constant values
|
||||
|
||||
use std::process::exit;
|
||||
|
||||
use lazy_static::lazy_static;
|
||||
@ -30,6 +32,8 @@ If -e is in effect, the following sequences are recognized:
|
||||
\0NNN byte with octal value NNN (1 to 3 digits)
|
||||
\xHH byte with hexadecimal value HH (1 to 2 digits)
|
||||
"#;
|
||||
|
||||
/// Special characters, that can be replaced without further logic
|
||||
pub const SIMPLE_SPECIAL_SEQUENCES: [(&str, &str); 8] = [
|
||||
(r#"\a"#, "\x07"),
|
||||
(r#"\b"#, "\x08"),
|
||||
@ -41,6 +45,7 @@ pub const SIMPLE_SPECIAL_SEQUENCES: [(&str, &str); 8] = [
|
||||
(r#"\v"#, "\x0b"),
|
||||
];
|
||||
lazy_static! {
|
||||
// \NNN or \0NNN with N in octal
|
||||
pub static ref OCTAL_REGEX: Regex = Regex::new(r#"\\(?:([1-7][0-7]{0,2}|0[0-7]{0,3}))"#)
|
||||
.map_or_else(
|
||||
|e| {
|
||||
@ -52,7 +57,8 @@ lazy_static! {
|
||||
},
|
||||
|v| v
|
||||
);
|
||||
pub static ref HEX_REGEX: Regex = Regex::new(r#"\\x([0-9A-F]{0,2})"#).map_or_else(
|
||||
// \xFF with F in octal
|
||||
pub static ref HEX_REGEX: Regex = Regex::new(r#"\\x([0-9A-F]{1,2})"#).map_or_else(
|
||||
|e| {
|
||||
eprintln!(
|
||||
"programming error: cannot compile regex pattern for hex regex match: {}",
|
||||
|
42
src/main.rs
42
src/main.rs
@ -1,3 +1,5 @@
|
||||
//! Basic rewrite of the echo GNU core utility, maintaining compatability
|
||||
|
||||
use std::{
|
||||
env::args,
|
||||
io::{self, Write},
|
||||
@ -8,6 +10,7 @@ mod consts;
|
||||
|
||||
use crate::consts::{HELP_DIALOG, HEX_REGEX, OCTAL_REGEX, SIMPLE_SPECIAL_SEQUENCES, VERSION};
|
||||
|
||||
/// Settings to be read from cli
|
||||
struct Settings {
|
||||
trailing_newline: bool,
|
||||
interpret_backslash_escapes: bool,
|
||||
@ -22,6 +25,7 @@ impl Default for Settings {
|
||||
}
|
||||
}
|
||||
|
||||
/// Replaces escaped octal representations with corresponding characters
|
||||
fn replace_octal(string: String) -> String {
|
||||
let mut res = string;
|
||||
while let Some(captures) = OCTAL_REGEX.captures(
|
||||
@ -29,19 +33,12 @@ fn replace_octal(string: String) -> String {
|
||||
&res.clone(),
|
||||
) {
|
||||
if let (Some(entire_match), Some(capture)) = (captures.get(0), captures.get(1)) {
|
||||
let mut contents = capture.as_str();
|
||||
if contents.is_empty() {
|
||||
contents = "0" // GNU echo interprets \0 as \00
|
||||
}
|
||||
res = format!(
|
||||
"{}{}",
|
||||
"{}{}{}",
|
||||
&res[..entire_match.start()],
|
||||
OCTAL_REGEX.replace(
|
||||
&res[entire_match.start()..],
|
||||
&u8::from_str_radix(contents, 8)
|
||||
.map_or_else(|_| 255 as char, |v| v as char)
|
||||
.to_string(),
|
||||
)
|
||||
&u8::from_str_radix(capture.as_str(), 8)
|
||||
.map_or_else(|_| 255 as char, |v| v as char),
|
||||
&res[entire_match.end()..],
|
||||
);
|
||||
} else {
|
||||
println!("error matching octal regex. aborting");
|
||||
@ -51,29 +48,20 @@ fn replace_octal(string: String) -> String {
|
||||
res
|
||||
}
|
||||
|
||||
/// Replaces escaped hex representations with corresponding characters
|
||||
fn replace_hex(string: String) -> String {
|
||||
let mut res = string;
|
||||
let mut search_at = 0;
|
||||
while let Some(captures) = HEX_REGEX.captures_at(
|
||||
while let Some(captures) = HEX_REGEX.captures(
|
||||
#[allow(clippy::redundant_clone)]
|
||||
&res.clone(),
|
||||
search_at,
|
||||
) {
|
||||
if let (Some(entire_match), Some(capture)) = (captures.get(0), captures.get(1)) {
|
||||
let contents = capture.as_str();
|
||||
if contents.is_empty() {
|
||||
search_at = entire_match.end();
|
||||
continue; // GNU echo does not interpret \x
|
||||
}
|
||||
res = format!(
|
||||
"{}{}",
|
||||
"{}{}{}",
|
||||
&res[..entire_match.start()],
|
||||
HEX_REGEX.replace(
|
||||
&res[entire_match.start()..],
|
||||
&u8::from_str_radix(contents, 16)
|
||||
.map_or_else(|_| 255 as char, |v| v as char)
|
||||
.to_string(),
|
||||
)
|
||||
&u8::from_str_radix(capture.as_str(), 16)
|
||||
.map_or_else(|_| 255 as char, |v| v as char),
|
||||
&res[entire_match.end()..],
|
||||
);
|
||||
} else {
|
||||
println!("error matching hex regex. aborting");
|
||||
@ -83,6 +71,7 @@ fn replace_hex(string: String) -> String {
|
||||
res
|
||||
}
|
||||
|
||||
/// Format passed argument based on settings
|
||||
fn format_arg(arg: String, settings: &mut Settings) -> String {
|
||||
if settings.interpret_backslash_escapes {
|
||||
let mut res = arg;
|
||||
@ -116,6 +105,7 @@ fn format_arg(arg: String, settings: &mut Settings) -> String {
|
||||
}
|
||||
}
|
||||
|
||||
/// Write string to stdout as unicode characters
|
||||
fn write_as_unicode(string: String) {
|
||||
let stdout = io::stdout();
|
||||
if let Err(e) = stdout.lock().write_all(
|
||||
|
Loading…
Reference in New Issue
Block a user