summaryrefslogtreecommitdiffstats
path: root/scripts/lib/bsp/engine.py
diff options
context:
space:
mode:
authorTom Zanussi <tom.zanussi@linux.intel.com>2014-12-16 18:41:00 -0600
committerRichard Purdie <richard.purdie@linuxfoundation.org>2014-12-18 10:08:37 +0000
commited99aeeb682ed0ab04e2a02ece88b6d90059b774 (patch)
tree0d9127e351868a814a3c577975c2afbdae82dfe4 /scripts/lib/bsp/engine.py
parent8657c2fd57600e0b0eaf2a14692de7453c78e1bb (diff)
downloadpoky-ed99aeeb682ed0ab04e2a02ece88b6d90059b774.tar.gz
yocto-bsp: Add a processing pass to get rid of 'strange' filenames
Operating systems that can't handle filenames containing anything but uppercase letters don't like to see 'strange' characters in filenames such as the file and directory names yocto-bsp uses as part of its templating mechanism. To fix this, we essentially add another level of metadata into the template files themselves rather than into their names, and add a processing pass that internally gives us what we had before. Specifically: - strange characters in filenames are moved inside the files they apply to, to the first line of the file prepended with '# yocto-bsp-filename {{...}} filename | this' - strange characters in directory names are moved inside a new file of the same name but ending in .noinstall and with the first (and only) line of the file prepended with '# yocto-bsp-dirname {{...}} dirname' If the new filename contained in the yocto-bsp-* tag is 'this', the filename is the existing name of the file. For a dirname, this would be the filename with .noinstall removed. "Fixes" [YOCTO #5312]. (From meta-yocto rev: 3dad2decbd682713f717950fc39fa0f63f1b8c98) Signed-off-by: Tom Zanussi <tom.zanussi@linux.intel.com> Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
Diffstat (limited to 'scripts/lib/bsp/engine.py')
-rw-r--r--scripts/lib/bsp/engine.py173
1 files changed, 170 insertions, 3 deletions
diff --git a/scripts/lib/bsp/engine.py b/scripts/lib/bsp/engine.py
index 681720d20a..7d6be239da 100644
--- a/scripts/lib/bsp/engine.py
+++ b/scripts/lib/bsp/engine.py
@@ -756,6 +756,8 @@ class CheckInputLine(ListValInputLine):
756 return None 756 return None
757 757
758 758
759dirname_substitutions = {}
760
759class SubstrateBase(object): 761class SubstrateBase(object):
760 """ 762 """
761 Base class for both expanded and unexpanded file and dir container 763 Base class for both expanded and unexpanded file and dir container
@@ -764,6 +766,7 @@ class SubstrateBase(object):
764 def __init__(self, filename, filebase, out_filebase): 766 def __init__(self, filename, filebase, out_filebase):
765 self.filename = filename 767 self.filename = filename
766 self.filebase = filebase 768 self.filebase = filebase
769 self.translated_filename = filename
767 self.out_filebase = out_filebase 770 self.out_filebase = out_filebase
768 self.raw_lines = [] 771 self.raw_lines = []
769 self.expanded_lines = [] 772 self.expanded_lines = []
@@ -869,6 +872,167 @@ class SubstrateBase(object):
869 872
870 return self.expand_input_tag(tag, lineno) 873 return self.expand_input_tag(tag, lineno)
871 874
875 def append_translated_filename(self, filename):
876 """
877 Simply append filename to translated_filename
878 """
879 self.translated_filename = os.path.join(self.translated_filename, filename)
880
881 def get_substituted_file_or_dir_name(self, first_line, tag):
882 """
883 If file or dir names contain name substitutions, return the name
884 to substitute. Note that this is just the file or dirname and
885 doesn't include the path.
886 """
887 filename = first_line.find(tag)
888 if filename != -1:
889 filename += len(tag)
890 substituted_filename = first_line[filename:].strip()
891 this = substituted_filename.find(" this")
892 if this != -1:
893 head, tail = os.path.split(self.filename)
894 substituted_filename = substituted_filename[:this + 1] + tail
895 if tag == DIRNAME_TAG: # get rid of .noinstall in dirname
896 substituted_filename = substituted_filename.split('.')[0]
897
898 return substituted_filename
899
900 def get_substituted_filename(self, first_line):
901 """
902 If a filename contains a name substitution, return the name to
903 substitute. Note that this is just the filename and doesn't
904 include the path.
905 """
906 return self.get_substituted_file_or_dir_name(first_line, FILENAME_TAG)
907
908 def get_substituted_dirname(self, first_line):
909 """
910 If a dirname contains a name substitution, return the name to
911 substitute. Note that this is just the dirname and doesn't
912 include the path.
913 """
914 return self.get_substituted_file_or_dir_name(first_line, DIRNAME_TAG)
915
916 def substitute_filename(self, first_line):
917 """
918 Find the filename in first_line and append it to translated_filename.
919 """
920 substituted_filename = self.get_substituted_filename(first_line)
921 self.append_translated_filename(substituted_filename);
922
923 def substitute_dirname(self, first_line):
924 """
925 Find the dirname in first_line and append it to translated_filename.
926 """
927 substituted_dirname = self.get_substituted_dirname(first_line)
928 self.append_translated_filename(substituted_dirname);
929
930 def is_filename_substitution(self, line):
931 """
932 Do we have a filename subustition?
933 """
934 if line.find(FILENAME_TAG) != -1:
935 return True
936 return False
937
938 def is_dirname_substitution(self, line):
939 """
940 Do we have a dirname subustition?
941 """
942 if line.find(DIRNAME_TAG) != -1:
943 return True
944 return False
945
946 def translate_dirname(self, first_line):
947 """
948 Just save the first_line mapped by filename. The later pass
949 through the directories will look for a dirname.noinstall
950 match and grab the substitution line.
951 """
952 dirname_substitutions[self.filename] = first_line
953
954 def translate_dirnames_in_path(self, path):
955 """
956 Translate dirnames below this file or dir, not including tail.
957 dirname_substititions is keyed on actual untranslated filenames.
958 translated_path contains the subsititutions for each element.
959 """
960 remainder = path[len(self.filebase)+1:]
961 translated_path = untranslated_path = self.filebase
962
963 untranslated_dirs = remainder.split(os.sep)
964
965 for dir in untranslated_dirs:
966 key = os.path.join(untranslated_path, dir + '.noinstall')
967 try:
968 first_line = dirname_substitutions[key]
969 except KeyError:
970 translated_path = os.path.join(translated_path, dir)
971 untranslated_path = os.path.join(untranslated_path, dir)
972 continue
973 substituted_dir = self.get_substituted_dirname(first_line)
974 translated_path = os.path.join(translated_path, substituted_dir)
975 untranslated_path = os.path.join(untranslated_path, dir)
976
977 return translated_path
978
979 def translate_file_or_dir_name(self):
980 """
981 Originally we were allowed to use open/close/assign tags and python
982 code in the filename, which fit in nicely with the way we
983 processed the templates and generated code. Now that we can't
984 do that, we make those tags proper file contents and have this
985 pass substitute the nice but non-functional names with those
986 'strange' ones, and then proceed as usual.
987
988 So, if files or matching dir<.noinstall> files contain
989 filename substitutions, this function translates them into the
990 corresponding 'strange' names, which future passes will expand
991 as they always have. The resulting pathname is kept in the
992 file or directory's translated_filename. Another way to think
993 about it is that self.filename is the input filename, and
994 translated_filename is the output filename before expansion.
995 """
996 # remove leaf file or dirname
997 head, tail = os.path.split(self.filename)
998 translated_path = self.translate_dirnames_in_path(head)
999 self.translated_filename = translated_path
1000
1001 # This is a dirname - does it have a matching .noinstall with
1002 # a substitution? If so, apply the dirname subsititution.
1003 if not os.path.isfile(self.filename):
1004 key = self.filename + ".noinstall"
1005 try:
1006 first_line = dirname_substitutions[key]
1007 except KeyError:
1008 self.append_translated_filename(tail)
1009 return
1010 self.substitute_dirname(first_line)
1011 return
1012
1013 f = open(self.filename)
1014 first_line = f.readline()
1015 f.close()
1016
1017 # This is a normal filename not needing translation, just use
1018 # it as-is.
1019 if not first_line or not first_line.startswith("#"):
1020 self.append_translated_filename(tail)
1021 return
1022
1023 # If we have a filename substitution (first line in the file
1024 # is a FILENAME_TAG line) do the substitution now. If we have
1025 # a dirname substitution (DIRNAME_TAG in dirname.noinstall
1026 # meta-file), hash it so we can apply it when we see the
1027 # matching dirname later. Otherwise we have a regular
1028 # filename, just use it as-is.
1029 if self.is_filename_substitution(first_line):
1030 self.substitute_filename(first_line)
1031 elif self.is_dirname_substitution(first_line):
1032 self.translate_dirname(first_line)
1033 else:
1034 self.append_translated_filename(tail)
1035
872 def expand_file_or_dir_name(self): 1036 def expand_file_or_dir_name(self):
873 """ 1037 """
874 Expand file or dir names into codeline. Dirnames and 1038 Expand file or dir names into codeline. Dirnames and
@@ -878,7 +1042,7 @@ class SubstrateBase(object):
878 """ 1042 """
879 lineno = 0 1043 lineno = 0
880 1044
881 line = self.filename[len(self.filebase):] 1045 line = self.translated_filename[len(self.filebase):]
882 if line.startswith("/"): 1046 if line.startswith("/"):
883 line = line[1:] 1047 line = line[1:]
884 opentag_start = -1 1048 opentag_start = -1
@@ -897,7 +1061,6 @@ class SubstrateBase(object):
897 self.parse_error("No close tag found for open tag", lineno, line) 1061 self.parse_error("No close tag found for open tag", lineno, line)
898 # we have a {{ tag i.e. code 1062 # we have a {{ tag i.e. code
899 tag = line[opentag_start + len(OPEN_TAG):end].strip() 1063 tag = line[opentag_start + len(OPEN_TAG):end].strip()
900
901 if not tag.lstrip().startswith(IF_TAG): 1064 if not tag.lstrip().startswith(IF_TAG):
902 self.parse_error("Only 'if' tags are allowed in file or directory names", 1065 self.parse_error("Only 'if' tags are allowed in file or directory names",
903 lineno, line) 1066 lineno, line)
@@ -933,6 +1096,7 @@ class SubstrateBase(object):
933 Expand the file or dir name first, eventually this ends up 1096 Expand the file or dir name first, eventually this ends up
934 creating the file or dir. 1097 creating the file or dir.
935 """ 1098 """
1099 self.translate_file_or_dir_name()
936 self.expand_file_or_dir_name() 1100 self.expand_file_or_dir_name()
937 1101
938 1102
@@ -955,6 +1119,9 @@ class SubstrateFile(SubstrateBase):
955 self.read() 1119 self.read()
956 1120
957 for lineno, line in enumerate(self.raw_lines): 1121 for lineno, line in enumerate(self.raw_lines):
1122 # only first line can be a filename substitition
1123 if lineno == 0 and line.startswith("#") and FILENAME_TAG in line:
1124 continue # skip it - we've already expanded it
958 expanded_line = self.expand_tag(line, lineno + 1) # humans not 0-based 1125 expanded_line = self.expand_tag(line, lineno + 1) # humans not 0-based
959 if not expanded_line: 1126 if not expanded_line:
960 expanded_line = NormalLine(line.rstrip()) 1127 expanded_line = NormalLine(line.rstrip())
@@ -1141,7 +1308,7 @@ def gather_inputlines(files):
1141 for file in files: 1308 for file in files:
1142 if isinstance(file, SubstrateFile): 1309 if isinstance(file, SubstrateFile):
1143 group = None 1310 group = None
1144 basename = os.path.basename(file.filename) 1311 basename = os.path.basename(file.translated_filename)
1145 1312
1146 codeline = conditional_filename(basename) 1313 codeline = conditional_filename(basename)
1147 if codeline: 1314 if codeline: