Skip to content

Commit fbce575

Browse files
committed
Try #214:
2 parents ec6f461 + 477531b commit fbce575

File tree

3 files changed

+122
-47
lines changed

3 files changed

+122
-47
lines changed

src/lib.rs

Lines changed: 76 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -422,7 +422,82 @@
422422
//!
423423
//! - `#[feature(untagged_unions)]` for overlapping/overloaded registers
424424
425-
// NOTE This file is for documentation only
425+
#![recursion_limit = "128"]
426+
427+
extern crate cast;
428+
extern crate either;
429+
#[macro_use]
430+
extern crate error_chain;
431+
extern crate inflections;
432+
#[macro_use]
433+
extern crate quote;
434+
extern crate svd_parser as svd;
435+
extern crate syn;
436+
437+
mod errors;
438+
mod generate;
439+
mod util;
440+
441+
pub use util::Target;
442+
443+
pub struct Generation {
444+
pub lib_rs: String,
445+
pub device_specific: Option<DeviceSpecific>,
446+
447+
// Reserve the right to add more fields to this struct
448+
_extensible: (),
449+
}
450+
451+
pub struct DeviceSpecific {
452+
pub device_x: String,
453+
pub build_rs: String,
454+
455+
// Reserve the right to add more fields to this struct
456+
_extensible: (),
457+
}
458+
459+
type Result<T> = std::result::Result<T, SvdError>;
460+
#[derive(Debug)]
461+
pub enum SvdError {
462+
Fmt,
463+
Render,
464+
}
465+
466+
/// Generates rust code for the specified svd content.
467+
pub fn generate(xml: &str, target: &Target, nightly: bool) -> Result<Generation> {
468+
use std::fmt::Write;
469+
470+
let device = svd::parse(xml);
471+
let mut device_x = String::new();
472+
let items = generate::device::render(&device, target, nightly, &mut device_x)
473+
.or(Err(SvdError::Render))?;
474+
475+
let mut lib_rs = String::new();
476+
writeln!(
477+
&mut lib_rs,
478+
"{}",
479+
quote! {
480+
#(#items)*
481+
}
482+
)
483+
.or(Err(SvdError::Fmt))?;
484+
485+
let device_specific = if device_x.is_empty() {
486+
None
487+
} else {
488+
Some(DeviceSpecific {
489+
device_x: device_x,
490+
build_rs: util::build_rs().to_string(),
491+
_extensible: (),
492+
})
493+
};
494+
495+
Ok(Generation {
496+
lib_rs: lib_rs,
497+
device_specific: device_specific,
498+
_extensible: (),
499+
})
500+
}
426501

427502
/// Assigns a handler to an interrupt
428503
///

src/main.rs

Lines changed: 1 addition & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -19,30 +19,10 @@ use std::fs::File;
1919
use std::process;
2020
use std::io::{self, Write};
2121

22-
use quote::Tokens;
2322
use clap::{App, Arg};
2423

2524
use errors::*;
26-
27-
#[derive(Clone, Copy, PartialEq)]
28-
pub enum Target {
29-
CortexM,
30-
Msp430,
31-
RISCV,
32-
None,
33-
}
34-
35-
impl Target {
36-
fn parse(s: &str) -> Result<Self> {
37-
Ok(match s {
38-
"cortex-m" => Target::CortexM,
39-
"msp430" => Target::Msp430,
40-
"riscv" => Target::RISCV,
41-
"none" => Target::None,
42-
_ => bail!("unknown target {}", s),
43-
})
44-
}
45-
}
25+
use util::{build_rs, Target};
4626

4727
fn run() -> Result<()> {
4828
use std::io::Read;
@@ -135,28 +115,3 @@ fn main() {
135115
process::exit(1);
136116
}
137117
}
138-
139-
fn build_rs() -> Tokens {
140-
quote! {
141-
use std::env;
142-
use std::fs::File;
143-
use std::io::Write;
144-
use std::path::PathBuf;
145-
146-
fn main() {
147-
if env::var_os("CARGO_FEATURE_RT").is_some() {
148-
// Put the linker script somewhere the linker can find it
149-
let out = &PathBuf::from(env::var_os("OUT_DIR").unwrap());
150-
File::create(out.join("device.x"))
151-
.unwrap()
152-
.write_all(include_bytes!("device.x"))
153-
.unwrap();
154-
println!("cargo:rustc-link-search={}", out.display());
155-
156-
println!("cargo:rerun-if-changed=device.x");
157-
}
158-
159-
println!("cargo:rerun-if-changed=build.rs");
160-
}
161-
}
162-
}

src/util.rs

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,26 @@ pub const BITS_PER_BYTE: u32 = 8;
1414
/// that are not valid in Rust ident
1515
const BLACKLIST_CHARS : &[char] = &['(', ')', '[', ']', '/', ' '];
1616

17+
#[derive(Clone, Copy, PartialEq)]
18+
pub enum Target {
19+
CortexM,
20+
Msp430,
21+
RISCV,
22+
None,
23+
}
24+
25+
impl Target {
26+
pub fn parse(s: &str) -> Result<Self> {
27+
Ok(match s {
28+
"cortex-m" => Target::CortexM,
29+
"msp430" => Target::Msp430,
30+
"riscv" => Target::RISCV,
31+
"none" => Target::None,
32+
_ => bail!("unknown target {}", s),
33+
})
34+
}
35+
}
36+
1737
pub trait ToSanitizedPascalCase {
1838
fn to_sanitized_pascal_case(&self) -> Cow<str>;
1939
}
@@ -291,3 +311,28 @@ pub fn only_registers(ercs: &[Either<Register, Cluster>]) -> Vec<&Register> {
291311
.collect();
292312
registers
293313
}
314+
315+
pub fn build_rs() -> Tokens {
316+
quote! {
317+
use std::env;
318+
use std::fs::File;
319+
use std::io::Write;
320+
use std::path::PathBuf;
321+
322+
fn main() {
323+
if env::var_os("CARGO_FEATURE_RT").is_some() {
324+
// Put the linker script somewhere the linker can find it
325+
let out = &PathBuf::from(env::var_os("OUT_DIR").unwrap());
326+
File::create(out.join("device.x"))
327+
.unwrap()
328+
.write_all(include_bytes!("device.x"))
329+
.unwrap();
330+
println!("cargo:rustc-link-search={}", out.display());
331+
332+
println!("cargo:rerun-if-changed=device.x");
333+
}
334+
335+
println!("cargo:rerun-if-changed=build.rs");
336+
}
337+
}
338+
}

0 commit comments

Comments
 (0)