+\begin{code}
+-- Find TopDir
+-- for "installed" this is the root of GHC's support files
+-- for "in-place" it is the root of the build tree
+--
+-- Plan of action:
+-- 1. Set proto_top_dir
+-- a) look for (the last) -B flag, and use it
+-- b) if there are no -B flags, get the directory
+-- where GHC is running
+--
+-- 2. If package.conf exists in proto_top_dir, we are running
+-- installed; and TopDir = proto_top_dir
+--
+-- 3. Otherwise we are running in-place, so
+-- proto_top_dir will be /...stuff.../ghc/compiler
+-- Set TopDir to /...stuff..., which is the root of the build tree
+--
+-- This is very gruesome indeed
+
+getTopDir :: [String]
+ -> IO (Bool, -- True <=> am installed, False <=> in-place
+ String) -- TopDir
+
+getTopDir minusbs
+ = do { proto_top_dir <- get_proto
+
+ -- Discover whether we're running in a build tree or in an installation,
+ -- by looking for the package configuration file.
+ ; am_installed <- doesFileExist (proto_top_dir `slash` "package.conf")
+
+ ; if am_installed then
+ return (True, proto_top_dir)
+ else
+ return (False, remove_suffix proto_top_dir)
+ }
+ where
+ get_proto | not (null minusbs)
+ = return (dosifyPath (drop 2 (last minusbs)))
+ | otherwise
+ = do { maybe_exec_dir <- getExecDir -- Get directory of executable
+ ; case maybe_exec_dir of -- (only works on Windows)
+ Nothing -> throwDyn (InstallationError ("missing -B<dir> option"))
+ Just dir -> return dir }
+
+ remove_suffix dir -- "/...stuff.../ghc/compiler" --> "/...stuff..."
+ = ASSERT2( not (null p1) &&
+ not (null p2) &&
+ dosifyPath dir == dosifyPath (top_dir ++ "/ghc/compiler"),
+ text dir )
+ top_dir
+ where
+ p1 = dropWhile (not . isSlash) (reverse dir)
+ p2 = dropWhile (not . isSlash) (tail p1) -- head is '/'
+ top_dir = reverse (tail p2) -- head is '/'
+
+getExecDir = return Nothing
+\end{code}
+
+