9

I use cmdargs to write CLI parsers for my Haskell programs.

Let's assume this program, derived directly from their example:

{-# LANGUAGE DeriveDataTypeable #-}
import System.Console.CmdArgs.Implicit

data Sample = Sample {hello :: String} deriving (Show, Data, Typeable)

sample = Sample{hello = def &= help "World argument" &= opt "world"}
         &= summary "Sample v1"

main = print =<< cmdArgs sample

If this program is called cmdtest.hs, I can execute

$ runghc cmdtest.hs --hello=world
Sample {hello = "world"}

However, if I leave off the equals sign (like in the -o option in gcc -o foo foobar.c), cmdargs tries to recognize world as a positional argument

$ runghc cmdtest.hs --hello world
Unhandled argument, none expected: world

Is there any option / annotation I can set to allow this syntax in cmdargs?

Update: Using the short option exposes the same problem:

$ runghc cmdtest.hs -h world
Unhandled argument, none expected: world

Update 2: The FlagInfo data in the cmdargs Explicit module seems to suggest it is somehow possible, at least if using Explicit instead of Implicit

Uli Köhler
  • 13,012
  • 16
  • 70
  • 120

1 Answers1

4

Your problem is that you're using opt which makes the value of --hello optional. So --hello world is taken to mean --hello without a value, followed by world as a positional parameter. This is of course a design choice in cmdargs, but I think it's a reasonable one, and it matches the behaviour of most other programs. Take out the opt and see if it works the way you want.

Neil Mayhew
  • 14,206
  • 3
  • 33
  • 25
  • 2
    Apparently, the GNU C function getopt_long behaves the same way. See this [question](http://stackoverflow.com/questions/1052746/getopt-does-not-parse-optional-arguments-to-parameters), for example. – Neil Mayhew Mar 27 '14 at 02:40
  • I found it a bit surprising. See https://github.com/ndmitchell/cmdargs/issues/2 and linked discussion. – Simon Michael Aug 28 '14 at 00:32