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
26 changes: 26 additions & 0 deletions src/common/input_format.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
use anyhow::{anyhow, Result};
use std::str::FromStr;

#[derive(Clone, Copy, Debug, PartialEq, Eq)]
#[non_exhaustive]
pub enum InputFormat {
Xml,
#[cfg(feature = "yaml")]
Yaml,
#[cfg(feature = "json")]
Json,
}

impl FromStr for InputFormat {
type Err = anyhow::Error;
fn from_str(s: &str) -> Result<Self, Self::Err> {
match s {
"svd" | "SVD" | "xml" | "XML" => Ok(Self::Xml),
#[cfg(feature = "yaml")]
"yml" | "yaml" | "YAML" => Ok(Self::Yaml),
#[cfg(feature = "json")]
"json" | "JSON" => Ok(Self::Json),
_ => Err(anyhow!("Unknown input file format")),
}
}
}
1 change: 1 addition & 0 deletions src/common/mod.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
pub mod input_format;
pub mod str_utils;
pub mod svd_reader;
pub mod svd_utils;
25 changes: 1 addition & 24 deletions src/convert/convert_cli.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,33 +4,10 @@ use std::str::FromStr;
use std::{fs::File, path::Path};
use svd_rs::Device;

pub use crate::common::input_format::InputFormat;
use crate::get_encoder_config;
pub use crate::ConfigFormat;

#[derive(Clone, Copy, Debug, PartialEq, Eq)]
#[non_exhaustive]
pub enum InputFormat {
Xml,
#[cfg(feature = "yaml")]
Yaml,
#[cfg(feature = "json")]
Json,
}

impl FromStr for InputFormat {
type Err = anyhow::Error;
fn from_str(s: &str) -> Result<Self, Self::Err> {
match s {
"svd" | "SVD" | "xml" | "XML" => Ok(Self::Xml),
#[cfg(feature = "yaml")]
"yml" | "yaml" | "YAML" => Ok(Self::Yaml),
#[cfg(feature = "json")]
"json" | "JSON" => Ok(Self::Json),
_ => Err(anyhow!("Unknown input file format")),
}
}
}

