GithubHelp home page GithubHelp logo

cpphs's People

Stargazers

 avatar  avatar

Watchers

 avatar

cpphs's Issues

lexical error at character '\n'

@jstolarek reported an error installing Agda. A MWE is as follows

$ ghc -cpp -pgmPcpphs -optP--cpp Test.hs

Test.hs:0:2: error: lexical error at character '\n'
$ cat Test.hs
module Main where

#define FOO 1

#ifdef FOO
foo = 42
#endif

main = print foo
$ cpphs --version
cpphs 1.20.2

Blocking agda/agda#1285.

Line splicing should be applied everywhere

According to the C99 spec (section 5.1.1.2, "Translation phases"), line splicing -- gluing together lines which end with a backslash -- should be performed for every line ending in a backslash. cpphs, however, only seems to do this for lines containing cpp commands, i.e. lines starting with a #:

% cat foo.c
#define X  123\
456

int x1 = X;

int x2 = 123\
456;
% cpp foo.c
# 1 "foo.c"
# 1 "<built-in>"
# 1 "<command-line>"
# 31 "<command-line>"
# 1 "/usr/include/stdc-predef.h" 1 3 4
# 32 "<command-line>" 2
# 1 "foo.c"



int x1 = 123456;

int x2 = 123456;
% cpphs foo.c
#line 1 "foo.c"



int x1 = 123456;

int x2 = 123\
456;

Warning: Can't find file "C:\.../include\ghcversion.h" in directories

I'm not sure yet where this is coming from, but I'd like to report an unnecessary warning on Windows:

[00:03:39] Preprocessing library cardano-sl-0.1.0.0...
[00:03:39] Warning: Can't find file "C:\Users\appveyor\AppData\Local\Programs\stack\x86_64-windows\ghc-8.0.1\lib/include\ghcversion.h" in directories
[00:03:39] 	src/Pos
[00:03:39] 	.
[00:03:39] 	.stack-work\dist\b7fec021\build
[00:03:39] 	.stack-work\dist\b7fec021\build
[00:03:39] 	.stack-work\dist\b7fec021\build\autogen
[00:03:39] 	.stack-work\dist\b7fec021\build
[00:03:39] 	C:\OpenSSL-Win64\include
[00:03:39] 	C:\Users\appveyor\AppData\Local\Programs\stack\x86_64-windows\msys2-20150512\mingw64\include
[00:03:39] 	C:\projects\pos-haskell-prototype\rocksdb\include
[00:03:39] 	C:\OpenSSL-Win64\include
[00:03:39] 	C:\Users\appveyor\AppData\Local\Programs\stack\x86_64-windows\msys2-20150512\mingw64\include
[00:03:39] 	C:\projects\pos-haskell-prototype\rocksdb\include
[00:03:39] 	C:\sr\snapshots\a78c6a89\lib\x86_64-windows-ghc-8.0.1\vector-algorithms-0.7.0.1-8R8UpWgvBC926XMxBjYPpx\include
[00:03:39] 	C:\sr\snapshots\a78c6a89\lib\x86_64-windows-ghc-8.0.1\zlib-0.6.1.2-4CWLN1T27kOJhNvXgy46ZV\include
[00:03:39] 	C:\Users\appveyor\AppData\Local\Programs\stack\x86_64-windows\ghc-8.0.1\lib\process-1.4.2.0\include
[00:03:39] 	C:\sr\snapshots\a78c6a89\lib\x86_64-windows-ghc-8.0.1\vector-0.11.0.0-BEDZb5o2QOhGbIm6ky7rl6\include
[00:03:39] 	C:\sr\snapshots\a78c6a89\lib\x86_64-windows-ghc-8.0.1\old-time-1.1.0.3-IcvdkJUsE9M8t3io8peAEp\include
[00:03:39] 	C:\Users\appveyor\AppData\Local\Programs\stack\x86_64-windows\ghc-8.0.1\lib\directory-1.2.6.2\include
[00:03:39] 	C:\sr\snapshots\a78c6a89\lib\x86_64-windows-ghc-8.0.1\primitive-0.6.1.0-Ip44DqhfCp21tTUYbecwa\include
[00:03:39] 	C:\Users\appveyor\AppData\Local\Programs\stack\x86_64-windows\ghc-8.0.1\lib\time-1.6.0.1\include
[00:03:39] 	C:\Users\appveyor\AppData\Local\Programs\stack\x86_64-windows\ghc-8.0.1\lib\Win32-2.3.1.1\include
[00:03:39] 	C:\sr\snapshots\a78c6a89\lib\x86_64-windows-ghc-8.0.1\network-2.6.3.1-nK9qnsiJR03CWuPIGMmX\include
[00:03:39] 	C:\Users\appveyor\AppData\Local\Programs\stack\x86_64-windows\ghc-8.0.1\lib\bytestring-0.10.8.1\include
[00:03:39] 	C:\Users\appveyor\AppData\Local\Programs\stack\x86_64-windows\ghc-8.0.1\lib\base-4.9.0.0\include
[00:03:39] 	C:\Users\appveyor\AppData\Local\Programs\stack\x86_64-windows\ghc-8.0.1\lib\integer-gmp-1.0.0.1\include
[00:03:39] 	C:\Users\appveyor\AppData\Local\Programs\stack\x86_64-windows\ghc-8.0.1\lib/include
[00:03:39]   Asked for by: src/Pos/CLI.hs  at line 2 col 1

