Quellcodebibliothek Statistik Leitseite products/Sources/formale Sprachen/C/Firefox/third_party/chromium/build/apple/   (Browser von der Mozilla Stiftung Version 136.0.1©)  Datei vom 10.2.2025 mit Größe 8 kB image not shown  

Quelle  plist_util.py   Sprache: Python

 
# Copyright 2016 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

import argparse
import codecs
import plistlib
import os
import re
import subprocess
import sys
import tempfile
import shlex

if sys.version_info.major < 3:
  basestring_compat = basestring
else:
  basestring_compat = str

# Xcode substitutes variables like ${PRODUCT_NAME} or $(PRODUCT_NAME) when
# compiling Info.plist. It also supports supports modifiers like :identifier
# or :rfc1034identifier. SUBSTITUTION_REGEXP_LIST is a list of regular
# expressions matching a variable substitution pattern with an optional
# modifier, while INVALID_CHARACTER_REGEXP matches all characters that are
# not valid in an "identifier" value (used when applying the modifier).
INVALID_CHARACTER_REGEXP = re.compile(r'[_/\s]')
SUBSTITUTION_REGEXP_LIST = (
    re.compile(r'\$\{(?P[^}]*?)(?P:[^}]*)?\}'),
    re.compile(r'\$\((?P[^}]*?)(?P:[^}]*)?\)'),
)


class SubstitutionError(Exception):
  def __init__(self, key):
    super(SubstitutionError, self).__init__()
    self.key = key

  def __str__(self):
    return "SubstitutionError: {}".format(self.key)


def InterpolateString(value, substitutions):
  """Interpolates variable references into |value| using |substitutions|.

  Inputs:
    value: a string
    substitutions: a mapping of variable names to values

  Returns:
    A new string with all variables references ${VARIABLES} replaced by their
    value in |substitutions|. Raises SubstitutionError if a variable has no
    substitution.
  """

  def repl(match):
    variable = match.group('id')
    if variable not in substitutions:
      raise SubstitutionError(variable)
    # Some values need to be identifier and thus the variables references may
    # contains :modifier attributes to indicate how they should be converted
    # to identifiers ("identifier" replaces all invalid characters by '_' and
    # "rfc1034identifier" replaces them by "-" to make valid URI too).
    modifier = match.group('modifier')
    if modifier == ':identifier':
      return INVALID_CHARACTER_REGEXP.sub('_', substitutions[variable])
    elif modifier == ':rfc1034identifier':
      return INVALID_CHARACTER_REGEXP.sub('-', substitutions[variable])
    else:
      return substitutions[variable]

  for substitution_regexp in SUBSTITUTION_REGEXP_LIST:
    value = substitution_regexp.sub(repl, value)
  return value


def Interpolate(value, substitutions):
  """Interpolates variable references into |value| using |substitutions|.

  Inputs:
    value: a value, can be a dictionary, list, string or other
    substitutions: a mapping of variable names to values

  Returns:
    A new value with all variables references ${VARIABLES} replaced by their
    value in |substitutions|. Raises SubstitutionError if a variable has no
    substitution.
  """
  if isinstance(value, dict):
    return {k: Interpolate(v, substitutions) for k, v in value.items()}
  if isinstance(value, list):
    return [Interpolate(v, substitutions) for v in value]
  if isinstance(value, basestring_compat):
    return InterpolateString(value, substitutions)
  return value


