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'].iteritems():
        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.iteritems():
      # Skip "variables", which was already processed if present.
      if key != 'variables' and isinstance(value, str):
        expanded = ExpandVariables(value, phase, variables, build_file)
        if not isinstance(expanded, str) and not isinstance(expanded, 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.iteritems():
      # Skip "variables" and string values, which were already processed if
      # present.
      if key == 'variables' or isinstance(value, str):
        continue
      if isinstance(value, dict):
        # Pass a copy of the variables dict so that subdicts can't influence
        # parents.
        ProcessVariablesAndConditionsInDict(value, phase, variables,
                                            build_file, key)
      elif isinstance(value, 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 not isinstance(value, 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' ] . iteritems ( ) : 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 . iteritems ( ) : # Skip "variables", which was already processed if present. if key != 'variables' and isinstance ( value , str ) : expanded = ExpandVariables ( value , phase , variables , build_file ) if not isinstance ( expanded , str ) and not isinstance ( expanded , 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 . iteritems ( ) : # Skip "variables" and string values, which were already processed if # present. if key == 'variables' or isinstance ( value , str ) : continue if isinstance ( value , dict ) : # Pass a copy of the variables dict so that subdicts can't influence # parents. ProcessVariablesAndConditionsInDict ( value , phase , variables , build_file , key ) elif isinstance ( value , 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 not isinstance ( value , int ) : raise TypeError , 'Unknown type ' + value . __class__ . __name__ + ' for ' + key