#[derive(Clone, Copy, Debug, PartialEq, Eq)]
#[non_exhaustive]
pub enum OutputFormat {
Expand Down
27 changes: 21 additions & 6 deletions src/patch/device.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,16 @@ use svd_parser::svd::{Device, Peripheral, PeripheralInfo};
use yaml_rust::{yaml::Hash, Yaml};

use std::collections::HashSet;
use std::{fs::File, io::Read, path::Path};
use std::str::FromStr;
use std::{fs, path::Path};

use super::iterators::{MatchIter, Matched};
use super::peripheral::{PeripheralExt, RegisterBlockExt};
use super::yaml_ext::{AsType, GetVal};
use super::{abspath, adding_pos, matchname, Config, PatchResult, Spec, VAL_LVL};
use super::{make_address_block, make_address_blocks, make_cpu, make_interrupt, make_peripheral};
use super::{make_dim_element, modify_dim_element, modify_register_properties};
use crate::common::input_format::InputFormat;

pub type PerMatchIterMut<'a, 'b> = MatchIter<'b, std::slice::IterMut<'a, Peripheral>>;

Expand Down Expand Up @@ -195,11 +197,24 @@ impl DeviceExt for Device {
.collect::<Vec<_>>();
let mut new = match pcopysrc.as_slice() {
[ppath, pcopyname] => {
let f = File::open(abspath(path, Path::new(ppath))?)?;
let mut contents = String::new();
(&f).read_to_string(&mut contents).unwrap();
let filedev = svd_parser::parse(&contents)
.with_context(|| format!("Parsing file {contents}"))?;
let ppath = Path::new(ppath);
let input_format = ppath
.extension()
.map(|ext_os| ext_os.to_str().expect("ppath is str"))
.and_then(|ext| InputFormat::from_str(ext).ok())
.unwrap_or(InputFormat::Xml);
let filepath = abspath(path, ppath)?;
let contents = fs::read_to_string(filepath)?;
let filedev = match input_format {
InputFormat::Xml => svd_parser::parse(&contents)
.with_context(|| format!("Parsing svd file {contents}"))?,
#[cfg(feature = "yaml")]
InputFormat::Yaml => serde_yaml::from_str(&contents)
.with_context(|| format!("Parsing yaml file {contents}"))?,
#[cfg(feature = "json")]
InputFormat::Json => serde_json::from_str(&contents)
.with_context(|| format!("Parsing json file {contents}"))?,
};
filedev
.get_peripheral(pcopyname)
.ok_or_else(|| {
Expand Down
40 changes: 36 additions & 4 deletions src/patch/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ use std::borrow::Cow;
use std::fs::File;
use std::io::{Cursor, Read};
use std::path::{Path, PathBuf};
use std::str::FromStr;
use svd_parser::expand::{BlockPath, FieldPath, RegisterPath};
use svd_parser::svd::{
addressblock::AddressBlockBuilder, interrupt::InterruptBuilder, Access, AddressBlock,
Expand All @@ -17,7 +18,7 @@ use svd_parser::svd::{
WriteConstraintRange,
};
use svd_parser::SVDError::DimIndexParse;
use svd_rs::{BitRange, DimArrayIndex, DimElement, DimElementBuilder, MaybeArray};
use svd_rs::{BitRange, Device, DimArrayIndex, DimElement, DimElementBuilder, MaybeArray};
use yaml_rust::{yaml::Hash, Yaml, YamlLoader};

use hashlink::linked_hash_map;
Expand All @@ -35,6 +36,7 @@ mod register;
mod yaml_ext;
use yaml_ext::{AsType, GetVal, ToYaml};

use crate::common::input_format::InputFormat;
use crate::get_encoder_config;

const VAL_LVL: ValidateLevel = ValidateLevel::Weak;
Expand Down Expand Up @@ -115,8 +117,30 @@ pub fn process_file(

let encoder_config = get_encoder_config(format_config)?;

let mut svd_out = process_reader(File::open(svdpath)?, &doc, &encoder_config, config)?;
std::io::copy(&mut svd_out, &mut File::create(svdpath_out)?)?;
let input_format = svdpath
.extension()
.map(|ext_os| ext_os.to_str().expect("_svd is str"))
.and_then(|ext| InputFormat::from_str(ext).ok())
.unwrap_or(InputFormat::Xml);

match input_format {
InputFormat::Xml => {
let mut svd_out = process_reader(File::open(svdpath)?, &doc, &encoder_config, config)?;
std::io::copy(&mut svd_out, &mut File::create(svdpath_out)?)?;
}
#[cfg(feature = "yaml")]
InputFormat::Yaml => {
let dev = serde_yaml::from_str(&std::fs::read_to_string(svdpath)?)?;
let mut svd_out = process_device(dev, &doc, &encoder_config, config)?;
std::io::copy(&mut svd_out, &mut File::create(svdpath_out)?)?;
}
#[cfg(feature = "json")]
InputFormat::Json => {
let dev = serde_json::from_str(&std::fs::read_to_string(svdpath)?)?;
let mut svd_out = process_device(dev, &doc, &encoder_config, config)?;
std::io::copy(&mut svd_out, &mut File::create(svdpath_out)?)?;
}
};

Ok(())
}
Expand All @@ -131,8 +155,16 @@ pub fn process_reader<R: Read>(
svd.read_to_string(&mut contents)?;
let mut parser_config = svd_parser::Config::default();
parser_config.validate_level = ValidateLevel::Disabled;
let mut dev = svd_parser::parse_with_config(&contents, &parser_config)?;
let dev = svd_parser::parse_with_config(&contents, &parser_config)?;
process_device(dev, patch, format_config, config)
}

fn process_device(
mut dev: Device,
patch: &Yaml,
format_config: &EncoderConfig,
config: &Config,
) -> Result<impl Read> {
// Process device
dev.process(patch.hash()?, config).with_context(|| {
let name = &dev.name;
Expand Down
Loading