Skip to content

anyhow Error #398

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Apr 23, 2020
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
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ and this project adheres to [Semantic Versioning](http://semver.org/).

### Changed

- `anyhow` crate is used for error handling

- [breaking-change] Among other cleanups, MSP430 crates are now expected to
use the `msp430_rt::interrupt` attribute macro and `device.x` for interrupt
support. The `INTERRUPT` array has been renamed `__INTERRUPT`.
Expand Down
3 changes: 2 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -35,11 +35,12 @@ path = "src/main.rs"
cast = "0.2"
clap = "2.33"
env_logger = "~0.7"
error-chain = "0.12"
inflections = "1.1"
log = { version = "~0.4", features = ["std"] }
quote = "1.0"
proc-macro2 = "1.0"
anyhow = "1.0.19"
thiserror = "1.0.5"

[dependencies.svd-parser]
version = "0.9"
Expand Down
1 change: 0 additions & 1 deletion src/errors.rs

This file was deleted.

8 changes: 4 additions & 4 deletions src/generate/device.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@ use quote::ToTokens;
use std::fs::File;
use std::io::Write;

use crate::errors::*;
use crate::util::{self, ToSanitizedUpperCase};
use crate::Target;
use anyhow::Result;

use crate::generate::{interrupt, peripheral};

Expand Down Expand Up @@ -155,11 +155,11 @@ pub fn render(
});
}

