1
1
pub mod patch_cli;
2
2
3
+ use std:: borrow:: Cow ;
3
4
use std:: fs:: File ;
4
5
use std:: io:: { Read , Write } ;
5
6
use std:: path:: { Path , PathBuf } ;
7
+ use svd_parser:: expand:: { BlockPath , FieldPath , RegisterPath } ;
6
8
use svd_parser:: svd:: {
7
9
addressblock:: AddressBlockBuilder , interrupt:: InterruptBuilder , Access , AddressBlock ,
8
10
AddressBlockUsage , ClusterInfo , ClusterInfoBuilder , Cpu , CpuBuilder , Endian , EnumeratedValue ,
@@ -462,10 +464,10 @@ fn modify_dim_element<T: Clone>(
462
464
Ok ( ( ) )
463
465
}
464
466
465
- fn make_field ( fadd : & Hash ) -> Result < FieldInfoBuilder > {
467
+ fn make_field ( fadd : & Hash , rpath : Option < & RegisterPath > ) -> Result < FieldInfoBuilder > {
466
468
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" ) ?) )
469
471
. access ( fadd. get_str ( "access" ) ?. and_then ( Access :: parse_str) )
470
472
. modified_write_values (
471
473
fadd. get_str ( "modifiedWriteValues" ) ?
@@ -493,11 +495,11 @@ fn make_field(fadd: &Hash) -> Result<FieldInfoBuilder> {
493
495
Ok ( fnew)
494
496
}
495
497
496
- fn make_register ( radd : & Hash ) -> Result < RegisterInfoBuilder > {
498
+ fn make_register ( radd : & Hash , path : Option < & BlockPath > ) -> Result < RegisterInfoBuilder > {
497
499
let mut rnew = RegisterInfo :: builder ( )
498
500
. 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" ) ?) )
501
503
. alternate_group ( radd. get_string ( "alternateGroup" ) ?)
502
504
. alternate_register ( radd. get_string ( "alternateRegister" ) ?)
503
505
. properties ( get_register_properties ( radd) ?)
@@ -506,7 +508,7 @@ fn make_register(radd: &Hash) -> Result<RegisterInfoBuilder> {
506
508
let mut fields = Vec :: new ( ) ;
507
509
for ( fname, val) in h {
508
510
fields. push (
509
- make_field ( val. hash ( ) ?) ?
511
+ make_field ( val. hash ( ) ?, None ) ?
510
512
. name ( fname. str ( ) ?. into ( ) )
511
513
. build ( VAL_LVL ) ?
512
514
. single ( ) ,
@@ -552,18 +554,18 @@ fn make_register(radd: &Hash) -> Result<RegisterInfoBuilder> {
552
554
Ok ( rnew)
553
555
}
554
556
555
- fn make_cluster ( cadd : & Hash ) -> Result < ClusterInfoBuilder > {
557
+ fn make_cluster ( cadd : & Hash , path : Option < & BlockPath > ) -> Result < ClusterInfoBuilder > {
556
558
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" ) ?) )
559
561
. default_register_properties ( get_register_properties ( cadd) ?)
560
562
. children ( match cadd. get_hash ( "registers" ) ? {
561
563
Some ( h) => {
562
564
let mut ch = Vec :: new ( ) ;
563
565
for ( rname, val) in h {
564
566
ch. push ( RegisterCluster :: Register ( {
565
567
let radd = val. hash ( ) ?;
566
- let reg = make_register ( radd) ?
568
+ let reg = make_register ( radd, None ) ?
567
569
. name ( rname. str ( ) ?. into ( ) )
568
570
. build ( VAL_LVL ) ?;
569
571
if let Some ( dim) = make_dim_element ( radd) ? {
@@ -652,7 +654,7 @@ fn make_peripheral(padd: &Hash, modify: bool) -> Result<PeripheralInfoBuilder> {
652
654
for ( rname, val) in h. iter ( ) {
653
655
regs. push ( RegisterCluster :: Register ( {
654
656
let radd = val. hash ( ) ?;
655
- let reg = make_register ( radd) ?
657
+ let reg = make_register ( radd, None ) ?
656
658
. name ( rname. str ( ) ?. into ( ) )
657
659
. build ( VAL_LVL ) ?;
658
660
if let Some ( dim) = make_dim_element ( radd) ? {
@@ -802,3 +804,53 @@ impl Spec for str {
802
804
}
803
805
}
804
806
}
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