def execute(self, makefile, context): if context.weak: raise errors.DataError( "Static pattern rules not allowed in includedeps", self.targetexp.loc) targets = list( _expandwildcards( makefile, data.stripdotslashes( self.targetexp.resolvesplit(makefile, makefile.variables)))) if not len(targets): context.currule = DummyRule() return patterns = list( data.stripdotslashes( self.patternexp.resolvesplit(makefile, makefile.variables))) if len(patterns) != 1: raise errors.DataError( "Static pattern rules must have a single pattern", self.patternexp.loc) pattern = data.Pattern(patterns[0]) deps = [ data.Pattern(p) for p in _expandwildcards( makefile, data.stripdotslashes( self.depexp.resolvesplit(makefile, makefile.variables))) ] rule = data.PatternRule([pattern], deps, self.doublecolon, loc=self.targetexp.loc) for t in targets: if data.Pattern(t).ispattern(): raise errors.DataError( "Target '%s' of a static pattern rule must not be a pattern" % (t, ), self.targetexp.loc) stem = pattern.match(t) if stem is None: raise errors.DataError( "Target '%s' does not match the static pattern '%s'" % (t, pattern), self.targetexp.loc) makefile.gettarget(t).addrule( data.PatternRuleInstance(rule, '', stem, pattern.ismatchany())) makefile.foundtarget(targets[0]) context.currule = rule
def execute(self, makefile, context): assert context.currule is not None if context.weak: raise errors.DataError("rules not allowed in includedeps", self.exp.loc) context.currule.addcommand(self.exp)
def resolve(self, makefile, variables, fd, setting): vname = self._arguments[0].resolvestr(makefile, variables, setting) if vname in setting: raise errors.DataError("Recursively setting variable '%s'" % (vname, )) v = data.Variables(parent=variables) v.set('0', data.Variables.FLAVOR_SIMPLE, data.Variables.SOURCE_AUTOMATIC, vname) for i in range(1, len(self._arguments)): param = self._arguments[i].resolvestr(makefile, variables, setting) v.set(str(i), data.Variables.FLAVOR_SIMPLE, data.Variables.SOURCE_AUTOMATIC, param) flavor, source, e = variables.get(vname) if e is None: return if flavor == data.Variables.FLAVOR_SIMPLE: log.warning("%s: calling variable '%s' which is simply-expanded" % (self.loc, vname)) # but we'll do it anyway e.resolve(makefile, v, fd, setting + [vname])
def resolve(self, makefile, variables, fd, setting): vname = self.vname.resolvestr(makefile, variables, setting) if vname in setting: raise errors.DataError( "Setting variable '%s' recursively references itself." % (vname, ), self.loc) substfrom = self.substfrom.resolvestr(makefile, variables, setting) substto = self.substto.resolvestr(makefile, variables, setting) flavor, source, value = variables.get(vname) if value is None: log.debug("%s: variable '%s' was not set" % (self.loc, vname)) return f = data.Pattern(substfrom) if not f.ispattern(): f = data.Pattern('%' + substfrom) substto = '%' + substto fd.write(' '.join([ f.subst(substto, word, False) for word in value.resolvesplit(makefile, variables, setting + [vname]) ]))
def setup(self): argc = len(self._arguments) if argc < self.minargs: raise errors.DataError( "Not enough arguments to function %s, requires %s" % (self.name, self.minargs), self.loc) assert self.maxargs == 0 or argc <= self.maxargs, "Parser screwed up, gave us too many args"
def execute(self, makefile, context): if self.concurrent_set: vlist = [self.exp.resolvestr(makefile, makefile.variables)] else: vlist = list(self.exp.resolvesplit(makefile, makefile.variables)) if not len(vlist): raise errors.DataError( "Exporting all variables is not supported", self.exp.loc) for v in vlist: makefile.exportedvars[v] = True
def resolve(self, makefile, variables, fd, setting): if makefile.parsingfinished: # GNU make allows variables to be set by recursive expansion during # command execution. This seems really dumb to me, so I don't! raise errors.DataError( "$(eval) not allowed via recursive expansion after parsing is finished", self.loc) stmts = parser.parsestring( self._arguments[0].resolvestr(makefile, variables, setting), 'evaluation from %s' % self.loc) stmts.execute(makefile)
def resolve(self, makefile, variables, fd, setting): vname = self.vname.resolvestr(makefile, variables, setting) if vname in setting: raise errors.DataError( "Setting variable '%s' recursively references itself." % (vname, ), self.loc) flavor, source, value = variables.get(vname) if value is None: log.debug("%s: variable '%s' was not set" % (self.loc, vname)) return value.resolve(makefile, variables, fd, setting + [vname])
def execute(self, makefile, context): vname = self.vnameexp.resolvestr(makefile, makefile.variables) if len(vname) == 0: raise errors.DataError("Empty variable name", self.vnameexp.loc) if self.targetexp is None: setvariables = [makefile.variables] else: setvariables = [] targets = [ data.Pattern(t) for t in data.stripdotslashes( self.targetexp.resolvesplit(makefile, makefile.variables)) ] for t in targets: if t.ispattern(): setvariables.append(makefile.getpatternvariables(t)) else: setvariables.append( makefile.gettarget(t.gettarget()).variables) for v in setvariables: if self.token == '+=': v.append(vname, self.source, self.value, makefile.variables, makefile) continue if self.token == '?=': flavor = data.Variables.FLAVOR_RECURSIVE oldflavor, oldsource, oldval = v.get(vname, expand=False) if oldval is not None: continue value = self.value elif self.token == '=': flavor = data.Variables.FLAVOR_RECURSIVE value = self.value else: assert self.token == ':=' flavor = data.Variables.FLAVOR_SIMPLE d = parser.Data.fromstring(self.value, self.valueloc) e, t, o = parser.parsemakesyntax(d, 0, (), parser.iterdata) value = e.resolvestr(makefile, makefile.variables) v.set(vname, flavor, self.source, value)
def _execute(self, makefile, context): assert not context.weak atargets = data.stripdotslashes( self.targetexp.resolvesplit(makefile, makefile.variables)) targets = [ data.Pattern(p) for p in _expandwildcards(makefile, atargets) ] if not len(targets): context.currule = DummyRule() return ispatterns = set((t.ispattern() for t in targets)) if len(ispatterns) == 2: raise errors.DataError("Mixed implicit and normal rule", self.targetexp.loc) ispattern, = ispatterns deps = list( _expandwildcards( makefile, data.stripdotslashes( self.depexp.resolvesplit(makefile, makefile.variables)))) if ispattern: prerequisites = [data.Pattern(d) for d in deps] rule = data.PatternRule(targets, prerequisites, self.doublecolon, loc=self.targetexp.loc) makefile.appendimplicitrule(rule) else: rule = data.Rule(deps, self.doublecolon, loc=self.targetexp.loc, weakdeps=False) for t in targets: makefile.gettarget(t.gettarget()).addrule(rule) makefile.foundtarget(targets[0].gettarget()) context.currule = rule
def parsemakeflags(env): """ Parse MAKEFLAGS from the environment into a sequence of command-line arguments. """ makeflags = env.get('MAKEFLAGS', '') makeflags = makeflags.strip() if makeflags == '': return [] if _simpleopts.match(makeflags): makeflags = '-' + makeflags opts = [] curopt = '' i = 0 while i < len(makeflags): c = makeflags[i] if c.isspace(): opts.append(curopt) curopt = '' i += 1 while i < len(makeflags) and makeflags[i].isspace(): i += 1 continue if c == '\\': i += 1 if i == len(makeflags): raise errors.DataError("MAKEFLAGS has trailing backslash") c = makeflags[i] curopt += c i += 1 if curopt != '': opts.append(curopt) return opts
def execute(self, makefile, context): v = self.exp.resolvestr(makefile, makefile.variables) if v.strip() != '': raise errors.DataError("Line expands to non-empty value", self.exp.loc)
def resolve(self, makefile, variables, fd, setting): v = self._arguments[0].resolvestr(makefile, variables, setting) raise errors.DataError(v, self.loc)