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-2018, 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' or '3', 466 -- then by 's' 467 468 when 'R' => 469 Last_Stored := First_Stored; 470 Storing (Last_Stored) := 'R'; 471 Ptr := Ptr + 1; 472 473 if Ptr <= Max 474 and then Switch_Chars (Ptr) in '0' .. '9' 475 then 476 C := Switch_Chars (Ptr); 477 478 if C in '4' .. '9' then 479 Last := 0; 480 return; 481 482 else 483 Last_Stored := Last_Stored + 1; 484 Storing (Last_Stored) := C; 485 Ptr := Ptr + 1; 486 487 if Ptr <= Max 488 and then Switch_Chars (Ptr) = 's' 489 then 490 Last_Stored := Last_Stored + 1; 491 Storing (Last_Stored) := 's'; 492 Ptr := Ptr + 1; 493 end if; 494 end if; 495 end if; 496 497 Add_Switch_Component 498 (Storing (Storing'First .. Last_Stored)); 499 500 -- -gnatWx, x = 'h'. 'u', 's', 'e', '8' or 'b' 501 502 when 'W' => 503 Storing (First_Stored) := 'W'; 504 Ptr := Ptr + 1; 505 506 if Ptr <= Max then 507 case Switch_Chars (Ptr) is 508 when 'h' | 'u' | 's' | 'e' | '8' | 'b' => 509 Storing (First_Stored + 1) := Switch_Chars (Ptr); 510 Add_Switch_Component 511 (Storing (Storing'First .. First_Stored + 1)); 512 Ptr := Ptr + 1; 513 514 when others => 515 Last := 0; 516 return; 517 end case; 518 end if; 519 520 -- Multiple switches 521 522 when 'V' | 'w' | 'y' => 523 Storing (First_Stored) := C; 524 Ptr := Ptr + 1; 525 526 if Ptr > Max then 527 if C = 'y' then 528 Add_Switch_Component 529 (Storing (Storing'First .. First_Stored)); 530 531 else 532 Last := 0; 533 return; 534 end if; 535 end if; 536 537 -- Loop through remaining switch characters in string 538 539 while Ptr <= Max loop 540 C := Switch_Chars (Ptr); 541 Ptr := Ptr + 1; 542 543 -- -gnatyMxxx 544 545 if C = 'M' and then Storing (First_Stored) = 'y' then 546 Last_Stored := First_Stored + 1; 547 Storing (Last_Stored) := 'M'; 548 while Ptr <= Max loop 549 C := Switch_Chars (Ptr); 550 exit when C not in '0' .. '9'; 551 Last_Stored := Last_Stored + 1; 552 Storing (Last_Stored) := C; 553 Ptr := Ptr + 1; 554 end loop; 555 556 -- If there is no digit after -gnatyM, 557 -- the switch is invalid. 558 559 if Last_Stored = First_Stored + 1 then 560 Last := 0; 561 return; 562 563 else 564 Add_Switch_Component 565 (Storing (Storing'First .. Last_Stored)); 566 end if; 567 568 -- --gnatx.x 569 570 elsif C = '.' and then Ptr <= Max then 571 Storing (First_Stored + 1) := '.'; 572 Storing (First_Stored + 2) := Switch_Chars (Ptr); 573 Ptr := Ptr + 1; 574 Add_Switch_Component 575 (Storing (Storing'First .. First_Stored + 2)); 576 577 -- All other switches are -gnatxx 578 579 else 580 Storing (First_Stored + 1) := C; 581 Add_Switch_Component 582 (Storing (Storing'First .. First_Stored + 1)); 583 end if; 584 end loop; 585 586 -- -gnat95 -gnat05 587 588 when '0' | '9' => 589 Last_Stored := First_Stored; 590 Storing (Last_Stored) := C; 591 Ptr := Ptr + 1; 592 593 if Ptr /= Max or else Switch_Chars (Ptr) /= '5' then 594 595 -- Invalid switch 596 597 Last := 0; 598 return; 599 600 else 601 Last_Stored := Last_Stored + 1; 602 Storing (Last_Stored) := '5'; 603 Add_Switch_Component 604 (Storing (Storing'First .. Last_Stored)); 605 Ptr := Ptr + 1; 606 end if; 607 608 -- -gnat12 609 610 when '1' => 611 Last_Stored := First_Stored; 612 Storing (Last_Stored) := C; 613 Ptr := Ptr + 1; 614 615 if Ptr /= Max or else Switch_Chars (Ptr) /= '2' then 616 617 -- Invalid switch 618 619 Last := 0; 620 return; 621 622 else 623 Last_Stored := Last_Stored + 1; 624 Storing (Last_Stored) := '2'; 625 Add_Switch_Component 626 (Storing (Storing'First .. Last_Stored)); 627 Ptr := Ptr + 1; 628 end if; 629 630 -- -gnat2005 -gnat2012 631 632 when '2' => 633 if Ptr + 3 /= Max then 634 Last := 0; 635 return; 636 637 elsif Switch_Chars (Ptr + 1 .. Ptr + 3) = "005" then 638 Last_Stored := First_Stored + 3; 639 Storing (First_Stored .. Last_Stored) := "2005"; 640 Add_Switch_Component 641 (Storing (Storing'First .. Last_Stored)); 642 Ptr := Max + 1; 643 644 elsif Switch_Chars (Ptr + 1 .. Ptr + 3) = "012" then 645 Last_Stored := First_Stored + 3; 646 Storing (First_Stored .. Last_Stored) := "2012"; 647 Add_Switch_Component 648 (Storing (Storing'First .. Last_Stored)); 649 Ptr := Max + 1; 650 651 else 652 653 -- Invalid switch 654 655 Last := 0; 656 return; 657 658 end if; 659 660 -- -gnat83 661 662 when '8' => 663 Last_Stored := First_Stored; 664 Storing (Last_Stored) := '8'; 665 Ptr := Ptr + 1; 666 667 if Ptr /= Max or else Switch_Chars (Ptr) /= '3' then 668 669 -- Invalid switch 670 671 Last := 0; 672 return; 673 674 else 675 Last_Stored := Last_Stored + 1; 676 Storing (Last_Stored) := '3'; 677 Add_Switch_Component 678 (Storing (Storing'First .. Last_Stored)); 679 Ptr := Ptr + 1; 680 end if; 681 682 -- Not a valid switch 683 684 when others => 685 Last := 0; 686 return; 687 end case; 688 end case; 689 end loop; 690 end Normalize_Compiler_Switches; 691 692 function Normalize_Compiler_Switches 693 (Switch_Chars : String) return Argument_List 694 is 695 Last : Natural; 696 697 begin 698 Normalize_Compiler_Switches (Switch_Chars, Global_Switches, Last); 699 700 if Last = 0 then 701 return (1 .. 0 => null); 702 else 703 return Global_Switches (Global_Switches'First .. Last); 704 end if; 705 end Normalize_Compiler_Switches; 706 707 ------------------------ 708 -- Scan_Make_Switches -- 709 ------------------------ 710 711 procedure Scan_Make_Switches 712 (Switch_Chars : String; 713 Success : out Boolean) 714 is 715 Ptr : Integer := Switch_Chars'First; 716 Max : constant Integer := Switch_Chars'Last; 717 C : Character := ' '; 718 719 begin 720 -- Assume a good switch 721 722 Success := True; 723 724 -- Skip past the initial character (must be the switch character) 725 726 if Ptr = Max then 727 Bad_Switch (Switch_Chars); 728 729 else 730 Ptr := Ptr + 1; 731 end if; 732 733 -- A little check, "gnat" at the start of a switch is for the compiler 734 735 if Switch_Chars'Length >= Ptr + 3 736 and then Switch_Chars (Ptr .. Ptr + 3) = "gnat" 737 then 738 Success := False; 739 return; 740 end if; 741 742 C := Switch_Chars (Ptr); 743 744 -- Multiple character switches 745 746 -- To preserve building gnat_util, it is not possible to use the 747 -- constant Strings declare in Make_Util, as Make_Util is not in 748 -- gnat_util. 749 750 if Switch_Chars'Length > 2 then 751 if Switch_Chars = "--create-missing-dirs" then 752 Setup_Projects := True; 753 754 elsif Switch_Chars'Length > Subdirs_Option'Length 755 and then 756 Switch_Chars 757 (Switch_Chars'First .. 758 Switch_Chars'First + Subdirs_Option'Length - 1) = 759 Subdirs_Option 760 then 761 Subdirs := 762 new String'(Switch_Chars 763 (Switch_Chars'First + Subdirs_Option'Length .. 764 Switch_Chars'Last)); 765 766 elsif Switch_Chars = "--unchecked-shared-lib-imports" then 767 Opt.Unchecked_Shared_Lib_Imports := True; 768 769 elsif Switch_Chars = "--single-compile-per-obj-dir" then 770 Opt.One_Compilation_Per_Obj_Dir := True; 771 772 elsif Switch_Chars = "--no-exit-message" then 773 Opt.No_Exit_Message := True; 774 775 elsif Switch_Chars = "--keep-temp-files" then 776 Opt.Keep_Temporary_Files := True; 777 778 elsif Switch_Chars (Ptr) = '-' then 779 Bad_Switch (Switch_Chars); 780 781 elsif Switch_Chars'Length > 3 782 and then Switch_Chars (Ptr .. Ptr + 1) = "aP" 783 then 784 null; 785 -- This is only used by gprbuild 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 1053end Switch.M; 1054