+
+preprocessFile :: DynFlags -> FilePath -> Maybe (StringBuffer,ClockTime)
+ -> IO (DynFlags, FilePath, StringBuffer)
+preprocessFile dflags src_fn Nothing
+ = do
+ (dflags', hspp_fn) <- preprocess dflags src_fn
+ buf <- hGetStringBuffer hspp_fn
+ return (dflags', hspp_fn, buf)
+
+preprocessFile dflags src_fn (Just (buf, time))
+ = do
+ -- case we bypass the preprocessing stage?
+ let
+ local_opts = getOptionsFromStringBuffer buf
+ --
+ (dflags', errs) <- parseDynamicFlags dflags local_opts
+
+ let
+ needs_preprocessing
+ | Unlit _ <- startPhase src_fn = True
+ -- note: local_opts is only required if there's no Unlit phase
+ | dopt Opt_Cpp dflags' = True
+ | dopt Opt_Pp dflags' = True
+ | otherwise = False
+
+ when needs_preprocessing $
+ ghcError (ProgramError "buffer needs preprocesing; interactive check disabled")
+
+ return (dflags', "<buffer>", buf)
+
+
+-- code adapted from the file-based version in DriverUtil
+getOptionsFromStringBuffer :: StringBuffer -> [String]
+getOptionsFromStringBuffer buffer@(StringBuffer _ len# _) =
+ let
+ ls = lines (lexemeToString buffer (I# len#)) -- lazy, so it's ok
+ in
+ look ls
+ where
+ look [] = []
+ look (l':ls) = do
+ let l = removeSpaces l'
+ case () of
+ () | null l -> look ls
+ | prefixMatch "#" l -> look ls
+ | prefixMatch "{-# LINE" l -> look ls -- -}
+ | Just opts <- matchOptions l
+ -> opts ++ look ls
+ | otherwise -> []
+