let generic_file = std::str::from_utf8(include_bytes!("generic.rs")).unwrap();
let generic_file = std::str::from_utf8(include_bytes!("generic.rs"))?;
if generic_mod {
writeln!(File::create("generic.rs").unwrap(), "{}", generic_file).unwrap();
writeln!(File::create("generic.rs")?, "{}", generic_file)?;
} else {
let tokens = syn::parse_file(generic_file).unwrap().into_token_stream();
let tokens = syn::parse_file(generic_file)?.into_token_stream();

out.extend(quote! {
#[allow(unused_imports)]
Expand Down
4 changes: 2 additions & 2 deletions src/generate/interrupt.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@ use crate::svd::Peripheral;
use cast::u64;
use proc_macro2::{Ident, Span, TokenStream};

use crate::errors::*;
use crate::util::{self, ToSanitizedUpperCase};
use crate::Target;
use anyhow::Result;

/// Generates code for `src/interrupt.rs`
pub fn render(
Expand Down Expand Up @@ -72,7 +72,7 @@ pub fn render(
match target {
Target::CortexM => {
for name in &names {
writeln!(device_x, "PROVIDE({} = DefaultHandler);", name).unwrap();
writeln!(device_x, "PROVIDE({} = DefaultHandler);", name)?;
}

root.extend(quote! {
Expand Down
111 changes: 54 additions & 57 deletions src/generate/peripheral.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@ use quote::ToTokens;
use svd_parser::derive_from::DeriveFrom;
use syn::{parse_str, Token};

use crate::errors::*;
use crate::util::{self, ToSanitizedSnakeCase, ToSanitizedUpperCase, BITS_PER_BYTE};
use anyhow::{anyhow, bail, Context, Result};

use crate::generate::register;

Expand All @@ -31,11 +31,10 @@ pub fn render(
let p_merged = p_derivedfrom.map(|ancestor| p_original.derive_from(ancestor));
let p = p_merged.as_ref().unwrap_or(p_original);

if p_original.derived_from.is_some() && p_derivedfrom.is_none() {
if let (Some(df), None) = (p_original.derived_from.as_ref(), &p_derivedfrom) {
eprintln!(
"Couldn't find derivedFrom original: {} for {}, skipping",
p_original.derived_from.as_ref().unwrap(),
p_original.name
df, p_original.name
);
return Ok(out);
}
Expand All @@ -44,13 +43,12 @@ pub fn render(
let name_pc = Ident::new(&p.name.to_sanitized_upper_case(), span);
let address = util::hex(p.base_address as u64);
let description = util::respace(p.description.as_ref().unwrap_or(&p.name));
let derive_regs = p_derivedfrom.is_some() && p_original.registers.is_none();

let name_sc = Ident::new(&p.name.to_sanitized_snake_case(), span);
let base = if derive_regs {
Ident::new(&p_derivedfrom.unwrap().name.to_sanitized_snake_case(), span)
let (derive_regs, base) = if let (Some(df), None) = (p_derivedfrom, &p_original.registers) {
(true, Ident::new(&df.name.to_sanitized_snake_case(), span))
} else {
name_sc.clone()
(false, name_sc.clone())
};

// Insert the peripheral structure
Expand Down Expand Up @@ -607,11 +605,11 @@ fn expand_cluster(cluster: &Cluster, defs: &RegisterProperties) -> Result<Vec<Re
let defs = cluster.default_register_properties.derive_from(defs);

let cluster_size = cluster_size_in_bits(cluster, &defs)
.chain_err(|| format!("Cluster {} has no determinable `size` field", cluster.name))?;
.with_context(|| format!("Cluster {} has no determinable `size` field", cluster.name))?;

match cluster {
Cluster::Single(info) => cluster_expanded.push(RegisterBlockField {
field: convert_svd_cluster(cluster),
field: convert_svd_cluster(cluster)?,
description: info.description.as_ref().unwrap_or(&info.name).into(),
offset: info.address_offset,
size: cluster_size,
Expand All @@ -631,13 +629,13 @@ fn expand_cluster(cluster: &Cluster, defs: &RegisterProperties) -> Result<Vec<Re

if array_convertible {
cluster_expanded.push(RegisterBlockField {
field: convert_svd_cluster(&cluster),
field: convert_svd_cluster(&cluster)?,
description: info.description.as_ref().unwrap_or(&info.name).into(),
offset: info.address_offset,
size: cluster_size * array_info.dim,
});
} else {
for (field_num, field) in expand_svd_cluster(cluster).iter().enumerate() {
for (field_num, field) in expand_svd_cluster(cluster)?.iter().enumerate() {
cluster_expanded.push(RegisterBlockField {
field: field.clone(),
description: info.description.as_ref().unwrap_or(&info.name).into(),
Expand All @@ -664,12 +662,12 @@ fn expand_register(
let register_size = register
.size
.or(defs.size)
.ok_or_else(|| format!("Register {} has no `size` field", register.name))?;
.ok_or_else(|| anyhow!("Register {} has no `size` field", register.name))?;

match register {
Register::Single(info) => register_expanded.push(RegisterBlockField {
field: convert_svd_register(register, name),
description: info.description.clone().unwrap_or_else(|| "".to_string()),
field: convert_svd_register(register, name)?,
description: info.description.clone().unwrap_or_default(),
offset: info.address_offset,
size: register_size,
}),
Expand All @@ -688,16 +686,16 @@ fn expand_register(

if array_convertible {
register_expanded.push(RegisterBlockField {
field: convert_svd_register(&register, name),
description: info.description.clone().unwrap_or_else(|| "".to_string()),
field: convert_svd_register(&register, name)?,
description: info.description.clone().unwrap_or_default(),
offset: info.address_offset,
size: register_size * array_info.dim,
});
} else {
for (field_num, field) in expand_svd_register(register, name).iter().enumerate() {
for (field_num, field) in expand_svd_register(register, name)?.iter().enumerate() {
register_expanded.push(RegisterBlockField {
field: field.clone(),
description: info.description.clone().unwrap_or_else(|| "".to_string()),
description: info.description.clone().unwrap_or_default(),
offset: info.address_offset + field_num as u32 * array_info.dim_increment,
size: register_size,
});
Expand Down Expand Up @@ -768,8 +766,11 @@ fn cluster_block(

/// Takes a svd::Register which may be a register array, and turn in into
/// a list of syn::Field where the register arrays have been expanded.
fn expand_svd_register(register: &Register, name: Option<&str>) -> Vec<syn::Field> {
let name_to_ty = |name: &String, ns: Option<&str>| -> syn::Type {
fn expand_svd_register(
register: &Register,
name: Option<&str>,
) -> Result<Vec<syn::Field>, syn::Error> {
let name_to_ty = |name: &String, ns: Option<&str>| -> Result<syn::Type, syn::Error> {
let ident = if let Some(ns) = ns {
Cow::Owned(
String::from("self::")
Expand All @@ -781,13 +782,13 @@ fn expand_svd_register(register: &Register, name: Option<&str>) -> Vec<syn::Fiel
name.to_sanitized_upper_case()
};

syn::Type::Path(parse_str::<syn::TypePath>(&ident).unwrap())
Ok(syn::Type::Path(parse_str::<syn::TypePath>(&ident)?))
};

let mut out = vec![];

match register {
Register::Single(_info) => out.push(convert_svd_register(register, name)),
Register::Single(_info) => out.push(convert_svd_register(register, name)?),
Register::Array(info, array_info) => {
let indices = array_info
.dim_index
Expand All @@ -806,17 +807,17 @@ fn expand_svd_register(register: &Register, name: Option<&str>) -> Vec<syn::Fiel
for (idx, _i) in indices.iter().zip(0..) {
let nb_name = util::replace_suffix(&info.name, idx);

let ty = name_to_ty(&ty_name, name);
let ty = name_to_ty(&ty_name, name)?;

out.push(new_syn_field(&nb_name.to_sanitized_snake_case(), ty));
}
}
}
out
Ok(out)
}

/// Convert a parsed `Register` into its `Field` equivalent
fn convert_svd_register(register: &Register, name: Option<&str>) -> syn::Field {
fn convert_svd_register(register: &Register, name: Option<&str>) -> Result<syn::Field, syn::Error> {
let name_to_ty = |name: &String, ns: Option<&str>| -> String {
if let Some(ns) = ns {
String::from("self::")
Expand All @@ -828,39 +829,38 @@ fn convert_svd_register(register: &Register, name: Option<&str>) -> syn::Field {
}
};

match register {
Ok(match register {
Register::Single(info) => new_syn_field(
&info.name.to_sanitized_snake_case(),
syn::Type::Path(parse_str::<syn::TypePath>(&name_to_ty(&info.name, name)).unwrap()),
syn::Type::Path(parse_str::<syn::TypePath>(&name_to_ty(&info.name, name))?),
),
Register::Array(info, array_info) => {
let nb_name = util::replace_suffix(&info.name, "");

let ty = syn::Type::Array(
parse_str::<syn::TypeArray>(&format!(
"[{};{}]",
name_to_ty(&nb_name, name),
u64::from(array_info.dim)
))
.unwrap(),
);
let ty = syn::Type::Array(parse_str::<syn::TypeArray>(&format!(
"[{};{}]",
name_to_ty(&nb_name, name),
u64::from(array_info.dim)
))?);

new_syn_field(&nb_name.to_sanitized_snake_case(), ty)
}
}
})
}

/// Takes a svd::Cluster which may contain a register array, and turn in into
/// a list of syn::Field where the register arrays have been expanded.
fn expand_svd_cluster(cluster: &Cluster) -> Vec<syn::Field> {
let name_to_ty = |name: &String| -> syn::Type {
syn::Type::Path(parse_str::<syn::TypePath>(&name.to_sanitized_upper_case()).unwrap())
fn expand_svd_cluster(cluster: &Cluster) -> Result<Vec<syn::Field>, syn::Error> {
let name_to_ty = |name: &String| -> Result<syn::Type, syn::Error> {
Ok(syn::Type::Path(parse_str::<syn::TypePath>(
&name.to_sanitized_upper_case(),
)?))
};

let mut out = vec![];

match &cluster {
Cluster::Single(_info) => out.push(convert_svd_cluster(cluster)),
Cluster::Single(_info) => out.push(convert_svd_cluster(cluster)?),
Cluster::Array(info, array_info) => {
let indices = array_info
.dim_index
Expand All @@ -879,39 +879,36 @@ fn expand_svd_cluster(cluster: &Cluster) -> Vec<syn::Field> {
for (idx, _i) in indices.iter().zip(0..) {
let name = util::replace_suffix(&info.name, idx);

let ty = name_to_ty(&ty_name);
let ty = name_to_ty(&ty_name)?;

out.push(new_syn_field(&name.to_sanitized_snake_case(), ty));
}
}
}
out
Ok(out)
}

/// Convert a parsed `Cluster` into its `Field` equivalent
fn convert_svd_cluster(cluster: &Cluster) -> syn::Field {
match cluster {
fn convert_svd_cluster(cluster: &Cluster) -> Result<syn::Field, syn::Error> {
Ok(match cluster {
Cluster::Single(info) => new_syn_field(
&info.name.to_sanitized_snake_case(),
syn::Type::Path(
parse_str::<syn::TypePath>(&info.name.to_sanitized_upper_case()).unwrap(),
),
syn::Type::Path(parse_str::<syn::TypePath>(
&info.name.to_sanitized_upper_case(),
)?),
),
Cluster::Array(info, array_info) => {
let name = util::replace_suffix(&info.name, "");

let ty = syn::Type::Array(
parse_str::<syn::TypeArray>(&format!(
"[{};{}]",
&name.to_sanitized_upper_case(),
u64::from(array_info.dim)
))
.unwrap(),
);
let ty = syn::Type::Array(parse_str::<syn::TypeArray>(&format!(
"[{};{}]",
&name.to_sanitized_upper_case(),
u64::from(array_info.dim)
))?);

new_syn_field(&name.to_sanitized_snake_case(), ty)
}
}
})
}

fn new_syn_field(ident: &str, ty: syn::Type) -> syn::Field {
Expand Down
Loading