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