Man Linux: Main Page and Category List


       cpphs - liberalised cpp-a-like preprocessor for Haskell


       cpphs [FILENAME|OPTION]...


       cpphs  is  a  liberalised  re-implementation  of  cpp  (1),  the C pre-
       processor, in and for Haskell.

       Why re-implement cpp?  Rightly  or  wrongly,  the  C  pre-processor  is
       widely used in Haskell source code.  It enables conditional compilation
       for different compilers, different versions of the same  compiler,  and
       different  OS  platforms.   It  is also occasionally used for its macro
       language, which can enable certain forms of  platform-specific  detail-
       filling,  such  as  the  tedious  boilerplate  generation  of  instance
       definitions and FFI declarations.  However, there are two problems with
       cpp, aside from the obvious aesthetic ones:

              For some Haskell systems, notably Hugs on Windows, a true cpp is
              not available by default.

              Even for the other Haskell systems, the common cpp  provided  by
              the  gcc  3.x  series  is  changing  subtly  in  ways  that  are
              incompatible with Haskell’s  syntax.   There  have  always  been
              problems  with,  for instance, string gaps, and prime characters
              in identifiers.  These problems are only going to get worse.

       So, it seemed right to attempt to provide an alternative to  cpp,  both
       more  compatible with Haskell, and itself written in Haskell so that it
       can be distributed with compilers.

       cpphs  is  pretty-much  feature-complete,  and  compatible   with   the
       -traditional style of cpp.  It has two modes:

              conditional compilation only (--nomacro),

              and full macro-expansion (default).

       In --nomacro mode, cpphs performs only conditional compilation actions,
       i.e.  #include’s, #if’s, and #ifdef’s are processed according to  text-
       replacement  definitions  (both  command-line  and  internal),  but  no
       parameterised macro expansion is performed.  In full compatibility mode
       (the  default),  textual  replacements  and  macro  expansions are also
       processed in the remaining body of non-cpp text.

       Working Features:

       #ifdef simple conditional compilation

       #if    the full boolean language of defined(), &&, ||, ==, etc.

       #elif  chained conditionals

              in-line definitions (text replacements and macros)

       #undef in-line revocation of definitions

              file inclusion

       #line  line number directives

       \n     line continuations within all # directives

       /**/   token catenation within a macro definition

       ##     ANSI-style token catenation

       #      ANSI-style token stringisation

              special text replacement for DIY error messages

              special text replacement for DIY error messages

              special text replacement

              special text replacement

       Macro expansion is recursive.  Redefinition of a macro  name  does  not
       generate  a warning.  Macros can be defined on the command-line with -D
       just like textual  replacements.   Macro  names  are  permitted  to  be
       Haskell  identifiers  e.g.  with the prime ` and backtick ´ characters,
       which is slightly looser than in C, but  they  still  may  not  include
       operator symbols.

       Numbering  of  lines  in  the  output  is  preserved  so that any later
       processor  can  give  meaningful  error  messages.   When  a  file   is
       #include’d,  cpphs  inserts  #line  directives  for  the  same  reason.
       Numbering should be correct even in the presence of line continuations.
       If  you  don’t  want  #line  directives  in  the  final output, use the
       --noline option.

       Any syntax errors in cpp directives gives a message to stderr and halts
       the  program.   Failure to find a #include’d file produces a warning to
       stderr, but processing continues.

       You can give any number of filenames on the command-line.  The  results
       are catenated on standard output.

       -Dsym  define a textual replacement (default value is 1)

              define a textual replacement with a specific value

       -Ipath add a directory to the search path for #include’s

       -Ofile specify a file for output (default is stdout)

              only process #ifdef’s and #include’s,
                                    do not expand macros

              remove #line droppings from the output

              convert C-style comments to whitespace, even outside
                                    cpp directives

              recognise the ANSI # stringise operator, and ## for
                                    token catenation, within macros

       --text treat the input as plain text, not Haskell code

              preserve newlines within macro expansions

              remove literate-style comments

              report version number of cpphs and stop

       There  are  NO  textual  replacements  defined by default.  (Normal cpp
       usually has definitions for machine, OS, etc.  These  could  easily  be
       added  to  the  cpphs  source  code  if  you wish.)  The search path is
       searched in order of the -I options, except that the directory  of  the
       calling  file,  then  the current directory, are always searched first.
       Again, there is no default search path (and again, this could easily be


       In  general,  cpphs is based on the -traditional behaviour, not ANSI C,
       and has the following main differences from the standard cpp.


       The # that introduces any cpp directive must be in the first column  of
       a line (whereas ANSI permits whitespace before the # ).

       Generates  the  #line  n  "filename"  syntax,  not  the  # n "filename"

       C comments are only removed from within cpp directives.  They  are  not
       stripped  from  other text.  Consider for instance that in Haskell, all
       of the following are valid operator symbols: /* */ */* However, you can
       turn on C-comment removal with the --strip option.

       Macro language

       Accepts  /**/  for token-pasting in a macro definition.  However, /* */
       (with any text between the open/close comment) inserts whitespace.

       The ANSI ## token-pasting operator is available with the --hashes flag.
       This is to avoid misinterpreting any valid Haskell operator of the same

       Replaces a macro formal parameter with the actual, even inside a string
       (double  or  single  quoted).   This  is  -traditional  behaviour,  not
       supported in ANSI.

       Recognises the # stringisation operator in a macro definition  only  if
       you  use  the  --hashes  option.   (It is an ANSI addition, only needed
       because quoted stringisation (above) is prohibited by ANSI.)

       Preserves whitespace within a textual  replacement  definition  exactly
       (modulo newlines), but leading and trailing space is eliminated.

       Preserves  whitespace  within  a  macro  definition  (and  trailing it)
       exactly (modulo newlines), but leading space is eliminated.

       Preserves whitespace within macro  call  arguments  exactly  (including
       newlines), but leading and trailing space is eliminated.

       With  the  --layout option, line continuations in a textual replacement
       or macro definition are preserved as line-breaks  in  the  macro  call.
       (Useful for layout-sensitive code in Haskell.)


       Bug  reports, and any other feedback, should be sent to Malcolm Wallace


       Copyright © 2004-2005 Malcolm Wallace, except for ParseLib (Copyright ©
       1995 Graham Hutton and Erik Meijer).

       The  library  modules  in  cpphs are distributed under the terms of the
       LGPL.  If  that’s  a  problem  for  you,  contact  me  to  make   other
       arrangements. The application module Main.hs itself is GPL.




       This  manual  page  was  written,  based  on  index.html, by Ian Lynagh
       <> for the Debian system (but may be used by others).