use std::path::PathBuf;
use log::{debug, error, info};
use crate::State;
use crate::mi::{
MEMORY_MAP_BEGIN, MEMORY_MAP_START_STR_NEW, MEMORY_MAP_START_STR_NEW_2,
MEMORY_MAP_START_STR_OLD, Mapping,
};
pub fn stream_output(
t: &str,
s: &str,
state: &mut State,
current_map: &mut (Option<Mapping>, String),
) {
if s.starts_with("The target endianness") {
state.endian = if s.contains("little") {
Some(deku::ctx::Endian::Little)
} else {
Some(deku::ctx::Endian::Big)
};
debug!("endian: {:?}", state.endian);
return;
}
if state.filepath.is_none() {
let symbols = "Reading symbols from ";
if s.starts_with(symbols) {
let filepath = &s[symbols.len()..];
let filepath = filepath.trim_end();
if let Some(filepath) = filepath.strip_suffix("...") {
info!("new filepath: {filepath}");
state.filepath = Some(PathBuf::from(filepath));
}
}
}
if s.starts_with("process") || s.starts_with("Mapped address spaces:") {
return;
}
if s.contains("warning: unable to open /proc file '/proc/1/maps'") {
log::trace!("proc file could not be read, abort memory map reading");
return;
}
let split: Vec<&str> = s.split_whitespace().collect();
if split == MEMORY_MAP_START_STR_NEW {
current_map.0 = Some(Mapping::New);
} else if split == MEMORY_MAP_START_STR_NEW_2 {
current_map.0 = Some(Mapping::New);
} else if split == MEMORY_MAP_START_STR_OLD {
current_map.0 = Some(Mapping::Old);
} else if split.starts_with(&MEMORY_MAP_BEGIN) {
error!("Expected memory mapping, was not expected mapping");
}
if current_map.0.is_some() {
current_map.1.push_str(s);
return;
}
let split: Vec<String> =
s.split('\n').map(String::from).map(|a| a.trim_end().to_string()).collect();
for s in split {
if !s.is_empty() {
state.output.push(s);
}
}
if t == "~" && !s.contains('\n') {
state.stream_output_prompt = s.to_string();
}
}