@@ -35,11 +35,11 @@ pub fn render(
3535 let p = p_merged. as_ref ( ) . unwrap_or ( p_original) ;
3636
3737 if let ( Some ( df) , None ) = ( p_original. derived_from . as_ref ( ) , & p_derivedfrom) {
38- eprintln ! (
38+ return Err ( anyhow ! (
3939 "Couldn't find derivedFrom original: {} for {}, skipping" ,
40- df, p_original . name
41- ) ;
42- return Ok ( out ) ;
40+ df,
41+ p_original . name
42+ ) ) ;
4343 }
4444
4545 let name = util:: name_of ( p, config. ignore_groups ) ;
@@ -149,7 +149,7 @@ pub fn render(
149149 }
150150
151151 // erc: *E*ither *R*egister or *C*luster
152- let ercs = p. registers . as_ref ( ) . map ( |x| x. as_ref ( ) ) . unwrap_or ( & [ ] [ ..] ) ;
152+ let ercs_in = p. registers . as_ref ( ) . map ( |x| x. as_ref ( ) ) . unwrap_or ( & [ ] [ ..] ) ;
153153
154154 // make a pass to expand derived registers and clusters. Ideally, for the most minimal
155155 // code size, we'd do some analysis to figure out if we can 100% reuse the
@@ -159,48 +159,15 @@ pub fn render(
159159
160160 // Build a map so that we can look up registers within this peripheral
161161 let mut erc_map = HashMap :: new ( ) ;
162- for erc in ercs {
163- erc_map. insert ( util:: erc_name ( erc) , erc. clone ( ) ) ;
162+ for erc in ercs_in {
163+ erc_map. insert ( util:: erc_name ( erc) , erc) ;
164164 }
165165
166166 // Build up an alternate erc list by expanding any derived registers/clusters
167- let ercs: Vec < RegisterCluster > = ercs
168- . iter ( )
169- . filter_map ( |erc| match util:: erc_derived_from ( erc) {
170- Some ( ref derived) => {
171- let ancestor = match erc_map. get ( derived) {
172- Some ( erc) => erc,
173- None => {
174- eprintln ! (
175- "register/cluster {} derivedFrom missing register/cluster {}" ,
176- util:: erc_name( erc) ,
177- derived
178- ) ;
179- return None ;
180- }
181- } ;
182-
183- match ( erc, ancestor) {
184- ( RegisterCluster :: Register ( reg) , RegisterCluster :: Register ( other_reg) ) => {
185- Some ( RegisterCluster :: Register ( reg. derive_from ( other_reg) ) )
186- }
187- (
188- RegisterCluster :: Cluster ( cluster) ,
189- RegisterCluster :: Cluster ( other_cluster) ,
190- ) => Some ( RegisterCluster :: Cluster ( cluster. derive_from ( other_cluster) ) ) ,
191- _ => {
192- eprintln ! (
193- "{} can't derive from {}" ,
194- util:: erc_name( erc) ,
195- util:: erc_name( ancestor)
196- ) ;
197- None
198- }
199- }
200- }
201- None => Some ( erc. clone ( ) ) ,
202- } )
203- . collect ( ) ;
167+ let mut ercs = Vec :: with_capacity ( ercs_in. len ( ) ) ;
168+ for erc in ercs_in {
169+ ercs. push ( derive_register_cluster ( erc, & erc_map) ?. into_owned ( ) ) ;
170+ }
204171
205172 // And revise registers, clusters and ercs to refer to our expanded versions
206173 let registers: & [ & Register ] = & util:: only_registers ( & ercs) [ ..] ;
@@ -259,6 +226,42 @@ pub fn render(
259226 Ok ( out)
260227}
261228
229+ fn derive_register_cluster < ' a > (
230+ erc : & ' a RegisterCluster ,
231+ erc_map : & ' a HashMap < & ' a String , & ' a RegisterCluster > ,
232+ ) -> Result < Cow < ' a , RegisterCluster > > {
233+ Ok ( if let Some ( derived) = util:: erc_derived_from ( erc) {
234+ let ancestor = erc_map. get ( derived) . ok_or_else ( || {
235+ anyhow ! (
236+ "register/cluster {} derivedFrom missing register/cluster {}" ,
237+ util:: erc_name( erc) ,
238+ derived
239+ )
240+ } ) ?;
241+
242+ let ancestor = derive_register_cluster ( ancestor, erc_map) ?;
243+
244+ use RegisterCluster :: * ;
245+ match ( erc, ancestor. as_ref ( ) ) {
246+ ( Register ( reg) , Register ( other_reg) ) => {
247+ Cow :: Owned ( Register ( reg. derive_from ( other_reg) ) )
248+ }
249+ ( Cluster ( cluster) , Cluster ( other_cluster) ) => {
250+ Cow :: Owned ( Cluster ( cluster. derive_from ( other_cluster) ) )
251+ }
252+ _ => {
253+ return Err ( anyhow ! (
254+ "{} can't derive from {}" ,
255+ util:: erc_name( erc) ,
256+ util:: erc_name( & ancestor)
257+ ) ) ;
258+ }
259+ }
260+ } else {
261+ Cow :: Borrowed ( erc)
262+ } )
263+ }
264+
262265#[ derive( Clone , Debug ) ]
263266struct RegisterBlockField {
264267 field : syn:: Field ,
0 commit comments