[project @ 2001-01-21 16:37:06 by sewardj]
[ghc-hetmet.git] / ghc / compiler / main / CmdLineOpts.lhs
1 %
2 % (c) The University of Glasgow, 1996-2000
3 %
4 \section[CmdLineOpts]{Things to do with command-line options}
5
6 \begin{code}
7
8 module CmdLineOpts (
9         CoreToDo(..),
10         SimplifierSwitch(..), isAmongSimpl,
11         StgToDo(..),
12         SwitchResult(..),
13
14         HscLang(..),
15         DynFlag(..),    -- needed non-abstractly by DriverFlags
16         DynFlags(..),
17         defaultDynFlags,
18
19         v_Static_hsc_opts,
20
21         intSwitchSet,
22         switchIsOn,
23         isStaticHscFlag,
24
25         opt_PprStyle_NoPrags,
26         opt_PprStyle_RawTypes,
27         opt_PprUserLength,
28         opt_PprStyle_Debug,
29
30         dopt,
31
32         -- other dynamic flags
33         dopt_CoreToDo,
34         dopt_StgToDo,
35         dopt_HscLang,
36         dopt_OutName,
37
38         -- profiling opts
39         opt_AutoSccsOnAllToplevs,
40         opt_AutoSccsOnExportedToplevs,
41         opt_AutoSccsOnIndividualCafs,
42         opt_AutoSccsOnDicts,
43         opt_SccProfilingOn,
44         opt_DoTickyProfiling,
45
46         -- language opts
47         opt_AllStrict,
48         opt_DictsStrict,
49         opt_MaxContextReductionDepth,
50         opt_IrrefutableTuples,
51         opt_NumbersStrict,
52         opt_Parallel,
53         opt_SMP,
54         opt_NoMonomorphismRestriction,
55
56         -- optimisation opts
57         opt_DoSemiTagging,
58         opt_FoldrBuildOn,
59         opt_LiberateCaseThreshold,
60         opt_StgDoLetNoEscapes,
61         opt_UnfoldCasms,
62         opt_UsageSPOn,
63         opt_UnboxStrictFields,
64         opt_SimplNoPreInlining,
65         opt_SimplDoEtaReduction,
66         opt_SimplDoLambdaEtaExpansion,
67         opt_SimplCaseOfCase,
68         opt_SimplCaseMerge,
69         opt_SimplPedanticBottoms,
70         opt_SimplExcessPrecision,
71
72         -- Unfolding control
73         opt_UF_HiFileThreshold,
74         opt_UF_CreationThreshold,
75         opt_UF_UseThreshold,
76         opt_UF_FunAppDiscount,
77         opt_UF_KeenessFactor,
78         opt_UF_UpdateInPlace,
79         opt_UF_CheapOp,
80         opt_UF_DearOp,
81
82         -- misc opts
83         opt_InPackage,
84         opt_EmitCExternDecls,
85         opt_EnsureSplittableC,
86         opt_GranMacros,
87         opt_HiVersion,
88         opt_HistorySize,
89         opt_IgnoreAsserts,
90         opt_IgnoreIfacePragmas,
91         opt_NoHiCheck,
92         opt_OmitBlackHoling,
93         opt_OmitInterfacePragmas,
94         opt_NoPruneTyDecls,
95         opt_NoPruneDecls,
96         opt_Static,
97         opt_Unregisterised
98     ) where
99
100 #include "HsVersions.h"
101
102 import Array    ( array, (//) )
103 import GlaExts
104 import IOExts   ( IORef, readIORef )
105 import Constants        -- Default values for some flags
106 import Util
107 import FastTypes
108 import Config
109
110 import Maybes           ( firstJust )
111 import Panic            ( panic )
112
113 #if __GLASGOW_HASKELL__ < 301
114 import ArrBase  ( Array(..) )
115 #else
116 import PrelArr  ( Array(..) )
117 #endif
118 \end{code}
119
120 %************************************************************************
121 %*                                                                      *
122 \subsection{Command-line options}
123 %*                                                                      *
124 %************************************************************************
125
126 The hsc command-line options are split into two categories:
127
128   - static flags
129   - dynamic flags
130
131 Static flags are represented by top-level values of type Bool or Int,
132 for example.  They therefore have the same value throughout the
133 invocation of hsc.
134
135 Dynamic flags are represented by an abstract type, DynFlags, which is
136 passed into hsc by the compilation manager for every compilation.
137 Dynamic flags are those that change on a per-compilation basis,
138 perhaps because they may be present in the OPTIONS pragma at the top
139 of a module.
140
141 Other flag-related blurb:
142
143 A list of {\em ToDo}s is things to be done in a particular part of
144 processing.  A (fictitious) example for the Core-to-Core simplifier
145 might be: run the simplifier, then run the strictness analyser, then
146 run the simplifier again (three ``todos'').
147
148 There are three ``to-do processing centers'' at the moment.  In the
149 main loop (\tr{main/Main.lhs}), in the Core-to-Core processing loop
150 (\tr{simplCore/SimplCore.lhs), and in the STG-to-STG processing loop
151 (\tr{simplStg/SimplStg.lhs}).
152
153 %************************************************************************
154 %*                                                                      *
155 \subsection{Datatypes associated with command-line options}
156 %*                                                                      *
157 %************************************************************************
158
159 \begin{code}
160 data SwitchResult
161   = SwBool      Bool            -- on/off
162   | SwString    FAST_STRING     -- nothing or a String
163   | SwInt       Int             -- nothing or an Int
164 \end{code}
165
166 \begin{code}
167 data CoreToDo           -- These are diff core-to-core passes,
168                         -- which may be invoked in any order,
169                         -- as many times as you like.
170
171   = CoreDoSimplify      -- The core-to-core simplifier.
172         (SimplifierSwitch -> SwitchResult)
173                         -- Each run of the simplifier can take a different
174                         -- set of simplifier-specific flags.
175   | CoreDoFloatInwards
176   | CoreDoFloatOutwards Bool    -- True <=> float lambdas to top level
177   | CoreLiberateCase
178   | CoreDoPrintCore
179   | CoreDoStaticArgs
180   | CoreDoStrictness
181   | CoreDoWorkerWrapper
182   | CoreDoSpecialising
183   | CoreDoUSPInf
184   | CoreDoCPResult
185   | CoreDoGlomBinds
186   | CoreCSE
187
188   | CoreDoNothing        -- useful when building up lists of these things
189 \end{code}
190
191 \begin{code}
192 data StgToDo
193   = StgDoMassageForProfiling  -- should be (next to) last
194   -- There's also setStgVarInfo, but its absolute "lastness"
195   -- is so critical that it is hardwired in (no flag).
196   | D_stg_stats
197 \end{code}
198
199 \begin{code}
200 data SimplifierSwitch
201   = MaxSimplifierIterations Int
202   | SimplInlinePhase Int
203   | DontApplyRules
204   | NoCaseOfCase
205   | SimplLetToCase
206 \end{code}
207
208 %************************************************************************
209 %*                                                                      *
210 \subsection{Dynamic command-line options}
211 %*                                                                      *
212 %************************************************************************
213
214 \begin{code}
215 data DynFlag
216
217    -- debugging flags
218    = Opt_D_dump_absC
219    | Opt_D_dump_asm
220    | Opt_D_dump_cpranal
221    | Opt_D_dump_deriv
222    | Opt_D_dump_ds
223    | Opt_D_dump_flatC
224    | Opt_D_dump_foreign
225    | Opt_D_dump_inlinings
226    | Opt_D_dump_occur_anal
227    | Opt_D_dump_parsed
228    | Opt_D_dump_realC
229    | Opt_D_dump_rn
230    | Opt_D_dump_simpl
231    | Opt_D_dump_simpl_iterations
232    | Opt_D_dump_spec
233    | Opt_D_dump_sat
234    | Opt_D_dump_stg
235    | Opt_D_dump_stranal
236    | Opt_D_dump_tc
237    | Opt_D_dump_types
238    | Opt_D_dump_rules
239    | Opt_D_dump_usagesp
240    | Opt_D_dump_cse
241    | Opt_D_dump_worker_wrapper
242    | Opt_D_dump_rn_trace
243    | Opt_D_dump_rn_stats
244    | Opt_D_dump_stix
245    | Opt_D_dump_simpl_stats
246    | Opt_D_dump_BCOs
247    | Opt_D_source_stats
248    | Opt_D_verbose_core2core
249    | Opt_D_verbose_stg2stg
250    | Opt_D_dump_hi
251    | Opt_D_dump_hi_diffs
252    | Opt_D_dump_minimal_imports
253    | Opt_DoCoreLinting
254    | Opt_DoStgLinting
255    | Opt_DoUSPLinting
256
257    | Opt_WarnDuplicateExports
258    | Opt_WarnHiShadows
259    | Opt_WarnIncompletePatterns
260    | Opt_WarnMissingFields
261    | Opt_WarnMissingMethods
262    | Opt_WarnMissingSigs
263    | Opt_WarnNameShadowing
264    | Opt_WarnOverlappingPatterns
265    | Opt_WarnSimplePatterns
266    | Opt_WarnTypeDefaults
267    | Opt_WarnUnusedBinds
268    | Opt_WarnUnusedImports
269    | Opt_WarnUnusedMatches
270    | Opt_WarnDeprecations
271
272    -- language opts
273    | Opt_AllowOverlappingInstances
274    | Opt_AllowUndecidableInstances
275    | Opt_GlasgowExts
276    | Opt_Generics
277    | Opt_NoImplicitPrelude 
278
279    -- misc
280    | Opt_ReportCompile
281    deriving (Eq)
282
283 data DynFlags = DynFlags {
284   coreToDo              :: [CoreToDo],
285   stgToDo               :: [StgToDo],
286   hscLang               :: HscLang,
287   hscOutName            :: String,      -- name of the output file
288   verbosity             :: Int,         -- verbosity level
289   cppFlag               :: Bool,        -- preprocess with cpp?
290   stolen_x86_regs       :: Int,         
291   cmdlineHcIncludes     :: [String],    -- -#includes
292
293   -- options for particular phases
294   opt_L                 :: [String],
295   opt_P                 :: [String],
296   opt_c                 :: [String],
297   opt_a                 :: [String],
298   opt_m                 :: [String],
299
300   -- hsc dynamic flags
301   flags                 :: [DynFlag]
302  }
303
304 defaultDynFlags = DynFlags {
305   coreToDo = [], stgToDo = [], 
306   hscLang = HscC, 
307   hscOutName = "", 
308   verbosity = 0, 
309   cppFlag               = False,
310   stolen_x86_regs       = 4,
311   cmdlineHcIncludes     = [],
312   opt_L                 = [],
313   opt_P                 = [],
314   opt_c                 = [],
315   opt_a                 = [],
316   opt_m                 = [],
317   flags = []
318   }
319
320 {- 
321     Verbosity levels:
322         
323     0   |   print errors & warnings only
324     1   |   minimal verbosity: print "compiling M ... done." for each module.
325     2   |   equivalent to -dshow-passes
326     3   |   equivalent to existing "ghc -v"
327     4   |   "ghc -v -ddump-most"
328     5   |   "ghc -v -ddump-all"
329 -}
330
331 dopt :: DynFlag -> DynFlags -> Bool
332 dopt f dflags  = f `elem` (flags dflags)
333
334 dopt_CoreToDo :: DynFlags -> [CoreToDo]
335 dopt_CoreToDo = coreToDo
336
337 dopt_StgToDo :: DynFlags -> [StgToDo]
338 dopt_StgToDo = stgToDo
339
340 dopt_OutName :: DynFlags -> String
341 dopt_OutName = hscOutName
342
343 data HscLang
344   = HscC
345   | HscAsm
346   | HscJava
347   | HscInterpreted
348     deriving (Eq, Show)
349
350 dopt_HscLang :: DynFlags -> HscLang
351 dopt_HscLang = hscLang
352 \end{code}
353
354 %************************************************************************
355 %*                                                                      *
356 \subsection{Classifying command-line options}
357 %*                                                                      *
358 %************************************************************************
359
360 \begin{code}
361 -- v_Statis_hsc_opts is here to avoid a circular dependency with
362 -- main/DriverState.
363 GLOBAL_VAR(v_Static_hsc_opts, [], [String])
364
365 lookUp           :: FAST_STRING -> Bool
366 lookup_int       :: String -> Maybe Int
367 lookup_def_int   :: String -> Int -> Int
368 lookup_def_float :: String -> Float -> Float
369 lookup_str       :: String -> Maybe String
370
371 unpacked_static_opts = unsafePerformIO (readIORef v_Static_hsc_opts)
372 packed_static_opts   = map _PK_ unpacked_static_opts
373
374 lookUp     sw = sw `elem` packed_static_opts
375         
376 lookup_str sw = firstJust (map (startsWith sw) unpacked_static_opts)
377
378 lookup_int sw = case (lookup_str sw) of
379                   Nothing -> Nothing
380                   Just xx -> Just (read xx)
381
382 lookup_def_int sw def = case (lookup_str sw) of
383                             Nothing -> def              -- Use default
384                             Just xx -> read xx
385
386 lookup_def_float sw def = case (lookup_str sw) of
387                             Nothing -> def              -- Use default
388                             Just xx -> read xx
389
390
391 {-
392  Putting the compiler options into temporary at-files
393  may turn out to be necessary later on if we turn hsc into
394  a pure Win32 application where I think there's a command-line
395  length limit of 255. unpacked_opts understands the @ option.
396
397 unpacked_opts :: [String]
398 unpacked_opts =
399   concat $
400   map (expandAts) $
401   map _UNPK_ argv  -- NOT ARGV any more: v_Static_hsc_opts
402   where
403    expandAts ('@':fname) = words (unsafePerformIO (readFile fname))
404    expandAts l = [l]
405 -}
406 \end{code}
407
408 %************************************************************************
409 %*                                                                      *
410 \subsection{Static options}
411 %*                                                                      *
412 %************************************************************************
413
414 \begin{code}
415 -- debugging opts
416 opt_PprStyle_NoPrags            = lookUp  SLIT("-dppr-noprags")
417 opt_PprStyle_Debug              = lookUp  SLIT("-dppr-debug")
418 opt_PprStyle_RawTypes           = lookUp  SLIT("-dppr-rawtypes")
419 opt_PprUserLength               = lookup_def_int "-dppr-user-length" 5 --ToDo: give this a name
420
421 -- profiling opts
422 opt_AutoSccsOnAllToplevs        = lookUp  SLIT("-fauto-sccs-on-all-toplevs")
423 opt_AutoSccsOnExportedToplevs   = lookUp  SLIT("-fauto-sccs-on-exported-toplevs")
424 opt_AutoSccsOnIndividualCafs    = lookUp  SLIT("-fauto-sccs-on-individual-cafs")
425 opt_AutoSccsOnDicts             = lookUp  SLIT("-fauto-sccs-on-dicts")
426 opt_SccProfilingOn              = lookUp  SLIT("-fscc-profiling")
427 opt_DoTickyProfiling            = lookUp  SLIT("-fticky-ticky")
428
429 -- language opts
430 opt_AllStrict                   = lookUp  SLIT("-fall-strict")
431 opt_NoMonomorphismRestriction   = lookUp  SLIT("-fno-monomorphism-restriction")
432 opt_DictsStrict                 = lookUp  SLIT("-fdicts-strict")
433 opt_IrrefutableTuples           = lookUp  SLIT("-firrefutable-tuples")
434 opt_MaxContextReductionDepth    = lookup_def_int "-fcontext-stack" mAX_CONTEXT_REDUCTION_DEPTH
435 opt_NumbersStrict               = lookUp  SLIT("-fnumbers-strict")
436 opt_Parallel                    = lookUp  SLIT("-fparallel")
437 opt_SMP                         = lookUp  SLIT("-fsmp")
438
439 -- optimisation opts
440 opt_DoSemiTagging               = lookUp  SLIT("-fsemi-tagging")
441 opt_FoldrBuildOn                = lookUp  SLIT("-ffoldr-build-on")
442 opt_LiberateCaseThreshold       = lookup_def_int "-fliberate-case-threshold" (10::Int)
443 opt_StgDoLetNoEscapes           = lookUp  SLIT("-flet-no-escape")
444 opt_UnfoldCasms                 = lookUp SLIT("-funfold-casms-in-hi-file")
445 opt_UsageSPOn                   = lookUp  SLIT("-fusagesp-on")
446 opt_UnboxStrictFields           = lookUp  SLIT("-funbox-strict-fields")
447
448 {-
449    The optional '-inpackage=P' flag tells what package
450    we are compiling this module for.
451    The Prelude, for example is compiled with '-package prelude'
452 -}
453 opt_InPackage                   = case lookup_str "-inpackage=" of
454                                     Just p  -> _PK_ p
455                                     Nothing -> SLIT("Main")     -- The package name if none is specified
456
457 opt_EmitCExternDecls            = lookUp  SLIT("-femit-extern-decls")
458 opt_EnsureSplittableC           = lookUp  SLIT("-fglobalise-toplev-names")
459 opt_GranMacros                  = lookUp  SLIT("-fgransim")
460 opt_HiVersion                   = read cProjectVersionInt :: Int
461 opt_HistorySize                 = lookup_def_int "-fhistory-size" 20
462 opt_IgnoreAsserts               = lookUp  SLIT("-fignore-asserts")
463 opt_IgnoreIfacePragmas          = lookUp  SLIT("-fignore-interface-pragmas")
464 opt_NoHiCheck                   = lookUp  SLIT("-fno-hi-version-check")
465 opt_OmitBlackHoling             = lookUp  SLIT("-dno-black-holing")
466 opt_OmitInterfacePragmas        = lookUp  SLIT("-fomit-interface-pragmas")
467
468 -- Simplifier switches
469 opt_SimplNoPreInlining          = lookUp SLIT("-fno-pre-inlining")
470         -- NoPreInlining is there just to see how bad things
471         -- get if you don't do it!
472 opt_SimplDoEtaReduction         = lookUp SLIT("-fdo-eta-reduction")
473 opt_SimplDoLambdaEtaExpansion   = lookUp SLIT("-fdo-lambda-eta-expansion")
474 opt_SimplCaseOfCase             = lookUp SLIT("-fcase-of-case")
475 opt_SimplCaseMerge              = lookUp SLIT("-fcase-merge")
476 opt_SimplPedanticBottoms        = lookUp SLIT("-fpedantic-bottoms")
477 opt_SimplExcessPrecision        = lookUp SLIT("-fexcess-precision")
478
479 -- Unfolding control
480 opt_UF_HiFileThreshold          = lookup_def_int "-funfolding-interface-threshold" (45::Int)
481 opt_UF_CreationThreshold        = lookup_def_int "-funfolding-creation-threshold"  (45::Int)
482 opt_UF_UseThreshold             = lookup_def_int "-funfolding-use-threshold"       (8::Int)     -- Discounts can be big
483 opt_UF_FunAppDiscount           = lookup_def_int "-funfolding-fun-discount"        (6::Int)     -- It's great to inline a fn
484 opt_UF_KeenessFactor            = lookup_def_float "-funfolding-keeness-factor"    (1.5::Float)
485 opt_UF_UpdateInPlace            = lookUp  SLIT("-funfolding-update-in-place")
486
487 opt_UF_CheapOp  = ( 1 :: Int)   -- Only one instruction; and the args are charged for
488 opt_UF_DearOp   = ( 4 :: Int)
489                         
490 opt_NoPruneDecls                = lookUp SLIT("-fno-prune-decls")
491 opt_NoPruneTyDecls              = lookUp SLIT("-fno-prune-tydecls")
492 opt_Static                      = lookUp SLIT("-static")
493 opt_Unregisterised              = lookUp SLIT("-funregisterised")
494 \end{code}
495
496 %************************************************************************
497 %*                                                                      *
498 \subsection{List of static hsc flags}
499 %*                                                                      *
500 %************************************************************************
501
502 \begin{code}
503 isStaticHscFlag f =
504   f `elem` [
505         "fauto-sccs-on-all-toplevs",
506         "fauto-sccs-on-exported-toplevs",
507         "fauto-sccs-on-individual-cafs",
508         "fauto-sccs-on-dicts",
509         "fscc-profiling",
510         "fticky-ticky",
511         "fall-strict",
512         "fdicts-strict",
513         "firrefutable-tuples",
514         "fnumbers-strict",
515         "fparallel",
516         "fsmp",
517         "fsemi-tagging",
518         "ffoldr-build-on",
519         "flet-no-escape",
520         "funfold-casms-in-hi-file",
521         "fusagesp-on",
522         "funbox-strict-fields",
523         "femit-extern-decls",
524         "fglobalise-toplev-names",
525         "fgransim",
526         "fignore-asserts",
527         "fignore-interface-pragmas",
528         "fno-hi-version-check",
529         "dno-black-holing",
530         "fomit-interface-pragmas",
531         "fno-pre-inlining",
532         "fdo-eta-reduction",
533         "fdo-lambda-eta-expansion",
534         "fcase-of-case",
535         "fcase-merge",
536         "fpedantic-bottoms",
537         "fexcess-precision",
538         "funfolding-update-in-place",
539         "freport-compile",
540         "fno-prune-decls",
541         "fno-prune-tydecls",
542         "static",
543         "funregisterised"
544         ]
545   || any (flip prefixMatch f) [
546         "fcontext-stack",
547         "fliberate-case-threshold",
548         "fhistory-size",
549         "funfolding-interface-threshold",
550         "funfolding-creation-threshold",
551         "funfolding-use-threshold",
552         "funfolding-fun-discount",
553         "funfolding-keeness-factor"
554      ]
555 \end{code}
556
557 %************************************************************************
558 %*                                                                      *
559 \subsection{Switch ordering}
560 %*                                                                      *
561 %************************************************************************
562
563 These things behave just like enumeration types.
564
565 \begin{code}
566 instance Eq SimplifierSwitch where
567     a == b = tagOf_SimplSwitch a ==# tagOf_SimplSwitch b
568
569 instance Ord SimplifierSwitch where
570     a <  b  = tagOf_SimplSwitch a <# tagOf_SimplSwitch b
571     a <= b  = tagOf_SimplSwitch a <=# tagOf_SimplSwitch b
572
573
574 tagOf_SimplSwitch (SimplInlinePhase _)          = _ILIT(1)
575 tagOf_SimplSwitch (MaxSimplifierIterations _)   = _ILIT(2)
576 tagOf_SimplSwitch DontApplyRules                = _ILIT(3)
577 tagOf_SimplSwitch SimplLetToCase                = _ILIT(4)
578 tagOf_SimplSwitch NoCaseOfCase                  = _ILIT(5)
579
580 -- If you add anything here, be sure to change lAST_SIMPL_SWITCH_TAG, too!
581
582 lAST_SIMPL_SWITCH_TAG = 5
583 \end{code}
584
585 %************************************************************************
586 %*                                                                      *
587 \subsection{Switch lookup}
588 %*                                                                      *
589 %************************************************************************
590
591 \begin{code}
592 isAmongSimpl :: [SimplifierSwitch] -> SimplifierSwitch -> SwitchResult
593 isAmongSimpl on_switches                -- Switches mentioned later occur *earlier*
594                                         -- in the list; defaults right at the end.
595   = let
596         tidied_on_switches = foldl rm_dups [] on_switches
597                 -- The fold*l* ensures that we keep the latest switches;
598                 -- ie the ones that occur earliest in the list.
599
600         sw_tbl :: Array Int SwitchResult
601         sw_tbl = (array (0, lAST_SIMPL_SWITCH_TAG) -- bounds...
602                         all_undefined)
603                  // defined_elems
604
605         all_undefined = [ (i, SwBool False) | i <- [0 .. lAST_SIMPL_SWITCH_TAG ] ]
606
607         defined_elems = map mk_assoc_elem tidied_on_switches
608     in
609     -- (avoid some unboxing, bounds checking, and other horrible things:)
610 #if __GLASGOW_HASKELL__ < 405
611     case sw_tbl of { Array bounds_who_needs_'em stuff ->
612 #else
613     case sw_tbl of { Array _ _ stuff ->
614 #endif
615     \ switch ->
616         case (indexArray# stuff (tagOf_SimplSwitch switch)) of
617 #if __GLASGOW_HASKELL__ < 400
618           Lift v -> v
619 #elif __GLASGOW_HASKELL__ < 403
620           (# _, v #) -> v
621 #else
622           (# v #) -> v
623 #endif
624     }
625   where
626     mk_assoc_elem k@(MaxSimplifierIterations lvl)
627         = (iBox (tagOf_SimplSwitch k), SwInt lvl)
628     mk_assoc_elem k@(SimplInlinePhase n)
629         = (iBox (tagOf_SimplSwitch k), SwInt n)
630     mk_assoc_elem k
631         = (iBox (tagOf_SimplSwitch k), SwBool True) -- I'm here, Mom!
632
633     -- cannot have duplicates if we are going to use the array thing
634     rm_dups switches_so_far switch
635       = if switch `is_elem` switches_so_far
636         then switches_so_far
637         else switch : switches_so_far
638       where
639         sw `is_elem` []     = False
640         sw `is_elem` (s:ss) = (tagOf_SimplSwitch sw) ==# (tagOf_SimplSwitch s)
641                             || sw `is_elem` ss
642 \end{code}
643
644
645 %************************************************************************
646 %*                                                                      *
647 \subsection{Misc functions for command-line options}
648 %*                                                                      *
649 %************************************************************************
650
651
652 \begin{code}
653 switchIsOn :: (switch -> SwitchResult) -> switch -> Bool
654
655 switchIsOn lookup_fn switch
656   = case (lookup_fn switch) of
657       SwBool False -> False
658       _            -> True
659
660 intSwitchSet :: (switch -> SwitchResult)
661              -> (Int -> switch)
662              -> Maybe Int
663
664 intSwitchSet lookup_fn switch
665   = case (lookup_fn (switch (panic "intSwitchSet"))) of
666       SwInt int -> Just int
667       _         -> Nothing
668 \end{code}
669
670 \begin{code}
671 startsWith :: String -> String -> Maybe String
672 -- startsWith pfx (pfx++rest) = Just rest
673
674 startsWith []     str = Just str
675 startsWith (c:cs) (s:ss)
676   = if c /= s then Nothing else startsWith cs ss
677 startsWith  _     []  = Nothing
678
679 endsWith  :: String -> String -> Maybe String
680 endsWith cs ss
681   = case (startsWith (reverse cs) (reverse ss)) of
682       Nothing -> Nothing
683       Just rs -> Just (reverse rs)
684 \end{code}