config: Rework the SysPaths functions into functors.
authorGabe Black <gabeblack@google.com>
Tue, 31 Oct 2017 01:31:07 +0000 (18:31 -0700)
committerGabe Black <gabeblack@google.com>
Tue, 31 Oct 2017 22:18:26 +0000 (22:18 +0000)
These functions were already being treated as psuedo objects and had
properties assigned to them setting what their paths were. That's a bit
unusual and made it less obvious what the code was doing, but also
forced the "system" function to know what all the possible path
searching functions were so that they'd have their "path" property
initialized properly in a central location.

This change introduces a PathSearcFunc class which encapsulates the
mechanisms of the old code and makes it implicitly extensible so that
other path searching functions which might look in other directories
can be added in other places.

Change-Id: I7be28e51481a06ec83997677af99927709b18003
Reviewed-on: https://gem5-review.googlesource.com/5341
Reviewed-by: Andreas Sandberg <andreas.sandberg@arm.com>
Maintainer: Andreas Sandberg <andreas.sandberg@arm.com>

configs/common/SysPaths.py

index 316fd0399ccc3df2e68e4c90c7d4a6f6560e23ff..c012846ce3bf5f5e72eb1551870302ff17295758 100644 (file)
 # Authors: Ali Saidi
 
 import os, sys
-from os.path import join as joinpath
-from os import environ as env
 
 config_path = os.path.dirname(os.path.abspath(__file__))
 config_root = os.path.dirname(config_path)
 
-def searchpath(path, filename):
-    for p in path:
-        f = joinpath(p, filename)
-        if os.path.exists(f):
-            return f
-    raise IOError, "Can't find file '%s' on path." % filename
+class PathSearchFunc(object):
+    _sys_paths = None
 
-def disk(filename):
-    system()
-    return searchpath(disk.path, filename)
+    def __init__(self, *subdirs):
+        self._subdir = os.path.join(*subdirs)
 
-def binary(filename):
-    system()
-    return searchpath(binary.path, filename)
+    def __call__(self, filename):
+        if self._sys_paths is None:
+            try:
+                paths = os.environ['M5_PATH'].split(':')
+            except KeyError:
+                paths = [ '/dist/m5/system', '/n/poolfs/z/dist/m5/system' ]
 
-def script(filename):
-    system()
-    return searchpath(script.path, filename)
+            # expand '~' and '~user' in paths
+            paths = map(os.path.expanduser, paths)
 
-def system():
-    if not system.path:
-        try:
-            path = env['M5_PATH'].split(':')
-        except KeyError:
-            path = [ '/dist/m5/system', '/n/poolfs/z/dist/m5/system' ]
-
-        # expand '~' and '~user' in paths
-        path = map(os.path.expanduser, path)
+            # filter out non-existent directories
+            paths = filter(os.path.isdir, paths)
 
-        # filter out non-existent directories
-        system.path = filter(os.path.isdir, path)
+            if not paths:
+                raise IOError, "Can't find a path to system files."
 
-        if not system.path:
-            raise IOError, "Can't find a path to system files."
+            self._sys_paths = paths
 
-    if not binary.path:
-        binary.path = [joinpath(p, 'binaries') for p in system.path]
-    if not disk.path:
-        disk.path = [joinpath(p, 'disks') for p in system.path]
-    if not script.path:
-        script.path = [joinpath(config_root, 'boot')]
+        filepath = os.path.join(self._subdir, filename)
+        paths = (os.path.join(p, filepath) for p in self._sys_paths)
+        try:
+            return next(p for p in paths if os.path.exists(p))
+        except StopIteration:
+            raise IOError, "Can't find file '%s' on path." % filename
 
-system.path = None
-binary.path = None
-disk.path = None
-script.path = None
+disk = PathSearchFunc('disks')
+binary = PathSearchFunc('binaries')
+script = PathSearchFunc('boot')