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