diff --git a/CHANGELOG.md b/CHANGELOG.md
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,8 @@
+# 0.6.1
+- Added the `--only-macros` command line flag. Does not splice lines, remove comments, or do trigraph replacement. It does macro processing and #line marker output (which can be disabled with the `-P` option)
+
+- Changed the default configuration to emit `#line` markers. Can be disabled with `-P`.
+
 # 0.6.0
 
 - Various bug fixes by @rahulmutt. These may change behavior not captured by the MCPP test suite.
diff --git a/hpp.cabal b/hpp.cabal
--- a/hpp.cabal
+++ b/hpp.cabal
@@ -1,5 +1,5 @@
 name:                hpp
-version:             0.6.0.1
+version:             0.6.1
 synopsis:            A Haskell pre-processor
 description:         See the README for usage examples
 license:             BSD3
@@ -12,7 +12,7 @@
 extra-source-files:  tests/mcpp-validation.sh, CHANGELOG.md, README.md
 cabal-version:       >=1.10
 homepage:            https://github.com/acowley/hpp
-tested-with:         GHC == 7.10.3, GHC == 8.0.1
+tested-with:         GHC == 7.10.3, GHC == 8.0.2, GHC == 8.2.2, GHC == 8.4.3
 
 source-repository head
   type:     git
@@ -48,7 +48,7 @@
 
 executable hpp
   main-is:             src/Main.hs
-  build-depends:       hpp, base >=4.8 && <4.12, directory, time >=1.5, filepath
+  build-depends:       hpp, base, directory, time >=1.5, filepath
   hs-source-dirs:      .
   default-language:    Haskell2010
   ghc-options: -Wall
diff --git a/src/Hpp/CmdLine.hs b/src/Hpp/CmdLine.hs
--- a/src/Hpp/CmdLine.hs
+++ b/src/Hpp/CmdLine.hs
@@ -75,6 +75,10 @@
           go env acc (cfg { eraseCCommentsF = Just True }) out rst
         go env acc cfg out ("--freplace-trigraphs":rst) =
           go env acc (cfg { replaceTrigraphsF = Just True }) out rst
+        go env acc cfg out ("--only-macros":rst) =
+          go env acc (cfg { replaceTrigraphsF = Just False
+                          , spliceLongLinesF = Just False
+                          , eraseCCommentsF = Just False }) out rst
         go env acc cfg _ ("-o":file:rst) =
           go env acc cfg (Just file) rst
         go env acc cfg out ("-x":_lang:rst) =
diff --git a/src/Hpp/Config.hs b/src/Hpp/Config.hs
--- a/src/Hpp/Config.hs
+++ b/src/Hpp/Config.hs
@@ -102,7 +102,7 @@
 -- markers are inhibited, and trigraph replacement is disabled.
 defaultConfigF :: ConfigF Maybe
 defaultConfigF = Config Nothing (Just [])
-                        (Just True) (Just True) (Just True) (Just False)
+                        (Just True) (Just True) (Just False) (Just False)
                         (Just (DateString "??? ?? ????"))
                         (Just (TimeString "??:??:??"))
 
@@ -122,3 +122,28 @@
                            t = formatPrepTime now
                        return $ defaultConfigF { prepDateF = Just d
                                                , prepTimeF = Just t }
