Skip to content

Commit ac474a7

Browse files
authored
Merge pull request #296 from flaviojs/patch-yaml-json-svd
patch: allow yaml and json file in _svd
2 parents 0ad6714 + 3f9f951 commit ac474a7

File tree

5 files changed

+85
-34
lines changed

5 files changed

+85
-34
lines changed

src/common/input_format.rs

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
use anyhow::{anyhow, Result};
2+
use std::str::FromStr;
3+
4+
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
5+
#[non_exhaustive]
6+
pub enum InputFormat {
7+
Xml,
8+
#[cfg(feature = "yaml")]
9+
Yaml,
10+
#[cfg(feature = "json")]
11+
Json,
12+
}
13+
14+
impl FromStr for InputFormat {
15+
type Err = anyhow::Error;
16+
fn from_str(s: &str) -> Result<Self, Self::Err> {
17+
match s {
18+
"svd" | "SVD" | "xml" | "XML" => Ok(Self::Xml),
19+
#[cfg(feature = "yaml")]
20+
"yml" | "yaml" | "YAML" => Ok(Self::Yaml),
21+
#[cfg(feature = "json")]
22+
"json" | "JSON" => Ok(Self::Json),
23+
_ => Err(anyhow!("Unknown input file format")),
24+
}
25+
}
26+
}

src/common/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
pub mod input_format;
12
pub mod str_utils;
23
pub mod svd_reader;
34
pub mod svd_utils;

src/convert/convert_cli.rs

Lines changed: 1 addition & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -4,33 +4,10 @@ use std::str::FromStr;
44
use std::{fs::File, path::Path};
55
use svd_rs::Device;
66

7+
pub use crate::common::input_format::InputFormat;
78
use crate::get_encoder_config;
89
pub use crate::ConfigFormat;
910

