{-# LANGUAGE OverloadedStrings #-}
module Ormolu.Processing.Cpp
( State (..),
processLine,
unmaskLine,
)
where
import Control.Monad
import Data.Char (isSpace)
import qualified Data.List as L
import Data.Maybe (isJust)
import Data.String
import Data.Text (Text)
import qualified Data.Text as T
data State
=
Outside
|
InConditional
|
InContinuation
deriving (Eq, Show)
processLine :: String -> State -> (String, State)
processLine line state
| for "define " = (masked, state')
| for "include " = (masked, state')
| for "undef " = (masked, state')
| for "ifdef " = (masked, InConditional)
| for "ifndef " = (masked, InConditional)
| for "if " = (masked, InConditional)
| for "else" = (masked, InConditional)
| for "elif" = (masked, InConditional)
| for "endif" = (masked, state')
| otherwise =
case state of
Outside -> (line, Outside)
InConditional -> (masked, InConditional)
InContinuation -> (masked, state')
where
for directive = isJust $ do
s <- dropWhile isSpace <$> L.stripPrefix "#" line
void (L.stripPrefix directive s)
masked = maskLine line
state' =
if "\\" `L.isSuffixOf` line
then InContinuation
else Outside
maskLine :: String -> String
maskLine x = maskPrefix ++ x
unmaskLine :: Text -> Text
unmaskLine x =
case T.stripPrefix maskPrefix (T.stripStart x) of
Nothing -> x
Just x' -> x'
maskPrefix :: IsString s => s
maskPrefix = "-- ORMOLU_CPP_MASK"