27
27
from extract .pinctrl import pinctrl
28
28
from extract .default import default
29
29
30
- class Loader (yaml .Loader ):
30
+ class Bindings (yaml .Loader ):
31
+
32
+ ##
33
+ # List of all yaml files available for yaml loaders
34
+ # of this class. Must be preset before the first
35
+ # load operation.
36
+ _files = []
37
+
38
+ ##
39
+ # Files that are already included.
40
+ # Must be reset on the load of every new binding
41
+ _included = []
42
+
43
+ @classmethod
44
+ def bindings (cls , compatibles , yaml_dirs ):
45
+ # find unique set of compatibles across all active nodes
46
+ s = set ()
47
+ for k , v in compatibles .items ():
48
+ if isinstance (v , list ):
49
+ for item in v :
50
+ s .add (item )
51
+ else :
52
+ s .add (v )
53
+
54
+ # scan YAML files and find the ones we are interested in
55
+ cls ._files = []
56
+ for yaml_dir in yaml_dirs :
57
+ for root , dirnames , filenames in os .walk (yaml_dir ):
58
+ for filename in fnmatch .filter (filenames , '*.yaml' ):
59
+ cls ._files .append (os .path .join (root , filename ))
60
+
61
+ yaml_list = {}
62
+ file_load_list = set ()
63
+ for file in cls ._files :
64
+ for line in open (file , 'r' ):
65
+ if re .search ('^\s+constraint:*' , line ):
66
+ c = line .split (':' )[1 ].strip ()
67
+ c = c .strip ('"' )
68
+ if c in s :
69
+ if file not in file_load_list :
70
+ file_load_list .add (file )
71
+ with open (file , 'r' ) as yf :
72
+ cls ._included = []
73
+ yaml_list [c ] = yaml .load (yf , cls )
74
+ return yaml_list
75
+
31
76
def __init__ (self , stream ):
32
- self ._root = os .path .realpath (stream .name )
33
- super (Loader , self ).__init__ (stream )
34
- Loader .add_constructor ('!include' , Loader .include )
35
- Loader .add_constructor ('!import' , Loader .include )
77
+ filepath = os .path .realpath (stream .name )
78
+ if filepath in self ._included :
79
+ print ("Error:: circular inclusion for file name '{}'" .
80
+ format (stream .name ))
81
+ raise yaml .constructor .ConstructorError
82
+ self ._included .append (filepath )
83
+ super (Bindings , self ).__init__ (stream )
84
+ Bindings .add_constructor ('!include' , Bindings ._include )
85
+ Bindings .add_constructor ('!import' , Bindings ._include )
36
86
37
- def include (self , node ):
87
+ def _include (self , node ):
38
88
if isinstance (node , yaml .ScalarNode ):
39
- return self .extractFile (self .construct_scalar (node ))
89
+ return self ._extract_file (self .construct_scalar (node ))
40
90
41
91
elif isinstance (node , yaml .SequenceNode ):
42
92
result = []
43
93
for filename in self .construct_sequence (node ):
44
- result .append (self .extractFile (filename ))
94
+ result .append (self ._extract_file (filename ))
45
95
return result
46
96
47
97
elif isinstance (node , yaml .MappingNode ):
48
98
result = {}
49
99
for k , v in self .construct_mapping (node ).iteritems ():
50
- result [k ] = self .extractFile (v )
100
+ result [k ] = self ._extract_file (v )
51
101
return result
52
102
53
103
else :
54
104
print ("Error:: unrecognised node type in !include statement" )
55
105
raise yaml .constructor .ConstructorError
56
106
57
- def extractFile (self , filename ):
58
- filepath = os .path .join (os .path .dirname (self ._root ), filename )
59
- if not os .path .isfile (filepath ):
60
- # we need to look in bindings/* directories
61
- # take path and back up 1 directory and parse in '/bindings/*'
62
- filepath = os .path .dirname (os .path .dirname (self ._root ))
63
- for root , dirnames , file in os .walk (filepath ):
64
- if fnmatch .filter (file , filename ):
65
- filepath = os .path .join (root , filename )
66
- with open (filepath , 'r' ) as f :
67
- return yaml .load (f , Loader )
107
+ def _extract_file (self , filename ):
108
+ filepaths = [filepath for filepath in self ._files if filepath .endswith (filename )]
109
+ if len (filepaths ) == 0 :
110
+ print ("Error:: unknown file name '{}' in !include statement" .
111
+ format (filename ))
112
+ raise yaml .constructor .ConstructorError
113
+ elif len (filepaths ) > 1 :
114
+ # multiple candidates for filename
115
+ files = []
116
+ for filepath in filepaths :
117
+ if os .path .basename (filename ) == os .path .basename (filepath ):
118
+ files .append (filepath )
119
+ if len (files ) > 1 :
120
+ print ("Error:: multiple candidates for file name '{}' in !include statement" .
121
+ format (filename ), filepaths )
122
+ raise yaml .constructor .ConstructorError
123
+ filepaths = files
124
+ with open (filepaths [0 ], 'r' ) as f :
125
+ return yaml .load (f , Bindings )
68
126
69
127
70
128
def extract_reg_prop (node_address , names , def_label , div , post_label ):
@@ -663,36 +721,10 @@ def load_and_parse_dts(dts_file):
663
721
return dts
664
722
665
723
666
- def load_yaml_descriptions (dts , yaml_dir ):
724
+ def load_yaml_descriptions (dts , yaml_dirs ):
667
725
compatibles = get_all_compatibles (dts ['/' ], '/' , {})
668
- # find unique set of compatibles across all active nodes
669
- s = set ()
670
- for k , v in compatibles .items ():
671
- if isinstance (v , list ):
672
- for item in v :
673
- s .add (item )
674
- else :
675
- s .add (v )
676
-
677
- # scan YAML files and find the ones we are interested in
678
- yaml_files = []
679
- for root , dirnames , filenames in os .walk (yaml_dir ):
680
- for filename in fnmatch .filter (filenames , '*.yaml' ):
681
- yaml_files .append (os .path .join (root , filename ))
682
-
683
- yaml_list = {}
684
- file_load_list = set ()
685
- for file in yaml_files :
686
- for line in open (file , 'r' ):
687
- if re .search ('^\s+constraint:*' , line ):
688
- c = line .split (':' )[1 ].strip ()
689
- c = c .strip ('"' )
690
- if c in s :
691
- if file not in file_load_list :
692
- file_load_list .add (file )
693
- with open (file , 'r' ) as yf :
694
- yaml_list [c ] = yaml .load (yf , Loader )
695
726
727
+ yaml_list = Bindings .bindings (compatibles , yaml_dirs )
696
728
if yaml_list == {}:
697
729
raise Exception ("Missing YAML information. Check YAML sources" )
698
730
@@ -735,8 +767,8 @@ def parse_arguments():
735
767
parser = argparse .ArgumentParser (description = __doc__ , formatter_class = rdh )
736
768
737
769
parser .add_argument ("-d" , "--dts" , nargs = 1 , required = True , help = "DTS file" )
738
- parser .add_argument ("-y" , "--yaml" , nargs = 1 , required = True ,
739
- help = "YAML file" )
770
+ parser .add_argument ("-y" , "--yaml" , nargs = '+' , required = True ,
771
+ help = "YAML file directories, we allow multiple " )
740
772
parser .add_argument ("-f" , "--fixup" , nargs = '+' ,
741
773
help = "Fixup file(s), we allow multiple" )
742
774
parser .add_argument ("-i" , "--include" , nargs = 1 , required = True ,
@@ -757,7 +789,7 @@ def main():
757
789
get_aliases (dts ['/' ])
758
790
get_chosen (dts ['/' ])
759
791
760
- yaml_list = load_yaml_descriptions (dts , args .yaml [ 0 ] )
792
+ yaml_list = load_yaml_descriptions (dts , args .yaml )
761
793
762
794
defs = generate_node_definitions (yaml_list )
763
795
0 commit comments