Better locations for command execution notices.
authorBenjamin Smedberg <benjamin@smedbergs.us>
Thu, 12 Feb 2009 16:03:19 -0500
changeset 110 0e1d287af7c6c0160544be4a93b6293a46cde4cb
parent 109 fcb2f68e9a9556104ca14757ab8eba577eb7dc7d
child 111 8f414e9cd252d7c84becee307e6dba1dd0b42c8c
push id59
push userbsmedberg@mozilla.com
push dateThu, 12 Feb 2009 21:03:28 +0000
Better locations for command execution notices.
pymake/data.py
pymake/parser.py
--- a/pymake/data.py
+++ b/pymake/data.py
@@ -70,19 +70,20 @@ def _if_else(c, t, f):
         return t()
     return f()
 
 class Expansion(object):
     """
     A representation of expanded data, such as that for a recursively-expanded variable, a command, etc.
     """
 
-    def __init__(self):
+    def __init__(self, loc=None):
         # Each element is either a string or a function
         self._elements = []
+        self.loc = loc
 
     @staticmethod
     def fromstring(s):
         e = Expansion()
         e.append(s)
         return e
 
     def append(self, object):
@@ -822,20 +823,20 @@ class Rule(object):
 
         for c in self.commands:
             cstring = c.resolve(v)
             for cline in splitcommand(cstring):
                 cline, isHidden, isRecursive, ignoreErrors = findmodifiers(cline)
                 if not len(cline) or cline.isspace():
                     continue
                 if not isHidden:
-                    print "%s $ %s" % (self.loc, cline)
+                    print "%s $ %s" % (c.loc, cline)
                 r = subprocess.call(cline, shell=True, env=env)
                 if r != 0 and not ignoreErrors:
-                    raise DataError("command '%s' failed, return code was %s" % (cline, r), self.loc)
+                    raise DataError("command '%s' failed, return code was %s" % (cline, r), c.loc)
 
 class PatternRuleInstance(object):
     """
     This represents a pattern rule instance for a particular target. It has the same API as Rule, but
     different internals, forwarding most information on to the PatternRule.
     """
     def __init__(self, prule, dir, stem, ismatchany):
         assert isinstance(prule, PatternRule)
@@ -923,19 +924,21 @@ class PatternRule(object):
         env = makefile.getsubenvironment(v)
 
         for c in self.commands:
             cstring = c.resolve(v)
             for cline in splitcommand(cstring):
                 cline, isHidden, isRecursive, ignoreErrors = findmodifiers(cline)
                 if not len(cline) or cline.isspace():
                     continue
+                if not isHidden:
+                    print "%s $ %s" % (c.loc, cline)
                 r = subprocess.call(cline, shell=True, env=env)
                 if r != 0 and not ignoreErrors:
-                    raise DataError("command '%s' failed, return code was %s" % (cline, r), self.loc)
+                    raise DataError("command '%s' failed, return code was %s" % (cline, r), c.loc)
 
 class Makefile(object):
     def __init__(self, workdir=None, restarts=0, make=None, makeflags=None, makelevel=0):
         self.defaulttarget = None
 
         self.variables = Variables()
         self.variables.readfromenvironment()
 
--- a/pymake/parser.py
+++ b/pymake/parser.py
@@ -120,16 +120,19 @@ class Data(object):
 
     def getloc(self, offset):
         """
         Get the location of an offset within data.
         """
         if offset is None or offset >= len(self.data):
             offset = len(self.data) - 1
 
+        if offset == -1:
+            offset = 0
+
         begin, loc = findlast(lambda (o, l): o <= offset, self._locs)
         return loc + self.data[begin:offset]
 
     def skipwhitespace(self, offset):
         """
         Return the offset into data after skipping whitespace.
         """
         while offset < len(self.data):
@@ -777,17 +780,18 @@ def parsemakesyntax(d, startat, stopon, 
     token and offset will be None
     """
 
     # print "parsemakesyntax(%r)" % d.data
 
     assert callable(iterfunc)
 
     stack = [
-        ParseStackFrame(PARSESTATE_TOPLEVEL, data.Expansion(), stopon, closebrace=None)
+        ParseStackFrame(PARSESTATE_TOPLEVEL, data.Expansion(loc=d.getloc(startat)),
+                        stopon, closebrace=None)
     ]
 
     di = iterfunc(d, startat)
     offset = startat
 
     while True: # this is not a for loop because `di` changes during the function
         stacktop = stack[-1]
         try: