files: # Copyright 2012-2017 The Meson development team
  
  # Licensed under the Apache License, Version 2.0 (the "License");
  # you may not use this file except in compliance with the License.
  # You may obtain a copy of the License at
  
  #     http://www.apache.org/licenses/LICENSE-2.0
  
  # Unless required by applicable law or agreed to in writing, software
  # distributed under the License is distributed on an "AS IS" BASIS,
  # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  # See the License for the specific language governing permissions and
  # limitations under the License.
  
  import os, pickle, re, shlex, subprocess
  from collections import OrderedDict
  import itertools
  from pathlib import PurePath
  
  from . import backends
  from .. import modules
  from .. import environment, mesonlib
  from .. import build
  from .. import mlog
  from .. import dependencies
  from .. import compilers
  from ..compilers import CompilerArgs
  from ..linkers import ArLinker
  from ..mesonlib import File, MesonException, OrderedSet
  from ..mesonlib import get_compiler_for_source, has_path_sep
  from .backends import CleanTrees, InstallData
  from ..build import InvalidArguments
  
  if mesonlib.is_windows():
      quote_func = lambda s: '"{}"'.format(s)
      execute_wrapper = 'cmd /c'
      rmfile_prefix = 'del /f /s /q {} &&'
  else:
      quote_func = shlex.quote
      execute_wrapper = ''
      rmfile_prefix = 'rm -f {} &&'
  
  def ninja_quote(text, is_build_line=False):
      if is_build_line:
          qcs = ('$', ' ', ':')
      else:
          qcs = ('$', ' ')
      for char in qcs:
          text = text.replace(char, '$' + char)
      if '\n' in text:
          errmsg = '''Ninja does not support newlines in rules. The content was:
  
  %s
  
  Please report this error with a test case to the Meson bug tracker.''' % text
          raise MesonException(errmsg)
      return text
  
  
  class NinjaBuildElement:
      def __init__(self, all_outputs, outfilenames, rule, infilenames):
          if isinstance(outfilenames, str):
              self.outfilenames = [outfilenames]
          else:
              self.outfilenames = outfilenames
          assert(isinstance(rule, str))
          self.rule = rule
          if isinstance(infilenames, str):
              self.infilenames = [infilenames]
          else:
              self.infilenames = infilenames
          self.deps = set()
          self.orderdeps = set()
          self.elems = []
          self.all_outputs = all_outputs
  
      def add_dep(self, dep):
          if isinstance(dep, list):
              self.deps.update(dep)
          else:
              self.deps.add(dep)
  
      def add_orderdep(self, dep):
          if isinstance(dep, list):
              self.orderdeps.update(dep)
          else:
              self.orderdeps.add(dep)
  
      def add_item(self, name, elems):
          if isinstance(elems, str):
              elems = [elems]
          self.elems.append((name, elems))
  
      def write(self, outfile):
          self.check_outputs()
          line = 'build %s: %s %s' % (' '.join([ninja_quote(i, True) for i in self.outfilenames]),
                                      self.rule,
                                      ' '.join([ninja_quote(i, True) for i in self.infilenames]))
          if len(self.deps) > 0:
              line += ' | ' + ' '.join([ninja_quote(x, True) for x in self.deps])
          if len(self.orderdeps) > 0:
              line += ' || ' + ' '.join([ninja_quote(x, True) for x in self.orderdeps])
          line += '\n'
          # This is the only way I could find to make this work on all
          # platforms including Windows command shell. Slash is a dir separator
          # on Windows, too, so all characters are unambiguous and, more importantly,
          # do not require quoting, unless explicitely specified, which is necessary for
          # the csc compiler.
          line = line.replace('\\', '/')
          outfile.write(line)
  
          # All the entries that should remain unquoted
          raw_names = {'DEP
  
  [... the rest is omitted ...]
files: mesonbuild/backend/ninjabackend.py
files: # Copyright 2012-2017 The Meson development team
  
  # Licensed under the Apache License, Version 2.0 (the "License");
  # you may not use this file except in compliance with the License.
  # You may obtain a copy of the License at
  
  #     http://www.apache.org/licenses/LICENSE-2.0
  
  # Unless required by applicable law or agreed to in writing, software
  # distributed under the License is distributed on an "AS IS" BASIS,
  # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  # See the License for the specific language governing permissions and
  # limitations under the License.
  
  import os, pickle, re, shlex, subprocess
  from collections import OrderedDict
  import itertools
  from pathlib import PurePath
  
  from . import backends
  from .. import modules
  from .. import environment, mesonlib
  from .. import build
  from .. import mlog
  from .. import dependencies
  from .. import compilers
  from ..compilers import CompilerArgs
  from ..linkers import ArLinker
  from ..mesonlib import File, MesonException, OrderedSet
  from ..mesonlib import get_compiler_for_source, has_path_sep
  from .backends import CleanTrees, InstallData
  from ..build import InvalidArguments
  
  if mesonlib.is_windows():
      quote_func = lambda s: '"{}"'.format(s)
      execute_wrapper = 'cmd /c'
      rmfile_prefix = 'del /f /s /q {} &&'
  else:
      quote_func = shlex.quote
      execute_wrapper = ''
      rmfile_prefix = 'rm -f {} &&'
  
  def ninja_quote(text, is_build_line=False):
      if is_build_line:
          qcs = ('$', ' ', ':')
      else:
          qcs = ('$', ' ')
      for char in qcs:
          text = text.replace(char, '$' + char)
      if '\n' in text:
          errmsg = '''Ninja does not support newlines in rules. The content was:
  
  %s
  
  Please report this error with a test case to the Meson bug tracker.''' % text
          raise MesonException(errmsg)
      return text
  
  
  class NinjaBuildElement:
      def __init__(self, all_outputs, outfilenames, rule, infilenames):
          if isinstance(outfilenames, str):
              self.outfilenames = [outfilenames]
          else:
              self.outfilenames = outfilenames
          assert(isinstance(rule, str))
          self.rule = rule
          if isinstance(infilenames, str):
              self.infilenames = [infilenames]
          else:
              self.infilenames = infilenames
          self.deps = set()
          self.orderdeps = set()
          self.elems = []
          self.all_outputs = all_outputs
  
      def add_dep(self, dep):
          if isinstance(dep, list):
              self.deps.update(dep)
          else:
              self.deps.add(dep)
  
      def add_orderdep(self, dep):
          if isinstance(dep, list):
              self.orderdeps.update(dep)
          else:
              self.orderdeps.add(dep)
  
      def add_item(self, name, elems):
          if isinstance(elems, str):
              elems = [elems]
          self.elems.append((name, elems))
  
      def write(self, outfile):
          self.check_outputs()
          line = 'build %s: %s %s' % (' '.join([ninja_quote(i, True) for i in self.outfilenames]),
                                      self.rule,
                                      ' '.join([ninja_quote(i, True) for i in self.infilenames]))
          if len(self.deps) > 0:
              line += ' | ' + ' '.join([ninja_quote(x, True) for x in self.deps])
          if len(self.orderdeps) > 0:
              line += ' || ' + ' '.join([ninja_quote(x, True) for x in self.orderdeps])
          line += '\n'
          # This is the only way I could find to make this work on all
          # platforms including Windows command shell. Slash is a dir separator
          # on Windows, too, so all characters are unambiguous and, more importantly,
          # do not require quoting, unless explicitely specified, which is necessary for
          # the csc compiler.
          line = line.replace('\\', '/')
          outfile.write(line)
  
          # All the entries that should remain unquoted
          raw_names = {'DEP
  
  [... the rest is omitted ...]
files: mesonbuild/backend/ninjabackend.py
files: # Copyright 2012-2017 The Meson development team
  
  # Licensed under the Apache License, Version 2.0 (the "License");
  # you may not use this file except in compliance with the License.
  # You may obtain a copy of the License at
  
  #     http://www.apache.org/licenses/LICENSE-2.0
  
  # Unless required by applicable law or agreed to in writing, software
  # distributed under the License is distributed on an "AS IS" BASIS,
  # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  # See the License for the specific language governing permissions and
  # limitations under the License.
  
  import copy, os, re
  from collections import OrderedDict
  import itertools, pathlib
  import pickle
  
  from . import environment
  from . import dependencies
  from . import mlog
  from .mesonlib import File, MesonException, listify, extract_as_list
  from .mesonlib import typeslistify, stringlistify, classify_unity_sources
  from .mesonlib import get_filenames_templates_dict, substitute_values
  from .mesonlib import for_windows, for_darwin, for_cygwin, for_android, has_path_sep
  from .compilers import is_object, clike_langs, sort_clike, lang_suffixes
  from .interpreterbase import FeatureNew, FeatureNewKwargs
  
  pch_kwargs = set(['c_pch', 'cpp_pch'])
  
  lang_arg_kwargs = set([
      'c_args',
      'cpp_args',
      'd_args',
      'd_import_dirs',
      'd_unittest',
      'd_module_versions',
      'fortran_args',
      'java_args',
      'objc_args',
      'objcpp_args',
      'rust_args',
      'vala_args',
      'cs_args',
  ])
  
  vala_kwargs = set(['vala_header', 'vala_gir', 'vala_vapi'])
  rust_kwargs = set(['rust_crate_type'])
  cs_kwargs = set(['resources', 'cs_args'])
  
  buildtarget_kwargs = set([
      'build_by_default',
      'build_rpath',
      'dependencies',
      'extra_files',
      'gui_app',
      'link_with',
      'link_whole',
      'link_args',
      'link_depends',
      'implicit_include_directories',
      'include_directories',
      'install',
      'install_rpath',
      'install_dir',
      'install_mode',
      'name_prefix',
      'name_suffix',
      'native',
      'objects',
      'override_options',
      'sources',
  ])
  
  known_build_target_kwargs = (
      buildtarget_kwargs |
      lang_arg_kwargs |
      pch_kwargs |
      vala_kwargs |
      rust_kwargs |
      cs_kwargs)
  
  known_exe_kwargs = known_build_target_kwargs | {'implib', 'export_dynamic'}
  known_shlib_kwargs = known_build_target_kwargs | {'version', 'soversion', 'vs_module_defs'}
  known_shmod_kwargs = known_build_target_kwargs
  known_stlib_kwargs = known_build_target_kwargs | {'pic'}
  known_jar_kwargs = known_exe_kwargs | {'main_class'}
  
  class InvalidArguments(MesonException):
      pass
  
  class Build:
      """A class that holds the status of one build including
      all dependencies and so on.
      """
  
      def __init__(self, environment):
          self.project_name = 'name of master project'
          self.project_version = None
          self.environment = environment
          self.projects = {}
          self.targets = OrderedDict()
          self.compilers = OrderedDict()
          self.cross_compilers = OrderedDict()
          self.global_args = {}
          self.projects_args = {}
          self.global_link_args = {}
          self.projects_link_args = {}
          self.tests = []
          self.benchmarks = []
          self.headers = []
          self.man = []
          self.data = []
          self.static_linker = None
          self.static_cross_linker = None
          self.subprojects = {}
          self.subproject_dir = ''
          self.install_scripts = []
          self.postconf_scripts = []
          self.install_dirs = []
          self.dep_manifest_name = None
          self.dep_manifest = {}
          self.cross_stdlibs = {}
          self.test_setups = {}
          self.find_overrides = {}
          self.searched_programs = set() # The list of all programs that have been
  
  [... the rest is omitted ...]
files: mesonbuild/build.py
files: # Copyright 2012-2017 The Meson development team
  
  # Licensed under the Apache License, Version 2.0 (the "License");
  # you may not use this file except in compliance with the License.
  # You may obtain a copy of the License at
  
  #     http://www.apache.org/licenses/LICENSE-2.0
  
  # Unless required by applicable law or agreed to in writing, software
  # distributed under the License is distributed on an "AS IS" BASIS,
  # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  # See the License for the specific language governing permissions and
  # limitations under the License.
  
  import copy, os, re
  from collections import OrderedDict
  import itertools, pathlib
  import pickle
  
  from . import environment
  from . import dependencies
  from . import mlog
  from .mesonlib import File, MesonException, listify, extract_as_list
  from .mesonlib import typeslistify, stringlistify, classify_unity_sources
  from .mesonlib import get_filenames_templates_dict, substitute_values
  from .mesonlib import for_windows, for_darwin, for_cygwin, for_android, has_path_sep
  from .compilers import is_object, clike_langs, sort_clike, lang_suffixes
  from .interpreterbase import FeatureNew, FeatureNewKwargs
  
  pch_kwargs = set(['c_pch', 'cpp_pch'])
  
  lang_arg_kwargs = set([
      'c_args',
      'cpp_args',
      'd_args',
      'd_import_dirs',
      'd_unittest',
      'd_module_versions',
      'fortran_args',
      'java_args',
      'objc_args',
      'objcpp_args',
      'rust_args',
      'vala_args',
      'cs_args',
  ])
  
  vala_kwargs = set(['vala_header', 'vala_gir', 'vala_vapi'])
  rust_kwargs = set(['rust_crate_type'])
  cs_kwargs = set(['resources', 'cs_args'])
  
  buildtarget_kwargs = set([
      'build_by_default',
      'build_rpath',
      'dependencies',
      'extra_files',
      'gui_app',
      'link_with',
      'link_whole',
      'link_args',
      'link_depends',
      'implicit_include_directories',
      'include_directories',
      'install',
      'install_rpath',
      'install_dir',
      'name_prefix',
      'name_suffix',
      'native',
      'objects',
      'override_options',
      'sources',
  ])
  
  known_build_target_kwargs = (
      buildtarget_kwargs |
      lang_arg_kwargs |
      pch_kwargs |
      vala_kwargs |
      rust_kwargs |
      cs_kwargs)
  
  known_exe_kwargs = known_build_target_kwargs | {'implib', 'export_dynamic'}
  known_shlib_kwargs = known_build_target_kwargs | {'version', 'soversion', 'vs_module_defs'}
  known_shmod_kwargs = known_build_target_kwargs
  known_stlib_kwargs = known_build_target_kwargs | {'pic'}
  known_jar_kwargs = known_exe_kwargs | {'main_class'}
  
  class InvalidArguments(MesonException):
      pass
  
  class Build:
      """A class that holds the status of one build including
      all dependencies and so on.
      """
  
      def __init__(self, environment):
          self.project_name = 'name of master project'
          self.project_version = None
          self.environment = environment
          self.projects = {}
          self.targets = OrderedDict()
          self.compilers = OrderedDict()
          self.cross_compilers = OrderedDict()
          self.global_args = {}
          self.projects_args = {}
          self.global_link_args = {}
          self.projects_link_args = {}
          self.tests = []
          self.benchmarks = []
          self.headers = []
          self.man = []
          self.data = []
          self.static_linker = None
          self.static_cross_linker = None
          self.subprojects = {}
          self.subproject_dir = ''
          self.install_scripts = []
          self.postconf_scripts = []
          self.install_dirs = []
          self.dep_manifest_name = None
          self.dep_manifest = {}
          self.cross_stdlibs = {}
          self.test_setups = {}
          self.find_overrides = {}
          self.searched_programs = set() # The list of all programs that have been searched for.
  
      def
  
  [... the rest is omitted ...]
files: mesonbuild/build.py
files: # Copyright 2012-2018 The Meson development team
  # Licensed under the Apache License, Version 2.0 (the "License");
  # you may not use this file except in compliance with the License.
  # You may obtain a copy of the License at
  
  #     http://www.apache.org/licenses/LICENSE-2.0
  
  # Unless required by applicable law or agreed to in writing, software
  # distributed under the License is distributed on an "AS IS" BASIS,
  # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  # See the License for the specific language governing permissions and
  # limitations under the License.
  
  from . import mparser
  from . import environment
  from . import coredata
  from . import dependencies
  from . import mlog
  from . import build
  from . import optinterpreter
  from . import compilers
  from .wrap import wrap, WrapMode
  from . import mesonlib
  from .mesonlib import FileMode, Popen_safe, listify, extract_as_list, has_path_sep
  from .dependencies import ExternalProgram
  from .dependencies import InternalDependency, Dependency, NotFoundDependency, DependencyException
  from .interpreterbase import InterpreterBase
  from .interpreterbase import check_stringlist, flatten, noPosargs, noKwargs, stringArgs, permittedKwargs, noArgsFlattening
  from .interpreterbase import InterpreterException, InvalidArguments, InvalidCode, SubdirDoneRequest
  from .interpreterbase import InterpreterObject, MutableInterpreterObject, Disabler
  from .interpreterbase import FeatureNew, FeatureDeprecated, FeatureNewKwargs
  from .modules import ModuleReturnValue
  
  import os, sys, shutil, uuid
  import re, shlex
  from collections import namedtuple
  from pathlib import PurePath
  
  import importlib
  
  permitted_method_kwargs = {
      'partial_dependency': {'compile_args', 'link_args', 'links', 'includes',
                             'sources'},
  }
  
  def stringifyUserArguments(args):
      if isinstance(args, list):
          return '[%s]' % ', '.join([stringifyUserArguments(x) for x in args])
      elif isinstance(args, dict):
          return '{%s}' % ', '.join(['%s : %s' % (stringifyUserArguments(k), stringifyUserArguments(v)) for k, v in args.items()])
      elif isinstance(args, int):
          return str(args)
      elif isinstance(args, str):
          return "'%s'" % args
      raise InvalidArguments('Function accepts only strings, integers, lists and lists thereof.')
  
  
  class ObjectHolder:
      def __init__(self, obj):
          self.held_object = obj
  
      def __repr__(self):
          return '<Holder: {!r}>'.format(self.held_object)
  
  
  class TryRunResultHolder(InterpreterObject):
      def __init__(self, res):
          super().__init__()
          self.res = res
          self.methods.update({'returncode': self.returncode_method,
                               'compiled': self.compiled_method,
                               'stdout': self.stdout_method,
                               'stderr': self.stderr_method,
                               })
  
      @noPosargs
      @permittedKwargs({})
      def returncode_method(self, args, kwargs):
          return self.res.returncode
  
      @noPosargs
      @permittedKwargs({})
      def compiled_method(self, args, kwargs):
          return self.res.compiled
  
      @noPosargs
      @permittedKwargs({})
      def stdout_method(self, args, kwargs):
          return self.res.stdout
  
      @noPosargs
      @permittedKwargs({})
      def stderr_method(self, args, kwargs):
          return self.res.stderr
  
  class RunProcess(InterpreterObject):
  
      def __init__(self, cmd, args, source_dir, build_dir, subdir, mesonintrospect, in_builddir=False, check=False):
          super().__init__()
          if not isinstance(cmd, ExternalProgram):
              raise AssertionError('BUG: RunProcess must be passed an ExternalProgram')
          pc, self.stdout, self.stderr = self.run_command(cmd, args, source_dir, build_dir, subdir, mesonintrospect, in_builddir, check)
          self.returncode = pc.returncode
          self.methods.update({'returncode': self.returncode_method,
                               'stdout': self.stdout_method,
                               'stderr': self.stderr_method,
                               })
  
      def run_command(self, cmd, args, source_dir, build_dir, subdir, mesonintrospect, in_builddir, check=False):
          command_array = cmd.get_command
  
  [... the rest is omitted ...]
files: mesonbuild/interpreter.py
files: # Copyright 2012-2018 The Meson development team
  # Licensed under the Apache License, Version 2.0 (the "License");
  # you may not use this file except in compliance with the License.
  # You may obtain a copy of the License at
  
  #     http://www.apache.org/licenses/LICENSE-2.0
  
  # Unless required by applicable law or agreed to in writing, software
  # distributed under the License is distributed on an "AS IS" BASIS,
  # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  # See the License for the specific language governing permissions and
  # limitations under the License.
  
  from . import mparser
  from . import environment
  from . import coredata
  from . import dependencies
  from . import mlog
  from . import build
  from . import optinterpreter
  from . import compilers
  from .wrap import wrap, WrapMode
  from . import mesonlib
  from .mesonlib import FileMode, Popen_safe, listify, extract_as_list, has_path_sep
  from .dependencies import ExternalProgram
  from .dependencies import InternalDependency, Dependency, NotFoundDependency, DependencyException
  from .interpreterbase import InterpreterBase
  from .interpreterbase import check_stringlist, flatten, noPosargs, noKwargs, stringArgs, permittedKwargs, noArgsFlattening
  from .interpreterbase import InterpreterException, InvalidArguments, InvalidCode, SubdirDoneRequest
  from .interpreterbase import InterpreterObject, MutableInterpreterObject, Disabler
  from .interpreterbase import FeatureNew, FeatureDeprecated, FeatureNewKwargs
  from .modules import ModuleReturnValue
  
  import os, sys, shutil, uuid
  import re, shlex
  from collections import namedtuple
  from pathlib import PurePath
  
  import importlib
  
  permitted_method_kwargs = {
      'partial_dependency': {'compile_args', 'link_args', 'links', 'includes',
                             'sources'},
  }
  
  def stringifyUserArguments(args):
      if isinstance(args, list):
          return '[%s]' % ', '.join([stringifyUserArguments(x) for x in args])
      elif isinstance(args, dict):
          return '{%s}' % ', '.join(['%s : %s' % (stringifyUserArguments(k), stringifyUserArguments(v)) for k, v in args.items()])
      elif isinstance(args, int):
          return str(args)
      elif isinstance(args, str):
          return "'%s'" % args
      raise InvalidArguments('Function accepts only strings, integers, lists and lists thereof.')
  
  
  class ObjectHolder:
      def __init__(self, obj):
          self.held_object = obj
  
      def __repr__(self):
          return '<Holder: {!r}>'.format(self.held_object)
  
  
  class TryRunResultHolder(InterpreterObject):
      def __init__(self, res):
          super().__init__()
          self.res = res
          self.methods.update({'returncode': self.returncode_method,
                               'compiled': self.compiled_method,
                               'stdout': self.stdout_method,
                               'stderr': self.stderr_method,
                               })
  
      @noPosargs
      @permittedKwargs({})
      def returncode_method(self, args, kwargs):
          return self.res.returncode
  
      @noPosargs
      @permittedKwargs({})
      def compiled_method(self, args, kwargs):
          return self.res.compiled
  
      @noPosargs
      @permittedKwargs({})
      def stdout_method(self, args, kwargs):
          return self.res.stdout
  
      @noPosargs
      @permittedKwargs({})
      def stderr_method(self, args, kwargs):
          return self.res.stderr
  
  class RunProcess(InterpreterObject):
  
      def __init__(self, cmd, args, source_dir, build_dir, subdir, mesonintrospect, in_builddir=False, check=False):
          super().__init__()
          if not isinstance(cmd, ExternalProgram):
              raise AssertionError('BUG: RunProcess must be passed an ExternalProgram')
          pc, self.stdout, self.stderr = self.run_command(cmd, args, source_dir, build_dir, subdir, mesonintrospect, in_builddir, check)
          self.returncode = pc.returncode
          self.methods.update({'returncode': self.returncode_method,
                               'stdout': self.stdout_method,
                               'stderr': self.stderr_method,
                               })
  
      def run_command(self, cmd, args, source_dir, build_dir, subdir, mesonintrospect, in_builddir, check=False):
          command_array = cmd.get_command
  
  [... the rest is omitted ...]
files: mesonbuild/interpreter.py
files: # Copyright 2013-2014 The Meson development team
  
  # Licensed under the Apache License, Version 2.0 (the "License");
  # you may not use this file except in compliance with the License.
  # You may obtain a copy of the License at
  
  #     http://www.apache.org/licenses/LICENSE-2.0
  
  # Unless required by applicable law or agreed to in writing, software
  # distributed under the License is distributed on an "AS IS" BASIS,
  # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  # See the License for the specific language governing permissions and
  # limitations under the License.
  
  import sys, pickle, os, shutil, subprocess, gzip, platform, errno
  import shlex
  from glob import glob
  from . import depfixer
  from . import destdir_join
  from ..mesonlib import is_windows, Popen_safe
  from __main__ import __file__ as main_file
  
  install_log_file = None
  selinux_updates = []
  
  class DirMaker:
      def __init__(self):
          self.dirs = []
  
      def makedirs(self, path, exist_ok=False):
          dirname = os.path.normpath(path)
          dirs = []
          while dirname != os.path.dirname(dirname):
              if not os.path.exists(dirname):
                  dirs.append(dirname)
              dirname = os.path.dirname(dirname)
          os.makedirs(path, exist_ok=exist_ok)
  
          # store the directories in creation order, with the parent directory
          # before the child directories. Future calls of makedir() will not
          # create the parent directories, so the last element in the list is
          # the last one to be created. That is the first one to be removed on
          # __exit__
          dirs.reverse()
          self.dirs += dirs
  
      def __enter__(self):
          return self
  
      def __exit__(self, type, value, traceback):
          self.dirs.reverse()
          for d in self.dirs:
              append_to_log(d)
  
  def is_executable(path):
      '''Checks whether any of the "x" bits are set in the source file mode.'''
      return bool(os.stat(path).st_mode & 0o111)
  
  def sanitize_permissions(path, umask):
      if umask is None:
          return
      new_perms = 0o777 if is_executable(path) else 0o666
      new_perms &= ~umask
      try:
          os.chmod(path, new_perms)
      except PermissionError as e:
          msg = '{!r}: Unable to set permissions {!r}: {}, ignoring...'
          print(msg.format(path, new_perms, e.strerror))
  
  def set_mode(path, mode, default_umask):
      if mode is None or (mode.perms_s or mode.owner or mode.group) is None:
          # Just sanitize permissions with the default umask
          sanitize_permissions(path, default_umask)
          return
      # No chown() on Windows, and must set one of owner/group
      if not is_windows() and (mode.owner or mode.group) is not None:
          try:
              shutil.chown(path, mode.owner, mode.group)
          except PermissionError as e:
              msg = '{!r}: Unable to set owner {!r} and group {!r}: {}, ignoring...'
              print(msg.format(path, mode.owner, mode.group, e.strerror))
          except LookupError:
              msg = '{!r}: Non-existent owner {!r} or group {!r}: ignoring...'
              print(msg.format(path, mode.owner, mode.group))
          except OSError as e:
              if e.errno == errno.EINVAL:
                  msg = '{!r}: Non-existent numeric owner {!r} or group {!r}: ignoring...'
                  print(msg.format(path, mode.owner, mode.group))
              else:
                  raise
      # Must set permissions *after* setting owner/group otherwise the
      # setuid/setgid bits will get wiped by chmod
      # NOTE: On Windows you can set read/write perms; the rest are ignored
      if mode.perms_s is not None:
          try:
              os.chmod(path, mode.perms)
          except PermissionError as e:
              msg = '{!r}: Unable to set permissions {!r}: {}, ignoring...'
              print(msg.format(path, mode.perms_s, e.strerror))
      else:
          sanitize_permissions(path, default_umask)
  
  def restore_selinux_contexts():
     
  
  [... the rest is omitted ...]
files: mesonbuild/scripts/meson_install.py
files: # Copyright 2013-2014 The Meson development team
  
  # Licensed under the Apache License, Version 2.0 (the "License");
  # you may not use this file except in compliance with the License.
  # You may obtain a copy of the License at
  
  #     http://www.apache.org/licenses/LICENSE-2.0
  
  # Unless required by applicable law or agreed to in writing, software
  # distributed under the License is distributed on an "AS IS" BASIS,
  # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  # See the License for the specific language governing permissions and
  # limitations under the License.
  
  import sys, pickle, os, shutil, subprocess, gzip, platform, errno
  import shlex
  from glob import glob
  from . import depfixer
  from . import destdir_join
  from ..mesonlib import is_windows, Popen_safe
  from __main__ import __file__ as main_file
  
  install_log_file = None
  selinux_updates = []
  
  class DirMaker:
      def __init__(self):
          self.dirs = []
  
      def makedirs(self, path, exist_ok=False):
          dirname = os.path.normpath(path)
          dirs = []
          while dirname != os.path.dirname(dirname):
              if not os.path.exists(dirname):
                  dirs.append(dirname)
              dirname = os.path.dirname(dirname)
          os.makedirs(path, exist_ok=exist_ok)
  
          # store the directories in creation order, with the parent directory
          # before the child directories. Future calls of makedir() will not
          # create the parent directories, so the last element in the list is
          # the last one to be created. That is the first one to be removed on
          # __exit__
          dirs.reverse()
          self.dirs += dirs
  
      def __enter__(self):
          return self
  
      def __exit__(self, type, value, traceback):
          self.dirs.reverse()
          for d in self.dirs:
              append_to_log(d)
  
  def is_executable(path):
      '''Checks whether any of the "x" bits are set in the source file mode.'''
      return bool(os.stat(path).st_mode & 0o111)
  
  def sanitize_permissions(path, umask):
      if umask is None:
          return
      new_perms = 0o777 if is_executable(path) else 0o666
      new_perms &= ~umask
      try:
          os.chmod(path, new_perms)
      except PermissionError as e:
          msg = '{!r}: Unable to set permissions {!r}: {}, ignoring...'
          print(msg.format(path, new_perms, e.strerror))
  
  def set_mode(path, mode, default_umask):
      if mode is None or (mode.perms_s or mode.owner or mode.group) is None:
          # Just sanitize permissions with the default umask
          sanitize_permissions(path, default_umask)
          return
      # No chown() on Windows, and must set one of owner/group
      if not is_windows() and (mode.owner or mode.group) is not None:
          try:
              shutil.chown(path, mode.owner, mode.group)
          except PermissionError as e:
              msg = '{!r}: Unable to set owner {!r} and group {!r}: {}, ignoring...'
              print(msg.format(path, mode.owner, mode.group, e.strerror))
          except LookupError:
              msg = '{!r}: Non-existent owner {!r} or group {!r}: ignoring...'
              print(msg.format(path, mode.owner, mode.group))
          except OSError as e:
              if e.errno == errno.EINVAL:
                  msg = '{!r}: Non-existent numeric owner {!r} or group {!r}: ignoring...'
                  print(msg.format(path, mode.owner, mode.group))
              else:
                  raise
      # Must set permissions *after* setting owner/group otherwise the
      # setuid/setgid bits will get wiped by chmod
      # NOTE: On Windows you can set read/write perms; the rest are ignored
      if mode.perms_s is not None:
          try:
              os.chmod(path, mode.perms)
          except PermissionError as e:
              msg = '{!r}: Unable to set permissions {!r}: {}, ignoring...'
              print(msg.format(path, mode.perms_s, e.strerror))
      else:
          sanitize_permissions(path, default_umask)
  
  def restore_selinux_contexts():
     
  
  [... the rest is omitted ...]
files: mesonbuild/scripts/meson_install.py