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