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