mirror of
https://github.com/uutils/diffutils.git
synced 2026-06-10 15:48:59 -07:00
Merge pull request #117 from sami-daniel/main
Create the side-by-side option (-y) feature for the diff command (Incomplete)
This commit is contained in:
@@ -46,6 +46,7 @@ jobs:
|
||||
- { name: fuzz_ed, should_pass: true }
|
||||
- { name: fuzz_normal, should_pass: true }
|
||||
- { name: fuzz_patch, should_pass: true }
|
||||
- { name: fuzz_side, should_pass: true }
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: dtolnay/rust-toolchain@nightly
|
||||
|
||||
+5
-1
@@ -47,4 +47,8 @@ path = "fuzz_targets/fuzz_ed.rs"
|
||||
test = false
|
||||
doc = false
|
||||
|
||||
|
||||
[[bin]]
|
||||
name = "fuzz_side"
|
||||
path = "fuzz_targets/fuzz_side.rs"
|
||||
test = false
|
||||
doc = false
|
||||
@@ -0,0 +1,42 @@
|
||||
#![no_main]
|
||||
#[macro_use]
|
||||
extern crate libfuzzer_sys;
|
||||
|
||||
use diffutilslib::side_diff;
|
||||
|
||||
use std::fs::File;
|
||||
use std::io::Write;
|
||||
use diffutilslib::params::Params;
|
||||
|
||||
fuzz_target!(|x: (Vec<u8>, Vec<u8>, /* usize, usize */ bool)| {
|
||||
let (original, new, /* width, tabsize, */ expand) = x;
|
||||
|
||||
// if width == 0 || tabsize == 0 {
|
||||
// return;
|
||||
// }
|
||||
|
||||
let params = Params {
|
||||
// width,
|
||||
// tabsize,
|
||||
expand_tabs: expand,
|
||||
..Default::default()
|
||||
};
|
||||
let mut output_buf = vec![];
|
||||
side_diff::diff(&original, &new, &mut output_buf, ¶ms);
|
||||
File::create("target/fuzz.file.original")
|
||||
.unwrap()
|
||||
.write_all(&original)
|
||||
.unwrap();
|
||||
File::create("target/fuzz.file.new")
|
||||
.unwrap()
|
||||
.write_all(&new)
|
||||
.unwrap();
|
||||
File::create("target/fuzz.file")
|
||||
.unwrap()
|
||||
.write_all(&original)
|
||||
.unwrap();
|
||||
File::create("target/fuzz.diff")
|
||||
.unwrap()
|
||||
.write_all(&output_buf)
|
||||
.unwrap();
|
||||
});
|
||||
+6
-2
@@ -5,11 +5,11 @@
|
||||
|
||||
use crate::params::{parse_params, Format};
|
||||
use crate::utils::report_failure_to_read_input_file;
|
||||
use crate::{context_diff, ed_diff, normal_diff, unified_diff};
|
||||
use crate::{context_diff, ed_diff, normal_diff, side_diff, unified_diff};
|
||||
use std::env::ArgsOs;
|
||||
use std::ffi::OsString;
|
||||
use std::fs;
|
||||
use std::io::{self, Read, Write};
|
||||
use std::io::{self, stdout, Read, Write};
|
||||
use std::iter::Peekable;
|
||||
use std::process::{exit, ExitCode};
|
||||
|
||||
@@ -79,6 +79,10 @@ pub fn main(opts: Peekable<ArgsOs>) -> ExitCode {
|
||||
eprintln!("{error}");
|
||||
exit(2);
|
||||
}),
|
||||
Format::SideBySide => {
|
||||
let mut output = stdout().lock();
|
||||
side_diff::diff(&from_content, &to_content, &mut output, ¶ms)
|
||||
}
|
||||
};
|
||||
if params.brief && !result.is_empty() {
|
||||
println!(
|
||||
|
||||
@@ -4,6 +4,7 @@ pub mod ed_diff;
|
||||
pub mod macros;
|
||||
pub mod normal_diff;
|
||||
pub mod params;
|
||||
pub mod side_diff;
|
||||
pub mod unified_diff;
|
||||
pub mod utils;
|
||||
|
||||
@@ -11,4 +12,5 @@ pub mod utils;
|
||||
pub use context_diff::diff as context_diff;
|
||||
pub use ed_diff::diff as ed_diff;
|
||||
pub use normal_diff::diff as normal_diff;
|
||||
pub use side_diff::diff as side_by_side_diff;
|
||||
pub use unified_diff::diff as unified_diff;
|
||||
|
||||
@@ -18,6 +18,7 @@ mod ed_diff;
|
||||
mod macros;
|
||||
mod normal_diff;
|
||||
mod params;
|
||||
mod side_diff;
|
||||
mod unified_diff;
|
||||
mod utils;
|
||||
|
||||
|
||||
+42
-3
@@ -11,6 +11,7 @@ pub enum Format {
|
||||
Unified,
|
||||
Context,
|
||||
Ed,
|
||||
SideBySide,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Eq, PartialEq)]
|
||||
@@ -24,6 +25,7 @@ pub struct Params {
|
||||
pub brief: bool,
|
||||
pub expand_tabs: bool,
|
||||
pub tabsize: usize,
|
||||
pub width: usize,
|
||||
}
|
||||
|
||||
impl Default for Params {
|
||||
@@ -38,6 +40,7 @@ impl Default for Params {
|
||||
brief: false,
|
||||
expand_tabs: false,
|
||||
tabsize: 8,
|
||||
width: 130,
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -57,6 +60,7 @@ pub fn parse_params<I: Iterator<Item = OsString>>(mut opts: Peekable<I>) -> Resu
|
||||
let mut format = None;
|
||||
let mut context = None;
|
||||
let tabsize_re = Regex::new(r"^--tabsize=(?<num>\d+)$").unwrap();
|
||||
let width_re = Regex::new(r"--width=(?P<long>\d+)$").unwrap();
|
||||
while let Some(param) = opts.next() {
|
||||
let next_param = opts.peek();
|
||||
if param == "--" {
|
||||
@@ -101,6 +105,34 @@ pub fn parse_params<I: Iterator<Item = OsString>>(mut opts: Peekable<I>) -> Resu
|
||||
format = Some(Format::Ed);
|
||||
continue;
|
||||
}
|
||||
if param == "-y" || param == "--side-by-side" {
|
||||
if format.is_some() && format != Some(Format::SideBySide) {
|
||||
return Err("Conflicting output style option".to_string());
|
||||
}
|
||||
format = Some(Format::SideBySide);
|
||||
continue;
|
||||
}
|
||||
if width_re.is_match(param.to_string_lossy().as_ref()) {
|
||||
let param = param.into_string().unwrap();
|
||||
let width_str: &str = width_re
|
||||
.captures(param.as_str())
|
||||
.unwrap()
|
||||
.name("long")
|
||||
.unwrap()
|
||||
.as_str();
|
||||
|
||||
params.width = match width_str.parse::<usize>() {
|
||||
Ok(num) => {
|
||||
if num == 0 {
|
||||
return Err("invalid width «0»".to_string());
|
||||
}
|
||||
|
||||
num
|
||||
}
|
||||
Err(_) => return Err(format!("invalid width «{width_str}»")),
|
||||
};
|
||||
continue;
|
||||
}
|
||||
if tabsize_re.is_match(param.to_string_lossy().as_ref()) {
|
||||
// Because param matches the regular expression,
|
||||
// it is safe to assume it is valid UTF-8.
|
||||
@@ -112,9 +144,16 @@ pub fn parse_params<I: Iterator<Item = OsString>>(mut opts: Peekable<I>) -> Resu
|
||||
.unwrap()
|
||||
.as_str();
|
||||
params.tabsize = match tabsize_str.parse::<usize>() {
|
||||
Ok(num) => num,
|
||||
Ok(num) => {
|
||||
if num == 0 {
|
||||
return Err("invalid tabsize «0»".to_string());
|
||||
}
|
||||
|
||||
num
|
||||
}
|
||||
Err(_) => return Err(format!("invalid tabsize «{tabsize_str}»")),
|
||||
};
|
||||
|
||||
continue;
|
||||
}
|
||||
match match_context_diff_params(¶m, next_param, format) {
|
||||
@@ -704,11 +743,11 @@ mod tests {
|
||||
executable: os("diff"),
|
||||
from: os("foo"),
|
||||
to: os("bar"),
|
||||
tabsize: 0,
|
||||
tabsize: 1,
|
||||
..Default::default()
|
||||
}),
|
||||
parse_params(
|
||||
[os("diff"), os("--tabsize=0"), os("foo"), os("bar")]
|
||||
[os("diff"), os("--tabsize=1"), os("foo"), os("bar")]
|
||||
.iter()
|
||||
.cloned()
|
||||
.peekable()
|
||||
|
||||
+1266
File diff suppressed because it is too large
Load Diff
+1
-2
@@ -3,9 +3,8 @@
|
||||
// For the full copyright and license information, please view the LICENSE-*
|
||||
// files that was distributed with this source code.
|
||||
|
||||
use std::{ffi::OsString, io::Write};
|
||||
|
||||
use regex::Regex;
|
||||
use std::{ffi::OsString, io::Write};
|
||||
use unicode_width::UnicodeWidthStr;
|
||||
|
||||
/// Replace tabs by spaces in the input line.
|
||||
|
||||
Reference in New Issue
Block a user