Fergus Henderson writes:
>
> > module CmdLineOpts where
> >
> > argv = unsafePerformIO getArgs
> >
> > unfoldSize :: Int
> > unfoldSize = lookupInt "-funfold-size" argv
> >
> > useCleverFiniteMap :: Bool
> > useCleverFiniteMap = lookup "-fclever" argv
>
> I have a comment, and couple of questions.
>
> First, this will involve scanning argv once for each possible option;
> I guess option handling is not likely to be a bottleneck, but still...
> this offends some aesthetic sense of mine.
>
Mine too :), you're very right that this isn't critical to the overall
performance of a program, but I think being efficient here is a Good
Idea anyhow, as it brings down startup times of applications. Getting a
one pass solution is not hard, here's one way of doing it:
data GhcOpts
= GhcOpts {
opt_useCleverFiniteMap :: Bool,
opt_unfoldSize :: Bool,
...
unrecognised :: [String]
}
default_ghc_opts :: GhcOpts
default_ghc_opts = GhcOpts {....}
getOpts :: Opt a -> a -> [String] -> a
ghc_opts :: GhcOpts
ghc_opts = getOpts opts_spec default_ghc_opts System.argv
useCleverFiniteMap = opt_useCleverFiniteMap ghc_opts
unfoldSize = opt_unfoldSize ghc_opts
i.e., make one pass over argv, filling up a record holding the
different options supported. For the actual scanning, I'm using a
monadic library for specifying matching conditions and how to
record the option match.
>
> Second, how do you handle syntax errors in the command line arguments?
> What does lookupInt do if the integer overflows, or if the argument
> is not valid syntax for an integer? Do you check for misspelt or
> invalid option names?
>
Validation is still the same, you would check the arguments for
suitability when `read'ing the character string for the different
options, or at the point of use, e.g., does the input file really exist?
Unrecognised options and/or other bogus stuff could just be
accumulated in ghc_opts, and then inspect it in `main'.
Re: argv, I'd actually prefer if it had an abstract type or was a list
of packed strings, representing bona fide finite character strings as
a list of characters is another Death Wish, IMHO. Don't know the
status of the PackedString library though, and whether it will be made
standard or not.
> > PS. I'm less steamed up about the stdin issue; but I think you missed
> > Sigbjorn's point. Yes stdin is a constant now, but he'd like stdin *not* to
> > be a constant, so that he could take a value of type IO () that used stdin,
> > and reconnect its stdin to (say) a file.
>
> Even if stdin remains a constant, you could still do that, because even
> if the handle is a constant, the connection between handle and file can
> still vary, just as the file contents can vary.
>
A multi-threaded setting and/or non-strict reads (hGetContents)
restricts that possibility quite a bit, as mentioned in other mails.
Regards,
--Sigbjorn