-----------------------------------------------------------------------------
-- |
-- Module      :  Distribution.Simple.Program.Internal
--
-- Maintainer  :  [email protected]
-- Portability :  portable
--
-- Internal utilities used by Distribution.Simple.Program.*.

module Distribution.Simple.Program.Internal (
    stripExtractVersion,
  ) where

import Data.Char (isDigit)
import Data.List (isPrefixOf, isSuffixOf)

-- | Extract the version number from the output of 'strip --version'.
--
-- Invoking "strip --version" gives very inconsistent results. We ignore
-- everything in parentheses (see #2497), look for the first word that starts
-- with a number, and try parsing out the first two components of it. Non-GNU
-- 'strip' doesn't appear to have a version flag.
stripExtractVersion :: String -> String
stripExtractVersion str =
  let numeric ""    = False
      numeric (x:_) = isDigit x

      -- Filter out everything in parentheses.
      filterPar' :: Int -> [String] -> [String]
      filterPar' _ []                   = []
      filterPar' n (x:xs)
        | n >= 0 && "(" `isPrefixOf` x = filterPar' (n+1) ((tail x):xs)
        | n >  0 && ")" `isSuffixOf` x = filterPar' (n-1) xs
        | n >  0                       = filterPar' n xs
        | otherwise                    = x:filterPar' n xs

      filterPar = filterPar' 0

  in case dropWhile (not . numeric) (filterPar . words $ str) of
    (ver:_) ->
      -- take the first two version components
      let isDot         = (== '.')
          (major, rest) = break isDot ver
          minor         = takeWhile isDigit (dropWhile isDot rest)
      in major ++ "." ++ minor
    _ -> ""