def __certainlyNotEmpty(value): """Returns True if the given expression can be determined to be non-empty. Returns False if it is either empty or we don't know for sure. Input is non-empty, with surrounding whitespace already stripped.""" if value[0] != '$': # the simple case return True class __Helper: pass helper = __Helper() helper.ok = False def varCb(helper, expr, use_options, target, add_dict): if not helper.ok: # don't waste time otherwise if expr in mk.options: if mk.options[expr].isNeverEmpty(): helper.ok = True # FIXME: it would be nice to be able to do this for condvars too, # but they default to empty value if the set of its # conditions is not exhaustive and so checking all items # of its 'values' members is not enough, we'd have to verify return '' def textCb(helper, txt): if len(txt) > 0: helper.ok = True return '' mk.__doEvalExpr(value, varCb, textCb, helper, # extra argument passed to callbacks 1, # use_options None, # target None) # add_dict return helper.ok
def substitute2(str, callback, desc=None, cond=None, hints='', caller=None): """Same as substitute, but the callbacks takes two arguments (text and condition object) instead of one.""" if caller == None: caller = 'substitute2' if desc == None: global substVarNameCounter desc = '%i' % substVarNameCounter substVarNameCounter += 1 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 callbackTxt(cond, expr): if len(expr) == 0 or expr.isspace(): return expr return callback(cond, expr) return mk.__doEvalExpr(str, callbackVar, callbackTxt, cond, # moreArgs 1, # use_options None, # target None) # add_dict
def getPossibleValues(expr): """Attempts to get all possible values of 'str' expansion. For now, this function assumes that variable parts (condvars references) are separated from other parts with whitespace. Returns generator for list of values as split on whitespace. """ # FIXME: see docstring def callbackVar(nothing, expr, use_options, target, add_dict): ret = [] if expr in mk.cond_vars: cond = mk.cond_vars[expr] for v in cond.values: if '$' in v.value: ret += getPossibleValues(v.value) else: ret.append(v.value) return ' '.join(ret) if expr in mk.options and mk.options[expr].values != None: opt = mk.options[expr] for v in opt.values: if '$' in v.value: ret += getPossibleValues(v) else: ret.append(v) return ' '.join(ret) # don't know what else to try, return as-is return expr def callbackTxt(nothing, expr): return expr return mk.__doEvalExpr(expr, callbackVar, callbackTxt, None, 1, None, None).split()