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