9227351f6d63157722c11407957b52f750477641
[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   hscStubHOutName       :: String,      -- name of the .stub_h output file
293   hscStubCOutName       :: String,      -- name of the .stub_c output file
294   verbosity             :: Int,         -- verbosity level
295   cppFlag               :: Bool,        -- preprocess with cpp?
296   stolen_x86_regs       :: Int,         
297   cmdlineHcIncludes     :: [String],    -- -#includes
298
299   -- options for particular phases
300   opt_L                 :: [String],
301   opt_P                 :: [String],
302   opt_c                 :: [String],
303   opt_a                 :: [String],
304   opt_m                 :: [String],
305
306   -- hsc dynamic flags
307   flags                 :: [DynFlag]
308  }
309
310 defaultDynFlags = DynFlags {
311   coreToDo = [], stgToDo = [], 
312   hscLang = HscC, 
313   hscOutName = "", 
314   hscStubHOutName = "", hscStubCOutName = "",
315   verbosity = 0, 
316   cppFlag               = False,
317   stolen_x86_regs       = 4,
318   cmdlineHcIncludes     = [],
319   opt_L                 = [],
320   opt_P                 = [],
321   opt_c                 = [],
322   opt_a                 = [],
323   opt_m                 = [],
324   flags = standardWarnings,
325   }
326
327 {- 
328     Verbosity levels:
329         
330     0   |   print errors & warnings only
331     1   |   minimal verbosity: print "compiling M ... done." for each module.
332     2   |   equivalent to -dshow-passes
333     3   |   equivalent to existing "ghc -v"
334     4   |   "ghc -v -ddump-most"
335     5   |   "ghc -v -ddump-all"
336 -}
337
338 dopt :: DynFlag -> DynFlags -> Bool
339 dopt f dflags  = f `elem` (flags dflags)
340
341 dopt_CoreToDo :: DynFlags -> [CoreToDo]
342 dopt_CoreToDo = coreToDo
343
344 dopt_StgToDo :: DynFlags -> [StgToDo]
345 dopt_StgToDo = stgToDo
346
347 dopt_OutName :: DynFlags -> String
348 dopt_OutName = hscOutName
349
350 data HscLang
351   = HscC
352   | HscAsm
353   | HscJava
354 #ifdef ILX
355   | HscILX
356 #endif
357   | HscInterpreted
358     deriving (Eq, Show)
359
360 dopt_HscLang :: DynFlags -> HscLang
361 dopt_HscLang = hscLang
362 \end{code}
363
364 %************************************************************************
365 %*                                                                      *
366 \subsection{Warnings}
367 %*                                                                      *
368 %************************************************************************
369
370 \begin{code}
371 standardWarnings
372     = [ Opt_WarnDeprecations,
373         Opt_WarnOverlappingPatterns,
374         Opt_WarnMissingFields,
375         Opt_WarnMissingMethods,
376         Opt_WarnDuplicateExports
377       ]
378
379 minusWOpts
380     = standardWarnings ++ 
381       [ Opt_WarnUnusedBinds,
382         Opt_WarnUnusedMatches,
383         Opt_WarnUnusedImports,
384         Opt_WarnIncompletePatterns
385       ]
386
387 minusWallOpts
388     = minusWOpts ++
389       [ Opt_WarnTypeDefaults,
390         Opt_WarnNameShadowing,
391         Opt_WarnMissingSigs,
392         Opt_WarnHiShadows
393       ]
394 \end{code}
395
396 %************************************************************************
397 %*                                                                      *
398 \subsection{Classifying command-line options}
399 %*                                                                      *
400 %************************************************************************
401
402 \begin{code}
403 -- v_Statis_hsc_opts is here to avoid a circular dependency with
404 -- main/DriverState.
405 GLOBAL_VAR(v_Static_hsc_opts, [], [String])
406
407 lookUp           :: FAST_STRING -> Bool
408 lookup_int       :: String -> Maybe Int
409 lookup_def_int   :: String -> Int -> Int
410 lookup_def_float :: String -> Float -> Float
411 lookup_str       :: String -> Maybe String
412
413 unpacked_static_opts = unsafePerformIO (readIORef v_Static_hsc_opts)
414 packed_static_opts   = map _PK_ unpacked_static_opts
415
416 lookUp     sw = sw `elem` packed_static_opts
417         
418 lookup_str sw = firstJust (map (startsWith sw) unpacked_static_opts)
419
420 lookup_int sw = case (lookup_str sw) of
421                   Nothing -> Nothing
422                   Just xx -> Just (read xx)
423
424 lookup_def_int sw def = case (lookup_str sw) of
425                             Nothing -> def              -- Use default
426                             Just xx -> read xx
427
428 lookup_def_float sw def = case (lookup_str sw) of
429                             Nothing -> def              -- Use default
430                             Just xx -> read xx
431
432
433 {-
434  Putting the compiler options into temporary at-files
435  may turn out to be necessary later on if we turn hsc into
436  a pure Win32 application where I think there's a command-line
437  length limit of 255. unpacked_opts understands the @ option.
438
439 unpacked_opts :: [String]
440 unpacked_opts =
441   concat $
442   map (expandAts) $
443   map _UNPK_ argv  -- NOT ARGV any more: v_Static_hsc_opts
444   where
445    expandAts ('@':fname) = words (unsafePerformIO (readFile fname))
446    expandAts l = [l]
447 -}
448 \end{code}
449
450 %************************************************************************
451 %*                                                                      *
452 \subsection{Static options}
453 %*                                                                      *
454 %************************************************************************
455
456 \begin{code}
457 -- debugging opts
458 opt_PprStyle_NoPrags            = lookUp  SLIT("-dppr-noprags")
459 opt_PprStyle_Debug              = lookUp  SLIT("-dppr-debug")
460 opt_PprStyle_RawTypes           = lookUp  SLIT("-dppr-rawtypes")
461 opt_PprUserLength               = lookup_def_int "-dppr-user-length" 5 --ToDo: give this a name
462
463 -- profiling opts
464 opt_AutoSccsOnAllToplevs        = lookUp  SLIT("-fauto-sccs-on-all-toplevs")
465 opt_AutoSccsOnExportedToplevs   = lookUp  SLIT("-fauto-sccs-on-exported-toplevs")
466 opt_AutoSccsOnIndividualCafs    = lookUp  SLIT("-fauto-sccs-on-individual-cafs")
467 opt_AutoSccsOnDicts             = lookUp  SLIT("-fauto-sccs-on-dicts")
468 opt_SccProfilingOn              = lookUp  SLIT("-fscc-profiling")
469 opt_DoTickyProfiling            = lookUp  SLIT("-fticky-ticky")
470
471 -- language opts
472 opt_AllStrict                   = lookUp  SLIT("-fall-strict")
473 opt_NoMonomorphismRestriction   = lookUp  SLIT("-fno-monomorphism-restriction")
474 opt_DictsStrict                 = lookUp  SLIT("-fdicts-strict")
475 opt_IrrefutableTuples           = lookUp  SLIT("-firrefutable-tuples")
476 opt_MaxContextReductionDepth    = lookup_def_int "-fcontext-stack" mAX_CONTEXT_REDUCTION_DEPTH
477 opt_NumbersStrict               = lookUp  SLIT("-fnumbers-strict")
478 opt_Parallel                    = lookUp  SLIT("-fparallel")
479 opt_SMP                         = lookUp  SLIT("-fsmp")
480
481 -- optimisation opts
482 opt_NoMethodSharing             = lookUp  SLIT("-fno-method-sharing")
483 opt_DoSemiTagging               = lookUp  SLIT("-fsemi-tagging")
484 opt_FoldrBuildOn                = lookUp  SLIT("-ffoldr-build-on")
485 opt_LiberateCaseThreshold       = lookup_def_int "-fliberate-case-threshold" (10::Int)
486 opt_StgDoLetNoEscapes           = lookUp  SLIT("-flet-no-escape")
487 opt_UnfoldCasms                 = lookUp  SLIT("-funfold-casms-in-hi-file")
488 opt_UsageSPOn                   = lookUp  SLIT("-fusagesp-on")
489 opt_UnboxStrictFields           = lookUp  SLIT("-funbox-strict-fields")
490
491 {-
492    The optional '-inpackage=P' flag tells what package
493    we are compiling this module for.
494    The Prelude, for example is compiled with '-inpackage std'
495 -}
496 opt_InPackage                   = case lookup_str "-inpackage=" of
497                                     Just p  -> _PK_ p
498                                     Nothing -> SLIT("Main")     -- The package name if none is specified
499
500 opt_EmitCExternDecls            = lookUp  SLIT("-femit-extern-decls")
501 opt_EnsureSplittableC           = lookUp  SLIT("-fglobalise-toplev-names")
502 opt_GranMacros                  = lookUp  SLIT("-fgransim")
503 opt_HiVersion                   = read cProjectVersionInt :: Int
504 opt_HistorySize                 = lookup_def_int "-fhistory-size" 20
505 opt_IgnoreAsserts               = lookUp  SLIT("-fignore-asserts")
506 opt_IgnoreIfacePragmas          = lookUp  SLIT("-fignore-interface-pragmas")
507 opt_NoHiCheck                   = lookUp  SLIT("-fno-hi-version-check")
508 opt_OmitBlackHoling             = lookUp  SLIT("-dno-black-holing")
509 opt_OmitInterfacePragmas        = lookUp  SLIT("-fomit-interface-pragmas")
510 opt_KeepStgTypes                = lookUp  SLIT("-fkeep-stg-types")
511
512 -- Simplifier switches
513 opt_SimplNoPreInlining          = lookUp  SLIT("-fno-pre-inlining")
514         -- NoPreInlining is there just to see how bad things
515         -- get if you don't do it!
516 opt_SimplDoEtaReduction         = lookUp  SLIT("-fdo-eta-reduction")
517 opt_SimplDoLambdaEtaExpansion   = lookUp  SLIT("-fdo-lambda-eta-expansion")
518 opt_SimplCaseMerge              = lookUp  SLIT("-fcase-merge")
519 opt_SimplExcessPrecision        = lookUp  SLIT("-fexcess-precision")
520
521 -- Unfolding control
522 opt_UF_CreationThreshold        = lookup_def_int "-funfolding-creation-threshold"  (45::Int)
523 opt_UF_UseThreshold             = lookup_def_int "-funfolding-use-threshold"       (8::Int)     -- Discounts can be big
524 opt_UF_FunAppDiscount           = lookup_def_int "-funfolding-fun-discount"        (6::Int)     -- It's great to inline a fn
525 opt_UF_KeenessFactor            = lookup_def_float "-funfolding-keeness-factor"    (1.5::Float)
526 opt_UF_UpdateInPlace            = lookUp  SLIT("-funfolding-update-in-place")
527
528 opt_UF_CheapOp  = ( 1 :: Int)   -- Only one instruction; and the args are charged for
529 opt_UF_DearOp   = ( 4 :: Int)
530                         
531 opt_NoPruneDecls                = lookUp  SLIT("-fno-prune-decls")
532 opt_NoPruneTyDecls              = lookUp  SLIT("-fno-prune-tydecls")
533 opt_Static                      = lookUp  SLIT("-static")
534 opt_Unregisterised              = lookUp  SLIT("-funregisterised")
535 \end{code}
536
537 %************************************************************************
538 %*                                                                      *
539 \subsection{List of static hsc flags}
540 %*                                                                      *
541 %************************************************************************
542
543 \begin{code}
544 isStaticHscFlag f =
545   f `elem` [
546         "fauto-sccs-on-all-toplevs",
547         "fauto-sccs-on-exported-toplevs",
548         "fauto-sccs-on-individual-cafs",
549         "fauto-sccs-on-dicts",
550         "fscc-profiling",
551         "fticky-ticky",
552         "fall-strict",
553         "fdicts-strict",
554         "firrefutable-tuples",
555         "fnumbers-strict",
556         "fparallel",
557         "fsmp",
558         "fsemi-tagging",
559         "ffoldr-build-on",
560         "flet-no-escape",
561         "funfold-casms-in-hi-file",
562         "fusagesp-on",
563         "funbox-strict-fields",
564         "femit-extern-decls",
565         "fglobalise-toplev-names",
566         "fgransim",
567         "fignore-asserts",
568         "fignore-interface-pragmas",
569         "fno-hi-version-check",
570         "dno-black-holing",
571         "fno-method-sharing",
572         "fno-monomorphism-restriction",
573         "fomit-interface-pragmas",
574         "fkeep-stg-types",
575         "fno-pre-inlining",
576         "fdo-eta-reduction",
577         "fdo-lambda-eta-expansion",
578         "fcase-merge",
579         "fexcess-precision",
580         "funfolding-update-in-place",
581         "fno-prune-decls",
582         "fno-prune-tydecls",
583         "static",
584         "funregisterised"
585         ]
586   || any (flip prefixMatch f) [
587         "fcontext-stack",
588         "fliberate-case-threshold",
589         "fhistory-size",
590         "funfolding-creation-threshold",
591         "funfolding-use-threshold",
592         "funfolding-fun-discount",
593         "funfolding-keeness-factor"
594      ]
595 \end{code}
596
597 %************************************************************************
598 %*                                                                      *
599 \subsection{Switch ordering}
600 %*                                                                      *
601 %************************************************************************
602
603 These things behave just like enumeration types.
604
605 \begin{code}
606 instance Eq SimplifierSwitch where
607     a == b = tagOf_SimplSwitch a ==# tagOf_SimplSwitch b
608
609 instance Ord SimplifierSwitch where
610     a <  b  = tagOf_SimplSwitch a <# tagOf_SimplSwitch b
611     a <= b  = tagOf_SimplSwitch a <=# tagOf_SimplSwitch b
612
613
614 tagOf_SimplSwitch (SimplInlinePhase _)          = _ILIT(1)
615 tagOf_SimplSwitch (MaxSimplifierIterations _)   = _ILIT(2)
616 tagOf_SimplSwitch DontApplyRules                = _ILIT(3)
617 tagOf_SimplSwitch SimplLetToCase                = _ILIT(4)
618 tagOf_SimplSwitch NoCaseOfCase                  = _ILIT(5)
619
620 -- If you add anything here, be sure to change lAST_SIMPL_SWITCH_TAG, too!
621
622 lAST_SIMPL_SWITCH_TAG = 5
623 \end{code}
624
625 %************************************************************************
626 %*                                                                      *
627 \subsection{Switch lookup}
628 %*                                                                      *
629 %************************************************************************
630
631 \begin{code}
632 isAmongSimpl :: [SimplifierSwitch] -> SimplifierSwitch -> SwitchResult
633 isAmongSimpl on_switches                -- Switches mentioned later occur *earlier*
634                                         -- in the list; defaults right at the end.
635   = let
636         tidied_on_switches = foldl rm_dups [] on_switches
637                 -- The fold*l* ensures that we keep the latest switches;
638                 -- ie the ones that occur earliest in the list.
639
640         sw_tbl :: Array Int SwitchResult
641         sw_tbl = (array (0, lAST_SIMPL_SWITCH_TAG) -- bounds...
642                         all_undefined)
643                  // defined_elems
644
645         all_undefined = [ (i, SwBool False) | i <- [0 .. lAST_SIMPL_SWITCH_TAG ] ]
646
647         defined_elems = map mk_assoc_elem tidied_on_switches
648     in
649     -- (avoid some unboxing, bounds checking, and other horrible things:)
650 #if __GLASGOW_HASKELL__ < 405
651     case sw_tbl of { Array bounds_who_needs_'em stuff ->
652 #else
653     case sw_tbl of { Array _ _ stuff ->
654 #endif
655     \ switch ->
656         case (indexArray# stuff (tagOf_SimplSwitch switch)) of
657 #if __GLASGOW_HASKELL__ < 400
658           Lift v -> v
659 #elif __GLASGOW_HASKELL__ < 403
660           (# _, v #) -> v
661 #else
662           (# v #) -> v
663 #endif
664     }
665   where
666     mk_assoc_elem k@(MaxSimplifierIterations lvl)
667         = (iBox (tagOf_SimplSwitch k), SwInt lvl)
668     mk_assoc_elem k@(SimplInlinePhase n)
669         = (iBox (tagOf_SimplSwitch k), SwInt n)
670     mk_assoc_elem k
671         = (iBox (tagOf_SimplSwitch k), SwBool True) -- I'm here, Mom!
672
673     -- cannot have duplicates if we are going to use the array thing
674     rm_dups switches_so_far switch
675       = if switch `is_elem` switches_so_far
676         then switches_so_far
677         else switch : switches_so_far
678       where
679         sw `is_elem` []     = False
680         sw `is_elem` (s:ss) = (tagOf_SimplSwitch sw) ==# (tagOf_SimplSwitch s)
681                             || sw `is_elem` ss
682 \end{code}
683
684
685 %************************************************************************
686 %*                                                                      *
687 \subsection{Misc functions for command-line options}
688 %*                                                                      *
689 %************************************************************************
690
691
692 \begin{code}
693 switchIsOn :: (switch -> SwitchResult) -> switch -> Bool
694
695 switchIsOn lookup_fn switch
696   = case (lookup_fn switch) of
697       SwBool False -> False
698       _            -> True
699
700 intSwitchSet :: (switch -> SwitchResult)
701              -> (Int -> switch)
702              -> Maybe Int
703
704 intSwitchSet lookup_fn switch
705   = case (lookup_fn (switch (panic "intSwitchSet"))) of
706       SwInt int -> Just int
707       _         -> Nothing
708 \end{code}
709
710 \begin{code}
711 startsWith :: String -> String -> Maybe String
712 -- startsWith pfx (pfx++rest) = Just rest
713
714 startsWith []     str = Just str
715 startsWith (c:cs) (s:ss)
716   = if c /= s then Nothing else startsWith cs ss
717 startsWith  _     []  = Nothing
718
719 endsWith  :: String -> String -> Maybe String
720 endsWith cs ss
721   = case (startsWith (reverse cs) (reverse ss)) of
722       Nothing -> Nothing
723       Just rs -> Just (reverse rs)
724 \end{code}