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