+
+-- * Lens-like accessors for Config
+
+-- | Lens for the "splice long lines" option (prepend a line ending
+-- with a backslash to the next line).
+spliceLongLinesL :: Functor f => (Bool -> f Bool) -> Config -> f Config
+spliceLongLinesL f cfg = (\x -> cfg { spliceLongLinesF = pure x })
+                         <$> f (spliceLongLines cfg)
+
+-- | Lens for the "erase C-style comments" option (comments delimited
+-- by @/*@ and @*/@).
+eraseCCommentsL :: Functor f => (Bool -> f Bool) -> Config -> f Config
+eraseCCommentsL f cfg = (\x -> cfg { eraseCCommentsF = pure x })
+                        <$> f (eraseCComments cfg)
+
+-- | Lens for the "inhibit line markers" option. Option to disable the
+-- emission of #line pragmas in the output.
+inhibitLinemarkersL :: Functor f => (Bool -> f Bool) -> Config -> f Config
+inhibitLinemarkersL f cfg = (\x -> cfg { inhibitLinemarkersF = pure x })
+                            <$> f (inhibitLinemarkers cfg)
+
+-- | Lens for the "replace trigraphs" option.
+replaceTrigraphsL :: Functor f => (Bool -> f Bool) -> Config -> f Config
+replaceTrigraphsL f cfg = (\x -> cfg { replaceTrigraphsF = pure x })
+                          <$> f (replaceTrigraphs cfg)
diff --git a/src/Hpp/Directive.hs b/src/Hpp/Directive.hs
--- a/src/Hpp/Directive.hs
+++ b/src/Hpp/Directive.hs
@@ -75,7 +75,9 @@
                         Just def -> env %= insertPair def)
           "undef" -> do name <- lift . onElements $ do
                           droppingWhile (not . isImportant)
-                          Important name <- awaitJust "undef"
+                          name <- awaitJust "undef" >>= \case
+                                    Important n -> return n
+                                    _ -> error "undef directive got Other token"
                           return name
                         lift dropLine
                         env %= deleteKey name
diff --git a/src/Hpp/Preprocessing.hs b/src/Hpp/Preprocessing.hs
--- a/src/Hpp/Preprocessing.hs
+++ b/src/Hpp/Preprocessing.hs
@@ -130,6 +130,9 @@
        _ | (eraseCComments cfg && spliceLongLines cfg
             && (not (replaceTrigraphs cfg))) ->
            pure haskellCPP
+       _ | not (any ($ cfg) [ eraseCComments
+                            , spliceLongLines
+                            , replaceTrigraphs ]) -> pure onlyMacrosCPP
        _ | otherwise -> pure (genericConfig cfg)
 
 -- * HPP configurations
@@ -147,6 +150,12 @@
            . lineSplicing
            . cCommentRemoval
 {-# INLINABLE haskellCPP #-}
+
+-- | No C-style comment removal; no line splicing; no trigraph
+-- replacement. This variant only supports macros and conditionals.
+onlyMacrosCPP :: [String] -> [[TOKEN]]
+onlyMacrosCPP = map ((++[Other "\n"]) . tokenize)
+{-# INLINABLE onlyMacrosCPP #-}
 
 -- | If we don't have a predefined processor, we build one based on a
 -- 'Config' value.
diff --git a/src/Main.hs b/src/Main.hs
--- a/src/Main.hs
+++ b/src/Main.hs
@@ -16,30 +16,34 @@
   , "-I dir"
   , "  Add directory dir to the search path for includes."
   , "-o file"
-  , "  Write output to file."
+  , "  Write output to file. If not given, outputs to stdout."
   , "-include file"
   , "  Acts as if #include \"file\" were the first line "
   , "  in the primary source file. -include options are "
   , "  processed after -D and -U options."
-  , "-imacros file"
-  , "  Like -include, except that output is discarded. Only"
-  , "  macro definitions are kept."
   , "--cpp"
   , "  C98 compatibility."
   , "  Implies: --fline-splice --ferase-comments --freplace-trigraphs"
   , "  -D __STDC__  -D __STDC_VERSION__=199409L -D _POSIX_C_SOURCE=200112L"
+  , "--only-macros"
+  , "  No line splicing, no comment removal, no trigraph replacement."
+  , "  Only macros (including conditionals) and line marker output."
   , "-P"
-  , "  Inhibit #line markers (when this option is given after --cpp)"
+  , "  Inhibit #line markers."
   , "--fline-splice"
   , "  Enable continued line splicing."
   , "--ferase-comments"
   , "  Remove all C-style comments before processing."
   , "--freplace-trigraphs"
-  , "  Replace trigraph sequences before processing." ]
+  , "  Replace trigraph sequences before processing."]
 
 main :: IO ()
 main = do getArgs >>= \case
             [] -> usage
+            ["--help"] -> usage
+            ["-help"] -> usage
+            ["-h"] -> usage
+            ["--h"] -> usage
             args -> runWithArgs args >> return ()
 
 
