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 ,
@@ -429,10 +431,10 @@ fn modify_dim_element<T: Clone>(
429
431
Ok ( ( ) )
430
432
}
431
433
432
- fn make_field ( fadd : & Hash ) -> Result < FieldInfoBuilder > {
434
+ fn make_field ( fadd : & Hash , rpath : Option < & RegisterPath > ) -> Result < FieldInfoBuilder > {
433
435
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" ) ?) )
436
438
. access ( fadd. get_str ( "access" ) ?. and_then ( Access :: parse_str) )
437
439
. modified_write_values (
438
440
fadd. get_str ( "modifiedWriteValues" ) ?
@@ -460,11 +462,11 @@ fn make_field(fadd: &Hash) -> Result<FieldInfoBuilder> {
460
462
Ok ( fnew)
461
463
}
462
464
463
- fn make_register ( radd : & Hash ) -> Result < RegisterInfoBuilder > {
465
+ fn make_register ( radd : & Hash , path : Option < & BlockPath > ) -> Result < RegisterInfoBuilder > {
464
466
let mut rnew = RegisterInfo :: builder ( )
465
467
. 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" ) ?) )
468
470
. alternate_group ( radd. get_string ( "alternateGroup" ) ?)
469
471
. alternate_register ( radd. get_string ( "alternateRegister" ) ?)
470
472
. properties ( get_register_properties ( radd) ?)
@@ -473,7 +475,7 @@ fn make_register(radd: &Hash) -> Result<RegisterInfoBuilder> {
473
475
let mut fields = Vec :: new ( ) ;
474
476
for ( fname, val) in h {
475
477
fields. push (
476
- make_field ( val. hash ( ) ?) ?
478
+ make_field ( val. hash ( ) ?, None ) ?
477
479
. name ( fname. str ( ) ?. into ( ) )
478
480
. build ( VAL_LVL ) ?
479
481
. single ( ) ,
@@ -519,18 +521,18 @@ fn make_register(radd: &Hash) -> Result<RegisterInfoBuilder> {
519
521
Ok ( rnew)
520
522
}
521
523
522
- fn make_cluster ( cadd : & Hash ) -> Result < ClusterInfoBuilder > {
524
+ fn make_cluster ( cadd : & Hash , path : Option < & BlockPath > ) -> Result < ClusterInfoBuilder > {
523
525
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" ) ?) )
526
528
. default_register_properties ( get_register_properties ( cadd) ?)
527
529
. children ( match cadd. get_hash ( "registers" ) ? {
528
530
Some ( h) => {
529
531
let mut ch = Vec :: new ( ) ;
530
532
for ( rname, val) in h {
531
533
ch. push ( RegisterCluster :: Register ( {
532
534
let radd = val. hash ( ) ?;
533
- let reg = make_register ( radd) ?
535
+ let reg = make_register ( radd, None ) ?
534
536
. name ( rname. str ( ) ?. into ( ) )
535
537
. build ( VAL_LVL ) ?;
536
538
if let Some ( dim) = make_dim_element ( radd) ? {
@@ -619,7 +621,7 @@ fn make_peripheral(padd: &Hash, modify: bool) -> Result<PeripheralInfoBuilder> {
619
621
for ( rname, val) in h. iter ( ) {
620
622
regs. push ( RegisterCluster :: Register ( {
621
623
let radd = val. hash ( ) ?;
622
- let reg = make_register ( radd) ?
624
+ let reg = make_register ( radd, None ) ?
623
625
. name ( rname. str ( ) ?. into ( ) )
624
626
. build ( VAL_LVL ) ?;
625
627
if let Some ( dim) = make_dim_element ( radd) ? {
@@ -769,3 +771,53 @@ impl Spec for str {
769
771
}
770
772
}
771
773
}
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