@@ -296,7 +296,7 @@ pub fn fields(
296
296
( ( self . bits >> OFFSET ) & MASK as #rty) #cast
297
297
} ;
298
298
299
- if let Some ( ( evs, base) ) = util :: lookup (
299
+ if let Some ( ( evs, base) ) = lookup (
300
300
f. evs ,
301
301
fields,
302
302
parent,
@@ -584,7 +584,7 @@ pub fn fields(
584
584
let mask = & f. mask ;
585
585
let width = f. width ;
586
586
587
- if let Some ( ( evs, base) ) = util :: lookup (
587
+ if let Some ( ( evs, base) ) = lookup (
588
588
& f. evs ,
589
589
fields,
590
590
parent,
@@ -803,3 +803,213 @@ pub fn fields(
803
803
804
804
Ok ( ( ) )
805
805
}
806
+
807
+ #[ derive( Clone , Debug ) ]
808
+ pub struct Base < ' a > {
809
+ pub peripheral : Option < & ' a str > ,
810
+ pub register : Option < & ' a str > ,
811
+ pub field : & ' a str ,
812
+ }
813
+
814
+ fn lookup < ' a > (
815
+ evs : & ' a [ EnumeratedValues ] ,
816
+ fields : & ' a [ Field ] ,
817
+ register : & ' a Register ,
818
+ all_registers : & ' a [ Register ] ,
819
+ peripheral : & ' a Peripheral ,
820
+ all_peripherals : & ' a [ Peripheral ] ,
821
+ usage : Usage ,
822
+ ) -> Result < Option < ( & ' a EnumeratedValues , Option < Base < ' a > > ) > > {
823
+ let evs = evs. iter ( )
824
+ . map ( |evs| if let Some ( ref base) = evs. derived_from {
825
+ let mut parts = base. split ( '.' ) ;
826
+
827
+ match ( parts. next ( ) , parts. next ( ) , parts. next ( ) , parts. next ( ) ) {
828
+ ( Some ( base_peripheral) , Some ( base_register) , Some ( base_field) , Some ( base_evs) ) => {
829
+ lookup_in_peripherals (
830
+ base_peripheral,
831
+ base_register,
832
+ base_field,
833
+ base_evs,
834
+ all_peripherals,
835
+ )
836
+ }
837
+ ( Some ( base_register) , Some ( base_field) , Some ( base_evs) , None ) => {
838
+ lookup_in_peripheral (
839
+ None ,
840
+ base_register,
841
+ base_field,
842
+ base_evs,
843
+ all_registers,
844
+ peripheral,
845
+ )
846
+ }
847
+ ( Some ( base_field) , Some ( base_evs) , None , None ) => {
848
+ lookup_in_fields ( base_evs, base_field, fields, register)
849
+ }
850
+ ( Some ( base_evs) , None , None , None ) => lookup_in_register ( base_evs, register) ,
851
+ _ => unreachable ! ( ) ,
852
+ }
853
+ } else {
854
+ Ok ( ( evs, None ) )
855
+ } )
856
+ . collect :: < Result < Vec < _ > > > ( ) ?;
857
+
858
+ for & ( ref evs, ref base) in evs. iter ( ) {
859
+ if evs. usage == Some ( usage) {
860
+ return Ok ( Some ( ( * evs, base. clone ( ) ) ) ) ;
861
+ }
862
+ }
863
+
864
+ Ok ( evs. first ( ) . cloned ( ) )
865
+ }
866
+
867
+ fn lookup_in_fields < ' f > (
868
+ base_evs : & str ,
869
+ base_field : & str ,
870
+ fields : & ' f [ Field ] ,
871
+ register : & Register ,
872
+ ) -> Result < ( & ' f EnumeratedValues , Option < Base < ' f > > ) > {
873
+ if let Some ( base_field) = fields. iter ( ) . find ( |f| f. name == base_field) {
874
+ return lookup_in_field ( base_evs, None , None , base_field) ;
875
+ } else {
876
+ Err ( format ! (
877
+ "Field {} not found in register {}" ,
878
+ base_field,
879
+ register. name
880
+ ) ) ?
881
+ }
882
+ }
883
+
884
+ fn lookup_in_peripheral < ' p > (
885
+ base_peripheral : Option < & ' p str > ,
886
+ base_register : & ' p str ,
887
+ base_field : & str ,
888
+ base_evs : & str ,
889
+ all_registers : & ' p [ Register ] ,
890
+ peripheral : & ' p Peripheral ,
891
+ ) -> Result < ( & ' p EnumeratedValues , Option < Base < ' p > > ) > {
892
+ if let Some ( register) = all_registers. iter ( ) . find ( |r| r. name == base_register) {
893
+ if let Some ( field) = register
894
+ . fields
895
+ . as_ref ( )
896
+ . map ( |fs| & * * fs)
897
+ . unwrap_or ( & [ ] )
898
+ . iter ( )
899
+ . find ( |f| f. name == base_field)
900
+ {
901
+ lookup_in_field ( base_evs, Some ( base_register) , base_peripheral, field)
902
+ } else {
903
+ Err ( format ! (
904
+ "No field {} in register {}" ,
905
+ base_field,
906
+ register. name
907
+ ) ) ?
908
+ }
909
+ } else {
910
+ Err ( format ! (
911
+ "No register {} in peripheral {}" ,
912
+ base_register,
913
+ peripheral. name
914
+ ) ) ?
915
+ }
916
+ }
917
+
918
+ fn lookup_in_field < ' f > (
919
+ base_evs : & str ,
920
+ base_register : Option < & ' f str > ,
921
+ base_peripheral : Option < & ' f str > ,
922
+ field : & ' f Field ,
923
+ ) -> Result < ( & ' f EnumeratedValues , Option < Base < ' f > > ) > {
924
+ for evs in & field. enumerated_values {
925
+ if evs. name . as_ref ( ) . map ( |s| & * * s) == Some ( base_evs) {
926
+ return Ok (
927
+ (
928
+ evs,
929
+ Some ( Base {
930
+ field : & field. name ,
931
+ register : base_register,
932
+ peripheral : base_peripheral,
933
+ } ) ,
934
+ ) ,
935
+ ) ;
936
+ }
937
+ }
938
+
939
+ Err ( format ! (
940
+ "No EnumeratedValues {} in field {}" ,
941
+ base_evs,
942
+ field. name
943
+ ) ) ?
944
+ }
945
+
946
+ fn lookup_in_register < ' r > (
947
+ base_evs : & str ,
948
+ register : & ' r Register ,
949
+ ) -> Result < ( & ' r EnumeratedValues , Option < Base < ' r > > ) > {
950
+ let mut matches = vec ! [ ] ;
951
+
952
+ for f in register. fields . as_ref ( ) . map ( |v| & * * v) . unwrap_or ( & [ ] ) {
953
+ if let Some ( evs) = f. enumerated_values
954
+ . iter ( )
955
+ . find ( |evs| evs. name . as_ref ( ) . map ( |s| & * * s) == Some ( base_evs) )
956
+ {
957
+ matches. push ( ( evs, & f. name ) )
958
+ }
959
+ }
960
+
961
+ match matches. first ( ) {
962
+ None => Err ( format ! (
963
+ "EnumeratedValues {} not found in register {}" ,
964
+ base_evs,
965
+ register. name
966
+ ) ) ?,
967
+ Some ( & ( evs, field) ) => if matches. len ( ) == 1 {
968
+ return Ok ( (
969
+ evs,
970
+ Some ( Base {
971
+ field : field,
972
+ register : None ,
973
+ peripheral : None ,
974
+ } ) ,
975
+ ) ) ;
976
+ } else {
977
+ let fields = matches
978
+ . iter ( )
979
+ . map ( |& ( ref f, _) | & f. name )
980
+ . collect :: < Vec < _ > > ( ) ;
981
+ Err ( format ! (
982
+ "Fields {:?} have an \
983
+ enumeratedValues named {}",
984
+ fields,
985
+ base_evs
986
+ ) ) ?
987
+ } ,
988
+ }
989
+ }
990
+
991
+ fn lookup_in_peripherals < ' p > (
992
+ base_peripheral : & ' p str ,
993
+ base_register : & ' p str ,
994
+ base_field : & str ,
995
+ base_evs : & str ,
996
+ all_peripherals : & ' p [ Peripheral ] ,
997
+ ) -> Result < ( & ' p EnumeratedValues , Option < Base < ' p > > ) > {
998
+ if let Some ( peripheral) = all_peripherals. iter ( ) . find ( |p| p. name == base_peripheral) {
999
+ let all_registers = peripheral
1000
+ . registers
1001
+ . as_ref ( )
1002
+ . map ( |x| x. as_ref ( ) )
1003
+ . unwrap_or ( & [ ] [ ..] ) ;
1004
+ lookup_in_peripheral (
1005
+ Some ( base_peripheral) ,
1006
+ base_register,
1007
+ base_field,
1008
+ base_evs,
1009
+ all_registers,
1010
+ peripheral,
1011
+ )
1012
+ } else {
1013
+ Err ( format ! ( "No peripheral {}" , base_peripheral) ) ?
1014
+ }
1015
+ }
0 commit comments