Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 9 additions & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,21 @@ on:
pull_request:

jobs:
build:
name: Build and run atdf2svd CLI tool
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions-rust-lang/setup-rust-toolchain@v1
- run: cargo run -- tests/atmega328p.atdf /dev/null

test:
name: Run atdf2svd regression tests
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions-rust-lang/setup-rust-toolchain@v1
- run: cargo test
- run: cargo test --no-default-features

rustfmt:
name: Rustfmt
Expand Down
7 changes: 7 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

17 changes: 13 additions & 4 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -17,15 +17,24 @@ exclude = [
".github/",
]

[[bin]]
name = "atdf2svd"
required-features = ["cli"]

[features]
cli = ["dep:colored", "dep:env_logger", "dep:gumdrop", "dep:git-version"]
default = ["cli"]

[dependencies]
xmltree = "0.10.3"
colored = "2.0.0"
colored = { version = "2.0.0", optional = true }
log = "0.4.22"
env_logger = "0.11.5"
gumdrop = "0.8.1"
git-version = "0.3.5"
env_logger = { version = "0.11.5", optional = true }
gumdrop = { version = "0.8.1", optional = true }
git-version = { version = "0.3.5", optional = true }
svd-rs = "0.14.1"
svd-encoder = "0.14.2"
cfg-if = "1.0.0"

[dev-dependencies]
insta = { version = "1.41.1", features = ["yaml"] }
Expand Down
14 changes: 11 additions & 3 deletions src/atdf/error.rs
Original file line number Diff line number Diff line change
@@ -1,15 +1,23 @@
use crate::ElementExt;
use colored::Colorize;

pub struct UnsupportedError(String, String);

impl crate::DisplayError for UnsupportedError {
fn format(&self, w: &mut dyn std::io::Write) -> std::io::Result<()> {
let maybe_styled_element = {
cfg_if::cfg_if! {
if #[cfg(feature = "cli")] {
use colored::Colorize;
self.1.dimmed()
} else {
&self.1
}
}
};
write!(
w,
"{} is unsupported in element\n {}",
self.0,
self.1.dimmed()
self.0, maybe_styled_element,
)
}
}
Expand Down
6 changes: 0 additions & 6 deletions src/cli.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,9 +34,3 @@ pub fn exit_with_error(e: crate::Error) -> ! {
writeln!(stderr).unwrap();
std::process::exit(1);
}

pub fn panic_with_error(e: crate::Error) -> ! {
let mut message: Vec<u8> = "Error: ".into();
e.format(&mut message).unwrap();
panic!("{}", String::from_utf8_lossy(&message));
}
30 changes: 26 additions & 4 deletions src/elementext.rs
Original file line number Diff line number Diff line change
Expand Up @@ -112,17 +112,25 @@ impl ElementExt for xmltree::Element {

pub mod error {
use super::ElementExt;
use colored::Colorize;

pub struct MissingAttribute(String, String);

impl crate::DisplayError for MissingAttribute {
fn format(&self, w: &mut dyn std::io::Write) -> std::io::Result<()> {
let maybe_styled_element = {
cfg_if::cfg_if! {
if #[cfg(feature = "cli")] {
use colored::Colorize;
self.1.dimmed()
} else {
&self.1
}
}
};
write!(
w,
"Missing attribute {:?} on\n {}",
self.0,
self.1.dimmed()
self.0, maybe_styled_element,
)
}
}
Expand All @@ -137,7 +145,21 @@ pub mod error {

impl crate::DisplayError for MissingElement {
fn format(&self, w: &mut dyn std::io::Write) -> std::io::Result<()> {
write!(w, "Missing child {:?} in\n {}", self.0, self.1.dimmed())
let maybe_styled_element = {
cfg_if::cfg_if! {
if #[cfg(feature = "cli")] {
use colored::Colorize;
self.1.dimmed()
} else {
&self.1
}
}
};
write!(
w,
"Missing child {:?} in\n {}",
self.0, maybe_styled_element
)
}
}

Expand Down
6 changes: 6 additions & 0 deletions src/error.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
pub trait DisplayError {
fn format(&self, w: &mut dyn std::io::Write) -> std::io::Result<()>;

fn into_panic(&self) -> ! {
let mut message: Vec<u8> = "Error: ".into();
self.format(&mut message).unwrap();
panic!("{}", String::from_utf8_lossy(&message));
}
}

pub type Error = Box<dyn DisplayError>;
Expand Down
8 changes: 6 additions & 2 deletions src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#[macro_use]
pub mod error;
#[cfg(feature = "cli")]
pub mod cli;

pub mod atdf;
Expand All @@ -10,10 +11,12 @@ pub mod util;

pub use elementext::ElementExt;
pub use error::{DisplayError, Error, Result};
#[cfg(feature = "cli")]
pub use gumdrop::Options;
use std::collections::HashSet;
use std::iter::FromIterator;

#[cfg(feature = "cli")]
#[derive(Debug, Options)]
/// A tool to convert AVR chip description files (.atdf) to SVD.
pub struct Atdf2SvdOptions {
Expand Down Expand Up @@ -41,6 +44,7 @@ pub struct Atdf2SvdOptions {
version: bool,
}

#[cfg(feature = "cli")]
pub fn run(args: Atdf2SvdOptions) {
if args.version {
println!(
Expand Down Expand Up @@ -83,8 +87,8 @@ pub fn run(args: Atdf2SvdOptions) {

pub fn run_test(atdf: &mut dyn std::io::Read, auto_patches: Vec<&str>) -> String {
let patches = HashSet::from_iter(auto_patches.iter().map(|s| s.to_string()));
let chip = atdf::parse(atdf, &patches).unwrap_or_else(|e| cli::panic_with_error(e));
let chip = atdf::parse(atdf, &patches).unwrap_or_else(|e| e.into_panic());
let mut output = Vec::new();
svd::generate(&chip, &mut output).unwrap_or_else(|e| cli::panic_with_error(e));
svd::generate(&chip, &mut output).unwrap_or_else(|e| e.into_panic());
String::from_utf8(output).unwrap()
}
Loading