It appears to trigger for each module using cpphs. The file is present, so I suspect the problem is in unix path character in C:\Users\appveyor\AppData\Local\Programs\stack\x86_64-windows\ghc-8.0.1\lib/include\ghcversion.h.

EDIT: I suspect that this bug comes from the packaging and cpphs is just called with --include by stack/cabal. Need to find a way to see how cpphs is invoked.

Continuous integration?

In response to #8 I got a bad patch merged (see #9 and #11 for fallout)--sorry! Sidenote: the latest suggestion is to apply this patch.

To avoid similar mistakes getting released in the future it would help to have CI. As explained in #9 (comment) I started cpphs-blackbox to do some very basic blackbox testing on the cpphs executable with help of TravisCI for Linux and AppVeyor for Windows. This allowed me to smoke test my latest patch, but it's not proper CI. cpphs-blackbox doesn't:

  • get triggered by PRs to cpphs codebase
  • do whitebox testing

@malcolmwallace: Since TravisCI and AppVeyor work well with GitHub repos would you consider migrating the cpphs codebase to GitHub?

Broken compilation on GHC 8.6.1

Using GHC 8.6.1 I'm getting various errors like this

$ cabal install --allow-newer
...
Building library for polyparse-1.12..
...
[ 8 of 18] Compiling Text.Parse       ( src/Text/Parse.hs, dist/build/Text/Parse.o )

src/Text/Parse.hs:230:20: error:
    • Could not deduce (Control.Monad.Fail.MonadFail (Parser Char))
        arising from a do statement
        with the failable pattern ‘'-'’
      from the context: Real a
        bound by the type signature for:
                   parseSigned :: forall a. Real a => TextParser a -> TextParser a
        at src/Text/Parse.hs:229:1-53
    • In a stmt of a 'do' block: '-' <- next
      In the first argument of ‘onFail’, namely
        ‘do '-' <- next
            commit (fmap negate p)’
      In the expression:
        do '-' <- next
           commit (fmap negate p)
          `onFail` do p
    |
230 | parseSigned p = do '-' <- next; commit (fmap negate p)
    |                    ^^^^^^^^^^^

The errors in polyparse are due to the implementation of the MonadFail proposal in GHC 8.6.1. See the reason for the errors and possible solutions here.

CPPHS fails to substitute constant

This program:

