def reduceConditions(cond1, cond2): """Reduces conditions: 1) A & B, A & notB |- A 2) A, A & B |- A """ all = containers.OrderedDict() values = {} for e in cond1.exprs: all[e.option] = e for e in cond2.exprs: if e.option in all: if e.value == all[e.option].value: values[e.option] = all[e.option].value all[e.option] = True elif e.value != all[e.option].value and \ e.option.values != None and len(e.option.values) == 2: all[e.option] = False else: return None else: return None ret = [] for e in all: if all[e] is False: pass elif all[e] is True: ret.append("%s=='%s'" % (e.name, values[e])) else: return None if len(ret) == 0: return '1' else: return mk.makeCondition(' and '.join(ret))
def callbackVar(cnd, expr, use_options, target, add_dict): if expr in mk.cond_vars: cond = mk.cond_vars[expr] var = mk.CondVar(makeUniqueCondVarName('%s_%s' % (cond.name, desc))) mk.addCondVar(var, hints) for v in cond.values: cond2 = mk.mergeConditions(cnd, v.cond) if '$' in v.value: var.add(v.cond, substitute2(v.value, callback, desc, cond2, hints)) else: if len(v.value) == 0 or v.value.isspace(): var.add(v.cond, v.value) else: var.add(v.cond, callback(cond2, v.value)) return '$(%s)' % var.name if expr in mk.options and mk.options[expr].values != None: opt = mk.options[expr] var = mk.CondVar(makeUniqueCondVarName('%s_%s' % (opt.name, desc))) mk.addCondVar(var, hints) for v in opt.values: cond = mk.makeCondition("%s=='%s'" % (opt.name, v)) cond2 = mk.mergeConditions(cnd, cond) if '$' in v: var.add(cond, substitute2(v, callback, desc, cond2, hints)) else: if len(v) == 0 or v.isspace(): var.add(cond, v) else: var.add(cond, callback(cond2, v)) return '$(%s)' % var.name if expr in __substituteCallbacks: for func in __substituteCallbacks[expr]: rval = func(expr, callback, caller) if rval != None: return rval raise errors.Error("'%s' can't be used in this context, "%expr + "not a conditional variable or option with listed values")
def handleTarget(e): if e.name not in rules: raise ReaderError(e, "unknown target type") rule = rules[e.name] if rule.pseudo and 'id' not in e.props: global _pseudoTargetLastID id = 'pseudotgt%i' % _pseudoTargetLastID _pseudoTargetLastID += 1 else: if 'id' not in e.props: raise ReaderError(e, "target doesn't have id") id = e.props['id'] cond = None if 'cond' in e.props: isCond = 1 # Handle conditional targets: condstr = evalConstExpr(e, e.props['cond']) typ = mk.evalCondition(condstr) # Condition never met, ignore the target: if typ == '0': utils.deadTargets.append(id) return # Condition always met: elif typ == '1': isCond = 0 elif typ != None: raise ReaderError(e, "malformed condition: '%s'" % condstr) if isCond: checkConditionsSupport(e) cond = mk.makeCondition(condstr) if cond == None: raise ReaderError(e, "malformed condition: '%s'" % condstr) tags = rule.getTagsDict() e = applyTemplates(e, rule.getTemplates() + extractTemplates(e, post=0), extractTemplates(e, post=1)) if id in mk.targets: raise ReaderError(e, "duplicate target name '%s'" % id) if 'category' in e.props: try: cats = { 'all' : mk.Target.CATEG_ALL, 'normal' : mk.Target.CATEG_NORMAL, 'automatic' : mk.Target.CATEG_AUTOMATIC } category = cats[e.props['category']] except KeyError: raise ReaderError(e, "unknown category '%s'" % e.props['category']) else: category = mk.Target.CATEG_NORMAL target = mk.Target(e.name, id, cond, rule.pseudo, category) mk.addTarget(target) errors.pushCtx("when processing target '%s' at %s" % (target.id, e.location())) _processTargetNodes(e, target, tags, None) errors.popCtx()
def handleSet(e, target=None, add_dict=None): try: errors.pushCtx("in <set> at %s" % e.location()) name = basename = evalConstExpr(e, e.props['var'], target) if (name in mk.override_vars) and target == None: return # can't change value of variable overriden with -D=xxx doEval = not ('eval' in e.props and e.props['eval'] == '0') overwrite = not ('overwrite' in e.props and e.props['overwrite'] == '0') isCond = (len(e.children) > 0) isMakeVar = 'make_var' in e.props and e.props['make_var'] == '1' value = e.value if 'hints' in e.props: hints = e.props['hints'] else: hints = '' # Handle conditions: if isCond: if e.value: raise ReaderError(e, "cannot set unconditional value when <if> is used") noValueSet = 1 for e_if in e.children: try: errors.pushCtx(e_if) if e_if.name != 'if': raise ReaderError(e_if, "malformed <set> command") # Preprocess always true or always false conditions: condstr = evalConstExpr(e_if, e_if.props['cond'], target=target, add_dict=add_dict) condstr = translateSpecialCondition(e_if, condstr, target) typ = mk.evalCondition(condstr) # Condition never met when generating this target: if typ == '0': if config.debug: print "[dbg] removing never-met condition '%s' for variable '%s'" % (condstr, name) continue # Condition always met: elif typ == '1': if config.debug: print "[dbg] condition '%s' for variable '%s' is always met" % (condstr, name) noValueSet = 0 isCond = 0 value = e_if.value break elif typ != None: raise ReaderError(e, "malformed condition '%s': doesn't evaluate to boolean value" % condstr) cond = mk.makeCondition(condstr) noValueSet = 0 # Real conditions: checkConditionsSupport(e) if 'scope' in e.props: raise ReaderError(e, "conditional variable can't have nondefault scope ('%s')" % e.props['scope']) if target != None: if (not overwrite) and (name in target.vars): return name = '__%s_%s' % (target.id.replace('-','_').replace('.','_').replace('/','_'), basename) mk.setVar(e.props['var'], '$(%s)' % name, eval=0, target=target, add_dict=add_dict, hints=hints) if cond == None: raise ReaderError(e, "malformed condition: '%s': must be constant expression, equality test or conjunction of them" % condstr) if name in mk.cond_vars: if not overwrite: return var = mk.cond_vars[name] else: var = mk.CondVar(name, target) mk.addCondVar(var, hints) if doEval: value = mk.evalExpr(e_if.value,target=target,add_dict=add_dict) else: value = e_if.value var.add(cond, value) finally: errors.popCtx() if noValueSet: isCond = 0 value = '' if isCond: return # Non-conditional variables: if value == None: value = '' if 'append' in e.props and e.props['append'] == '1': doAppend = 1 else: doAppend = 0 if 'prepend' in e.props and e.props['prepend'] == '1': doPrepend = 1 else: doPrepend = 0 store_in = None if 'scope' in e.props: sc = evalConstExpr(e, e.props['scope'], target=target) if sc == 'local': pass elif sc == 'global': store_in = mk.vars else: if sc in mk.targets: store_in = mk.targets[sc].vars else: raise ReaderError(e, "invalid scope '%s': must be 'global', 'local' or target name" % sc) if isMakeVar: if doAppend or store_in != None or not doEval: raise ReaderError(e, "make variable (%s) can't be appended or stored in nondefault scope or not evaluated" % name) mk.setVar(name, value, eval=doEval, target=target, add_dict=add_dict, store_in=store_in, append=doAppend, prepend=doPrepend, overwrite=overwrite, makevar=isMakeVar, hints=hints) finally: errors.popCtx()
def handleTarget(e): if e.name not in rules: raise ReaderError(e, "unknown target type") rule = rules[e.name] if rule.pseudo and 'id' not in e.props: global _pseudoTargetLastID id = 'pseudotgt%i' % _pseudoTargetLastID _pseudoTargetLastID += 1 else: if 'id' not in e.props: raise ReaderError(e, "target doesn't have id") id = e.props['id'] cond = None if 'cond' in e.props: isCond = 1 # Handle conditional targets: condstr = evalConstExpr(e, e.props['cond']) typ = mk.evalCondition(condstr) # Condition never met, ignore the target: if typ == '0': utils.deadTargets.append(id) return # Condition always met: elif typ == '1': isCond = 0 elif typ != None: raise ReaderError(e, "malformed condition: '%s'" % condstr) if isCond: checkConditionsSupport(e) cond = mk.makeCondition(condstr) if cond == None: raise ReaderError(e, "malformed condition: '%s'" % condstr) tags = rule.getTagsDict() e = applyTemplates(e, rule.getTemplates() + extractTemplates(e, post=0), extractTemplates(e, post=1)) if id in mk.targets: raise ReaderError(e, "duplicate target name '%s'" % id) if 'category' in e.props: try: cats = { 'all': mk.Target.CATEG_ALL, 'normal': mk.Target.CATEG_NORMAL, 'automatic': mk.Target.CATEG_AUTOMATIC } category = cats[e.props['category']] except KeyError: raise ReaderError(e, "unknown category '%s'" % e.props['category']) else: category = mk.Target.CATEG_NORMAL target = mk.Target(e.name, id, cond, rule.pseudo, category) mk.addTarget(target) errors.pushCtx("when processing target '%s' at %s" % (target.id, e.location())) _processTargetNodes(e, target, tags, None) errors.popCtx()
def handleSet(e, target=None, add_dict=None): try: errors.pushCtx("in <set> at %s" % e.location()) name = basename = evalConstExpr(e, e.props['var'], target) if (name in mk.override_vars) and target == None: return # can't change value of variable overriden with -D=xxx doEval = not ('eval' in e.props and e.props['eval'] == '0') overwrite = not ('overwrite' in e.props and e.props['overwrite'] == '0') isCond = (len(e.children) > 0) isMakeVar = 'make_var' in e.props and e.props['make_var'] == '1' value = e.value if 'hints' in e.props: hints = e.props['hints'] else: hints = '' # Handle conditions: if isCond: if e.value: raise ReaderError( e, "cannot set unconditional value when <if> is used") noValueSet = 1 for e_if in e.children: try: errors.pushCtx(e_if) if e_if.name != 'if': raise ReaderError(e_if, "malformed <set> command") # Preprocess always true or always false conditions: condstr = evalConstExpr(e_if, e_if.props['cond'], target=target, add_dict=add_dict) condstr = translateSpecialCondition(e_if, condstr, target) typ = mk.evalCondition(condstr) # Condition never met when generating this target: if typ == '0': if config.debug: print "[dbg] removing never-met condition '%s' for variable '%s'" % ( condstr, name) continue # Condition always met: elif typ == '1': if config.debug: print "[dbg] condition '%s' for variable '%s' is always met" % ( condstr, name) noValueSet = 0 isCond = 0 value = e_if.value break elif typ != None: raise ReaderError( e, "malformed condition '%s': doesn't evaluate to boolean value" % condstr) cond = mk.makeCondition(condstr) noValueSet = 0 # Real conditions: checkConditionsSupport(e) if 'scope' in e.props: raise ReaderError( e, "conditional variable can't have nondefault scope ('%s')" % e.props['scope']) if target != None: if (not overwrite) and (name in target.vars): return name = '__%s_%s' % (target.id.replace( '-', '_').replace('.', '_').replace('/', '_'), basename) mk.setVar(e.props['var'], '$(%s)' % name, eval=0, target=target, add_dict=add_dict, hints=hints) if cond == None: raise ReaderError( e, "malformed condition: '%s': must be constant expression, equality test or conjunction of them" % condstr) if name in mk.cond_vars: if not overwrite: return var = mk.cond_vars[name] else: var = mk.CondVar(name, target) mk.addCondVar(var, hints) if doEval: value = mk.evalExpr(e_if.value, target=target, add_dict=add_dict) else: value = e_if.value var.add(cond, value) finally: errors.popCtx() if noValueSet: isCond = 0 value = '' if isCond: return # Non-conditional variables: if value == None: value = '' if 'append' in e.props and e.props['append'] == '1': doAppend = 1 else: doAppend = 0 if 'prepend' in e.props and e.props['prepend'] == '1': doPrepend = 1 else: doPrepend = 0 store_in = None if 'scope' in e.props: sc = evalConstExpr(e, e.props['scope'], target=target) if sc == 'local': pass elif sc == 'global': store_in = mk.vars else: if sc in mk.targets: store_in = mk.targets[sc].vars else: raise ReaderError( e, "invalid scope '%s': must be 'global', 'local' or target name" % sc) if isMakeVar: if doAppend or store_in != None or not doEval: raise ReaderError( e, "make variable (%s) can't be appended or stored in nondefault scope or not evaluated" % name) mk.setVar(name, value, eval=doEval, target=target, add_dict=add_dict, store_in=store_in, append=doAppend, prepend=doPrepend, overwrite=overwrite, makevar=isMakeVar, hints=hints) finally: errors.popCtx()