OSDN Git Service

* rs6000.c (rs6000_override_options): Only use DI ops when
[pf3gnuchains/gcc-fork.git] / gcc / ada / switch.adb
1 ------------------------------------------------------------------------------
2 --                                                                          --
3 --                         GNAT COMPILER COMPONENTS                         --
4 --                                                                          --
5 --                               S W I T C H                                --
6 --                                                                          --
7 --                                 B o d y                                  --
8 --                                                                          --
9 --                            $Revision$
10 --                                                                          --
11 --          Copyright (C) 1992-2001, Free Software Foundation, Inc.         --
12 --                                                                          --
13 -- GNAT is free software;  you can  redistribute it  and/or modify it under --
14 -- terms of the  GNU General Public License as published  by the Free Soft- --
15 -- ware  Foundation;  either version 2,  or (at your option) any later ver- --
16 -- sion.  GNAT is distributed in the hope that it will be useful, but WITH- --
17 -- OUT ANY WARRANTY;  without even the  implied warranty of MERCHANTABILITY --
18 -- or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License --
19 -- for  more details.  You should have  received  a copy of the GNU General --
20 -- Public License  distributed with GNAT;  see file COPYING.  If not, write --
21 -- to  the Free Software Foundation,  59 Temple Place - Suite 330,  Boston, --
22 -- MA 02111-1307, USA.                                                      --
23 --                                                                          --
24 -- GNAT was originally developed  by the GNAT team at  New York University. --
25 -- It is now maintained by Ada Core Technologies Inc (http://www.gnat.com). --
26 --                                                                          --
27 ------------------------------------------------------------------------------
28
29 --  Option switch scanning for both the compiler and the binder
30
31 --  Note: this version of the package should be usable in both Unix and DOS
32
33 with Debug;    use Debug;
34 with Osint;    use Osint;
35 with Opt;      use Opt;
36 with Validsw;  use Validsw;
37 with Stylesw;  use Stylesw;
38 with Types;    use Types;
39
40 with System.WCh_Con; use System.WCh_Con;
41
42 package body Switch is
43
44    Bad_Switch : exception;
45    --  Exception raised if bad switch encountered
46
47    Bad_Switch_Value : exception;
48    --  Exception raised if bad switch value encountered
49
50    Missing_Switch_Value : exception;
51    --  Exception raised if no switch value encountered
52
53    Too_Many_Output_Files : exception;
54    --  Exception raised if the -o switch is encountered more than once
55
56    Switch_Max_Value : constant := 999;
57    --  Maximum value permitted in switches that take a value
58
59    procedure Scan_Nat
60      (Switch_Chars : String;
61       Max          : Integer;
62       Ptr          : in out Integer;
63       Result       : out Nat);
64    --  Scan natural integer parameter for switch. On entry, Ptr points
65    --  just past the switch character, on exit it points past the last
66    --  digit of the integer value.
67
68    procedure Scan_Pos
69      (Switch_Chars : String;
70       Max          : Integer;
71       Ptr          : in out Integer;
72       Result       : out Pos);
73    --  Scan positive integer parameter for switch. On entry, Ptr points
74    --  just past the switch character, on exit it points past the last
75    --  digit of the integer value.
76
77    -------------------------
78    -- Is_Front_End_Switch --
79    -------------------------
80
81    function Is_Front_End_Switch (Switch_Chars : String) return Boolean is
82       Ptr       : constant Positive := Switch_Chars'First;
83    begin
84       return Is_Switch (Switch_Chars)
85         and then
86           (Switch_Chars (Ptr + 1) = 'I'
87              or else
88           (Switch_Chars'Length >= 5
89                          and then Switch_Chars (Ptr + 1 .. Ptr + 4) = "gnat"));
90    end Is_Front_End_Switch;
91
92    ---------------
93    -- Is_Switch --
94    ---------------
95
96    function Is_Switch (Switch_Chars : String) return Boolean is
97    begin
98       return Switch_Chars'Length > 1
99         and then (Switch_Chars (Switch_Chars'First) = '-'
100                      or
101                   Switch_Chars (Switch_Chars'First) = Switch_Character);
102    end Is_Switch;
103
104    --------------------------
105    -- Scan_Binder_Switches --
106    --------------------------
107
108    procedure Scan_Binder_Switches (Switch_Chars : String) is
109       Ptr : Integer := Switch_Chars'First;
110       Max : Integer := Switch_Chars'Last;
111       C   : Character := ' ';
112
113    begin
114       --  Skip past the initial character (must be the switch character)
115
116       if Ptr = Max then
117          raise Bad_Switch;
118       else
119          Ptr := Ptr + 1;
120       end if;
121
122       --  A little check, "gnat" at the start of a switch is not allowed
123       --  except for the compiler
124
125       if Switch_Chars'Last >= Ptr + 3
126         and then Switch_Chars (Ptr .. Ptr + 3) = "gnat"
127       then
128          Osint.Fail ("invalid switch: """, Switch_Chars, """"
129             & " (gnat not needed here)");
130
131       end if;
132
133       --  Loop to scan through switches given in switch string
134
135       while Ptr <= Max loop
136          C := Switch_Chars (Ptr);
137
138          case C is
139
140          --  Processing for A switch
141
142          when 'A' =>
143             Ptr := Ptr + 1;
144
145             Ada_Bind_File := True;
146
147          --  Processing for b switch
148
149          when 'b' =>
150             Ptr := Ptr + 1;
151             Brief_Output := True;
152
153          --  Processing for c switch
154
155          when 'c' =>
156             Ptr := Ptr + 1;
157
158             Check_Only := True;
159
160          --  Processing for C switch
161
162          when 'C' =>
163             Ptr := Ptr + 1;
164
165             Ada_Bind_File := False;
166
167          --  Processing for d switch
168
169          when 'd' =>
170
171             --  Note: for the debug switch, the remaining characters in this
172             --  switch field must all be debug flags, since all valid switch
173             --  characters are also valid debug characters.
174
175             --  Loop to scan out debug flags
176
177             while Ptr < Max loop
178                Ptr := Ptr + 1;
179                C := Switch_Chars (Ptr);
180                exit when C = ASCII.NUL or else C = '/' or else C = '-';
181
182                if C in '1' .. '9' or else
183                   C in 'a' .. 'z' or else
184                   C in 'A' .. 'Z'
185                then
186                   Set_Debug_Flag (C);
187                else
188                   raise Bad_Switch;
189                end if;
190             end loop;
191
192             --  Make sure Zero_Cost_Exceptions is set if gnatdX set. This
193             --  is for backwards compatibility with old versions and usage.
194
195             if Debug_Flag_XX then
196                Zero_Cost_Exceptions_Set := True;
197                Zero_Cost_Exceptions_Val := True;
198             end if;
199
200             return;
201
202          --  Processing for e switch
203
204          when 'e' =>
205             Ptr := Ptr + 1;
206             Elab_Dependency_Output := True;
207
208          --  Processing for E switch
209
210          when 'E' =>
211             Ptr := Ptr + 1;
212             Exception_Tracebacks := True;
213
214          --  Processing for f switch
215
216          when 'f' =>
217             Ptr := Ptr + 1;
218             Force_RM_Elaboration_Order := True;
219
220          --  Processing for g switch
221
222          when 'g' =>
223             Ptr := Ptr + 1;
224
225             if Ptr <= Max then
226                C := Switch_Chars (Ptr);
227
228                if C in '0' .. '3' then
229                   Debugger_Level :=
230                     Character'Pos
231                       (Switch_Chars (Ptr)) - Character'Pos ('0');
232                   Ptr := Ptr + 1;
233                end if;
234
235             else
236                Debugger_Level := 2;
237             end if;
238
239          --  Processing for G switch
240
241          when 'G' =>
242             Ptr := Ptr + 1;
243             Print_Generated_Code := True;
244
245          --  Processing for h switch
246
247          when 'h' =>
248             Ptr := Ptr + 1;
249             Usage_Requested := True;
250
251          --  Processing for i switch
252
253          when 'i' =>
254             if Ptr = Max then
255                raise Bad_Switch;
256             end if;
257
258             Ptr := Ptr + 1;
259             C := Switch_Chars (Ptr);
260
261             if C in  '1' .. '5'
262               or else C = '8'
263               or else C = 'p'
264               or else C = 'f'
265               or else C = 'n'
266               or else C = 'w'
267             then
268                Identifier_Character_Set := C;
269                Ptr := Ptr + 1;
270             else
271                raise Bad_Switch;
272             end if;
273
274          --  Processing for K switch
275
276          when 'K' =>
277             Ptr := Ptr + 1;
278
279             if Program = Binder then
280                Output_Linker_Option_List := True;
281             else
282                raise Bad_Switch;
283             end if;
284
285          --  Processing for l switch
286
287          when 'l' =>
288             Ptr := Ptr + 1;
289             Elab_Order_Output := True;
290
291          --  Processing for m switch
292
293          when 'm' =>
294             Ptr := Ptr + 1;
295             Scan_Pos (Switch_Chars, Max, Ptr, Maximum_Errors);
296
297          --  Processing for n switch
298
299          when 'n' =>
300             Ptr := Ptr + 1;
301             Bind_Main_Program := False;
302
303             --  Note: The -L option of the binder also implies -n, so
304             --  any change here must also be reflected in the processing
305             --  for -L that is found in Gnatbind.Scan_Bind_Arg.
306
307          --  Processing for o switch
308
309          when 'o' =>
310             Ptr := Ptr + 1;
311
312             if Output_File_Name_Present then
313                raise Too_Many_Output_Files;
314
315             else
316                Output_File_Name_Present := True;
317             end if;
318
319          --  Processing for O switch
320
321          when 'O' =>
322             Ptr := Ptr + 1;
323             Output_Object_List := True;
324
325          --  Processing for p switch
326
327          when 'p' =>
328             Ptr := Ptr + 1;
329             Pessimistic_Elab_Order := True;
330
331          --  Processing for q switch
332
333          when 'q' =>
334             Ptr := Ptr + 1;
335             Quiet_Output := True;
336
337          --  Processing for s switch
338
339          when 's' =>
340             Ptr := Ptr + 1;
341             All_Sources := True;
342             Check_Source_Files := True;
343
344          --  Processing for t switch
345
346          when 't' =>
347             Ptr := Ptr + 1;
348             Tolerate_Consistency_Errors := True;
349
350          --  Processing for T switch
351
352          when 'T' =>
353             Ptr := Ptr + 1;
354             Time_Slice_Set := True;
355             Scan_Nat (Switch_Chars, Max, Ptr, Time_Slice_Value);
356
357          --  Processing for v switch
358
359          when 'v' =>
360             Ptr := Ptr + 1;
361             Verbose_Mode := True;
362
363          --  Processing for w switch
364
365          when 'w' =>
366
367             --  For the binder we only allow suppress/error cases
368
369             Ptr := Ptr + 1;
370
371             case Switch_Chars (Ptr) is
372
373                when 'e' =>
374                   Warning_Mode  := Treat_As_Error;
375
376                when 's' =>
377                   Warning_Mode  := Suppress;
378
379                when others =>
380                   raise Bad_Switch;
381             end case;
382
383             Ptr := Ptr + 1;
384
385          --  Processing for W switch
386
387          when 'W' =>
388             Ptr := Ptr + 1;
389
390             for J in WC_Encoding_Method loop
391                if Switch_Chars (Ptr) = WC_Encoding_Letters (J) then
392                   Wide_Character_Encoding_Method := J;
393                   exit;
394
395                elsif J = WC_Encoding_Method'Last then
396                   raise Bad_Switch;
397                end if;
398             end loop;
399
400             Upper_Half_Encoding :=
401               Wide_Character_Encoding_Method in
402                 WC_Upper_Half_Encoding_Method;
403
404             Ptr := Ptr + 1;
405
406          --  Processing for x switch
407
408          when 'x' =>
409             Ptr := Ptr + 1;
410             All_Sources := False;
411             Check_Source_Files := False;
412
413          --  Processing for z switch
414
415          when 'z' =>
416             Ptr := Ptr + 1;
417             No_Main_Subprogram := True;
418
419          --  Ignore extra switch character
420
421          when '/' | '-' =>
422             Ptr := Ptr + 1;
423
424          --  Anything else is an error (illegal switch character)
425
426          when others =>
427             raise Bad_Switch;
428          end case;
429       end loop;
430
431    exception
432       when Bad_Switch =>
433          Osint.Fail ("invalid switch: ", (1 => C));
434
435       when Bad_Switch_Value =>
436          Osint.Fail ("numeric value too big for switch: ", (1 => C));
437
438       when Missing_Switch_Value =>
439          Osint.Fail ("missing numeric value for switch: ", (1 => C));
440
441       when Too_Many_Output_Files =>
442          Osint.Fail ("duplicate -o switch");
443    end Scan_Binder_Switches;
444
445    -----------------------------
446    -- Scan_Front_End_Switches --
447    -----------------------------
448
449    procedure Scan_Front_End_Switches (Switch_Chars : String) is
450       Switch_Starts_With_Gnat : Boolean;
451       Ptr : Integer := Switch_Chars'First;
452       Max : constant Integer := Switch_Chars'Last;
453       C   : Character := ' ';
454
455    begin
456       --  Skip past the initial character (must be the switch character)
457
458       if Ptr = Max then
459          raise Bad_Switch;
460
461       else
462          Ptr := Ptr + 1;
463       end if;
464
465       --  A little check, "gnat" at the start of a switch is not allowed
466       --  except for the compiler (where it was already removed)
467
468       Switch_Starts_With_Gnat :=
469          Ptr + 3 <= Max and then Switch_Chars (Ptr .. Ptr + 3) = "gnat";
470
471       if Switch_Starts_With_Gnat then
472          Ptr := Ptr + 4;
473       end if;
474
475       --  Loop to scan through switches given in switch string
476
477       while Ptr <= Max loop
478          C := Switch_Chars (Ptr);
479
480          --  Processing for a switch
481
482          case Switch_Starts_With_Gnat is
483
484          when False =>
485             --  There is only one front-end switch that
486             --  does not start with -gnat, namely -I
487
488             case C is
489
490             when 'I' =>
491                Ptr := Ptr + 1;
492
493                if Ptr > Max then
494                   raise Bad_Switch;
495                end if;
496
497                --  Find out whether this is a -I- or regular -Ixxx switch
498
499                if Ptr = Max and then Switch_Chars (Ptr) = '-' then
500                   Look_In_Primary_Dir := False;
501
502                else
503                   Add_Src_Search_Dir (Switch_Chars (Ptr .. Max));
504                end if;
505
506                Ptr := Max + 1;
507
508             when others =>
509                --  Should not happen, as Scan_Switches is supposed
510                --  to be called for front-end switches only.
511                --  Still, it is safest to raise Bad_Switch error.
512
513                raise Bad_Switch;
514             end case;
515
516          when True =>
517             --  Process -gnat* options
518
519             case C is
520
521             when 'a' =>
522                Ptr := Ptr + 1;
523                Assertions_Enabled := True;
524
525             --  Processing for A switch
526
527             when 'A' =>
528                Ptr := Ptr + 1;
529                Config_File := False;
530
531             --  Processing for b switch
532
533             when 'b' =>
534                Ptr := Ptr + 1;
535                Brief_Output := True;
536
537             --  Processing for c switch
538
539             when 'c' =>
540                Ptr := Ptr + 1;
541                Operating_Mode := Check_Semantics;
542
543             --  Processing for C switch
544
545             when 'C' =>
546                Ptr := Ptr + 1;
547                Compress_Debug_Names := True;
548
549             --  Processing for d switch
550
551             when 'd' =>
552
553                --  Note: for the debug switch, the remaining characters in this
554                --  switch field must all be debug flags, since all valid switch
555                --  characters are also valid debug characters.
556
557                --  Loop to scan out debug flags
558
559                while Ptr < Max loop
560                   Ptr := Ptr + 1;
561                   C := Switch_Chars (Ptr);
562                   exit when C = ASCII.NUL or else C = '/' or else C = '-';
563
564                   if C in '1' .. '9' or else
565                      C in 'a' .. 'z' or else
566                      C in 'A' .. 'Z'
567                   then
568                      Set_Debug_Flag (C);
569
570                   else
571                      raise Bad_Switch;
572                   end if;
573                end loop;
574
575                --  Make sure Zero_Cost_Exceptions is set if gnatdX set. This
576                --  is for backwards compatibility with old versions and usage.
577
578                if Debug_Flag_XX then
579                   Zero_Cost_Exceptions_Set := True;
580                   Zero_Cost_Exceptions_Val := True;
581                end if;
582
583                return;
584
585             --  Processing for D switch
586
587             when 'D' =>
588                Ptr := Ptr + 1;
589
590                --  Note: -gnatD also sets -gnatx (to turn off cross-reference
591                --  generation in the ali file) since otherwise this generation
592                --  gets confused by the "wrong" Sloc values put in the tree.
593
594                Debug_Generated_Code := True;
595                Xref_Active := False;
596                Set_Debug_Flag ('g');
597
598             --  Processing for e switch
599
600             when 'e' =>
601                Ptr := Ptr + 1;
602
603                if Ptr > Max then
604                   raise Bad_Switch;
605                end if;
606
607                case Switch_Chars (Ptr) is
608
609                   when 'c' =>
610                      Ptr := Ptr + 1;
611                      if Ptr > Max then
612                         Osint.Fail ("Invalid switch: ", "ec");
613                      end if;
614
615                      Config_File_Name :=
616                         new String'(Switch_Chars (Ptr .. Max));
617
618                      return;
619
620                   when others =>
621                      Osint.Fail ("Invalid switch: ",
622                                    (1 => 'e', 2 => Switch_Chars (Ptr)));
623                end case;
624
625             --  Processing for E switch
626
627             when 'E' =>
628                Ptr := Ptr + 1;
629                Dynamic_Elaboration_Checks := True;
630
631             --  Processing for f switch
632
633             when 'f' =>
634                Ptr := Ptr + 1;
635                All_Errors_Mode := True;
636
637             --  Processing for F switch
638
639             when 'F' =>
640                Ptr := Ptr + 1;
641                External_Name_Exp_Casing := Uppercase;
642                External_Name_Imp_Casing := Uppercase;
643
644             --  Processing for g switch
645
646             when 'g' =>
647                Ptr := Ptr + 1;
648                GNAT_Mode                := True;
649                Identifier_Character_Set := 'n';
650                Warning_Mode             := Treat_As_Error;
651                Check_Unreferenced       := True;
652                Check_Withs              := True;
653
654                Set_Default_Style_Check_Options;
655
656             --  Processing for G switch
657
658             when 'G' =>
659                Ptr := Ptr + 1;
660                Print_Generated_Code := True;
661
662             --  Processing for h switch
663
664             when 'h' =>
665                Ptr := Ptr + 1;
666                Usage_Requested := True;
667
668             --  Processing for H switch
669
670             when 'H' =>
671                Ptr := Ptr + 1;
672                HLO_Active := True;
673
674             --  Processing for i switch
675
676             when 'i' =>
677                if Ptr = Max then
678                   raise Bad_Switch;
679                end if;
680
681                Ptr := Ptr + 1;
682                C := Switch_Chars (Ptr);
683
684                if C in '1' .. '5'
685                  or else C = '8'
686                  or else C = 'p'
687                  or else C = 'f'
688                  or else C = 'n'
689                  or else C = 'w'
690                then
691                   Identifier_Character_Set := C;
692                   Ptr := Ptr + 1;
693
694                else
695                   raise Bad_Switch;
696                end if;
697
698             --  Processing for k switch
699
700             when 'k' =>
701                Ptr := Ptr + 1;
702                Scan_Pos (Switch_Chars, Max, Ptr, Maximum_File_Name_Length);
703
704             --  Processing for l switch
705
706             when 'l' =>
707                Ptr := Ptr + 1;
708                Full_List := True;
709
710             --  Processing for L switch
711
712             when 'L' =>
713                Ptr := Ptr + 1;
714                Zero_Cost_Exceptions_Set := True;
715                Zero_Cost_Exceptions_Val := False;
716
717             --  Processing for m switch
718
719             when 'm' =>
720                Ptr := Ptr + 1;
721                Scan_Pos (Switch_Chars, Max, Ptr, Maximum_Errors);
722
723             --  Processing for n switch
724
725             when 'n' =>
726                Ptr := Ptr + 1;
727                Inline_Active := True;
728
729             --  Processing for N switch
730
731             when 'N' =>
732                Ptr := Ptr + 1;
733                Inline_Active := True;
734                Front_End_Inlining := True;
735
736             --  Processing for o switch
737
738             when 'o' =>
739                Ptr := Ptr + 1;
740                Suppress_Options.Overflow_Checks := False;
741
742             --  Processing for O switch
743
744             when 'O' =>
745                Ptr := Ptr + 1;
746                Output_File_Name_Present := True;
747
748             --  Processing for p switch
749
750             when 'p' =>
751                Ptr := Ptr + 1;
752                Suppress_Options.Access_Checks        := True;
753                Suppress_Options.Accessibility_Checks := True;
754                Suppress_Options.Discriminant_Checks  := True;
755                Suppress_Options.Division_Checks      := True;
756                Suppress_Options.Elaboration_Checks   := True;
757                Suppress_Options.Index_Checks         := True;
758                Suppress_Options.Length_Checks        := True;
759                Suppress_Options.Overflow_Checks      := True;
760                Suppress_Options.Range_Checks         := True;
761                Suppress_Options.Division_Checks      := True;
762                Suppress_Options.Length_Checks        := True;
763                Suppress_Options.Range_Checks         := True;
764                Suppress_Options.Storage_Checks       := True;
765                Suppress_Options.Tag_Checks           := True;
766
767                Validity_Checks_On := False;
768
769             --  Processing for P switch
770
771             when 'P' =>
772                Ptr := Ptr + 1;
773                Polling_Required := True;
774
775             --  Processing for q switch
776
777             when 'q' =>
778                Ptr := Ptr + 1;
779                Try_Semantics := True;
780
781             --  Processing for q switch
782
783             when 'Q' =>
784                Ptr := Ptr + 1;
785                Force_ALI_Tree_File := True;
786                Try_Semantics := True;
787
788             --  Processing for r switch
789
790             when 'r' =>
791                Ptr := Ptr + 1;
792
793                --  Temporarily allow -gnatr to mean -gnatyl (use RM layout)
794                --  for compatibility with pre 3.12 versions of GNAT,
795                --  to be removed for 3.13 ???
796
797                Set_Style_Check_Options ("l");
798
799             --  Processing for R switch
800
801             when 'R' =>
802                Ptr := Ptr + 1;
803                Back_Annotate_Rep_Info := True;
804
805                if Ptr <= Max
806                  and then Switch_Chars (Ptr) in '0' .. '9'
807                then
808                   C := Switch_Chars (Ptr);
809
810                   if C in '4' .. '9' then
811                      raise Bad_Switch;
812                   else
813                      List_Representation_Info :=
814                        Character'Pos (C) - Character'Pos ('0');
815                      Ptr := Ptr + 1;
816                   end if;
817
818                else
819                   List_Representation_Info := 1;
820                end if;
821
822             --  Processing for s switch
823
824             when 's' =>
825                Ptr := Ptr + 1;
826                Operating_Mode := Check_Syntax;
827
828             --  Processing for t switch
829
830             when 't' =>
831                Ptr := Ptr + 1;
832                Tree_Output := True;
833                Back_Annotate_Rep_Info := True;
834
835             --  Processing for T switch
836
837             when 'T' =>
838                Ptr := Ptr + 1;
839                Time_Slice_Set := True;
840                Scan_Nat (Switch_Chars, Max, Ptr, Time_Slice_Value);
841
842             --  Processing for u switch
843
844             when 'u' =>
845                Ptr := Ptr + 1;
846                List_Units := True;
847
848             --  Processing for U switch
849
850             when 'U' =>
851                Ptr := Ptr + 1;
852                Unique_Error_Tag := True;
853
854             --  Processing for v switch
855
856             when 'v' =>
857                Ptr := Ptr + 1;
858                Verbose_Mode := True;
859
860             --  Processing for V switch
861
862             when 'V' =>
863                Ptr := Ptr + 1;
864
865                if Ptr > Max then
866                   raise Bad_Switch;
867
868                else
869                   declare
870                      OK  : Boolean;
871
872                   begin
873                      Set_Validity_Check_Options
874                        (Switch_Chars (Ptr .. Max), OK, Ptr);
875
876                      if not OK then
877                         raise Bad_Switch;
878                      end if;
879                   end;
880                end if;
881
882             --  Processing for w switch
883
884             when 'w' =>
885                Ptr := Ptr + 1;
886
887                if Ptr > Max then
888                   raise Bad_Switch;
889                end if;
890
891                while Ptr <= Max loop
892                   C := Switch_Chars (Ptr);
893
894                   case C is
895
896                      when 'a' =>
897                         Constant_Condition_Warnings  := True;
898                         Elab_Warnings                := True;
899                         Check_Unreferenced           := True;
900                         Check_Withs                  := True;
901                         Implementation_Unit_Warnings := True;
902                         Ineffective_Inline_Warnings  := True;
903                         Warn_On_Redundant_Constructs := True;
904
905                      when 'A' =>
906                         Constant_Condition_Warnings  := False;
907                         Elab_Warnings                := False;
908                         Check_Unreferenced           := False;
909                         Check_Withs                  := False;
910                         Implementation_Unit_Warnings := False;
911                         Warn_On_Biased_Rounding      := False;
912                         Warn_On_Hiding               := False;
913                         Warn_On_Redundant_Constructs := False;
914                         Ineffective_Inline_Warnings  := False;
915
916                      when 'c' =>
917                         Constant_Condition_Warnings := True;
918
919                      when 'C' =>
920                         Constant_Condition_Warnings := False;
921
922                      when 'b' =>
923                         Warn_On_Biased_Rounding := True;
924
925                      when 'B' =>
926                         Warn_On_Biased_Rounding := False;
927
928                      when 'e' =>
929                         Warning_Mode := Treat_As_Error;
930
931                      when 'h' =>
932                         Warn_On_Hiding := True;
933
934                      when 'H' =>
935                         Warn_On_Hiding := False;
936
937                      when 'i' =>
938                         Implementation_Unit_Warnings := True;
939
940                      when 'I' =>
941                         Implementation_Unit_Warnings := False;
942
943                      when 'l' =>
944                         Elab_Warnings := True;
945
946                      when 'L' =>
947                         Elab_Warnings := False;
948
949                      when 'o' =>
950                         Address_Clause_Overlay_Warnings := True;
951
952                      when 'O' =>
953                         Address_Clause_Overlay_Warnings := False;
954
955                      when 'p' =>
956                         Ineffective_Inline_Warnings := True;
957
958                      when 'P' =>
959                         Ineffective_Inline_Warnings := False;
960
961                      when 'r' =>
962                         Warn_On_Redundant_Constructs := True;
963
964                      when 'R' =>
965                         Warn_On_Redundant_Constructs := False;
966
967                      when 's' =>
968                         Warning_Mode  := Suppress;
969
970                      when 'u' =>
971                         Check_Unreferenced := True;
972                         Check_Withs        := True;
973
974                      when 'U' =>
975                         Check_Unreferenced := False;
976                         Check_Withs        := False;
977
978                         --  Allow and ignore 'w' so that the old
979                         --  format (e.g. -gnatwuwl) will work.
980
981                      when 'w' =>
982                         null;
983
984                      when others =>
985                         raise Bad_Switch;
986                   end case;
987
988                   Ptr := Ptr + 1;
989                end loop;
990
991                return;
992
993             --  Processing for W switch
994
995             when 'W' =>
996                Ptr := Ptr + 1;
997
998                for J in WC_Encoding_Method loop
999                   if Switch_Chars (Ptr) = WC_Encoding_Letters (J) then
1000                      Wide_Character_Encoding_Method := J;
1001                      exit;
1002
1003                   elsif J = WC_Encoding_Method'Last then
1004                      raise Bad_Switch;
1005                   end if;
1006                end loop;
1007
1008                Upper_Half_Encoding :=
1009                  Wide_Character_Encoding_Method in
1010                  WC_Upper_Half_Encoding_Method;
1011
1012                Ptr := Ptr + 1;
1013
1014             --  Processing for x switch
1015
1016             when 'x' =>
1017                Ptr := Ptr + 1;
1018                Xref_Active := False;
1019
1020             --  Processing for X switch
1021
1022             when 'X' =>
1023                Ptr := Ptr + 1;
1024                Extensions_Allowed := True;
1025
1026             --  Processing for y switch
1027
1028             when 'y' =>
1029                Ptr := Ptr + 1;
1030
1031                if Ptr > Max then
1032                   Set_Default_Style_Check_Options;
1033
1034                else
1035                   declare
1036                      OK  : Boolean;
1037
1038                   begin
1039                      Set_Style_Check_Options
1040                        (Switch_Chars (Ptr .. Max), OK, Ptr);
1041
1042                      if not OK then
1043                         raise Bad_Switch;
1044                      end if;
1045                   end;
1046                end if;
1047
1048             --  Processing for z switch
1049
1050             when 'z' =>
1051                Ptr := Ptr + 1;
1052
1053                --  Allowed for compiler, only if this is the only
1054                --  -z switch, we do not allow multiple occurrences
1055
1056                if Distribution_Stub_Mode = No_Stubs then
1057                   case Switch_Chars (Ptr) is
1058                      when 'r' =>
1059                         Distribution_Stub_Mode := Generate_Receiver_Stub_Body;
1060
1061                      when 'c' =>
1062                         Distribution_Stub_Mode := Generate_Caller_Stub_Body;
1063
1064                      when others =>
1065                         raise Bad_Switch;
1066                   end case;
1067
1068                   Ptr := Ptr + 1;
1069
1070                end if;
1071
1072             --  Processing for Z switch
1073
1074             when 'Z' =>
1075                Ptr := Ptr + 1;
1076                Zero_Cost_Exceptions_Set := True;
1077                Zero_Cost_Exceptions_Val := True;
1078
1079             --  Processing for 83 switch
1080
1081             when '8' =>
1082
1083                if Ptr = Max then
1084                   raise Bad_Switch;
1085                end if;
1086
1087                Ptr := Ptr + 1;
1088
1089                if Switch_Chars (Ptr) /= '3' then
1090                   raise Bad_Switch;
1091                else
1092                   Ptr := Ptr + 1;
1093                   Ada_95 := False;
1094                   Ada_83 := True;
1095                end if;
1096
1097             --  Ignore extra switch character
1098
1099             when '/' | '-' =>
1100                Ptr := Ptr + 1;
1101
1102             --  Anything else is an error (illegal switch character)
1103
1104             when others =>
1105                raise Bad_Switch;
1106             end case;
1107          end case;
1108       end loop;
1109
1110    exception
1111       when Bad_Switch =>
1112          Osint.Fail ("invalid switch: ", (1 => C));
1113
1114       when Bad_Switch_Value =>
1115          Osint.Fail ("numeric value too big for switch: ", (1 => C));
1116
1117       when Missing_Switch_Value =>
1118          Osint.Fail ("missing numeric value for switch: ", (1 => C));
1119
1120    end Scan_Front_End_Switches;
1121
1122    ------------------------
1123    -- Scan_Make_Switches --
1124    ------------------------
1125
1126    procedure Scan_Make_Switches (Switch_Chars : String) is
1127       Ptr : Integer := Switch_Chars'First;
1128       Max : Integer := Switch_Chars'Last;
1129       C   : Character := ' ';
1130
1131    begin
1132       --  Skip past the initial character (must be the switch character)
1133
1134       if Ptr = Max then
1135          raise Bad_Switch;
1136
1137       else
1138          Ptr := Ptr + 1;
1139       end if;
1140
1141       --  A little check, "gnat" at the start of a switch is not allowed
1142       --  except for the compiler (where it was already removed)
1143
1144       if Switch_Chars'Length >= Ptr + 3
1145         and then Switch_Chars (Ptr .. Ptr + 3) = "gnat"
1146       then
1147          Osint.Fail
1148            ("invalid switch: """, Switch_Chars, """ (gnat not needed here)");
1149       end if;
1150
1151       --  Loop to scan through switches given in switch string
1152
1153       while Ptr <= Max loop
1154          C := Switch_Chars (Ptr);
1155
1156          --  Processing for a switch
1157
1158          case C is
1159
1160          when 'a' =>
1161             Ptr := Ptr + 1;
1162             Check_Readonly_Files := True;
1163
1164          --  Processing for b switch
1165
1166          when 'b' =>
1167             Ptr := Ptr + 1;
1168             Bind_Only := True;
1169
1170          --  Processing for c switch
1171
1172          when 'c' =>
1173             Ptr := Ptr + 1;
1174             Compile_Only := True;
1175
1176          when 'd' =>
1177
1178             --  Note: for the debug switch, the remaining characters in this
1179             --  switch field must all be debug flags, since all valid switch
1180             --  characters are also valid debug characters.
1181
1182             --  Loop to scan out debug flags
1183
1184             while Ptr < Max loop
1185                Ptr := Ptr + 1;
1186                C := Switch_Chars (Ptr);
1187                exit when C = ASCII.NUL or else C = '/' or else C = '-';
1188
1189                if C in '1' .. '9' or else
1190                   C in 'a' .. 'z' or else
1191                   C in 'A' .. 'Z'
1192                then
1193                   Set_Debug_Flag (C);
1194                else
1195                   raise Bad_Switch;
1196                end if;
1197             end loop;
1198
1199             --  Make sure Zero_Cost_Exceptions is set if gnatdX set. This
1200             --  is for backwards compatibility with old versions and usage.
1201
1202             if Debug_Flag_XX then
1203                Zero_Cost_Exceptions_Set := True;
1204                Zero_Cost_Exceptions_Val := True;
1205             end if;
1206
1207             return;
1208
1209          --  Processing for f switch
1210
1211          when 'f' =>
1212             Ptr := Ptr + 1;
1213             Force_Compilations := True;
1214
1215          --  Processing for G switch
1216
1217          when 'G' =>
1218             Ptr := Ptr + 1;
1219             Print_Generated_Code := True;
1220
1221          --  Processing for h switch
1222
1223          when 'h' =>
1224             Ptr := Ptr + 1;
1225             Usage_Requested := True;
1226
1227          --  Processing for i switch
1228
1229          when 'i' =>
1230             Ptr := Ptr + 1;
1231             In_Place_Mode := True;
1232
1233          --  Processing for j switch
1234
1235          when 'j' =>
1236             Ptr := Ptr + 1;
1237
1238             declare
1239                Max_Proc : Pos;
1240             begin
1241                Scan_Pos (Switch_Chars, Max, Ptr, Max_Proc);
1242                Maximum_Processes := Positive (Max_Proc);
1243             end;
1244
1245          --  Processing for k switch
1246
1247          when 'k' =>
1248             Ptr := Ptr + 1;
1249             Keep_Going := True;
1250
1251          --  Processing for l switch
1252
1253          when 'l' =>
1254             Ptr := Ptr + 1;
1255             Link_Only := True;
1256
1257          when 'M' =>
1258             Ptr := Ptr + 1;
1259             List_Dependencies := True;
1260
1261          --  Processing for n switch
1262
1263          when 'n' =>
1264             Ptr := Ptr + 1;
1265             Do_Not_Execute := True;
1266
1267          --  Processing for o switch
1268
1269          when 'o' =>
1270             Ptr := Ptr + 1;
1271
1272             if Output_File_Name_Present then
1273                raise Too_Many_Output_Files;
1274             else
1275                Output_File_Name_Present := True;
1276             end if;
1277
1278          --  Processing for q switch
1279
1280          when 'q' =>
1281             Ptr := Ptr + 1;
1282             Quiet_Output := True;
1283
1284          --  Processing for s switch
1285
1286          when 's' =>
1287             Ptr := Ptr + 1;
1288             Check_Switches := True;
1289
1290          --  Processing for v switch
1291
1292          when 'v' =>
1293             Ptr := Ptr + 1;
1294             Verbose_Mode := True;
1295
1296          --  Processing for z switch
1297
1298          when 'z' =>
1299             Ptr := Ptr + 1;
1300             No_Main_Subprogram := True;
1301
1302          --  Ignore extra switch character
1303
1304          when '/' | '-' =>
1305             Ptr := Ptr + 1;
1306
1307          --  Anything else is an error (illegal switch character)
1308
1309          when others =>
1310             raise Bad_Switch;
1311
1312          end case;
1313       end loop;
1314
1315    exception
1316       when Bad_Switch =>
1317          Osint.Fail ("invalid switch: ", (1 => C));
1318
1319       when Bad_Switch_Value =>
1320          Osint.Fail ("numeric value too big for switch: ", (1 => C));
1321
1322       when Missing_Switch_Value =>
1323          Osint.Fail ("missing numeric value for switch: ", (1 => C));
1324
1325       when Too_Many_Output_Files =>
1326          Osint.Fail ("duplicate -o switch");
1327
1328    end Scan_Make_Switches;
1329
1330    --------------
1331    -- Scan_Nat --
1332    --------------
1333
1334    procedure Scan_Nat
1335      (Switch_Chars : String;
1336       Max          : Integer;
1337       Ptr          : in out Integer;
1338       Result       : out Nat) is
1339    begin
1340       Result := 0;
1341       if Ptr > Max or else Switch_Chars (Ptr) not in '0' .. '9' then
1342          raise Missing_Switch_Value;
1343       end if;
1344
1345       while Ptr <= Max and then Switch_Chars (Ptr) in '0' .. '9' loop
1346          Result := Result * 10 +
1347            Character'Pos (Switch_Chars (Ptr)) - Character'Pos ('0');
1348          Ptr := Ptr + 1;
1349
1350          if Result > Switch_Max_Value then
1351             raise Bad_Switch_Value;
1352          end if;
1353       end loop;
1354    end Scan_Nat;
1355
1356    --------------
1357    -- Scan_Pos --
1358    --------------
1359
1360    procedure Scan_Pos
1361      (Switch_Chars : String;
1362       Max          : Integer;
1363       Ptr          : in out Integer;
1364       Result       : out Pos) is
1365
1366    begin
1367       Scan_Nat (Switch_Chars, Max, Ptr, Result);
1368       if Result = 0 then
1369          raise Bad_Switch_Value;
1370       end if;
1371    end Scan_Pos;
1372
1373 end Switch;