diff --git a/tests/AsLib.hs b/tests/AsLib.hs
--- a/tests/AsLib.hs
+++ b/tests/AsLib.hs
@@ -4,6 +4,9 @@
 import Data.Maybe (fromMaybe)
 import Data.Monoid ((<>))
 import Hpp
+import qualified Hpp.Config as C
+import qualified Hpp.Types as T
+
 import System.Exit
 
 sourceIfdef :: [ByteString]
@@ -31,19 +34,73 @@
                               print (hppOutput res)
                               return False
 
+hppHelper' :: HppState -> [ByteString] -> [ByteString] -> IO Bool
+hppHelper' = hppHelper . T.over T.config (T.setL C.inhibitLinemarkersL True)
+
 testElse :: IO Bool
-testElse = hppHelper emptyHppState sourceIfdef ["x = 99\n","\n"]
+testElse = hppHelper' emptyHppState sourceIfdef ["x = 99\n","\n"]
 
 testIf :: IO Bool
-testIf = hppHelper (fromMaybe (error "Preprocessor definition did not parse")
-                              (addDefinition "FOO" "1" emptyHppState))
-                   sourceIfdef
-                   ["x = 42\n","\n"]
+testIf = hppHelper' (fromMaybe (error "Preprocessor definition did not parse")
+                      (addDefinition "FOO" "1" emptyHppState))
+                    sourceIfdef
+                    ["x = 42\n","\n"]
 
 testArith1 :: IO Bool
-testArith1 = (&&) <$> hppHelper emptyHppState (sourceArith1 "7") ["yay\n","\n"]
-                  <*> hppHelper emptyHppState (sourceArith1 "8") ["boo\n","\n"]
+testArith1 = (&&) <$> hppHelper' emptyHppState (sourceArith1 "7") ["yay\n","\n"]
+                  <*> hppHelper' emptyHppState (sourceArith1 "8") ["boo\n","\n"]
 
+sourceCommentsAndSplice :: [ByteString]
+sourceCommentsAndSplice =
+  [ "#ifdef FOO"
+  , "Some /* neat */ text"
+  , "#else"
+  , "I am /* an else branch"
+  , "whose importance must not"
+  , "be */ underestimated "
+  , "#endif"
+  , "Do you\\"
+  , "understand?"]
+
+-- | A configuration to not splice lines, leave C-style comments,
+-- ignore trigraphs, but emit line markers.
+hppConfig :: HppState -> HppState
+hppConfig st = T.over T.config opts $ st
+  where opts = T.setL C.spliceLongLinesL False
+             . T.setL C.eraseCCommentsL False
+             . T.setL C.replaceTrigraphsL False
+             . T.setL C.inhibitLinemarkersL False
+
+testCommentsAndSplice1 :: IO Bool
+testCommentsAndSplice1 =
+  hppHelper (hppConfig
+              (fromMaybe (error "Preprocessor definition did not parse")
+               (addDefinition "FOO" "1" emptyHppState)))
+            sourceCommentsAndSplice
+            [ "Some /* neat */ text\n"
+            , "#line 8\n"
+            , "Do you\\\n"
+            , "understand?\n" ]
+
+testCommentsAndSplice2 :: IO Bool
+testCommentsAndSplice2 =
+  hppHelper (hppConfig emptyHppState)
+            sourceCommentsAndSplice
+            [ "#line 4\n"
+            , "I am /* an else branch\n"
+            , "whose importance must not\n"
+            , "be */ underestimated \n"
+            , "Do you\\\n"
+            , "understand?\n" ]
+
 main :: IO ()
-main = do results <- sequenceA [testElse, testIf, testArith1]
-          if and results then exitWith ExitSuccess else exitWith (ExitFailure 1)
+main = do results <- sequenceA [ testElse, testIf, testArith1
+                               , testCommentsAndSplice1
+                               , testCommentsAndSplice2 ]
+          if and results
+            then do putStrLn (show (length results) ++ " tests passed")
+                    exitWith ExitSuccess
+            else do putStrLn (show (length (filter id results)) ++
+                              " of " ++ show (length results) ++
+                              " tests passed")
+                    exitWith (ExitFailure 1)