{-# LANGUAGE CPP                  #-}
{-# LANGUAGE DataKinds            #-}
{-# LANGUAGE KindSignatures       #-}
{-# LANGUAGE TypeOperators        #-}
{-# LANGUAGE TypeFamilies         #-}
{-# LANGUAGE UndecidableInstances #-}

import Data.Kind
import Data.Type.Equality
import GHC.TypeLits

#define N 2

type family V (e :: Nat) :: Constraint where
  V (e :: Nat) = (e `CmpNat` N ~ 'EQ, e `CmpNat` N ~ 'LT)

fails to generate a correctly expanded output, thus causing compilation failure down the line.

The relevant part of the expanded output is:

type family V (e :: Nat) :: Constraint where
  V (e :: Nat) = (e `CmpNat` 2 ~ 'EQ, e `CmpNat` N ~ 'LT)

Notice that CPPHS substituted for the first occurrence of N, but not the second. Most likely it's getting confused by the occurrence of two ' characters, and leaving whatever is inside untouched. But that's not a valid Haskell character, so I would've expected this to work correctly.

There's a simple work-around by putting the second part in a line by itself:

  V (e :: Nat) = ( e `CmpNat` N ~ 'EQ
                 , e `CmpNat` N ~ 'LT)

in which case the expansion correctly replaces N in both lines.

So, there's a work around; but would be nice if it wasn't needed.

cpphs fails to parse an `#if` directive

The code is compiled with:

   cpp-options: -DMIN_VERSION_GHC(x,y)=MIN_VERSION_GLASGOW_HASKELL(x,y,0,0)

And cpphs trips over

#if !MIN_VERSION_GHC(8,10)

(ref), with the following error:

cpphs: Cannot parse #if directive in file lib/GhcTags/Ghc.hs  at line 5 col 1:
    expected ) got *
CallStack (from HasCallStack):

  error, called at ./Language/Preprocessor/Cpphs/CppIfdef.hs:192:0: error:
Error:     28 in main:Language.Preprocessor.Cpphs.CppIfdef
cpphs: Cannot parse #if directive in file lib/GhcTags/Tag.hs  at line 52 col 1:
    expected ) got *
CallStack (from HasCallStack):

  error, called at ./Language/Preprocessor/Cpphs/CppIfdef.hs:192:0: error:
Error:     28 in main:Language.Preprocessor.Cpphs.CppIfdef

lib/GhcTags/Ghc.hs:1:1: error:
Error:     `cpphs' failed in phase `C pre-processor'. (Exit code: 1)
  |
1 | {-# LANGUAGE CPP                 #-}
  | ^

lib/GhcTags/Tag.hs:1:1: error:
Error:     `cpphs' failed in phase `C pre-processor'. (Exit code: 1)
  |
1 | {-# LANGUAGE CPP                 #-}
  | ^
Error: cabal: Failed to build ghc-tags-core-0.4.1.0 (which is required by
exe:gtp-check from ghc-tags-plugin-0.5.1.0 and test:test from
ghc-tags-core-0.4.1.0).

Here's CI log: https://github.com/coot/ghc-tags-plugin/actions/runs/3085403434/jobs/4988652786#step:15:1

cpphs 1.20.9 fails to build on GHC 7.8.4 because of time library

Log of the build failure:

vanessa@vanessa-desktop ~/git-builds/junk/cpphs-1.20.9 🌸 cabal build -w ghc-7.8.4
Build profile: -w ghc-7.8.4 -O1
In order, the following will be built (use -v for more details):
 - cpphs-1.20.9 (lib:cpphs, exe:cpphs) (first run)
Preprocessing executable 'cpphs' for cpphs-1.20.9..
Building executable 'cpphs' for cpphs-1.20.9..
[ 7 of 12] Compiling Language.Preprocessor.Cpphs.MacroPass ( Language/Preprocessor/Cpphs/MacroPass.hs, /home/vanessa/git-builds/junk/cpphs-1.20.9/dist-newstyle/build/x86_64-linux/ghc-7.8.4/cpphs-1.20.9/build/cpphs/cpphs-tmp/Language/Preprocessor/Cpphs/MacroPass.o )

Language/Preprocessor/Cpphs/MacroPass.hs:35:38:
    Module ‘Data.Time.Format’ does not export ‘defaultTimeLocale’

It seems to be building against time 1.4.2, perhaps a lower bound would fix that?

No option for newlines with --cpp

I'd like to use the preprocessor to automate writing doctests for an Enum, and so obviously need the generated Haddock to span multiple lines. cpphs sounds like it's by far the best way to do so, with --layout. My workflow also dictates that I use cabal to start things building; because of how it constructs the ghc command, that then requires --cpp to be set. Unfortunately, doing so means that --layout gets ignored, and the Haddock gets clobbered to a single line. I feel I should note that occurs with any invocation of cpphs, not just via cabal.

That should be disappointing but not debilitating as newline replacements should work just fine, according to the documentation, but the \\n expansion never seems to work (and //n just deletes to the end of the definition). Am I missing something in how it should be invoked, or is there actually an issue?

## concatenation operator isn't supported

If this is by design, it should be documented:

% cat foo.h
#define M(x) x##bar

M(foo)
M(quux)
% cpp foo.h 
# 1 "foo.h"
# 1 "<built-in>"
# 1 "<command-line>"
# 31 "<command-line>"
# 1 "/usr/include/stdc-predef.h" 1 3 4
# 32 "<command-line>" 2
# 1 "foo.h"


foobar
quuxbar
% cpphs foo.h 
#line 1 "foo.h"


foo##bar
quux##bar

cpphs 1.20.5 broken when using GHC 8.2.1 on Windows

On Linux, Installing Agda with cpphs 1.20.4, I got a large number of messages of the following shape:

$ cabal get Agda
$ cd Agda
$ cabal install
...
Warning: Can't find file "/usr/local/stow/ghc-8.0.2/lib/ghc-8.0.2/include/ghcversion.h" in directories
	
  Asked for by: src/full/Agda/Auto/Auto.hs  at line 2 col 1

I didn't get those warning when using cpphs 1.20.3.

Blocking agda/agda#2496.

Proposal: split cpphs in the library and the executable

cpphs has two different and independent uses: the library and the executable. For example, Agda uses the executable but not the library, and haskell-src-exts uses the library but not the executable. In fact, there are different Cabal fields for representing the different uses: build-depends for the library and build-tools for the executable. I suggest to split cpphs in the cpphs-library and the cpphs-executable.

cpphs only compiles on ghc 9.0 rc1` if you use --allow-new

cpphs only compiles on ghc 9.0 rc1` if you use --allow-new

$ cabal install cpphs
Warning: Unknown/unsupported 'ghc' version detected (Cabal 3.2.0.0 supports
'ghc' version < 8.12): /usr/local/bin/ghc is version 9.0.0.20201227
Warning: Unknown/unsupported 'ghc' version detected (Cabal 3.2.0.0 supports
'ghc' version < 8.12): /usr/local/bin/ghc is version 9.0.0.20201227
Resolving dependencies...
cabal: Could not resolve dependencies:
[__0] trying: cpphs-1.20.9.1 (user goal)
[__1] trying: polyparse-1.13 (dependency of cpphs)
[__2] next goal: base (dependency of cpphs)
[__2] rejecting: base-4.15.0.0/installed-4.15.0.0 (conflict: polyparse =>
base>=4.3.1.0 && <4.15)
[__2] rejecting: base-4.14.1.0, base-4.14.0.0, base-4.13.0.0, base-4.12.0.0,
base-4.11.1.0, base-4.11.0.0, base-4.10.1.0, base-4.10.0.0, base-4.9.1.0,
base-4.9.0.0, base-4.8.2.0, base-4.8.1.0, base-4.8.0.0, base-4.7.0.2,
base-4.7.0.1, base-4.7.0.0, base-4.6.0.1, base-4.6.0.0, base-4.5.1.0,
base-4.5.0.0, base-4.4.1.0, base-4.4.0.0, base-4.3.1.0, base-4.3.0.0,
base-4.2.0.2, base-4.2.0.1, base-4.2.0.0, base-4.1.0.0, base-4.0.0.0,
base-3.0.3.2, base-3.0.3.1 (constraint from non-upgradeable package requires
installed instance)
[__2] fail (backjumping, conflict set: base, cpphs, polyparse)
After searching the rest of the dependency tree exhaustively, these were the
goals I've had most trouble fulfilling: base, cpphs, polyparse

bash-3.2$ cabal install cpphs --allow-new
Warning: Unknown/unsupported 'ghc' version detected (Cabal 3.2.0.0 supports
'ghc' version < 8.12): /usr/local/bin/ghc is version 9.0.0.20201227
Warning: Unknown/unsupported 'ghc' version detected (Cabal 3.2.0.0 supports
'ghc' version < 8.12): /usr/local/bin/ghc is version 9.0.0.20201227
Resolving dependencies...
Build profile: -w ghc-9.0.0.20201227 -O1
In order, the following will be built (use -v for more details):
 - cpphs-1.20.9.1 (exe:cpphs) (requires build)
Starting     cpphs-1.20.9.1 (exe:cpphs)
Building     cpphs-1.20.9.1 (exe:cpphs)
Installing   cpphs-1.20.9.1 (exe:cpphs)
Completed    cpphs-1.20.9.1 (exe:cpphs)
Symlinking 'cpphs'
ghc --version
The Glorious Glasgow Haskell Compilation System, version 9.0.0.20201227

cpphs 1.20.8 chokes on sys/cdefs.h

When trying to parse "sys/cdefs.h", the following error occurs:


cpphs: Cannot parse #if directive in file /usr/include/x86_64-linux-gnu/sys/cdefs.h  at line 415 col 1:
    expected ) got ?
CallStack (from HasCallStack):
  error, called at ./Language/Preprocessor/Cpphs/CppIfdef.hs:192:28 in main:Language.Preprocessor.Cpphs.CppIfdef

Relevant statement:

#if (!defined _Noreturn \
     && (defined __STDC_VERSION__ ? __STDC_VERSION__ : 0) < 201112 \
     &&  !__GNUC_PREREQ (4,7))
# if __GNUC_PREREQ (2,8)
#  define _Noreturn __attribute__ ((__noreturn__))
# else
#  define _Noreturn
# endif
#endif

Error when using cpphs in some locale environments

Some Agda users have reported an error when installing Agda in their locale environments.

A MWE (adapted from this example) is the following:

$ cat Test.hs
module Main where

main = putStrLn "∀"
$ LC_CTYPE=C cpphs Test.hs > /dev/null
cpphs: Test.hs: hGetContents: invalid argument (invalid byte sequence)

@nad wrote here:

I guess that cpphs uses the standard, locale-aware methods to read files. I think all of our source files use the UTF-8 character encoding, so the problem can perhaps be solved by setting LC_CTYPE to .UTF-8 before invoking cpphs, for some locale .UTF-8 that is installed. However, I would not be surprised if it is impossible to do this in a system-independent way. Perhaps it would be better to add a --utf8 flag to cpphs.

Blocking agda/agda#2112.

Warnings about trailing characters always emitted

Even if you pass --nowarn (aka SuppressWarnings) to disable the warnings option, warnings about trailing characters are emitted anyway. Specifically this warning:

Warning: trailing characters after #if macro expansion in file FILE: CHARS

The warnings come from Language.Preprocessor.Cpphs.CppIfdef.gatherDefined. The warnings flag should be respected, like it is for Language.Preprocessor.Cpphs.ReadFirst.readFirst.

Pathnames beginning with more than one slash cause invalid output

If we pass pathnames starting with more than one slash to -include, cpphs generates invalid output. These are valid UNIX pathnames. I've tested with version 1.20.1 on Linux.

Example:

$ touch empty.hs
$ cpphs --cpp -include //dev/null empty.hs
#line 1 "test.hs"
#line 1 "
#line 2 "test.hs"
#line 1 "test.hs"

If I remove the extra '/', I get a good output:

$ touch empty.hs
$ cpphs --cpp -include /dev/null empty.hs
#line 1 "test.hs"
#line 1 "/dev/null"
#line 2 "test.hs"
#line 1 "test.hs"

compile error in xkbcommon on current arch

On current archlinux xkbcommon fails to compile.
I mainly care about my fork of it: https://github.com/ongy/haskell-xkbcommon it should be easier to compile.

The error:

    /home/simon/dev/waymonad/hsroots/haskell-xkbcommon/Text/XkbCommon/KeycodeList.hs:1:1: error:
        Exception when trying to run compile-time code:
          /home/simon/dev/waymonad/hsroots/haskell-xkbcommon/Language/Preprocessor/Cpphs/MacroPass.hs:(96,9)-(97,68): Irrefutable pattern failed for pattern Cmd (Just hd) : _                                                                                                   
    
        Code: runIO genKeycodes >>= return
      |
    1 | {-# LANGUAGE TemplateHaskell #-}
      | ^

The attached patch fixes it locally, but there may be some sideeffect I'm not aware of. Also I'm not sure how to properly submit patches for this project, so I'll just attach it here.

diff -rN -u old-cpphs/Language/Preprocessor/Cpphs/Tokenise.hs new-cpphs/Language/Preprocessor/Cpphs/Tokenise.hs
--- old-cpphs/Language/Preprocessor/Cpphs/Tokenise.hs	2018-05-08 16:57:53.934565562 +0200
+++ new-cpphs/Language/Preprocessor/Cpphs/Tokenise.hs	2018-05-08 16:57:53.934565562 +0200
@@ -204,6 +204,8 @@
     lexcpp LineComment w l ls (_:xs)      = lexcpp LineComment (' ':w) l ls xs
     lexcpp (NestComment _) w l ls ('*':'/':xs)
                                           = lexcpp Any [] (w*/*l) ls xs
+    lexcpp (NestComment _) w l ls xs@('\n':_)
+                                          = lexcpp Any [] (w*/*l) ls xs
     lexcpp (NestComment n) w l ls (x:xs)  = lexcpp (NestComment n) (white x:w) l
                                                                         ls xs
     lexcpp mode w l ((p,l'):ls) []        = cpp mode next w l p ls ('\n':l')

Stop using old-time

The package is hard to install and not required by most things. It would be good if cpphs switched to time, which makes the installation process on Windows a bit smoother.

Stringizing deviates from the spec

According to the specification, In stringization the parameters should not be replaced inside string constants i.e the argument should not be macro expanded.

A sample code demonstrating the problem:

{-#LANGUAGE CPP#-}

#define CHECK_FOR_EQUALITY(exp) if exp then "Equal" else #exp
#define x 3

check :: String
check = CHECK_FOR_EQUALITY(x == 0)

main :: IO ()
main = print check

Running it via cpphs gives this:

#line 1 "cppCode.hs"
{-#LANGUAGE CPP#-}

check :: String
check = if 3 == 0 then "Equal" else "3 == 0"

main :: IO ()
main = print check

But the check definition should be like this:

check = if 3 == 0 then "Equal" else "x == 0"

In fact, I can confirm that gnu's cpp behaves as expected

~/g/scripts $ cpp < cppCode.hs
# 1 "<stdin>"
# 1 "<built-in>"
# 1 "<command-line>"
# 1 "/usr/include/stdc-predef.h" 1 3 4
# 1 "<command-line>" 2
# 1 "<stdin>"
{-#LANGUAGE CPP#-}




check :: String
check = if 3 == 0 then "Equal" else "x == 0"

main :: IO ()
main = print check

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.