xref: /OK3568_Linux_fs/u-boot/tools/patman/tools.py (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun#
2*4882a593Smuzhiyun# Copyright (c) 2016 Google, Inc
3*4882a593Smuzhiyun#
4*4882a593Smuzhiyun# SPDX-License-Identifier:      GPL-2.0+
5*4882a593Smuzhiyun#
6*4882a593Smuzhiyun
7*4882a593Smuzhiyunimport os
8*4882a593Smuzhiyunimport shutil
9*4882a593Smuzhiyunimport tempfile
10*4882a593Smuzhiyun
11*4882a593Smuzhiyunimport tout
12*4882a593Smuzhiyun
13*4882a593Smuzhiyunoutdir = None
14*4882a593Smuzhiyunindirs = None
15*4882a593Smuzhiyunpreserve_outdir = False
16*4882a593Smuzhiyun
17*4882a593Smuzhiyundef PrepareOutputDir(dirname, preserve=False):
18*4882a593Smuzhiyun    """Select an output directory, ensuring it exists.
19*4882a593Smuzhiyun
20*4882a593Smuzhiyun    This either creates a temporary directory or checks that the one supplied
21*4882a593Smuzhiyun    by the user is valid. For a temporary directory, it makes a note to
22*4882a593Smuzhiyun    remove it later if required.
23*4882a593Smuzhiyun
24*4882a593Smuzhiyun    Args:
25*4882a593Smuzhiyun        dirname: a string, name of the output directory to use to store
26*4882a593Smuzhiyun                intermediate and output files. If is None - create a temporary
27*4882a593Smuzhiyun                directory.
28*4882a593Smuzhiyun        preserve: a Boolean. If outdir above is None and preserve is False, the
29*4882a593Smuzhiyun                created temporary directory will be destroyed on exit.
30*4882a593Smuzhiyun
31*4882a593Smuzhiyun    Raises:
32*4882a593Smuzhiyun        OSError: If it cannot create the output directory.
33*4882a593Smuzhiyun    """
34*4882a593Smuzhiyun    global outdir, preserve_outdir
35*4882a593Smuzhiyun
36*4882a593Smuzhiyun    preserve_outdir = dirname or preserve
37*4882a593Smuzhiyun    if dirname:
38*4882a593Smuzhiyun        outdir = dirname
39*4882a593Smuzhiyun        if not os.path.isdir(outdir):
40*4882a593Smuzhiyun            try:
41*4882a593Smuzhiyun                os.makedirs(outdir)
42*4882a593Smuzhiyun            except OSError as err:
43*4882a593Smuzhiyun                raise CmdError("Cannot make output directory '%s': '%s'" %
44*4882a593Smuzhiyun                                (outdir, err.strerror))
45*4882a593Smuzhiyun        tout.Debug("Using output directory '%s'" % outdir)
46*4882a593Smuzhiyun    else:
47*4882a593Smuzhiyun        outdir = tempfile.mkdtemp(prefix='binman.')
48*4882a593Smuzhiyun        tout.Debug("Using temporary directory '%s'" % outdir)
49*4882a593Smuzhiyun
50*4882a593Smuzhiyundef _RemoveOutputDir():
51*4882a593Smuzhiyun    global outdir
52*4882a593Smuzhiyun
53*4882a593Smuzhiyun    shutil.rmtree(outdir)
54*4882a593Smuzhiyun    tout.Debug("Deleted temporary directory '%s'" % outdir)
55*4882a593Smuzhiyun    outdir = None
56*4882a593Smuzhiyun
57*4882a593Smuzhiyundef FinaliseOutputDir():
58*4882a593Smuzhiyun    global outdir, preserve_outdir
59*4882a593Smuzhiyun
60*4882a593Smuzhiyun    """Tidy up: delete output directory if temporary and not preserved."""
61*4882a593Smuzhiyun    if outdir and not preserve_outdir:
62*4882a593Smuzhiyun        _RemoveOutputDir()
63*4882a593Smuzhiyun
64*4882a593Smuzhiyundef GetOutputFilename(fname):
65*4882a593Smuzhiyun    """Return a filename within the output directory.
66*4882a593Smuzhiyun
67*4882a593Smuzhiyun    Args:
68*4882a593Smuzhiyun        fname: Filename to use for new file
69*4882a593Smuzhiyun
70*4882a593Smuzhiyun    Returns:
71*4882a593Smuzhiyun        The full path of the filename, within the output directory
72*4882a593Smuzhiyun    """
73*4882a593Smuzhiyun    return os.path.join(outdir, fname)
74*4882a593Smuzhiyun
75*4882a593Smuzhiyundef _FinaliseForTest():
76*4882a593Smuzhiyun    """Remove the output directory (for use by tests)"""
77*4882a593Smuzhiyun    global outdir
78*4882a593Smuzhiyun
79*4882a593Smuzhiyun    if outdir:
80*4882a593Smuzhiyun        _RemoveOutputDir()
81*4882a593Smuzhiyun
82*4882a593Smuzhiyundef SetInputDirs(dirname):
83*4882a593Smuzhiyun    """Add a list of input directories, where input files are kept.
84*4882a593Smuzhiyun
85*4882a593Smuzhiyun    Args:
86*4882a593Smuzhiyun        dirname: a list of paths to input directories to use for obtaining
87*4882a593Smuzhiyun                files needed by binman to place in the image.
88*4882a593Smuzhiyun    """
89*4882a593Smuzhiyun    global indir
90*4882a593Smuzhiyun
91*4882a593Smuzhiyun    indir = dirname
92*4882a593Smuzhiyun    tout.Debug("Using input directories %s" % indir)
93*4882a593Smuzhiyun
94*4882a593Smuzhiyundef GetInputFilename(fname):
95*4882a593Smuzhiyun    """Return a filename for use as input.
96*4882a593Smuzhiyun
97*4882a593Smuzhiyun    Args:
98*4882a593Smuzhiyun        fname: Filename to use for new file
99*4882a593Smuzhiyun
100*4882a593Smuzhiyun    Returns:
101*4882a593Smuzhiyun        The full path of the filename, within the input directory
102*4882a593Smuzhiyun    """
103*4882a593Smuzhiyun    if not indir:
104*4882a593Smuzhiyun        return fname
105*4882a593Smuzhiyun    for dirname in indir:
106*4882a593Smuzhiyun        pathname = os.path.join(dirname, fname)
107*4882a593Smuzhiyun        if os.path.exists(pathname):
108*4882a593Smuzhiyun            return pathname
109*4882a593Smuzhiyun
110*4882a593Smuzhiyun    raise ValueError("Filename '%s' not found in input path (%s)" %
111*4882a593Smuzhiyun                     (fname, ','.join(indir)))
112*4882a593Smuzhiyun
113*4882a593Smuzhiyundef Align(pos, align):
114*4882a593Smuzhiyun    if align:
115*4882a593Smuzhiyun        mask = align - 1
116*4882a593Smuzhiyun        pos = (pos + mask) & ~mask
117*4882a593Smuzhiyun    return pos
118*4882a593Smuzhiyun
119*4882a593Smuzhiyundef NotPowerOfTwo(num):
120*4882a593Smuzhiyun    return num and (num & (num - 1))
121