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