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