11use std:: borrow:: Cow ;
2+ use std:: cmp:: Ordering ;
23
34use either:: Either ;
45use quote:: { ToTokens , Tokens } ;
@@ -120,43 +121,29 @@ struct Region {
120121}
121122
122123impl Region {
123- /// Find the longest common prefix of the identifier names
124- /// for the fields in this region, if any.
125- fn common_prefix ( & self ) -> Option < String > {
126- let mut char_vecs = Vec :: new ( ) ;
127- let mut min_len = usize:: max_value ( ) ;
128-
129- for f in & self . fields {
130- match f. field . ident {
131- None => return None ,
132- Some ( ref ident) => {
133- let chars : Vec < char > = ident. as_ref ( ) . chars ( ) . collect ( ) ;
134- min_len = min_len. min ( chars. len ( ) ) ;
135- char_vecs. push ( chars) ;
124+ fn shortest_ident ( & self ) -> Option < String > {
125+ let mut idents: Vec < _ > = self . fields
126+ . iter ( )
127+ . filter_map ( |f| {
128+ match f. field . ident {
129+ None => None ,
130+ Some ( ref ident) => {
131+ Some ( ident. as_ref ( ) )
132+ }
136133 }
137- }
134+ } )
135+ . collect ( ) ;
136+ if idents. is_empty ( ) {
137+ return None ;
138138 }
139-
140- let mut result = String :: new ( ) ;
141-
142- for i in 0 ..min_len {
143- let c = char_vecs[ 0 ] [ i] ;
144- for v in & char_vecs {
145- if v[ i] != c {
146- break ;
147- }
139+ idents. sort_by ( |a, b| {
140+ // Sort by length and then content
141+ match a. len ( ) . cmp ( & b. len ( ) ) {
142+ Ordering :: Equal => a. cmp ( b) ,
143+ cmp @ _ => cmp
148144 }
149-
150- // This character position is the same across
151- // all variants, so emit it into the result
152- result. push ( c) ;
153- }
154-
155- if result. is_empty ( ) {
156- None
157- } else {
158- Some ( result)
159- }
145+ } ) ;
146+ Some ( idents[ 0 ] . to_owned ( ) )
160147 }
161148
162149 /// Return a description of this region
@@ -298,6 +285,8 @@ fn register_or_cluster_block(
298285
299286 for reg_block_field in & region. fields {
300287 if reg_block_field. offset != region. offset {
288+ // TODO: need to emit padding for this case.
289+ // Happens for freescale_mkl43z4
301290 eprintln ! ( "WARNING: field {:?} has different offset {} than its union container {}" ,
302291 reg_block_field. field. ident,
303292 reg_block_field. offset,
@@ -319,15 +308,15 @@ fn register_or_cluster_block(
319308 }
320309
321310 if region. fields . len ( ) > 1 && !block_is_union {
322- let ( type_name, name) = match region. common_prefix ( ) {
311+ let ( type_name, name) = match region. shortest_ident ( ) {
323312 Some ( prefix) => {
324- ( Ident :: new ( format ! ( "{}_union " , prefix) ) ,
313+ ( Ident :: new ( format ! ( "{}Union " , prefix. to_sanitized_upper_case ( ) ) ) ,
325314 Ident :: new ( prefix) )
326315 }
327- // If we can't find a common prefix for the name, fall back to the
328- // region index as a unique-within-this-block identifier counter.
316+ // If we can't find a name, fall back to theregion index as a
317+ // unique-within-this-block identifier counter.
329318 None => {
330- let ident = Ident :: new ( format ! ( "u {}" , i) ) ;
319+ let ident = Ident :: new ( format ! ( "U {}" , i) ) ;
331320 ( ident. clone ( ) , ident)
332321 }
333322 } ;
0 commit comments