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