[MERGE] forward port of branch 8.0 up to 591e329
[odoo/odoo.git] / openerp / tools / misc.py
index f1651d0..7f69f28 100644 (file)
@@ -66,8 +66,11 @@ _logger = logging.getLogger(__name__)
 SKIPPED_ELEMENT_TYPES = (etree._Comment, etree._ProcessingInstruction, etree.CommentBase, etree.PIBase)
 
 def find_in_path(name):
+    path = os.environ.get('PATH', os.defpath).split(os.pathsep)
+    if config.get('bin_path') and config['bin_path'] != 'None':
+        path.append(config['bin_path'])
     try:
-        return which(name)
+        return which(name, path=os.pathsep.join(path))
     except IOError:
         return None
 
@@ -278,6 +281,36 @@ def reverse_enumerate(l):
     """
     return izip(xrange(len(l)-1, -1, -1), reversed(l))
 
+def topological_sort(elems):
+    """ Return a list of elements sorted so that their dependencies are listed
+    before them in the result.
+
+    :param elems: specifies the elements to sort with their dependencies; it is
+        a dictionary like `{element: dependencies}` where `dependencies` is a
+        collection of elements that must appear before `element`. The elements
+        of `dependencies` are not required to appear in `elems`; they will
+        simply not appear in the result.
+
+    :returns: a list with the keys of `elems` sorted according to their
+        specification.
+    """
+    # the algorithm is inspired by [Tarjan 1976],
+    # http://en.wikipedia.org/wiki/Topological_sorting#Algorithms
+    result = []
+    visited = set()
+
+    def visit(n):
+        if n not in visited:
+            visited.add(n)
+            if n in elems:
+                # first visit all dependencies of n, then append n to result
+                map(visit, elems[n])
+                result.append(n)
+
+    map(visit, elems)
+
+    return result
+
 
 class UpdateableStr(local):
     """ Class that stores an updateable string (used in wizards)
@@ -430,7 +463,7 @@ ALL_LANGUAGES = {
         'am_ET': u'Amharic / አምሃርኛ',
         'ar_SY': u'Arabic / الْعَرَبيّة',
         'bg_BG': u'Bulgarian / български език',
-        'bs_BS': u'Bosnian / bosanski jezik',
+        'bs_BA': u'Bosnian / bosanski jezik',
         'ca_ES': u'Catalan / Català',
         'cs_CZ': u'Czech / Čeština',
         'da_DK': u'Danish / Dansk',