10-
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
11-
#[non_exhaustive]
12-
pub enum InputFormat {
13-
Xml,
14-
#[cfg(feature = "yaml")]
15-
Yaml,
16-
#[cfg(feature = "json")]
17-
Json,
18-
}
19-
20-
impl FromStr for InputFormat {
21-
type Err = anyhow::Error;
22-
fn from_str(s: &str) -> Result<Self, Self::Err> {
23-
match s {
24-
"svd" | "SVD" | "xml" | "XML" => Ok(Self::Xml),
25-
#[cfg(feature = "yaml")]
26-
"yml" | "yaml" | "YAML" => Ok(Self::Yaml),
27-
#[cfg(feature = "json")]
28-
"json" | "JSON" => Ok(Self::Json),
29-
_ => Err(anyhow!("Unknown input file format")),
30-
}
31-
}
32-
}
33-
3411
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
3512
#[non_exhaustive]
3613
pub enum OutputFormat {

src/patch/device.rs

Lines changed: 21 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,16 @@ use svd_parser::svd::{Device, Peripheral, PeripheralInfo};
44
use yaml_rust::{yaml::Hash, Yaml};
55

66
use std::collections::HashSet;
7-
use std::{fs::File, io::Read, path::Path};
7+
use std::str::FromStr;
8+
use std::{fs, path::Path};
89

910
use super::iterators::{MatchIter, Matched};
1011
use super::peripheral::{PeripheralExt, RegisterBlockExt};
1112
use super::yaml_ext::{AsType, GetVal};
1213
use super::{abspath, adding_pos, matchname, Config, PatchResult, Spec, VAL_LVL};
1314
use super::{make_address_block, make_address_blocks, make_cpu, make_interrupt, make_peripheral};
1415
use super::{make_dim_element, modify_dim_element, modify_register_properties};
16+
use crate::common::input_format::InputFormat;
1517

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

@@ -195,11 +197,24 @@ impl DeviceExt for Device {
195197
.collect::<Vec<_>>();
196198
let mut new = match pcopysrc.as_slice() {
197199
[ppath, pcopyname] => {
198-
let f = File::open(abspath(path, Path::new(ppath))?)?;
199-
let mut contents = String::new();
200-
(&f).read_to_string(&mut contents).unwrap();
201-
let filedev = svd_parser::parse(&contents)
202-
.with_context(|| format!("Parsing file {contents}"))?;
200+
let ppath = Path::new(ppath);
201+
let input_format = ppath
202+
.extension()
203+
.map(|ext_os| ext_os.to_str().expect("ppath is str"))
204+
.and_then(|ext| InputFormat::from_str(ext).ok())
205+
.unwrap_or(InputFormat::Xml);
206+
let filepath = abspath(path, ppath)?;
207+
let contents = fs::read_to_string(filepath)?;
208+
let filedev = match input_format {
209+
InputFormat::Xml => svd_parser::parse(&contents)
210+
.with_context(|| format!("Parsing svd file {contents}"))?,
211+
#[cfg(feature = "yaml")]
212+
InputFormat::Yaml => serde_yaml::from_str(&contents)
213+
.with_context(|| format!("Parsing yaml file {contents}"))?,
214+
#[cfg(feature = "json")]
215+
InputFormat::Json => serde_json::from_str(&contents)
216+
.with_context(|| format!("Parsing json file {contents}"))?,
217+
};
203218
filedev
204219
.get_peripheral(pcopyname)
205220
.ok_or_else(|| {

src/patch/mod.rs

Lines changed: 36 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ use std::borrow::Cow;
77
use std::fs::File;
88
use std::io::{Cursor, Read};
99
use std::path::{Path, PathBuf};
10+
use std::str::FromStr;
1011
use svd_parser::expand::{BlockPath, FieldPath, RegisterPath};
1112
use svd_parser::svd::{
1213
addressblock::AddressBlockBuilder, interrupt::InterruptBuilder, Access, AddressBlock,
@@ -17,7 +18,7 @@ use svd_parser::svd::{
1718
WriteConstraintRange,
1819
};
1920
use svd_parser::SVDError::DimIndexParse;
20-
use svd_rs::{BitRange, DimArrayIndex, DimElement, DimElementBuilder, MaybeArray};
21+
use svd_rs::{BitRange, Device, DimArrayIndex, DimElement, DimElementBuilder, MaybeArray};
2122
use yaml_rust::{yaml::Hash, Yaml, YamlLoader};
2223

2324
use hashlink::linked_hash_map;
@@ -35,6 +36,7 @@ mod register;
3536
mod yaml_ext;
3637
use yaml_ext::{AsType, GetVal, ToYaml};
3738

39+
use crate::common::input_format::InputFormat;
3840
use crate::get_encoder_config;
3941

4042
const VAL_LVL: ValidateLevel = ValidateLevel::Weak;
@@ -115,8 +117,30 @@ pub fn process_file(
115117

116118
let encoder_config = get_encoder_config(format_config)?;
117119

118-
let mut svd_out = process_reader(File::open(svdpath)?, &doc, &encoder_config, config)?;
119-
std::io::copy(&mut svd_out, &mut File::create(svdpath_out)?)?;
120+
let input_format = svdpath
121+
.extension()
122+
.map(|ext_os| ext_os.to_str().expect("_svd is str"))
123+
.and_then(|ext| InputFormat::from_str(ext).ok())
124+
.unwrap_or(InputFormat::Xml);
125+
126+
match input_format {
127+
InputFormat::Xml => {
128+
let mut svd_out = process_reader(File::open(svdpath)?, &doc, &encoder_config, config)?;
129+
std::io::copy(&mut svd_out, &mut File::create(svdpath_out)?)?;
130+
}
131+
#[cfg(feature = "yaml")]
132+
InputFormat::Yaml => {
133+
let dev = serde_yaml::from_str(&std::fs::read_to_string(svdpath)?)?;
134+
let mut svd_out = process_device(dev, &doc, &encoder_config, config)?;
135+
std::io::copy(&mut svd_out, &mut File::create(svdpath_out)?)?;
136+
}
137+
#[cfg(feature = "json")]
138+
InputFormat::Json => {
139+
let dev = serde_json::from_str(&std::fs::read_to_string(svdpath)?)?;
140+
let mut svd_out = process_device(dev, &doc, &encoder_config, config)?;
141+
std::io::copy(&mut svd_out, &mut File::create(svdpath_out)?)?;
142+
}
143+
};
120144

121145
Ok(())
122146
}
@@ -131,8 +155,16 @@ pub fn process_reader<R: Read>(
131155
svd.read_to_string(&mut contents)?;
132156
let mut parser_config = svd_parser::Config::default();
133157
parser_config.validate_level = ValidateLevel::Disabled;
134-
let mut dev = svd_parser::parse_with_config(&contents, &parser_config)?;
158+
let dev = svd_parser::parse_with_config(&contents, &parser_config)?;
159+
process_device(dev, patch, format_config, config)
160+
}
135161

162+
fn process_device(
163+
mut dev: Device,
164+
patch: &Yaml,
165+
format_config: &EncoderConfig,
166+
config: &Config,
167+
) -> Result<impl Read> {
136168
// Process device
137169
dev.process(patch.hash()?, config).with_context(|| {
138170
let name = &dev.name;

0 commit comments

Comments
 (0)