parameters: (
      the_dict, phase, variables_in, build_file, the_dict_key=None
  )
docstring: Handle all variable and command expansion and conditional evaluation.
  
    This function is the public entry point for all variable expansions and
    conditional evaluations.  The variables_in dictionary will not be modified
    by this function.
docstring_summary: Handle all variable and command expansion and conditional evaluation.
docstring_tokens: Handle all variable and command expansion and conditional evaluation .
function: def ProcessVariablesAndConditionsInDict(
      the_dict, phase, variables_in, build_file, the_dict_key=None
  ):
      """Handle all variable and command expansion and conditional evaluation.
  
    This function is the public entry point for all variable expansions and
    conditional evaluations.  The variables_in dictionary will not be modified
    by this function.
    """
  
      # Make a copy of the variables_in dict that can be modified during the
      # loading of automatics and the loading of the variables dict.
      variables = variables_in.copy()
      LoadAutomaticVariablesFromDict(variables, the_dict)
  
      if "variables" in the_dict:
          # Make sure all the local variables are added to the variables
          # list before we process them so that you can reference one
          # variable from another.  They will be fully expanded by recursion
          # in ExpandVariables.
          for key, value in the_dict["variables"].items():
              variables[key] = value
  
          # Handle the associated variables dict first, so that any variable
          # references within can be resolved prior to using them as variables.
          # Pass a copy of the variables dict to avoid having it be tainted.
          # Otherwise, it would have extra automatics added for everything that
          # should just be an ordinary variable in this scope.
          ProcessVariablesAndConditionsInDict(
              the_dict["variables"], phase, variables, build_file, "variables"
          )
  
      LoadVariablesFromVariablesDict(variables, the_dict, the_dict_key)
  
      for key, value in the_dict.items():
          # Skip "variables", which was already processed if present.
          if key != "variables" and type(value) is str:
              expanded = ExpandVariables(value, phase, variables, build_file)
              if type(expanded) not in (str, int):
                  raise ValueError(
                      "Variable expansion in this context permits str and int "
                      + "only, found "
                      + expanded.__class__.__name__
                      + " for "
                      + key
                  )
              the_dict[key] = expanded
  
      # Variable expansion may have resulted in changes to automatics.  Reload.
      # TODO(mark): Optimization: only reload if no changes were made.
      variables = variables_in.copy()
      LoadAutomaticVariablesFromDict(variables, the_dict)
      LoadVariablesFromVariablesDict(variables, the_dict, the_dict_key)
  
      # Process conditions in this dict.  This is done after variable expansion
      # so that conditions may take advantage of expanded variables.  For example,
      # if the_dict contains:
      #   {'type':       '<(library_type)',
      #    'conditions': [['_type=="static_library"', { ... }]]},
      # _type, as used in the condition, will only be set to the value of
      # library_type if variable expansion is performed before condition
      # processing.  However, condition processing should occur prior to recursion
      # so that variables (both automatic and "variables" dict type) may be
      # adjusted by conditions sections, merged into the_dict, and have the
      # intended impact on contained dicts.
      #
      # This arrangement means that a "conditions" section containing a "variables"
      # section will only have those variables effective in subdicts, not in
      # the_dict.  The workaround is to put a "conditions" section within a
      # "variables" section.  For example:
      #   {'conditions': [['os=="mac"', {'variables': {'define': 'IS_MAC'}}]],
      #    'defines':    ['<(define)'],
      #    'my_subdict': {'defines': ['<(define)']}},
      # will not result in "IS_MAC" being appended to the "defines" list in the
      # current scope but would result in it being appended to the "defines" list
      # within "my_subdict".  By comparison:
      #   {'variables': {'conditions': [['os=="mac"', {'define': 'IS_MAC'}]]},
      #    'defines':    ['<(define)'],
      #    'my_subdict': {'defines': ['<(define)']}},
      # will append "IS_MAC" to both "defines" lists.
  
      # Evaluate conditions sections, allowing variable expansions within them
      # as well as nested conditionals.  This will process a 'conditions' or
      # 'target_conditions' section, perform appropriate merging and recursive
      # conditional and variable processing, and then remove the conditions section
      # from the_dict if it is present.
      ProcessConditionsInDict(the_dict, phase, variables, build_file)
  
      # Conditional processing may have resulted in changes to automatics or the
      # variables dict.  Reload.
      variables = variables_in.copy()
      LoadAutomaticVariablesFromDict(variables, the_dict)
      LoadVariablesFromVariablesDict(variables, the_dict, the_dict_key)
  
      # Recurse into child dicts, or process child lists which may result in
      # further recursion into descendant dicts.
      for key, value in the_dict.items():
          # Skip "variables" and string values, which were already processed if
          # present.
          if key == "variables" or type(value) is str:
              continue
          if type(value) is dict:
              # Pass a copy of the variables dict so that subdicts can't influence
              # parents.
              ProcessVariablesAndConditionsInDict(
                  value, phase, variables, build_file, key
              )
          elif type(value) is list:
              # The list itself can't influence the variables dict, and
              # ProcessVariablesAndConditionsInList will make copies of the variables
              # dict if it needs to pass it to something that can influence it.  No
              # copy is necessary here.
              ProcessVariablesAndConditionsInList(value, phase, variables, build_file)
          elif type(value) is not int:
              raise TypeError("Unknown type " + value.__class__.__name__ + " for " + key)
