mirror of
https://github.com/hrydgard/ppsspp.git
synced 2026-09-04 03:35:19 +02:00
149 lines
4.5 KiB
Rust
149 lines
4.5 KiB
Rust
// Super simplified ini file processor.
|
|
// Doesn't even bother with understanding comments.
|
|
// Just understands section headings and
|
|
// keys and values, split by ' = '.
|
|
|
|
#[derive(Debug, Clone)]
|
|
pub struct Section {
|
|
pub name: String,
|
|
pub title_line: String,
|
|
pub lines: Vec<String>,
|
|
}
|
|
|
|
impl Section {
|
|
pub fn remove_line(&mut self, key: &str) -> Option<String> {
|
|
let mut remove_index = None;
|
|
for (index, line) in self.lines.iter().enumerate() {
|
|
let prefix = if let Some(pos) = line.find(" =") {
|
|
&line[0..pos]
|
|
} else {
|
|
continue;
|
|
};
|
|
|
|
if prefix.eq_ignore_ascii_case(key) {
|
|
remove_index = Some(index);
|
|
break;
|
|
}
|
|
}
|
|
|
|
if let Some(remove_index) = remove_index {
|
|
Some(self.lines.remove(remove_index))
|
|
} else {
|
|
None
|
|
}
|
|
}
|
|
|
|
pub fn insert_line_if_missing(&mut self, line: &str) -> bool {
|
|
let prefix = if let Some(pos) = line.find(" =") {
|
|
&line[0..pos + 2]
|
|
} else {
|
|
return false;
|
|
};
|
|
|
|
// Ignore comments when copying lines.
|
|
if prefix.starts_with('#') {
|
|
return false;
|
|
}
|
|
// Need to decide a policy for these.
|
|
if prefix.starts_with("translators") {
|
|
return false;
|
|
}
|
|
let prefix = prefix.to_owned();
|
|
|
|
for iter_line in &self.lines {
|
|
if iter_line.starts_with(&prefix) {
|
|
// Already have it
|
|
return false;
|
|
}
|
|
}
|
|
|
|
// Now try to insert it at an alphabetic-ish location.
|
|
let prefix = prefix.to_ascii_lowercase();
|
|
|
|
// Then, find a suitable insertion spot
|
|
for (i, iter_line) in self.lines.iter().enumerate() {
|
|
if iter_line.to_ascii_lowercase() > prefix {
|
|
println!("Inserting line {} into {}", line, self.name);
|
|
self.lines.insert(i, line.to_owned());
|
|
return true;
|
|
}
|
|
}
|
|
|
|
for i in (0..self.lines.len()).rev() {
|
|
if self.lines[i].is_empty() {
|
|
continue;
|
|
}
|
|
println!("Inserting line {} into {}", line, self.name);
|
|
self.lines.insert(i + 1, line.to_owned());
|
|
return true;
|
|
}
|
|
|
|
println!("failed to insert {}", line);
|
|
true
|
|
}
|
|
|
|
pub fn rename_key(&mut self, old: &str, new: &str) {
|
|
let prefix = old.to_owned() + " =";
|
|
let mut found_index = None;
|
|
for (index, line) in self.lines.iter().enumerate() {
|
|
if line.starts_with(&prefix) {
|
|
found_index = Some(index);
|
|
}
|
|
}
|
|
if let Some(index) = found_index {
|
|
let line = self.lines.remove(index);
|
|
let line = new.to_owned() + " =" + line.strip_prefix(&prefix).unwrap();
|
|
self.insert_line_if_missing(&line);
|
|
} else {
|
|
let name = &self.name;
|
|
println!("didn't find a line starting with {prefix} in section {name}");
|
|
}
|
|
}
|
|
|
|
pub fn sort(&mut self) {
|
|
self.lines.sort();
|
|
}
|
|
|
|
pub fn comment_out_lines_if_not_in(&mut self, other: &Section) {
|
|
// Brute force (O(n^2)). Bad but not a problem.
|
|
|
|
for line in &mut self.lines {
|
|
let prefix = if let Some(pos) = line.find(" =") {
|
|
&line[0..pos + 2]
|
|
} else {
|
|
// Keep non-key lines.
|
|
continue;
|
|
};
|
|
if prefix.starts_with("Font") || prefix.starts_with('#') {
|
|
continue;
|
|
}
|
|
if !other.lines.iter().any(|line| line.starts_with(prefix)) {
|
|
if !prefix.contains("URL") {
|
|
println!("Commenting out from {}: {line}", other.name);
|
|
// Comment out the line.
|
|
*line = "#".to_owned() + line;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
pub fn remove_lines_if_not_in(&mut self, other: &Section) {
|
|
// Brute force (O(n^2)). Bad but not a problem.
|
|
|
|
self.lines.retain(|line| {
|
|
let prefix = if let Some(pos) = line.find(" =") {
|
|
&line[0..pos + 2]
|
|
} else {
|
|
// Keep non-key lines.
|
|
return true;
|
|
};
|
|
if prefix.starts_with("Font") || prefix.starts_with('#') {
|
|
return true;
|
|
}
|
|
|
|
// keeps the line if this expression returns true.
|
|
other.lines.iter().any(|line| line.starts_with(prefix))
|
|
});
|
|
}
|
|
}
|