mirror of
https://github.com/dexoron/dcr.git
synced 2026-10-21 09:48:31 +00:00
88 lines
3.0 KiB
Rust
88 lines
3.0 KiB
Rust
// DCR — Cargo-like C/C++ project manager.
|
|
//
|
|
// Copyright (C) 2026 Dexoron (Bezotechestvo Vladimir) <main@dexoron.su>
|
|
//
|
|
// This program is free software: you can redistribute it and/or modify
|
|
// it under the terms of the GNU General Public License as published by
|
|
// the Free Software Foundation, either version 3 of the License, or
|
|
// (at your option) any later version.
|
|
//
|
|
// This program is distributed in the hope that it will be useful,
|
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
// GNU General Public License for more details.
|
|
//
|
|
// You should have received a copy of the GNU General Public License
|
|
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
|
|
use std::path::{Path, PathBuf};
|
|
|
|
/// Joins the given directory and file into a single path string, trimming trailing slashes
|
|
/// for cross-platform compatibility.
|
|
pub fn join_dir(dir: &str, file: &str) -> String {
|
|
let trimmed = dir.trim_end_matches(['/', '\\']);
|
|
Path::new(trimmed).join(file).to_string_lossy().into_owned()
|
|
}
|
|
|
|
#[cfg_attr(not(windows), allow(dead_code))]
|
|
/// Adds `.exe` suffix to the name if it does not already have a recognized executable
|
|
/// extension (`.exe`, `.dll`, `.sys`, `.com`, `.efi`) or any extension at all.
|
|
pub fn with_exe_suffix(name: &str) -> String {
|
|
let lower = name.to_ascii_lowercase();
|
|
// Check if name already qualifies for no suffix (has executable ext or any ext)
|
|
if lower.ends_with(".exe")
|
|
|| lower.ends_with(".dll")
|
|
|| lower.ends_with(".sys")
|
|
|| lower.ends_with(".com")
|
|
|| lower.ends_with(".efi")
|
|
|| Path::new(name).extension().is_some()
|
|
{
|
|
name.to_string()
|
|
} else {
|
|
format!("{name}.exe")
|
|
}
|
|
}
|
|
|
|
/// Default relative binary path: `./target[/<triple>]/<profile>/<name>`.
|
|
pub fn default_bin_rel(profile: &str, name: &str, triple_segment: Option<&str>) -> String {
|
|
let mut p = PathBuf::from("./target");
|
|
if let Some(t) = triple_segment {
|
|
p = p.join(t);
|
|
}
|
|
p.join(profile).join(name).to_string_lossy().into_owned()
|
|
}
|
|
|
|
/// Default relative library path: `./target[/<triple>]/<profile>/<file>`.
|
|
pub fn default_lib_rel(profile: &str, file: &str, triple_segment: Option<&str>) -> String {
|
|
let mut p = PathBuf::from("./target");
|
|
if let Some(t) = triple_segment {
|
|
p = p.join(t);
|
|
}
|
|
p.join(profile).join(file).to_string_lossy().into_owned()
|
|
}
|
|
|
|
#[cfg(test)]
|
|
mod tests {
|
|
use super::*;
|
|
|
|
#[test]
|
|
fn join_dir_trims_both_slashes() {
|
|
assert_eq!(
|
|
join_dir("out/", "a"),
|
|
Path::new("out").join("a").to_string_lossy()
|
|
);
|
|
assert_eq!(
|
|
join_dir(r"out\", "a"),
|
|
Path::new("out").join("a").to_string_lossy()
|
|
);
|
|
}
|
|
|
|
#[test]
|
|
fn with_exe_no_double() {
|
|
assert_eq!(with_exe_suffix("hello"), "hello.exe");
|
|
assert_eq!(with_exe_suffix("hello.exe"), "hello.exe");
|
|
assert_eq!(with_exe_suffix("KERNEL.ELF"), "KERNEL.ELF");
|
|
assert_eq!(with_exe_suffix("x.dll"), "x.dll");
|
|
}
|
|
}
|