function_tokens: def ProcessVariablesAndConditionsInDict ( the_dict , phase , variables_in , build_file , the_dict_key = None ) : # Make a copy of the variables_in dict that can be modified during the # loading of automatics and the loading of the variables dict. variables = variables_in . copy ( ) LoadAutomaticVariablesFromDict ( variables , the_dict ) if "variables" in the_dict : # Make sure all the local variables are added to the variables # list before we process them so that you can reference one # variable from another.  They will be fully expanded by recursion # in ExpandVariables. for key , value in the_dict [ "variables" ] . items ( ) : variables [ key ] = value # Handle the associated variables dict first, so that any variable # references within can be resolved prior to using them as variables. # Pass a copy of the variables dict to avoid having it be tainted. # Otherwise, it would have extra automatics added for everything that # should just be an ordinary variable in this scope. ProcessVariablesAndConditionsInDict ( the_dict [ "variables" ] , phase , variables , build_file , "variables" ) LoadVariablesFromVariablesDict ( variables , the_dict , the_dict_key ) for key , value in the_dict . items ( ) : # Skip "variables", which was already processed if present. if key != "variables" and type ( value ) is str : expanded = ExpandVariables ( value , phase , variables , build_file ) if type ( expanded ) not in ( str , int ) : raise ValueError ( "Variable expansion in this context permits str and int " + "only, found " + expanded . __class__ . __name__ + " for " + key ) the_dict [ key ] = expanded # Variable expansion may have resulted in changes to automatics.  Reload. # TODO(mark): Optimization: only reload if no changes were made. variables = variables_in . copy ( ) LoadAutomaticVariablesFromDict ( variables , the_dict ) LoadVariablesFromVariablesDict ( variables , the_dict , the_dict_key ) # Process conditions in this dict.  This is done after variable expansion # so that conditions may take advantage of expanded variables.  For example, # if the_dict contains: #   {'type':       '<(library_type)', #    'conditions': [['_type=="static_library"', { ... }]]}, # _type, as used in the condition, will only be set to the value of # library_type if variable expansion is performed before condition # processing.  However, condition processing should occur prior to recursion # so that variables (both automatic and "variables" dict type) may be # adjusted by conditions sections, merged into the_dict, and have the # intended impact on contained dicts. # # This arrangement means that a "conditions" section containing a "variables" # section will only have those variables effective in subdicts, not in # the_dict.  The workaround is to put a "conditions" section within a # "variables" section.  For example: #   {'conditions': [['os=="mac"', {'variables': {'define': 'IS_MAC'}}]], #    'defines':    ['<(define)'], #    'my_subdict': {'defines': ['<(define)']}}, # will not result in "IS_MAC" being appended to the "defines" list in the # current scope but would result in it being appended to the "defines" list # within "my_subdict".  By comparison: #   {'variables': {'conditions': [['os=="mac"', {'define': 'IS_MAC'}]]}, #    'defines':    ['<(define)'], #    'my_subdict': {'defines': ['<(define)']}}, # will append "IS_MAC" to both "defines" lists. # Evaluate conditions sections, allowing variable expansions within them # as well as nested conditionals.  This will process a 'conditions' or # 'target_conditions' section, perform appropriate merging and recursive # conditional and variable processing, and then remove the conditions section # from the_dict if it is present. ProcessConditionsInDict ( the_dict , phase , variables , build_file ) # Conditional processing may have resulted in changes to automatics or the # variables dict.  Reload. variables = variables_in . copy ( ) LoadAutomaticVariablesFromDict ( variables , the_dict ) LoadVariablesFromVariablesDict ( variables , the_dict , the_dict_key ) # Recurse into child dicts, or process child lists which may result in # further recursion into descendant dicts. for key , value in the_dict . items ( ) : # Skip "variables" and string values, which were already processed if # present. if key == "variables" or type ( value ) is str : continue if type ( value ) is dict : # Pass a copy of the variables dict so that subdicts can't influence # parents. ProcessVariablesAndConditionsInDict ( value , phase , variables , build_file , key ) elif type ( value ) is list : # The list itself can't influence the variables dict, and # ProcessVariablesAndConditionsInList will make copies of the variables # dict if it needs to pass it to something that can influence it.  No # copy is necessary here. ProcessVariablesAndConditionsInList ( value , phase , variables , build_file ) elif type ( value ) is not int : raise TypeError ( "Unknown type " + value . __class__ . __name__ + " for " + key )