Hi Simon.
| I think what you are after is being able to build happy.msi and have it
| work standalone in the same way that GHC does. Probably best to use the
| same technique as GHC (see SysTools.lhs) and that'll require minor but
| ticklish changes to Happy. (and similarly the others)
Thanks for the suggestion.
I experimented with that code on Alex and await your's and Simon's opinions
on whether a "getExecutablePath()" should be put somewhere into a GHC
library rather than cutting and pasting GHC code across three different
utilities (see separate reply to Simon, and the diff to "alex/src/Main.hs"
below).
Hope everyone has a pleasant weekend.
Mike Thomas.
$ diff alex/src/Main.hs{,-}
31a32,34
> import Foreign.Marshal.Array
> import Foreign
> import Foreign.C
100,101c103,104
< let template_dir = templateDir cli
< template_name = templateFile template_dir target cli
---
> template_dir <- templateDir cli
> let template_name = templateFile template_dir target cli
193,194c196,201
< [] -> "."
< ds -> last ds
---
> [] -> base_dir
> ds -> return (last ds)
> where base_dir = do maybe_exec_dir <- getBaseDir -- Get directory of
execu
table
> case maybe_exec_dir of
> Nothing -> return "."
> Just dir -> return dir
302a310,345
>
>
> getBaseDir :: IO (Maybe String)
> -- Assuming we are running ghc, accessed by path $()/bin/ghc.exe,
> -- return the path $(stuff). Note that we drop the "bin/" directory too.
> #if defined(mingw32_HOST_OS)
> getBaseDir = do let len = (2048::Int) -- plenty, PATH_MAX is 512 under
Win32.
> buf <- mallocArray len
> ret <- getModuleFileName nullPtr buf len
> if ret == 0 then free buf >> return Nothing
> else do s <- peekCString buf
> free buf
> return (Just (rootDir s))
> where
> rootDir s = reverse (dropList "/alex.exe" (reverse (normalisePath s)))
>
> foreign import stdcall "GetModuleFileNameA" unsafe
> getModuleFileName :: Ptr () -> CString -> Int -> IO Int32
> #else
> getBaseDir :: IO (Maybe String) = do return Nothing
> #endif
>
> normalisePath :: String -> String
> -- Just changes '\' to '/'
>
>
> #if defined(mingw32_HOST_OS)
> normalisePath xs = subst '\\' '/' xs
> subst a b ls = map (\ x -> if x == a then b else x) ls
> #else
> normalisePath xs = xs
> #endif
> dropList :: [b] -> [a] -> [a]
> dropList [] xs = xs
> dropList _ xs@[] = xs
> dropList (_:xs) (_:ys) = dropList xs ys
|