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-2014, 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 = Makeutl.No_Exit_Message_Option then 794 Opt.No_Exit_Message := True; 795 796 elsif Switch_Chars = Makeutl.Keep_Temp_Files_Option then 797 Opt.Keep_Temporary_Files := True; 798 799 elsif Switch_Chars (Ptr) = '-' then 800 Bad_Switch (Switch_Chars); 801 802 elsif Switch_Chars'Length > 3 803 and then Switch_Chars (Ptr .. Ptr + 1) = "aP" 804 then 805 Add_Directories 806 (Env.Project_Path, 807 Switch_Chars (Ptr + 2 .. Switch_Chars'Last)); 808 809 elsif C = 'v' and then Switch_Chars'Length = 3 then 810 Ptr := Ptr + 1; 811 Verbose_Mode := True; 812 813 case Switch_Chars (Ptr) is 814 when 'l' => 815 Verbosity_Level := Opt.Low; 816 817 when 'm' => 818 Verbosity_Level := Opt.Medium; 819 820 when 'h' => 821 Verbosity_Level := Opt.High; 822 823 when others => 824 Success := False; 825 end case; 826 827 elsif C = 'd' then 828 829 -- Note: for the debug switch, the remaining characters in this 830 -- switch field must all be debug flags, since all valid switch 831 -- characters are also valid debug characters. This switch is not 832 -- documented on purpose because it is only used by the 833 -- implementors. 834 835 -- Loop to scan out debug flags 836 837 while Ptr < Max loop 838 Ptr := Ptr + 1; 839 C := Switch_Chars (Ptr); 840 841 if C in 'a' .. 'z' or else C in 'A' .. 'Z' then 842 Set_Debug_Flag (C); 843 else 844 Bad_Switch (Switch_Chars); 845 end if; 846 end loop; 847 848 elsif C = 'e' then 849 Ptr := Ptr + 1; 850 851 case Switch_Chars (Ptr) is 852 853 -- Processing for eI switch 854 855 when 'I' => 856 Ptr := Ptr + 1; 857 Scan_Pos (Switch_Chars, Max, Ptr, Main_Index, C); 858 859 if Ptr <= Max then 860 Bad_Switch (Switch_Chars); 861 end if; 862 863 -- Processing for eL switch 864 865 when 'L' => 866 if Ptr /= Max then 867 Bad_Switch (Switch_Chars); 868 869 else 870 Follow_Links_For_Files := True; 871 Follow_Links_For_Dirs := True; 872 end if; 873 874 -- Processing for eS switch 875 876 when 'S' => 877 if Ptr /= Max then 878 Bad_Switch (Switch_Chars); 879 880 else 881 Commands_To_Stdout := True; 882 end if; 883 884 when others => 885 Bad_Switch (Switch_Chars); 886 end case; 887 888 elsif C = 'j' then 889 Ptr := Ptr + 1; 890 891 declare 892 Max_Proc : Nat; 893 894 begin 895 Scan_Nat (Switch_Chars, Max, Ptr, Max_Proc, C); 896 897 if Ptr <= Max then 898 Bad_Switch (Switch_Chars); 899 900 else 901 if Max_Proc = 0 then 902 Max_Proc := Nat (Number_Of_CPUs); 903 904 if Max_Proc = 0 then 905 Max_Proc := 1; 906 end if; 907 end if; 908 909 Maximum_Processes := Positive (Max_Proc); 910 end if; 911 end; 912 913 elsif C = 'w' and then Switch_Chars'Length = 3 then 914 Ptr := Ptr + 1; 915 916 if Switch_Chars = "-we" then 917 Warning_Mode := Treat_As_Error; 918 919 elsif Switch_Chars = "-wn" then 920 Warning_Mode := Normal; 921 922 elsif Switch_Chars = "-ws" then 923 Warning_Mode := Suppress; 924 925 else 926 Success := False; 927 end if; 928 929 else 930 Success := False; 931 end if; 932 933 -- Single-character switches 934 935 else 936 Check_Switch : begin 937 938 case C is 939 940 when 'a' => 941 Check_Readonly_Files := True; 942 943 -- Processing for b switch 944 945 when 'b' => 946 Bind_Only := True; 947 Make_Steps := True; 948 949 -- Processing for B switch 950 951 when 'B' => 952 Build_Bind_And_Link_Full_Project := True; 953 954 -- Processing for c switch 955 956 when 'c' => 957 Compile_Only := True; 958 Make_Steps := True; 959 960 -- Processing for C switch 961 962 when 'C' => 963 Opt.Create_Mapping_File := True; 964 965 -- Processing for D switch 966 967 when 'D' => 968 if Object_Directory_Present then 969 Osint.Fail ("duplicate -D switch"); 970 971 else 972 Object_Directory_Present := True; 973 end if; 974 975 -- Processing for f switch 976 977 when 'f' => 978 Force_Compilations := True; 979 980 -- Processing for F switch 981 982 when 'F' => 983 Full_Path_Name_For_Brief_Errors := True; 984 985 -- Processing for h switch 986 987 when 'h' => 988 Usage_Requested := True; 989 990 -- Processing for i switch 991 992 when 'i' => 993 In_Place_Mode := True; 994 995 -- Processing for j switch 996 997 when 'j' => 998 -- -j not followed by a number is an error 999 1000 Bad_Switch (Switch_Chars); 1001 1002 -- Processing for k switch 1003 1004 when 'k' => 1005 Keep_Going := True; 1006 1007 -- Processing for l switch 1008 1009 when 'l' => 1010 Link_Only := True; 1011 Make_Steps := True; 1012 1013 -- Processing for M switch 1014 1015 when 'M' => 1016 List_Dependencies := True; 1017 1018 -- Processing for n switch 1019 1020 when 'n' => 1021 Do_Not_Execute := True; 1022 1023 -- Processing for o switch 1024 1025 when 'o' => 1026 if Output_File_Name_Present then 1027 Osint.Fail ("duplicate -o switch"); 1028 else 1029 Output_File_Name_Present := True; 1030 end if; 1031 1032 -- Processing for p switch 1033 1034 when 'p' => 1035 Setup_Projects := True; 1036 1037 -- Processing for q switch 1038 1039 when 'q' => 1040 Quiet_Output := True; 1041 1042 -- Processing for R switch 1043 1044 when 'R' => 1045 Run_Path_Option := False; 1046 1047 -- Processing for s switch 1048 1049 when 's' => 1050 Ptr := Ptr + 1; 1051 Check_Switches := True; 1052 1053 -- Processing for v switch 1054 1055 when 'v' => 1056 Verbose_Mode := True; 1057 Verbosity_Level := Opt.High; 1058 1059 -- Processing for x switch 1060 1061 when 'x' => 1062 External_Unit_Compilation_Allowed := True; 1063 Use_Include_Path_File := True; 1064 1065 -- Processing for z switch 1066 1067 when 'z' => 1068 No_Main_Subprogram := True; 1069 1070 -- Any other small letter is an illegal switch 1071 1072 when others => 1073 if C in 'a' .. 'z' then 1074 Bad_Switch (Switch_Chars); 1075 1076 else 1077 Success := False; 1078 end if; 1079 1080 end case; 1081 end Check_Switch; 1082 end if; 1083 end Scan_Make_Switches; 1084 1085end Switch.M; 1086