def LoadPList(path):
  """Loads Plist at |path| and returns it as a dictionary."""
  if sys.version_info.major == 2:
    fd, name = tempfile.mkstemp()
    try:
      subprocess.check_call(['plutil''-convert''xml1''-o', name, path])
      with os.fdopen(fd, 'rb'as f:
        return plistlib.readPlist(f)
    finally:
      os.unlink(name)
  else:
    with open(path, 'rb'as f:
      return plistlib.load(f)


def SavePList(path, format, data):
  """Saves |data| as a Plist to |path| in the specified |format|."""
  # The below does not replace the destination file but update it in place,
  # so if more than one hardlink points to destination all of them will be
  # modified. This is not what is expected, so delete destination file if
  # it does exist.
  if os.path.exists(path):
    os.unlink(path)
  if sys.version_info.major == 2:
    fd, name = tempfile.mkstemp()
    try:
      with os.fdopen(fd, 'wb'as f:
        plistlib.writePlist(data, f)
      subprocess.check_call(['plutil''-convert', format, '-o', path, name])
    finally:
      os.unlink(name)
  else:
    with open(path, 'wb'as f:
      plist_format = {'binary1': plistlib.FMT_BINARY, 'xml1': plistlib.FMT_XML}
      plistlib.dump(data, f, fmt=plist_format[format])


def MergePList(plist1, plist2):
  """Merges |plist1| with |plist2| recursively.

  Creates a new dictionary representing a Property List (.plist) files by
  merging the two dictionary |plist1| and |plist2| recursively (only for
  dictionary values). List value will be concatenated.

  Args:
    plist1: a dictionary representing a Property List (.plist) file
    plist2: a dictionary representing a Property List (.plist) file

  Returns:
    A new dictionary representing a Property List (.plist) file by merging
    |plist1| with |plist2|. If any value is a dictionary, they are merged
    recursively, otherwise |plist2| value is used. If values are list, they
    are concatenated.
  """
  result = plist1.copy()
  for key, value in plist2.items():
    if isinstance(value, dict):
      old_value = result.get(key)
      if isinstance(old_value, dict):
        value = MergePList(old_value, value)
    if isinstance(value, list):
      value = plist1.get(key, []) + plist2.get(key, [])
    result[key] = value
  return result


class Action(object):
  """Class implementing one action supported by the script."""

  @classmethod
  def Register(cls, subparsers):
    parser = subparsers.add_parser(cls.name, help=cls.help)
    parser.set_defaults(func=cls._Execute)
    cls._Register(parser)


class MergeAction(Action):
  """Class to merge multiple plist files."""

  name = 'merge'
  help = 'merge multiple plist files'

  @staticmethod
  def _Register(parser):
    parser.add_argument('-o',
                        '--output',
                        required=True,
                        help='path to the output plist file')
    parser.add_argument('-f',
                        '--format',
                        required=True,
                        choices=('xml1''binary1'),
                        help='format of the plist file to generate')
    parser.add_argument(
        '-x',
        '--xcode-version',
        help='version of Xcode, ignored (can be used to force rebuild)')
    parser.add_argument('path', nargs="+", help='path to plist files to merge')

  @staticmethod
  def _Execute(args):
    data = {}
    for filename in args.path:
      data = MergePList(data, LoadPList(filename))
    SavePList(args.output, args.format, data)


class SubstituteAction(Action):
  """Class implementing the variable substitution in a plist file."""

  name = 'substitute'
  help = 'perform pattern substitution in a plist file'

  @staticmethod
  def _Register(parser):
    parser.add_argument('-o',
                        '--output',
                        required=True,
                        help='path to the output plist file')
    parser.add_argument('-t',
                        '--template',
                        required=True,
                        help='path to the template file')
    parser.add_argument('-s',
                        '--substitution',
                        action='append',
                        default=[],
                        help='substitution rule in the format key=value')
    parser.add_argument('-f',
                        '--format',
                        required=True,
                        choices=('xml1''binary1'),
                        help='format of the plist file to generate')
    parser.add_argument(
        '-x',
        '--xcode-version',
        help='version of Xcode, ignored (can be used to force rebuild)')

  @staticmethod
  def _Execute(args):
    substitutions = {}
    for substitution in args.substitution:
      key, value = substitution.split('=', 1)
      substitutions[key] = value
    data = Interpolate(LoadPList(args.template), substitutions)
    SavePList(args.output, args.format, data)


def Main():
  # Cache this codec so that plistlib can find it. See
  https://crbug.com/1005190#c2 for more details.
  codecs.lookup('utf-8')

  parser = argparse.ArgumentParser(description='manipulate plist files')
  subparsers = parser.add_subparsers()

  for action in [MergeAction, SubstituteAction]:
    action.Register(subparsers)

  args = parser.parse_args()
  args.func(args)


if __name__ == '__main__':
  # TODO(https://crbug.com/941669): Temporary workaround until all scripts use
  # python3 by default.
  if sys.version_info[0] < 3:
    os.execvp('python3', ['python3'] + sys.argv)
  sys.exit(Main())

Messung V0.5
C=93 H=85 G=88

¤ Dauer der Verarbeitung: 0.13 Sekunden  (vorverarbeitet)  ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

Beweissystem der NASA

Beweissystem Isabelle

NIST Cobol Testsuite

Cephes Mathematical Library

Wiener Entwicklungsmethode

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.