[gnome-code-assistance] [backends/c] Recursively look for possible makefile targets



commit 668b46d6b7fd69675aa9c03e1abadf9ec6a68be8
Author: Jesse van den Kieboom <jessevdk gmail com>
Date:   Tue Nov 12 13:38:03 2013 +0100

    [backends/c] Recursively look for possible makefile targets

 backends/c/makefileintegration.py |   78 ++++++++++++++++++++++--------------
 1 files changed, 48 insertions(+), 30 deletions(-)
---
diff --git a/backends/c/makefileintegration.py b/backends/c/makefileintegration.py
index 7b3658c..c3dbc72 100644
--- a/backends/c/makefileintegration.py
+++ b/backends/c/makefileintegration.py
@@ -157,6 +157,13 @@ class MakefileIntegration:
 
         return None
 
+    def _sort_target(self, target, regs):
+        for i, reg in enumerate(regs):
+            if reg.match(target):
+                return i
+
+        return len(regs)
+
     def _targets_from_make(self, makefile, source):
         try:
             m = self._cache[makefile]
@@ -169,53 +176,64 @@ class MakefileIntegration:
         wd = os.path.dirname(makefile)
 
         lookfor = [
-            os.path.relpath(source, wd),
-            os.path.basename(source)
+            os.path.relpath(source, wd)
         ]
 
-        noext = [os.path.splitext(x)[0] for x in lookfor]
+        bname = os.path.basename(source)
+
+        if lookfor[0] != bname:
+            lookfor.append(bname)
+
+        origlookfor = lookfor
+
+        if self.debug:
+            print('  Looking for: [{0}]'.format(', '.join(lookfor)))
+
         args = ['make', '-p', '-n']
 
         try:
             with open(os.devnull, 'w') as stderr:
-                outstr = str(subprocess.check_output(args, cwd=wd, stderr=stderr), 'utf-8')
-        except:
+                outstr = subprocess.check_output(args, cwd=wd, stderr=stderr).decode('utf-8')
+        except StandardError as e:
+            if self.debug:
+                print('  Failed to run make: {0}'.format(e.message))
             return []
 
-        relookfor = [re.escape(x) for x in lookfor]
-        reg = re.compile('^([^:\n]+):.*({0})'.format('|'.join(relookfor)), re.M)
+        targets = []
+        found = {}
 
-        fnames = [re.escape(x) for x in noext]
+        while len(lookfor) > 0:
+            # Make a regular expression which will match all printed targets that
+            # depend on the file we are looking for
+            relookfor = [re.escape(x) for x in lookfor]
+            reg = re.compile('^([^:\n ]+):.*({0})'.format('|'.join(relookfor)), re.M)
+            lookfor = []
 
-        targetregs = [
-            re.compile('^([^:]*(({0})\\.(o|lo)))$'.format('|'.join(fnames))),
-            re.compile('^[a-z]+$')
-        ]
-
-        targets = {}
+            for match in reg.finditer(outstr):
+                target = match.group(1)
 
-        for match in reg.finditer(outstr):
-            target = match.group(1)
+                if target[0] == '#':
+                    continue
 
-            if target[0] == '#':
-                continue
+                if target in found:
+                    continue
 
-            for i, r in enumerate(targetregs):
-                if r.match(target):
-                    try:
-                        ic = targets[target]
+                targets.append(target)
+                found[target] = True
+                lookfor.append(target)
 
-                        if i < ic:
-                            targets[target] = i
-                    except KeyError:
-                        targets[target] = i
+        noext = [re.escape(os.path.splitext(x)[0]) for x in origlookfor]
 
-                    break
+        targetregs = [
+            # Targets that are object or libtool object files are good
+            re.compile('^(.*(({0})\\.(o|lo)))$'.format('|'.join(noext))),
 
-        ret = list(targets.keys())
-        ret.sort(key=lambda x: targets[x])
+            # Any object or libtool object file
+            re.compile('^(.*\\.(o|lo))$')
+        ]
 
-        return ret
+        targets.sort(key=lambda x: self._sort_target(x, targetregs))
+        return targets
 
     def _flags_from_targets(self, makefile, source, targets):
         if len(targets) == 0:


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]