11pub mod patch_cli;
22
3+ use std:: borrow:: Cow ;
34use std:: fs:: File ;
45use std:: io:: { Read , Write } ;
56use std:: path:: { Path , PathBuf } ;
7+ use svd_parser:: expand:: { BlockPath , FieldPath , RegisterPath } ;
68use svd_parser:: svd:: {
79 addressblock:: AddressBlockBuilder , interrupt:: InterruptBuilder , Access , AddressBlock ,
810 AddressBlockUsage , ClusterInfo , ClusterInfoBuilder , Cpu , CpuBuilder , Endian , EnumeratedValue ,
@@ -429,10 +431,10 @@ fn modify_dim_element<T: Clone>(
429431 Ok ( ( ) )
430432}
431433
432- fn make_field ( fadd : & Hash ) -> Result < FieldInfoBuilder > {
434+ fn make_field ( fadd : & Hash , rpath : Option < & RegisterPath > ) -> Result < FieldInfoBuilder > {
433435 let mut fnew = FieldInfo :: builder ( )
434- . description ( fadd. get_string ( "description" ) ?)
435- . derived_from ( fadd. get_string ( "derivedFrom" ) ?)
436+ . description ( opt_interpolate ( & rpath , fadd. get_str ( "description" ) ?) )
437+ . derived_from ( opt_interpolate ( & rpath , fadd. get_str ( "derivedFrom" ) ?) )
436438 . access ( fadd. get_str ( "access" ) ?. and_then ( Access :: parse_str) )
437439 . modified_write_values (
438440 fadd. get_str ( "modifiedWriteValues" ) ?
@@ -460,11 +462,11 @@ fn make_field(fadd: &Hash) -> Result<FieldInfoBuilder> {
460462 Ok ( fnew)
461463}
462464
463- fn make_register ( radd : & Hash ) -> Result < RegisterInfoBuilder > {
465+ fn make_register ( radd : & Hash , path : Option < & BlockPath > ) -> Result < RegisterInfoBuilder > {
464466 let mut rnew = RegisterInfo :: builder ( )
465467 . display_name ( radd. get_string ( "displayName" ) ?)
466- . description ( radd. get_string ( "description" ) ?)
467- . derived_from ( radd. get_string ( "derivedFrom" ) ?)
468+ . description ( opt_interpolate ( & path , radd. get_str ( "description" ) ?) )
469+ . derived_from ( opt_interpolate ( & path , radd. get_str ( "derivedFrom" ) ?) )
468470 . alternate_group ( radd. get_string ( "alternateGroup" ) ?)
469471 . alternate_register ( radd. get_string ( "alternateRegister" ) ?)
470472 . properties ( get_register_properties ( radd) ?)
@@ -473,7 +475,7 @@ fn make_register(radd: &Hash) -> Result<RegisterInfoBuilder> {
473475 let mut fields = Vec :: new ( ) ;
474476 for ( fname, val) in h {
475477 fields. push (
476- make_field ( val. hash ( ) ?) ?
478+ make_field ( val. hash ( ) ?, None ) ?
477479 . name ( fname. str ( ) ?. into ( ) )
478480 . build ( VAL_LVL ) ?
479481 . single ( ) ,
@@ -519,18 +521,18 @@ fn make_register(radd: &Hash) -> Result<RegisterInfoBuilder> {
519521 Ok ( rnew)
520522}
521523
522- fn make_cluster ( cadd : & Hash ) -> Result < ClusterInfoBuilder > {
524+ fn make_cluster ( cadd : & Hash , path : Option < & BlockPath > ) -> Result < ClusterInfoBuilder > {
523525 let mut cnew = ClusterInfo :: builder ( )
524- . description ( cadd. get_string ( "description" ) ?)
525- . derived_from ( cadd. get_string ( "derivedFrom" ) ?)
526+ . description ( opt_interpolate ( & path , cadd. get_str ( "description" ) ?) )
527+ . derived_from ( opt_interpolate ( & path , cadd. get_str ( "derivedFrom" ) ?) )
526528 . default_register_properties ( get_register_properties ( cadd) ?)
527529 . children ( match cadd. get_hash ( "registers" ) ? {
528530 Some ( h) => {
529531 let mut ch = Vec :: new ( ) ;
530532 for ( rname, val) in h {
531533 ch. push ( RegisterCluster :: Register ( {
532534 let radd = val. hash ( ) ?;
533- let reg = make_register ( radd) ?
535+ let reg = make_register ( radd, None ) ?
534536 . name ( rname. str ( ) ?. into ( ) )
535537 . build ( VAL_LVL ) ?;
536538 if let Some ( dim) = make_dim_element ( radd) ? {
@@ -619,7 +621,7 @@ fn make_peripheral(padd: &Hash, modify: bool) -> Result<PeripheralInfoBuilder> {
619621 for ( rname, val) in h. iter ( ) {
620622 regs. push ( RegisterCluster :: Register ( {
621623 let radd = val. hash ( ) ?;
622- let reg = make_register ( radd) ?
624+ let reg = make_register ( radd, None ) ?
623625 . name ( rname. str ( ) ?. into ( ) )
624626 . build ( VAL_LVL ) ?;
625627 if let Some ( dim) = make_dim_element ( radd) ? {
@@ -769,3 +771,53 @@ impl Spec for str {
769771 }
770772 }
771773}
774+
775+ fn opt_interpolate < T : Interpolate > ( path : & Option < & T > , s : Option < & str > ) -> Option < String > {
776+ path. and_then ( |path| path. interpolate_opt ( s) )
777+ }
778+
779+ trait Interpolate {
780+ fn interpolate < ' a > ( & self , s : & ' a str ) -> Cow < ' a , str > ;
781+ fn interpolate_opt ( & self , s : Option < & str > ) -> Option < String > {
782+ s. map ( |s| self . interpolate ( s) . into_owned ( ) )
783+ }
784+ }
785+
786+ impl Interpolate for BlockPath {
787+ fn interpolate < ' a > ( & self , s : & ' a str ) -> Cow < ' a , str > {
788+ let mut cow = Cow :: Borrowed ( s) ;
789+ if cow. contains ( "`peripheral`" ) {
790+ cow = cow. replace ( "`peripheral`" , & self . peripheral ) . into ( )
791+ }
792+ if cow. contains ( "`block_path`" ) {
793+ cow = cow. replace ( "`block_path`" , & self . to_string ( ) ) . into ( )
794+ }
795+ cow
796+ }
797+ }
798+
799+ impl Interpolate for RegisterPath {
800+ fn interpolate < ' a > ( & self , s : & ' a str ) -> Cow < ' a , str > {
801+ let mut cow = self . block . interpolate ( s) ;
802+ if cow. contains ( "`register`" ) {
803+ cow = cow. replace ( "`register`" , & self . name ) . into ( )
804+ }
805+ if cow. contains ( "`register_path`" ) {
806+ cow = cow. replace ( "`register_path`" , & self . to_string ( ) ) . into ( )
807+ }
808+ cow
809+ }
810+ }
811+
812+ impl Interpolate for FieldPath {
813+ fn interpolate < ' a > ( & self , s : & ' a str ) -> Cow < ' a , str > {
814+ let mut cow = self . register ( ) . interpolate ( s) ;
815+ if cow. contains ( "`field`" ) {
816+ cow = cow. replace ( "`field`" , & self . name ) . into ( )
817+ }
818+ if cow. contains ( "`field_path`" ) {
819+ cow = cow. replace ( "`field_path`" , & self . to_string ( ) ) . into ( )
820+ }
821+ cow
822+ }
823+ }
0 commit comments