sem_prag.adb (Analyze_Pragma): Add appropriate calls to Resolve_Suppressible in the...
[platform/upstream/gcc.git] / gcc / ada / switch-m.adb
1 ------------------------------------------------------------------------------
2 --                                                                          --
3 --                         GNAT COMPILER COMPONENTS                         --
4 --                                                                          --
5 --                             S W I T C H - M                              --
6 --                                                                          --
7 --                                 B o d y                                  --
8 --                                                                          --
9 --          Copyright (C) 2001-2016, Free Software Foundation, Inc.         --
10 --                                                                          --
11 -- GNAT is free software;  you can  redistribute it  and/or modify it under --
12 -- terms of the  GNU General Public License as published  by the Free Soft- --
13 -- ware  Foundation;  either version 3,  or (at your option) any later ver- --
14 -- sion.  GNAT is distributed in the hope that it will be useful, but WITH- --
15 -- OUT ANY WARRANTY;  without even the  implied warranty of MERCHANTABILITY --
16 -- or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License --
17 -- for  more details.  You should have  received  a copy of the GNU General --
18 -- Public License  distributed with GNAT; see file COPYING3.  If not, go to --
19 -- http://www.gnu.org/licenses for a complete copy of the license.          --
20 --                                                                          --
21 -- GNAT was originally developed  by the GNAT team at  New York University. --
22 -- Extensive contributions were provided by Ada Core Technologies Inc.      --
23 --                                                                          --
24 ------------------------------------------------------------------------------
25
26 with Debug;    use Debug;
27 with Makeutl;  use Makeutl;
28 with Osint;    use Osint;
29 with Opt;      use Opt;
30 with Prj;      use Prj;
31 with Prj.Env;  use Prj.Env;
32 with Table;
33
34 with System.Multiprocessors; use System.Multiprocessors;
35
36 package body Switch.M is
37
38    package Normalized_Switches is new Table.Table
39      (Table_Component_Type => String_Access,
40       Table_Index_Type     => Integer,
41       Table_Low_Bound      => 1,
42       Table_Initial        => 20,
43       Table_Increment      => 100,
44       Table_Name           => "Switch.M.Normalized_Switches");
45    --  This table is used to keep the normalized switches, so that they may be
46    --  reused for subsequent invocations of Normalize_Compiler_Switches with
47    --  similar switches.
48
49    Initial_Number_Of_Switches : constant := 10;
50
51    Global_Switches : Argument_List_Access := null;
52    --  Used by function Normalize_Compiler_Switches
53
54    ---------------------------------
55    -- Normalize_Compiler_Switches --
56    ---------------------------------
57
58    procedure Normalize_Compiler_Switches
59      (Switch_Chars : String;
60       Switches     : in out Argument_List_Access;
61       Last         : out Natural)
62    is
63       Switch_Starts_With_Gnat : Boolean;
64
65       Ptr : Integer := Switch_Chars'First;
66       Max : constant Integer := Switch_Chars'Last;
67       C   : Character := ' ';
68
69       Storing      : String := Switch_Chars;
70       First_Stored : Positive := Ptr + 1;
71       Last_Stored  : Positive := First_Stored;
72
73       procedure Add_Switch_Component (S : String);
74       --  Add a new String_Access component in Switches. If a string equal
75       --  to S is already stored in the table Normalized_Switches, use it.
76       --  Otherwise add a new component to the table.
77
78       --------------------------
79       -- Add_Switch_Component --
80       --------------------------
81
82       procedure Add_Switch_Component (S : String) is
83       begin
84          --  If Switches is null, allocate a new array
85
86          if Switches = null then
87             Switches := new Argument_List (1 .. Initial_Number_Of_Switches);
88
89          --  Otherwise, if Switches is full, extend it
90
91          elsif Last = Switches'Last then
92             declare
93                New_Switches : constant Argument_List_Access :=
94                                 new Argument_List
95                                       (1 .. Switches'Length + Switches'Length);
96             begin
97                New_Switches (1 .. Switches'Length) := Switches.all;
98                Last := Switches'Length;
99                Switches := New_Switches;
100             end;
101          end if;
102
103          --  If this is the first switch, Last designates the first component
104
105          if Last = 0 then
106             Last := Switches'First;
107          else
108             Last := Last + 1;
109          end if;
110
111          --  Look into the table Normalized_Switches for a similar string.
112          --  If one is found, put it at the added component, and return.
113
114          for Index in 1 .. Normalized_Switches.Last loop
115             if S = Normalized_Switches.Table (Index).all then
116                Switches (Last) := Normalized_Switches.Table (Index);
117                return;
118             end if;
119          end loop;
120
121          --  No string equal to S was found in the table Normalized_Switches.
122          --  Add a new component in the table.
123
124          Switches (Last) := new String'(S);
125          Normalized_Switches.Append (Switches (Last));
126       end Add_Switch_Component;
127
128    --  Start of processing for Normalize_Compiler_Switches
129
130    begin
131       Last := 0;
132
133       if Ptr = Max or else Switch_Chars (Ptr) /= '-' then
134          return;
135       end if;
136
137       Ptr := Ptr + 1;
138
139       Switch_Starts_With_Gnat :=
140          Ptr + 3 <= Max and then Switch_Chars (Ptr .. Ptr + 3) = "gnat";
141
142       if Switch_Starts_With_Gnat then
143          Ptr := Ptr + 4;
144          First_Stored := Ptr;
145       end if;
146
147       while Ptr <= Max loop
148          C := Switch_Chars (Ptr);
149
150          --  Processing for a switch
151
152          case Switch_Starts_With_Gnat is
153
154             when False =>
155
156                --  All switches that don't start with -gnat stay as is,
157                --  except -pg, -Wall, -k8, -w
158
159                if Switch_Chars = "-pg" or else Switch_Chars = "-p" then
160
161                   --  The gcc driver converts -pg to -p, so that is what
162                   --  is stored in the ALI file.
163
164                   Add_Switch_Component ("-p");
165
166                elsif Switch_Chars = "-Wall" then
167
168                   --  The gcc driver adds -gnatwa when -Wall is used
169
170                   Add_Switch_Component ("-gnatwa");
171                   Add_Switch_Component ("-Wall");
172
173                elsif Switch_Chars = "-k8" then
174
175                   --  The gcc driver transforms -k8 into -gnatk8
176
177                   Add_Switch_Component ("-gnatk8");
178
179                elsif Switch_Chars = "-w" then
180
181                   --  The gcc driver adds -gnatws when -w is used
182
183                   Add_Switch_Component ("-gnatws");
184                   Add_Switch_Component ("-w");
185
186                elsif Switch_Chars'Length > 6
187                  and then
188                    Switch_Chars (Switch_Chars'First .. Switch_Chars'First + 5)
189                                                              = "--RTS="
190                then
191                   Add_Switch_Component (Switch_Chars);
192
193                   --  When --RTS=mtp is used, the gcc driver adds -mrtp
194
195                   if Switch_Chars = "--RTS=mtp" then
196                      Add_Switch_Component ("-mrtp");
197                   end if;
198
199                --  Special case for -fstack-check (alias for
200                --  -fstack-check=specific)
201
202                elsif Switch_Chars = "-fstack-check" then
203                   Add_Switch_Component ("-fstack-check=specific");
204
205                --  Take only into account switches that are transmitted to
206                --  gnat1 by the gcc driver and stored by gnat1 in the ALI file.
207
208                else
209                   case C is
210                      when 'O' | 'W' | 'w' | 'f' | 'd' | 'g' | 'm' =>
211                         Add_Switch_Component (Switch_Chars);
212
213                      when others =>
214                         null;
215                   end case;
216                end if;
217
218                return;
219
220             when True =>
221
222                case C is
223
224                   --  One-letter switches
225
226                   when 'a' | 'A' | 'b' | 'B' | 'c' | 'C' | 'E' | 'f' |
227                        'F' | 'g' | 'h' | 'H' | 'I' | 'L' | 'N' | 'p' |
228                        'P' | 'q' | 'Q' | 'r' | 's' | 'S' | 't' | 'u' |
229                        'U' | 'v' | 'x' | 'X' | 'Z' =>
230                      Storing (First_Stored) := C;
231                      Add_Switch_Component
232                        (Storing (Storing'First .. First_Stored));
233                      Ptr := Ptr + 1;
234
235                   --  One-letter switches followed by a positive number
236
237                   when 'D' | 'G' | 'j' | 'k' | 'm' | 'T' =>
238                      Storing (First_Stored) := C;
239                      Last_Stored := First_Stored;
240
241                      if Ptr <= Max and then Switch_Chars (Ptr) = '=' then
242                         Ptr := Ptr + 1;
243                      end if;
244
245                      loop
246                         Ptr := Ptr + 1;
247                         exit when Ptr > Max
248                           or else Switch_Chars (Ptr) not in '0' .. '9';
249                         Last_Stored := Last_Stored + 1;
250                         Storing (Last_Stored) := Switch_Chars (Ptr);
251                      end loop;
252
253                      Add_Switch_Component
254                        (Storing (Storing'First .. Last_Stored));
255
256                   when 'd' =>
257                      Storing (First_Stored) := 'd';
258
259                      while Ptr < Max loop
260                         Ptr := Ptr + 1;
261                         C := Switch_Chars (Ptr);
262                         exit when C = ASCII.NUL or else C = '/'
263                           or else C = '-';
264
265                         if C in '1' .. '9' or else
266                            C in 'a' .. 'z' or else
267                            C in 'A' .. 'Z'
268                         then
269                            Storing (First_Stored + 1) := C;
270                            Add_Switch_Component
271                              (Storing (Storing'First .. First_Stored + 1));
272
273                         else
274                            Last := 0;
275                            return;
276                         end if;
277                      end loop;
278
279                      return;
280
281                   when 'e' =>
282
283                      --  Some of the gnate... switches are not stored
284
285                      Storing (First_Stored) := 'e';
286                      Ptr := Ptr + 1;
287
288                      if Ptr > Max then
289                         Last := 0;
290                         return;
291
292                      else
293                         case Switch_Chars (Ptr) is
294
295                            when 'A' =>
296                               Ptr := Ptr + 1;
297                               Add_Switch_Component ("-gnateA");
298
299                            when 'D' =>
300                               Storing (First_Stored + 1 ..
301                                          First_Stored + Max - Ptr + 1) :=
302                                   Switch_Chars (Ptr .. Max);
303                               Add_Switch_Component
304                                 (Storing (Storing'First ..
305                                    First_Stored + Max - Ptr + 1));
306                               Ptr := Max + 1;
307
308                            when 'E' | 'F' | 'G' | 'S' | 'u' | 'V' | 'Y' =>
309                               Add_Switch_Component
310                                 ("-gnate" & Switch_Chars (Ptr));
311                               Ptr := Ptr + 1;
312
313                            when 'i' | 'I' =>
314                               declare
315                                  First : constant Positive := Ptr;
316
317                               begin
318                                  Ptr := Ptr + 1;
319
320                                  if Ptr <= Max and then
321                                    Switch_Chars (Ptr) = '='
322                                  then
323                                     Ptr := Ptr + 1;
324                                  end if;
325
326                                  while Ptr <= Max and then
327                                        Switch_Chars (Ptr) in '0' .. '9'
328                                  loop
329                                     Ptr := Ptr + 1;
330                                  end loop;
331
332                                  Storing (First_Stored + 1 ..
333                                             First_Stored + Ptr - First) :=
334                                      Switch_Chars (First .. Ptr - 1);
335                                  Add_Switch_Component
336                                    (Storing (Storing'First ..
337                                       First_Stored + Ptr - First));
338                               end;
339
340                            when 'l' =>
341                               Ptr := Ptr + 1;
342                               Add_Switch_Component ("-gnatel");
343
344                            when 'L' =>
345                               Ptr := Ptr + 1;
346                               Add_Switch_Component ("-gnateL");
347
348                            when 'p' =>
349                               Ptr := Ptr + 1;
350
351                               if Ptr = Max then
352                                  Last := 0;
353                                  return;
354                               end if;
355
356                               if Switch_Chars (Ptr) = '=' then
357                                  Ptr := Ptr + 1;
358                               end if;
359
360                                  --  To normalize, always put a '=' after
361                                  --  -gnatep. Because that could lengthen the
362                                  --  switch string, declare a local variable.
363
364                               declare
365                                  To_Store : String (1 .. Max - Ptr + 9);
366                               begin
367                                  To_Store (1 .. 8) := "-gnatep=";
368                                  To_Store (9 .. Max - Ptr + 9) :=
369                                    Switch_Chars (Ptr .. Max);
370                                  Add_Switch_Component (To_Store);
371                               end;
372
373                               return;
374
375                            when others =>
376                               Last := 0;
377                               return;
378                         end case;
379                      end if;
380
381                   when 'i' =>
382                      Storing (First_Stored) := 'i';
383
384                      Ptr := Ptr + 1;
385
386                      if Ptr > Max then
387                         Last := 0;
388                         return;
389                      end if;
390
391                      C := Switch_Chars (Ptr);
392
393                      if C in '1' .. '5'
394                        or else C = '8'
395                        or else C = 'p'
396                        or else C = 'f'
397                        or else C = 'n'
398                        or else C = 'w'
399                      then
400                         Storing (First_Stored + 1) := C;
401                         Add_Switch_Component
402                           (Storing (Storing'First .. First_Stored + 1));
403                         Ptr := Ptr + 1;
404
405                      else
406                         Last := 0;
407                         return;
408                      end if;
409
410                   --  -gnatl may be -gnatl=<file name>
411
412                   when 'l' =>
413                      Ptr := Ptr + 1;
414
415                      if Ptr > Max or else Switch_Chars (Ptr) /= '=' then
416                         Add_Switch_Component ("-gnatl");
417
418                      else
419                         Add_Switch_Component
420                           ("-gnatl" & Switch_Chars (Ptr .. Max));
421                         return;
422                      end if;
423
424                   --  -gnatn may be -gnatn, -gnatn1, or -gnatn2
425
426                   when 'n' =>
427                      Last_Stored := First_Stored;
428                      Storing (Last_Stored) := 'n';
429                      Ptr := Ptr + 1;
430
431                      if Ptr <= Max
432                        and then Switch_Chars (Ptr) in '1' .. '2'
433                      then
434                         Last_Stored := Last_Stored + 1;
435                         Storing (Last_Stored) := Switch_Chars (Ptr);
436                         Ptr := Ptr + 1;
437                      end if;
438
439                      Add_Switch_Component
440                        (Storing (Storing'First .. Last_Stored));
441
442                   --  -gnato may be -gnatox or -gnatoxx, with x=0/1/2/3
443
444                   when 'o' =>
445                      Last_Stored := First_Stored;
446                      Storing (Last_Stored) := 'o';
447                      Ptr := Ptr + 1;
448
449                      if Ptr <= Max
450                        and then Switch_Chars (Ptr) in '0' .. '3'
451                      then
452                         Last_Stored := Last_Stored + 1;
453                         Storing (Last_Stored) := Switch_Chars (Ptr);
454                         Ptr := Ptr + 1;
455
456                         if Ptr <= Max
457                           and then Switch_Chars (Ptr) in '0' .. '3'
458                         then
459                            Last_Stored := Last_Stored + 1;
460                            Storing (Last_Stored) := Switch_Chars (Ptr);
461                            Ptr := Ptr + 1;
462                         end if;
463                      end if;
464
465                      Add_Switch_Component
466                        (Storing (Storing'First .. Last_Stored));
467
468                   --  -gnatR may be followed by '0', '1', '2' or '3',
469                   --  then by 's'
470
471                   when 'R' =>
472                      Last_Stored := First_Stored;
473                      Storing (Last_Stored) := 'R';
474                      Ptr := Ptr + 1;
475
476                      if Ptr <= Max
477                        and then Switch_Chars (Ptr) in '0' .. '9'
478                      then
479                         C := Switch_Chars (Ptr);
480
481                         if C in '4' .. '9' then
482                            Last := 0;
483                            return;
484
485                         else
486                            Last_Stored := Last_Stored + 1;
487                            Storing (Last_Stored) := C;
488                            Ptr := Ptr + 1;
489
490                            if Ptr <= Max
491                              and then Switch_Chars (Ptr) = 's'
492                            then
493                               Last_Stored := Last_Stored + 1;
494                               Storing (Last_Stored) := 's';
495                               Ptr := Ptr + 1;
496                            end if;
497                         end if;
498                      end if;
499
500                      Add_Switch_Component
501                        (Storing (Storing'First .. Last_Stored));
502
503                   --  -gnatWx, x = 'h'. 'u', 's', 'e', '8' or 'b'
504
505                   when 'W' =>
506                      Storing (First_Stored) := 'W';
507                      Ptr := Ptr + 1;
508
509                      if Ptr <= Max then
510                         case Switch_Chars (Ptr) is
511                            when 'h' | 'u' | 's' | 'e' | '8' | 'b' =>
512                               Storing (First_Stored + 1) := Switch_Chars (Ptr);
513                               Add_Switch_Component
514                                 (Storing (Storing'First .. First_Stored + 1));
515                               Ptr := Ptr + 1;
516
517                            when others =>
518                               Last := 0;
519                               return;
520                         end case;
521                      end if;
522
523                   --  Multiple switches
524
525                   when 'V' | 'w' | 'y' =>
526                      Storing (First_Stored) := C;
527                      Ptr := Ptr + 1;
528
529                      if Ptr > Max then
530                         if C = 'y' then
531                            Add_Switch_Component
532                              (Storing (Storing'First .. First_Stored));
533
534                         else
535                            Last := 0;
536                            return;
537                         end if;
538                      end if;
539
540                      --  Loop through remaining switch characters in string
541
542                      while Ptr <= Max loop
543                         C := Switch_Chars (Ptr);
544                         Ptr := Ptr + 1;
545
546                         --  -gnatyMxxx
547
548                         if C = 'M' and then Storing (First_Stored) = 'y' then
549                            Last_Stored := First_Stored + 1;
550                            Storing (Last_Stored) := 'M';
551                            while Ptr <= Max loop
552                               C := Switch_Chars (Ptr);
553                               exit when C not in '0' .. '9';
554                               Last_Stored := Last_Stored + 1;
555                               Storing (Last_Stored) := C;
556                               Ptr := Ptr + 1;
557                            end loop;
558
559                            --  If there is no digit after -gnatyM,
560                            --  the switch is invalid.
561
562                            if Last_Stored = First_Stored + 1 then
563                               Last := 0;
564                               return;
565
566                            else
567                               Add_Switch_Component
568                                 (Storing (Storing'First .. Last_Stored));
569                            end if;
570
571                         --  --gnatx.x
572
573                         elsif C = '.' and then Ptr <= Max then
574                            Storing (First_Stored + 1) := '.';
575                            Storing (First_Stored + 2) := Switch_Chars (Ptr);
576                            Ptr := Ptr + 1;
577                            Add_Switch_Component
578                              (Storing (Storing'First .. First_Stored + 2));
579
580                         --  All other switches are -gnatxx
581
582                         else
583                            Storing (First_Stored + 1) := C;
584                            Add_Switch_Component
585                              (Storing (Storing'First .. First_Stored + 1));
586                         end if;
587                      end loop;
588
589                   --  -gnat95 -gnat05
590
591                   when '0' | '9' =>
592                      Last_Stored := First_Stored;
593                      Storing (Last_Stored) := C;
594                      Ptr := Ptr + 1;
595
596                      if Ptr /= Max or else Switch_Chars (Ptr) /= '5' then
597
598                         --  Invalid switch
599
600                         Last := 0;
601                         return;
602
603                      else
604                         Last_Stored := Last_Stored + 1;
605                         Storing (Last_Stored) := '5';
606                         Add_Switch_Component
607                           (Storing (Storing'First .. Last_Stored));
608                         Ptr := Ptr + 1;
609                      end if;
610
611                      --  -gnat12
612
613                   when '1' =>
614                      Last_Stored := First_Stored;
615                      Storing (Last_Stored) := C;
616                      Ptr := Ptr + 1;
617
618                      if Ptr /= Max or else Switch_Chars (Ptr) /= '2' then
619
620                         --  Invalid switch
621
622                         Last := 0;
623                         return;
624
625                      else
626                         Last_Stored := Last_Stored + 1;
627                         Storing (Last_Stored) := '2';
628                         Add_Switch_Component
629                           (Storing (Storing'First .. Last_Stored));
630                         Ptr := Ptr + 1;
631                      end if;
632
633                      --  -gnat2005 -gnat2012
634
635                   when '2' =>
636                      if Ptr + 3 /= Max then
637                         Last := 0;
638                         return;
639
640                      elsif Switch_Chars (Ptr + 1 .. Ptr + 3) = "005" then
641                         Last_Stored := First_Stored + 3;
642                         Storing (First_Stored .. Last_Stored) := "2005";
643                         Add_Switch_Component
644                           (Storing (Storing'First .. Last_Stored));
645                         Ptr := Max + 1;
646
647                      elsif Switch_Chars (Ptr + 1 .. Ptr + 3) = "012" then
648                         Last_Stored := First_Stored + 3;
649                         Storing (First_Stored .. Last_Stored) := "2012";
650                         Add_Switch_Component
651                           (Storing (Storing'First .. Last_Stored));
652                         Ptr := Max + 1;
653
654                      else
655
656                         --  Invalid switch
657
658                         Last := 0;
659                         return;
660
661                      end if;
662
663                   --  -gnat83
664
665                   when '8' =>
666                      Last_Stored := First_Stored;
667                      Storing (Last_Stored) := '8';
668                      Ptr := Ptr + 1;
669
670                      if Ptr /= Max or else Switch_Chars (Ptr) /= '3' then
671
672                         --  Invalid switch
673
674                         Last := 0;
675                         return;
676
677                      else
678                         Last_Stored := Last_Stored + 1;
679                         Storing (Last_Stored) := '3';
680                         Add_Switch_Component
681                           (Storing (Storing'First .. Last_Stored));
682                         Ptr := Ptr + 1;
683                      end if;
684
685                   --  Not a valid switch
686
687                   when others =>
688                      Last := 0;
689                      return;
690
691                end case;
692
693          end case;
694       end loop;
695    end Normalize_Compiler_Switches;
696
697    function Normalize_Compiler_Switches
698      (Switch_Chars : String) return Argument_List
699    is
700       Last : Natural;
701
702    begin
703       Normalize_Compiler_Switches (Switch_Chars, Global_Switches, Last);
704
705       if Last = 0 then
706          return (1 .. 0 => null);
707       else
708          return Global_Switches (Global_Switches'First .. Last);
709       end if;
710    end Normalize_Compiler_Switches;
711
712    ------------------------
713    -- Scan_Make_Switches --
714    ------------------------
715
716    procedure Scan_Make_Switches
717      (Env               : in out Prj.Tree.Environment;
718       Switch_Chars      : String;
719       Success           : out Boolean)
720    is
721       Ptr : Integer          := Switch_Chars'First;
722       Max : constant Integer := Switch_Chars'Last;
723       C   : Character        := ' ';
724
725    begin
726       --  Assume a good switch
727
728       Success := True;
729
730       --  Skip past the initial character (must be the switch character)
731
732       if Ptr = Max then
733          Bad_Switch (Switch_Chars);
734
735       else
736          Ptr := Ptr + 1;
737       end if;
738
739       --  A little check, "gnat" at the start of a switch is for the compiler
740
741       if Switch_Chars'Length >= Ptr + 3
742         and then Switch_Chars (Ptr .. Ptr + 3) = "gnat"
743       then
744          Success := False;
745          return;
746       end if;
747
748       C := Switch_Chars (Ptr);
749
750       --  Multiple character switches
751
752       if Switch_Chars'Length > 2 then
753          if Switch_Chars = "--create-missing-dirs" then
754             Setup_Projects := True;
755
756          elsif Switch_Chars'Length > Subdirs_Option'Length
757            and then
758              Switch_Chars
759                (Switch_Chars'First ..
760                 Switch_Chars'First + Subdirs_Option'Length - 1) =
761                                                             Subdirs_Option
762          then
763             Subdirs :=
764               new String'
765                 (Switch_Chars
766                   (Switch_Chars'First + Subdirs_Option'Length ..
767                    Switch_Chars'Last));
768
769          elsif Switch_Chars = Makeutl.Unchecked_Shared_Lib_Imports then
770             Opt.Unchecked_Shared_Lib_Imports := True;
771
772          elsif Switch_Chars = Makeutl.Single_Compile_Per_Obj_Dir_Switch then
773             Opt.One_Compilation_Per_Obj_Dir := True;
774
775          elsif Switch_Chars = Makeutl.No_Exit_Message_Option then
776             Opt.No_Exit_Message := True;
777
778          elsif Switch_Chars = Makeutl.Keep_Temp_Files_Option then
779             Opt.Keep_Temporary_Files := True;
780
781          elsif Switch_Chars (Ptr) = '-' then
782             Bad_Switch (Switch_Chars);
783
784          elsif Switch_Chars'Length > 3
785            and then Switch_Chars (Ptr .. Ptr + 1) = "aP"
786          then
787             Add_Directories
788               (Env.Project_Path,
789                Switch_Chars (Ptr + 2 .. Switch_Chars'Last));
790
791          elsif C = 'v' and then Switch_Chars'Length = 3 then
792             Ptr := Ptr + 1;
793             Verbose_Mode := True;
794
795             case Switch_Chars (Ptr) is
796                when 'l' =>
797                   Verbosity_Level := Opt.Low;
798
799                when 'm' =>
800                   Verbosity_Level := Opt.Medium;
801
802                when 'h' =>
803                   Verbosity_Level := Opt.High;
804
805                when others =>
806                   Success := False;
807             end case;
808
809          elsif C = 'd' then
810
811             --  Note: for the debug switch, the remaining characters in this
812             --  switch field must all be debug flags, since all valid switch
813             --  characters are also valid debug characters. This switch is not
814             --  documented on purpose because it is only used by the
815             --  implementors.
816
817             --  Loop to scan out debug flags
818
819             while Ptr < Max loop
820                Ptr := Ptr + 1;
821                C := Switch_Chars (Ptr);
822
823                if C in 'a' .. 'z' or else C in 'A' .. 'Z' then
824                   Set_Debug_Flag (C);
825                else
826                   Bad_Switch (Switch_Chars);
827                end if;
828             end loop;
829
830          elsif C = 'e' then
831             Ptr := Ptr + 1;
832
833             case Switch_Chars (Ptr) is
834
835                --  Processing for eI switch
836
837                when 'I' =>
838                   Ptr := Ptr + 1;
839                   Scan_Pos (Switch_Chars, Max, Ptr, Main_Index, C);
840
841                   if Ptr <= Max then
842                      Bad_Switch (Switch_Chars);
843                   end if;
844
845                --  Processing for eL switch
846
847                when 'L' =>
848                   if Ptr /= Max then
849                      Bad_Switch (Switch_Chars);
850
851                   else
852                      Follow_Links_For_Files := True;
853                      Follow_Links_For_Dirs  := True;
854                   end if;
855
856                --  Processing for eS switch
857
858                when 'S' =>
859                   if Ptr /= Max then
860                      Bad_Switch (Switch_Chars);
861
862                   else
863                      Commands_To_Stdout := True;
864                   end if;
865
866                when others =>
867                   Bad_Switch (Switch_Chars);
868             end case;
869
870          elsif C = 'j' then
871             Ptr := Ptr + 1;
872
873             declare
874                Max_Proc : Nat;
875
876             begin
877                Scan_Nat (Switch_Chars, Max, Ptr, Max_Proc, C);
878
879                if Ptr <= Max then
880                   Bad_Switch (Switch_Chars);
881
882                else
883                   if Max_Proc = 0 then
884                      Max_Proc := Nat (Number_Of_CPUs);
885
886                      if Max_Proc = 0 then
887                         Max_Proc := 1;
888                      end if;
889                   end if;
890
891                   Maximum_Processes := Positive (Max_Proc);
892                end if;
893             end;
894
895          elsif C = 'w' and then Switch_Chars'Length = 3 then
896             Ptr := Ptr + 1;
897
898             if Switch_Chars = "-we" then
899                Warning_Mode := Treat_As_Error;
900
901             elsif Switch_Chars = "-wn" then
902                Warning_Mode := Normal;
903
904             elsif Switch_Chars = "-ws" then
905                Warning_Mode  := Suppress;
906
907             else
908                Success := False;
909             end if;
910
911          else
912             Success := False;
913          end if;
914
915       --  Single-character switches
916
917       else
918          Check_Switch : begin
919
920             case C is
921
922                when 'a' =>
923                   Check_Readonly_Files := True;
924
925                --  Processing for b switch
926
927                when 'b' =>
928                   Bind_Only  := True;
929                   Make_Steps := True;
930
931                --  Processing for B switch
932
933                when 'B' =>
934                   Build_Bind_And_Link_Full_Project := True;
935
936                --  Processing for c switch
937
938                when 'c' =>
939                   Compile_Only := True;
940                   Make_Steps   := True;
941
942                --  Processing for C switch
943
944                when 'C' =>
945                   Opt.Create_Mapping_File := True;
946
947                --  Processing for D switch
948
949                when 'D' =>
950                   if Object_Directory_Present then
951                      Osint.Fail ("duplicate -D switch");
952
953                   else
954                      Object_Directory_Present := True;
955                   end if;
956
957                --  Processing for f switch
958
959                when 'f' =>
960                   Force_Compilations := True;
961
962                --  Processing for F switch
963
964                when 'F' =>
965                   Full_Path_Name_For_Brief_Errors := True;
966
967                --  Processing for h switch
968
969                when 'h' =>
970                   Usage_Requested := True;
971
972                --  Processing for i switch
973
974                when 'i' =>
975                   In_Place_Mode := True;
976
977                --  Processing for j switch
978
979                when 'j' =>
980                   --  -j not followed by a number is an error
981
982                   Bad_Switch (Switch_Chars);
983
984                --  Processing for k switch
985
986                when 'k' =>
987                   Keep_Going := True;
988
989                --  Processing for l switch
990
991                when 'l' =>
992                   Link_Only  := True;
993                   Make_Steps := True;
994
995                --  Processing for M switch
996
997                when 'M' =>
998                   List_Dependencies := True;
999
1000                --  Processing for n switch
1001
1002                when 'n' =>
1003                   Do_Not_Execute := True;
1004
1005                --  Processing for o switch
1006
1007                when 'o' =>
1008                   if Output_File_Name_Present then
1009                      Osint.Fail ("duplicate -o switch");
1010                   else
1011                      Output_File_Name_Present := True;
1012                   end if;
1013
1014                --  Processing for p switch
1015
1016                when 'p' =>
1017                   Setup_Projects := True;
1018
1019                --  Processing for q switch
1020
1021                when 'q' =>
1022                   Quiet_Output := True;
1023
1024                --  Processing for R switch
1025
1026                when 'R' =>
1027                   Run_Path_Option := False;
1028
1029                --  Processing for s switch
1030
1031                when 's' =>
1032                   Ptr := Ptr + 1;
1033                   Check_Switches := True;
1034
1035                --  Processing for v switch
1036
1037                when 'v' =>
1038                   Verbose_Mode := True;
1039                   Verbosity_Level := Opt.High;
1040
1041                   --  Processing for x switch
1042
1043                when 'x' =>
1044                   External_Unit_Compilation_Allowed := True;
1045                   Use_Include_Path_File := True;
1046
1047                   --  Processing for z switch
1048
1049                when 'z' =>
1050                   No_Main_Subprogram := True;
1051
1052                   --  Any other small letter is an illegal switch
1053
1054                when others =>
1055                   if C in 'a' .. 'z' then
1056                      Bad_Switch (Switch_Chars);
1057
1058                   else
1059                      Success := False;
1060                   end if;
1061
1062             end case;
1063          end Check_Switch;
1064       end if;
1065    end Scan_Make_Switches;
1066
1067 end Switch.M;