Skip to content

Commit daea6a3

Browse files
committed
Added automatic fallback to gsed if sed fails with an error.
This at least somehow fixes #10.
1 parent 0732642 commit daea6a3

File tree

3 files changed

+31
-14
lines changed

3 files changed

+31
-14
lines changed

src/cli.rs

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ pub fn parse_arguments<'a, 'b>() -> Result<Options, String> {
4040
.long("sed-path")
4141
.help("Specify path to sed that should be used.")
4242
.takes_value(true)
43-
.default_value("sed"))
43+
.required(false))
4444
.arg(Arg::with_name("sed-script")
4545
.help("Input file with sed script")
4646
.required(true)
@@ -73,7 +73,7 @@ pub struct Options {
7373
pub input_file: PathBuf,
7474
pub sed_parameters: Vec<String>,
7575
pub debug: bool,
76-
pub sed_path: String,
76+
pub sed_path: Option<String>,
7777
}
7878
impl Options {
7979
pub fn from_matches(matches: ArgMatches) -> Result<Options, String> {
@@ -87,10 +87,7 @@ impl Options {
8787
Err(_) => return Err(String::from("Failed to load input file path.")),
8888
};
8989

90-
let sed_path: String = match matches.value_of("sed-path") {
91-
Some(x) => String::from(x),
92-
None => String::from("sed"),
93-
};
90+
let sed_path: Option<String> = matches.value_of("sed-path").map(|s| String::from(s));
9491

9592
let mut sed_parameters: Vec<String> = Vec::with_capacity(4);
9693
let mut debug = false;

src/sed/communication.rs

Lines changed: 27 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ impl SedCommunicator {
1111
pub fn new(options: Options) -> Self {
1212
SedCommunicator { options }
1313
}
14-
pub fn get_execution_info_from_sed(&self) -> Result<DebugInfoFromSed, String> {
14+
pub fn get_execution_info_from_sed(&mut self) -> Result<DebugInfoFromSed, String> {
1515
let output = self.get_sed_output()?;
1616

1717
let program_source = self.parse_program_source(&output);
@@ -23,7 +23,12 @@ impl SedCommunicator {
2323
last_output: frames.1,
2424
});
2525
}
26-
fn get_sed_output(&self) -> Result<String, String> {
26+
fn get_sed_output(&mut self) -> Result<String, String> {
27+
let mut path_to_be_used: &String = &String::from("sed");
28+
if let Some(path) = &self.options.sed_path {
29+
path_to_be_used = path;
30+
}
31+
2732
let mandatory_parameters = vec![
2833
"--debug",
2934
"-f",
@@ -43,26 +48,41 @@ impl SedCommunicator {
4348
.map(|s| s.as_str())
4449
.chain(mandatory_parameters.iter().map(|s| *s))
4550
.collect::<Vec<&str>>();
46-
let sed_debug_command = Command::new(&self.options.sed_path)
51+
let sed_debug_command = Command::new(path_to_be_used)
4752
.args(&constructed_cmd_line)
4853
.stdin(Stdio::null())
4954
.stdout(Stdio::piped())
5055
.stderr(Stdio::inherit())
5156
.output()
5257
.ok()
5358
.ok_or(
54-
format!("Sed failed to process your script. Are you using GNU sed? If so, please report the bug.\nINFO: Sed was called using \"{} {}\"", &self.options.sed_path, constructed_cmd_line.join(" ")),
59+
format!("[Error] Sed failed to start. Are you using GNU sed? Is the path correct?\n[Info] Sed was called using \"{} {}\"", &path_to_be_used, constructed_cmd_line.join(" ")),
5560
)?
5661
.stdout;
5762

5863
if self.options.debug {
5964
eprintln!(
60-
"[Info] Called sed with \"{} {}\"",
61-
self.options.sed_path,
62-
constructed_cmd_line.join(" ")
65+
"[Info] Called sed with \"{} {}\", which returned {} lines of output.",
66+
path_to_be_used,
67+
constructed_cmd_line.join(" "),
68+
sed_debug_command.len()
6369
);
6470
}
6571

72+
// If sed returned no output (so it failed) and sed
73+
// path wasn't specified by user,
74+
// change executing path to "gsed" and try again.
75+
if self.options.sed_path.is_none() {
76+
self.options.sed_path = Some(String::from("gsed"));
77+
if self.options.debug {
78+
eprintln!(
79+
"[Info] Sed failed and didn't return any output. As sed path wasn't specified, trying again with \"gsed\". If even that won't work, make sure \
80+
sed is able to process your script. Most common mistake is forgeting to use -E."
81+
);
82+
}
83+
return self.get_sed_output();
84+
}
85+
6686
Ok(String::from_utf8(sed_debug_command).ok().ok_or(String::from("String received from sed doesn't seem to be UTF-8. If this continues to happen, please report the bug."))?)
6787
}
6888

src/sed/debugger.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ pub struct Debugger {
2626
impl Debugger {
2727
/// Create new instance of debugger and launch sed.
2828
pub fn new(settings: Options) -> Result<Self, String> {
29-
let communicator = SedCommunicator::new(settings);
29+
let mut communicator = SedCommunicator::new(settings);
3030
let data: DebugInfoFromSed = communicator.get_execution_info_from_sed()?;
3131
// Shift all pattern matches one frame earlier.
3232
// The way it's done now (output appears one frame after it's source)

0 commit comments

Comments
 (0)