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