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 ,
@@ -462,10 +464,10 @@ fn modify_dim_element<T: Clone>(
462464 Ok ( ( ) )
463465}
464466
465- fn make_field ( fadd : & Hash ) -> Result < FieldInfoBuilder > {
467+ fn make_field ( fadd : & Hash , rpath : Option < & RegisterPath > ) -> Result < FieldInfoBuilder > {
466468 let mut fnew = FieldInfo :: builder ( )
467- . description ( fadd. get_string ( "description" ) ?)
468- . derived_from ( fadd. get_string ( "derivedFrom" ) ?)
469+ . description ( opt_interpolate ( & rpath , fadd. get_str ( "description" ) ?) )
470+ . derived_from ( opt_interpolate ( & rpath , fadd. get_str ( "derivedFrom" ) ?) )
469471 . access ( fadd. get_str ( "access" ) ?. and_then ( Access :: parse_str) )
470472 . modified_write_values (
471473 fadd. get_str ( "modifiedWriteValues" ) ?
@@ -493,11 +495,11 @@ fn make_field(fadd: &Hash) -> Result<FieldInfoBuilder> {
493495 Ok ( fnew)
494496}
495497
496- fn make_register ( radd : & Hash ) -> Result < RegisterInfoBuilder > {
498+ fn make_register ( radd : & Hash , path : Option < & BlockPath > ) -> Result < RegisterInfoBuilder > {
497499 let mut rnew = RegisterInfo :: builder ( )
498500 . display_name ( radd. get_string ( "displayName" ) ?)
499- . description ( radd. get_string ( "description" ) ?)
500- . derived_from ( radd. get_string ( "derivedFrom" ) ?)
501+ . description ( opt_interpolate ( & path , radd. get_str ( "description" ) ?) )
502+ . derived_from ( opt_interpolate ( & path , radd. get_str ( "derivedFrom" ) ?) )
501503 . alternate_group ( radd. get_string ( "alternateGroup" ) ?)
502504 . alternate_register ( radd. get_string ( "alternateRegister" ) ?)
503505 . properties ( get_register_properties ( radd) ?)
@@ -506,7 +508,7 @@ fn make_register(radd: &Hash) -> Result<RegisterInfoBuilder> {
506508 let mut fields = Vec :: new ( ) ;
507509 for ( fname, val) in h {
508510 fields. push (
509- make_field ( val. hash ( ) ?) ?
511+ make_field ( val. hash ( ) ?, None ) ?
510512 . name ( fname. str ( ) ?. into ( ) )
511513 . build ( VAL_LVL ) ?
512514 . single ( ) ,
@@ -552,18 +554,18 @@ fn make_register(radd: &Hash) -> Result<RegisterInfoBuilder> {
552554 Ok ( rnew)
553555}
554556
555- fn make_cluster ( cadd : & Hash ) -> Result < ClusterInfoBuilder > {
557+ fn make_cluster ( cadd : & Hash , path : Option < & BlockPath > ) -> Result < ClusterInfoBuilder > {
556558 let mut cnew = ClusterInfo :: builder ( )
557- . description ( cadd. get_string ( "description" ) ?)
558- . derived_from ( cadd. get_string ( "derivedFrom" ) ?)
559+ . description ( opt_interpolate ( & path , cadd. get_str ( "description" ) ?) )
560+ . derived_from ( opt_interpolate ( & path , cadd. get_str ( "derivedFrom" ) ?) )
559561 . default_register_properties ( get_register_properties ( cadd) ?)
560562 . children ( match cadd. get_hash ( "registers" ) ? {
561563 Some ( h) => {
562564 let mut ch = Vec :: new ( ) ;
563565 for ( rname, val) in h {
564566 ch. push ( RegisterCluster :: Register ( {
565567 let radd = val. hash ( ) ?;
566- let reg = make_register ( radd) ?
568+ let reg = make_register ( radd, None ) ?
567569 . name ( rname. str ( ) ?. into ( ) )
568570 . build ( VAL_LVL ) ?;
569571 if let Some ( dim) = make_dim_element ( radd) ? {
@@ -652,7 +654,7 @@ fn make_peripheral(padd: &Hash, modify: bool) -> Result<PeripheralInfoBuilder> {
652654 for ( rname, val) in h. iter ( ) {
653655 regs. push ( RegisterCluster :: Register ( {
654656 let radd = val. hash ( ) ?;
655- let reg = make_register ( radd) ?
657+ let reg = make_register ( radd, None ) ?
656658 . name ( rname. str ( ) ?. into ( ) )
657659 . build ( VAL_LVL ) ?;
658660 if let Some ( dim) = make_dim_element ( radd) ? {
@@ -802,3 +804,53 @@ impl Spec for str {
802804 }
803805 }
804806}
807+
808+ fn opt_interpolate < T : Interpolate > ( path : & Option < & T > , s : Option < & str > ) -> Option < String > {
809+ path. and_then ( |path| path. interpolate_opt ( s) )
810+ }
811+
812+ trait Interpolate {
813+ fn interpolate < ' a > ( & self , s : & ' a str ) -> Cow < ' a , str > ;
814+ fn interpolate_opt ( & self , s : Option < & str > ) -> Option < String > {
815+ s. map ( |s| self . interpolate ( s) . into_owned ( ) )
816+ }
817+ }
818+
819+ impl Interpolate for BlockPath {
820+ fn interpolate < ' a > ( & self , s : & ' a str ) -> Cow < ' a , str > {
821+ let mut cow = Cow :: Borrowed ( s) ;
822+ if cow. contains ( "`peripheral`" ) {
823+ cow = cow. replace ( "`peripheral`" , & self . peripheral ) . into ( )
824+ }
825+ if cow. contains ( "`block_path`" ) {
826+ cow = cow. replace ( "`block_path`" , & self . to_string ( ) ) . into ( )
827+ }
828+ cow
829+ }
830+ }
831+
832+ impl Interpolate for RegisterPath {
833+ fn interpolate < ' a > ( & self , s : & ' a str ) -> Cow < ' a , str > {
834+ let mut cow = self . block . interpolate ( s) ;
835+ if cow. contains ( "`register`" ) {
836+ cow = cow. replace ( "`register`" , & self . name ) . into ( )
837+ }
838+ if cow. contains ( "`register_path`" ) {
839+ cow = cow. replace ( "`register_path`" , & self . to_string ( ) ) . into ( )
840+ }
841+ cow
842+ }
843+ }
844+
845+ impl Interpolate for FieldPath {
846+ fn interpolate < ' a > ( & self , s : & ' a str ) -> Cow < ' a , str > {
847+ let mut cow = self . register ( ) . interpolate ( s) ;
848+ if cow. contains ( "`field`" ) {
849+ cow = cow. replace ( "`field`" , & self . name ) . into ( )
850+ }
851+ if cow. contains ( "`field_path`" ) {
852+ cow = cow. replace ( "`field_path`" , & self . to_string ( ) ) . into ( )
853+ }
854+ cow
855+ }
856+ }
0 commit comments