Path: blob/21.2-virgl/src/gallium/drivers/swr/rasterizer/codegen/gen_common.py
4574 views
# Copyright (C) 2014-2018 Intel Corporation. All Rights Reserved.1#2# Permission is hereby granted, free of charge, to any person obtaining a3# copy of this software and associated documentation files (the "Software"),4# to deal in the Software without restriction, including without limitation5# the rights to use, copy, modify, merge, publish, distribute, sublicense,6# and/or sell copies of the Software, and to permit persons to whom the7# Software is furnished to do so, subject to the following conditions:8#9# The above copyright notice and this permission notice (including the next10# paragraph) shall be included in all copies or substantial portions of the11# Software.12#13# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR14# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,15# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL16# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER17# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING18# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS19# IN THE SOFTWARE.2021# Python source22from __future__ import print_function23import os24import errno25import sys26import argparse27import tempfile28import filecmp29import shutil30from mako.template import Template31from mako.exceptions import RichTraceback3233#==============================================================================34def ConcatLists(list_of_lists):35output = []36for l in list_of_lists: output += l37return output3839#==============================================================================40def MakeTmpDir(suffix=''):41'''42Create temporary directory for use in codegen scripts.43'''44return tempfile.mkdtemp(suffix)4546#==============================================================================47def MakeDir(dir_path):48'''49Create a directory if it doesn't exist5051returns 0 on success, non-zero on failure52'''53dir_path = os.path.abspath(dir_path)5455if not os.path.exists(dir_path):56try:57os.makedirs(dir_path)58except OSError as err:59if err.errno != errno.EEXIST:60return 161else:62if not os.path.isdir(dir_path):63return 16465return 06667#==============================================================================68def DeleteDirTree(dir_path):69'''70Delete directory tree.7172returns 0 on success, non-zero on failure73'''74rval = 075try:76shutil.rmtree(dir_path, False)77except:78rval = 179return rval8081#==============================================================================82def CopyFileIfDifferent(src, dst, verbose = False):83'''84Copy <src> file to <dst> file if the <dst>85file either doesn't contain the file or the file86contents are different.8788returns 0 on success, non-zero on failure89'''9091assert os.path.isfile(src)92assert (False == os.path.exists(dst) or os.path.isfile(dst))9394need_copy = not os.path.exists(dst)95if not need_copy:96need_copy = not filecmp.cmp(src, dst)9798if need_copy:99try:100shutil.copy2(src, dst)101except:102print('ERROR: Could not copy %s to %s' % (src, dst), file=sys.stderr)103return 1104105if verbose:106print(src, '-->', dst)107108return 0109110#==============================================================================111def CopyDirFilesIfDifferent(src, dst, recurse = True, verbose = False, orig_dst = None):112'''113Copy files <src> directory to <dst> directory if the <dst>114directory either doesn't contain the file or the file115contents are different.116117Optionally recurses into subdirectories118119returns 0 on success, non-zero on failure120'''121122assert os.path.isdir(src)123assert os.path.isdir(dst)124125src = os.path.abspath(src)126dst = os.path.abspath(dst)127128if not orig_dst:129orig_dst = dst130131for f in os.listdir(src):132src_path = os.path.join(src, f)133dst_path = os.path.join(dst, f)134135# prevent recursion136if src_path == orig_dst:137continue138139if os.path.isdir(src_path):140if recurse:141if MakeDir(dst_path):142print('ERROR: Could not create directory:', dst_path, file=sys.stderr)143return 1144145if verbose:146print('mkdir', dst_path)147rval = CopyDirFilesIfDifferent(src_path, dst_path, recurse, verbose, orig_dst)148else:149rval = CopyFileIfDifferent(src_path, dst_path, verbose)150151if rval:152return rval153154return 0155156#==============================================================================157class MakoTemplateWriter:158'''159MakoTemplateWriter - Class (namespace) for functions to generate strings160or files using the Mako template module.161162See http://docs.makotemplates.org/en/latest/ for163mako documentation.164'''165166@staticmethod167def to_string(template_filename, **kwargs):168'''169Write template data to a string object and return the string170'''171from mako.template import Template172from mako.exceptions import RichTraceback173174try:175template = Template(filename=template_filename)176# Split + Join fixes line-endings for whatever platform you are using177return '\n'.join(template.render(**kwargs).splitlines())178except:179traceback = RichTraceback()180for (filename, lineno, function, line) in traceback.traceback:181print('File %s, line %s, in %s' % (filename, lineno, function))182print(line, '\n')183print('%s: %s' % (str(traceback.error.__class__.__name__), traceback.error))184raise185186@staticmethod187def to_file(template_filename, output_filename, **kwargs):188'''189Write template data to a file190'''191if MakeDir(os.path.dirname(output_filename)):192return 1193with open(output_filename, 'w') as outfile:194print(MakoTemplateWriter.to_string(template_filename, **kwargs), file=outfile)195return 0196197198#==============================================================================199class ArgumentParser(argparse.ArgumentParser):200'''201Subclass of argparse.ArgumentParser202203Allow parsing from command files that start with @204Example:205>bt run @myargs.txt206207Contents of myargs.txt:208-m <machine>209--target cdv_win7210211The below function allows multiple args to be placed on the same text-file line.212The default is one token per line, which is a little cumbersome.213214Also allow all characters after a '#' character to be ignored.215'''216217#==============================================================================218class _HelpFormatter(argparse.RawTextHelpFormatter):219''' Better help formatter for argument parser '''220221def _split_lines(self, text, width):222''' optimized split lines algorithm, indents split lines '''223lines = text.splitlines()224out_lines = []225if len(lines):226out_lines.append(lines[0])227for line in lines[1:]:228out_lines.append(' ' + line)229return out_lines230231#==============================================================================232def __init__(self, *args, **kwargs):233''' Constructor. Compatible with argparse.ArgumentParser(),234but with some modifications for better usage and help display.235'''236super(ArgumentParser, self).__init__(237*args,238fromfile_prefix_chars='@',239formatter_class=ArgumentParser._HelpFormatter,240**kwargs)241242#==========================================================================243def convert_arg_line_to_args(self, arg_line):244''' convert one line of parsed file to arguments '''245arg_line = arg_line.split('#', 1)[0]246if sys.platform == 'win32':247arg_line = arg_line.replace('\\', '\\\\')248for arg in shlex.split(arg_line):249if not arg.strip():250continue251yield arg252253#==========================================================================254def _read_args_from_files(self, arg_strings):255''' read arguments from files '''256# expand arguments referencing files257new_arg_strings = []258for arg_string in arg_strings:259260# for regular arguments, just add them back into the list261if arg_string[0] not in self.fromfile_prefix_chars:262new_arg_strings.append(arg_string)263264# replace arguments referencing files with the file content265else:266filename = arg_string[1:]267268# Search in sys.path269if not os.path.exists(filename):270for path in sys.path:271filename = os.path.join(path, arg_string[1:])272if os.path.exists(filename):273break274275try:276args_file = open(filename)277try:278arg_strings = []279for arg_line in args_file.read().splitlines():280for arg in self.convert_arg_line_to_args(arg_line):281arg_strings.append(arg)282arg_strings = self._read_args_from_files(arg_strings)283new_arg_strings.extend(arg_strings)284finally:285args_file.close()286except IOError:287err = sys.exc_info()[1]288self.error(str(err))289290# return the modified argument list291return new_arg_strings292293294