OSDN Git Service

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