1# 2# File : utils.py 3# This file is part of RT-Thread RTOS 4# COPYRIGHT (C) 2006 - 2015, RT-Thread Development Team 5# 6# This program is free software; you can redistribute it and/or modify 7# it under the terms of the GNU General Public License as published by 8# the Free Software Foundation; either version 2 of the License, or 9# (at your option) any later version. 10# 11# This program is distributed in the hope that it will be useful, 12# but WITHOUT ANY WARRANTY; without even the implied warranty of 13# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14# GNU General Public License for more details. 15# 16# You should have received a copy of the GNU General Public License along 17# with this program; if not, write to the Free Software Foundation, Inc., 18# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 19# 20# Change Logs: 21# Date Author Notes 22# 2015-01-20 Bernard Add copyright information 23# 24 25import sys 26import os 27 28def splitall(loc): 29 """ 30 Return a list of the path components in loc. (Used by relpath_). 31 32 The first item in the list will be either ``os.curdir``, ``os.pardir``, empty, 33 or the root directory of loc (for example, ``/`` or ``C:\\). 34 35 The other items in the list will be strings. 36 37 Adapted from *path.py* by Jason Orendorff. 38 """ 39 parts = [] 40 while loc != os.curdir and loc != os.pardir: 41 prev = loc 42 loc, child = os.path.split(prev) 43 if loc == prev: 44 break 45 parts.append(child) 46 parts.append(loc) 47 parts.reverse() 48 return parts 49 50def _make_path_relative(origin, dest): 51 """ 52 Return the relative path between origin and dest. 53 54 If it's not possible return dest. 55 56 57 If they are identical return ``os.curdir`` 58 59 Adapted from `path.py <http://www.jorendorff.com/articles/python/path/>`_ by Jason Orendorff. 60 """ 61 origin = os.path.abspath(origin).replace('\\', '/') 62 dest = os.path.abspath(dest).replace('\\', '/') 63 # 64 orig_list = splitall(os.path.normcase(origin)) 65 # Don't normcase dest! We want to preserve the case. 66 dest_list = splitall(dest) 67 # 68 if orig_list[0] != os.path.normcase(dest_list[0]): 69 # Can't get here from there. 70 return dest 71 # 72 # Find the location where the two paths start to differ. 73 i = 0 74 for start_seg, dest_seg in zip(orig_list, dest_list): 75 if start_seg != os.path.normcase(dest_seg): 76 break 77 i += 1 78 # 79 # Now i is the point where the two paths diverge. 80 # Need a certain number of "os.pardir"s to work up 81 # from the origin to the point of divergence. 82 segments = [os.pardir] * (len(orig_list) - i) 83 # Need to add the diverging part of dest_list. 84 segments += dest_list[i:] 85 if len(segments) == 0: 86 # If they happen to be identical, use os.curdir. 87 return os.curdir 88 else: 89 # return os.path.join(*segments).replace('\\', '/') 90 return os.path.join(*segments) 91 92def xml_indent(elem, level=0): 93 i = "\n" + level*" " 94 if len(elem): 95 if not elem.text or not elem.text.strip(): 96 elem.text = i + " " 97 if not elem.tail or not elem.tail.strip(): 98 elem.tail = i 99 for elem in elem: 100 xml_indent(elem, level+1) 101 if not elem.tail or not elem.tail.strip(): 102 elem.tail = i 103 else: 104 if level and (not elem.tail or not elem.tail.strip()): 105 elem.tail = i 106 107 108source_ext = ["c", "h", "s", "S", "cpp", "xpm"] 109source_list = [] 110 111def walk_children(child): 112 global source_list 113 global source_ext 114 115 # print child 116 full_path = child.rfile().abspath 117 file_type_list = full_path.rsplit('.',1) 118 #print file_type 119 if (len(file_type_list) > 1): 120 file_type = full_path.rsplit('.',1)[1] 121 122 if file_type in source_ext: 123 if full_path not in source_list: 124 source_list.append(full_path) 125 126 children = child.all_children() 127 if children != []: 128 for item in children: 129 walk_children(item) 130 131def PrefixPath(prefix, path): 132 path = os.path.abspath(path) 133 prefix = os.path.abspath(prefix) 134 135 if sys.platform == 'win32': 136 prefix = prefix.lower() 137 path = path.lower() 138 139 if path.startswith(prefix): 140 return True 141 142 return False 143 144def ListMap(l): 145 ret_list = [] 146 for item in l: 147 if type(item) == type(()): 148 ret = ListMap(item) 149 ret_list += ret 150 elif type(item) == type([]): 151 ret = ListMap(item) 152 ret_list += ret 153 else: 154 ret_list.append(item) 155 156 return ret_list 157 158def TargetGetList(env, postfix): 159 global source_ext 160 global source_list 161 162 target = env['target'] 163 164 source_ext = postfix 165 for item in target: 166 walk_children(item) 167 168 source_list.sort() 169 170 return source_list 171 172def ProjectInfo(env): 173 174 project = env['project'] 175 RTT_ROOT = env['RTT_ROOT'] 176 BSP_ROOT = env['BSP_ROOT'] 177 178 FILES = [] 179 DIRS = [] 180 HEADERS = [] 181 CPPPATH = [] 182 CPPDEFINES = [] 183 184 for group in project: 185 # get each files 186 if 'src' in group and group['src']: 187 FILES += group['src'] 188 189 # get each include path 190 if 'CPPPATH' in group and group['CPPPATH']: 191 CPPPATH += group['CPPPATH'] 192 193 if 'CPPDEFINES' in env: 194 CPPDEFINES = env['CPPDEFINES'] 195 CPPDEFINES = ListMap(CPPDEFINES) 196 197 # process FILES and DIRS 198 if len(FILES): 199 # use absolute path 200 for i in range(len(FILES)): 201 FILES[i] = os.path.abspath(str(FILES[i])) 202 DIRS.append(os.path.dirname(FILES[i])) 203 204 FILES.sort() 205 DIRS = list(set(DIRS)) 206 DIRS.sort() 207 208 # process HEADERS 209 HEADERS = TargetGetList(env, ['h']) 210 211 # process CPPPATH 212 if len(CPPPATH): 213 # use absolute path 214 for i in range(len(CPPPATH)): 215 CPPPATH[i] = os.path.abspath(CPPPATH[i]) 216 217 # remove repeat path 218 paths = [i for i in set(CPPPATH)] 219 CPPPATH = [] 220 for path in paths: 221 if PrefixPath(RTT_ROOT, path): 222 CPPPATH += [os.path.abspath(path).replace('\\', '/')] 223 224 elif PrefixPath(BSP_ROOT, path): 225 CPPPATH += [os.path.abspath(path).replace('\\', '/')] 226 227 else: 228 CPPPATH += ['"%s",' % path.replace('\\', '/')] 229 230 CPPPATH.sort() 231 232 # process CPPDEFINES 233 if len(CPPDEFINES): 234 CPPDEFINES = [i for i in set(CPPDEFINES)] 235 236 CPPDEFINES.sort() 237 238 proj = {} 239 proj['FILES'] = FILES 240 proj['DIRS'] = DIRS 241 proj['HEADERS'] = HEADERS 242 proj['CPPPATH'] = CPPPATH 243 proj['CPPDEFINES'] = CPPDEFINES 244 245 return proj 246 247def VersionCmp(ver1, ver2): 248 la=[]; 249 if ver1: 250 la = ver1.split('.') 251 lb = ver2.split('.') 252 f = 0 253 if len(la) > len(lb): 254 f = len(la) 255 else: 256 f = len(lb) 257 for i in range(f): 258 try: 259 if int(la[i]) > int(lb[i]): 260 return 1 261 elif int(la[i]) == int(lb[i]): 262 continue 263 else: 264 return -1 265 except IndexError as e: 266 if len(la) > len(lb): 267 return 1 268 else: 269 return -1 270 return 0 271 272def GCCC99Patch(cflags): 273 import building 274 gcc_version = building.GetDepend('GCC_VERSION') 275 if gcc_version: 276 gcc_version = gcc_version.replace('"', '') 277 if VersionCmp(gcc_version, "4.8.0"): 278 # remove -std=c99 after GCC 4.8.x 279 cflags = cflags.replace('-std=c99', '') 280 281 return cflags 282 283def ReloadModule(module): 284 import sys 285 if sys.version_info.major >= 3: 286 import importlib 287 importlib.reload(module) 288 else: 289 reload(module) 290 291 return 292