(extendsfdf2): Add pattern accidentally deleted when cirrus instructions were
[official-gcc.git] / gcc / ada / gnatcmd.adb
blobf138fe22950fde0fedfe9e7f4bf6514b48a8b1f5
1 ------------------------------------------------------------------------------
2 -- --
3 -- GNAT COMPILER COMPONENTS --
4 -- --
5 -- G N A T C M D --
6 -- --
7 -- B o d y --
8 -- --
9 -- --
10 -- Copyright (C) 1996-2002 Free Software Foundation, Inc. --
11 -- --
12 -- GNAT is free software; you can redistribute it and/or modify it under --
13 -- terms of the GNU General Public License as published by the Free Soft- --
14 -- ware Foundation; either version 2, or (at your option) any later ver- --
15 -- sion. GNAT is distributed in the hope that it will be useful, but WITH- --
16 -- OUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY --
17 -- or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License --
18 -- for more details. You should have received a copy of the GNU General --
19 -- Public License distributed with GNAT; see file COPYING. If not, write --
20 -- to the Free Software Foundation, 59 Temple Place - Suite 330, Boston, --
21 -- MA 02111-1307, USA. --
22 -- --
23 -- GNAT was originally developed by the GNAT team at New York University. --
24 -- Extensive contributions were provided by Ada Core Technologies Inc. --
25 -- --
26 ------------------------------------------------------------------------------
28 with GNAT.Directory_Operations; use GNAT.Directory_Operations;
30 with Csets;
31 with MLib.Tgt;
32 with MLib.Utl;
33 with Namet; use Namet;
34 with Opt;
35 with Osint; use Osint;
36 with Output;
37 with Prj; use Prj;
38 with Prj.Env;
39 with Prj.Ext; use Prj.Ext;
40 with Prj.Pars;
41 with Prj.Util; use Prj.Util;
42 with Sdefault; use Sdefault;
43 with Snames; use Snames;
44 with Stringt; use Stringt;
45 with Table;
46 with Types; use Types;
47 with Hostparm; use Hostparm;
48 -- Used to determine if we are in VMS or not for error message purposes
50 with Ada.Characters.Handling; use Ada.Characters.Handling;
51 with Ada.Command_Line; use Ada.Command_Line;
52 with Ada.Text_IO; use Ada.Text_IO;
54 with Gnatvsn;
55 with GNAT.OS_Lib; use GNAT.OS_Lib;
57 with Table;
59 procedure GNATCmd is
61 Ada_Include_Path : constant String := "ADA_INCLUDE_PATH";
62 Ada_Objects_Path : constant String := "ADA_OBJECTS_PATH";
64 Project_File : String_Access;
65 Project : Prj.Project_Id;
66 Current_Verbosity : Prj.Verbosity := Prj.Default;
67 Tool_Package_Name : Name_Id := No_Name;
69 -- This flag indicates a switch -p (for gnatxref and gnatfind) for
70 -- an old fashioned project file. -p cannot be used in conjonction
71 -- with -P.
73 Old_Project_File_Used : Boolean := False;
75 -- A table to keep the switches on the command line
77 package Last_Switches is new Table.Table
78 (Table_Component_Type => String_Access,
79 Table_Index_Type => Integer,
80 Table_Low_Bound => 1,
81 Table_Initial => 20,
82 Table_Increment => 100,
83 Table_Name => "Gnatcmd.Last_Switches");
85 -- A table to keep the switches from the project file
87 package First_Switches is new Table.Table
88 (Table_Component_Type => String_Access,
89 Table_Index_Type => Integer,
90 Table_Low_Bound => 1,
91 Table_Initial => 20,
92 Table_Increment => 100,
93 Table_Name => "Gnatcmd.First_Switches");
95 ------------------
96 -- SWITCH TABLE --
97 ------------------
99 -- The switch tables contain an entry for each switch recognized by the
100 -- command processor. The syntax of entries is as follows:
102 -- SWITCH_STRING ::= "/ command-qualifier-name TRANSLATION"
104 -- TRANSLATION ::=
105 -- DIRECT_TRANSLATION
106 -- | DIRECTORIES_TRANSLATION
107 -- | FILE_TRANSLATION
108 -- | NO_SPACE_FILE_TRANSL
109 -- | NUMERIC_TRANSLATION
110 -- | STRING_TRANSLATION
111 -- | OPTIONS_TRANSLATION
112 -- | COMMANDS_TRANSLATION
113 -- | ALPHANUMPLUS_TRANSLATION
114 -- | OTHER_TRANSLATION
116 -- DIRECT_TRANSLATION ::= space UNIX_SWITCHES
117 -- DIRECTORIES_TRANSLATION ::= =* UNIX_SWITCH *
118 -- DIRECTORY_TRANSLATION ::= =% UNIX_SWITCH %
119 -- FILE_TRANSLATION ::= =@ UNIX_SWITCH @
120 -- NO_SPACE_FILE_TRANSL ::= =< UNIX_SWITCH >
121 -- NUMERIC_TRANSLATION ::= =# UNIX_SWITCH # | # number #
122 -- STRING_TRANSLATION ::= =" UNIX_SWITCH "
123 -- OPTIONS_TRANSLATION ::= =OPTION {space OPTION}
124 -- COMMANDS_TRANSLATION ::= =? ARGS space command-name
125 -- ALPHANUMPLUS_TRANSLATION ::= =| UNIX_SWITCH |
127 -- UNIX_SWITCHES ::= UNIX_SWITCH {, UNIX_SWITCH}
129 -- UNIX_SWITCH ::= unix-switch-string | !unix-switch-string | `string'
131 -- OPTION ::= option-name space UNIX_SWITCHES
133 -- ARGS ::= -cargs | -bargs | -largs
135 -- Here command-qual is the name of the switch recognized by the GNATCmd.
136 -- This is always given in upper case in the templates, although in the
137 -- actual commands, either upper or lower case is allowed.
139 -- The unix-switch-string always starts with a minus, and has no commas
140 -- or spaces in it. Case is significant in the unix switch string. If a
141 -- unix switch string is preceded by the not sign (!) it means that the
142 -- effect of the corresponding command qualifer is to remove any previous
143 -- occurrence of the given switch in the command line.
145 -- The DIRECTORIES_TRANSLATION format is used where a list of directories
146 -- is given. This possible corresponding formats recognized by GNATCmd are
147 -- as shown by the following example for the case of PATH
149 -- PATH=direc
150 -- PATH=(direc,direc,direc,direc)
152 -- When more than one directory is present for the DIRECTORIES case, then
153 -- multiple instances of the corresponding unix switch are generated,
154 -- with the file name being substituted for the occurrence of *.
156 -- The FILE_TRANSLATION format is similar except that only a single
157 -- file is allowed, not a list of files, and only one unix switch is
158 -- generated as a result.
160 -- the NO_SPACE_FILE_TRANSL is similar to FILE_TRANSLATION, except that
161 -- no space is inserted between the switch and the file name.
163 -- The NUMERIC_TRANSLATION format is similar to the FILE_TRANSLATION case
164 -- except that the parameter is a decimal integer in the range 0 to 999.
166 -- For the OPTIONS_TRANSLATION case, GNATCmd similarly permits one or
167 -- more options to appear (although only in some cases does the use of
168 -- multiple options make logical sense). For example, taking the
169 -- case of ERRORS for GCC, the following are all allowed:
171 -- /ERRORS=BRIEF
172 -- /ERRORS=(FULL,VERBOSE)
173 -- /ERRORS=(BRIEF IMMEDIATE)
175 -- If no option is provided (e.g. just /ERRORS is written), then the
176 -- first option in the list is the default option. For /ERRORS this
177 -- is NORMAL, so /ERRORS with no option is equivalent to /ERRORS=NORMAL.
179 -- The COMMANDS_TRANSLATION case is only used for gnatmake, to correspond
180 -- to the use of -cargs, -bargs and -largs (the ARGS string as indicated
181 -- is one of these three possibilities). The name given by COMMAND is the
182 -- corresponding command name to be used to interprete the switches to be
183 -- passed on. Switches of this type set modes, e.g. /COMPILER_QUALIFIERS
184 -- sets the mode so that all subsequent switches, up to another switch
185 -- with COMMANDS_TRANSLATION apply to the corresponding commands issued
186 -- by the make utility. For example
188 -- /COMPILER_QUALIFIERS /LIST /BINDER_QUALIFIERS /MAIN
189 -- /COMPILER_QUALIFIERS /NOLIST /COMPILE_CHECKS=SYNTAX
191 -- Clearly these switches must come at the end of the list of switches
192 -- since all subsequent switches apply to an issued command.
194 -- For the DIRECT_TRANSLATION case, an implicit additional entry is
195 -- created by prepending NO to the name of the qualifer, and then
196 -- inverting the sense of the UNIX_SWITCHES string. For example,
197 -- given the entry:
199 -- "/LIST -gnatl"
201 -- An implicit entry is created:
203 -- "/NOLIST !-gnatl"
205 -- In the case where, a ! is already present, inverting the sense of the
206 -- switch means removing it.
208 subtype S is String;
209 -- A synonym to shorten the table
211 type String_Ptr is access constant String;
212 -- String pointer type used throughout
214 type Switches is array (Natural range <>) of String_Ptr;
215 -- Type used for array of swtiches
217 type Switches_Ptr is access constant Switches;
219 --------------------------------
220 -- Switches for project files --
221 --------------------------------
223 S_Ext_Ref : aliased constant S := "/EXTERNAL_REFERENCE=" & '"' &
224 "-X" & '"';
226 S_Project_File : aliased constant S := "/PROJECT_FILE=<" &
227 "-P>";
228 S_Project_Verb : aliased constant S := "/PROJECT_FILE_VERBOSITY=" &
229 "DEFAULT " &
230 "-vP0 " &
231 "MEDIUM " &
232 "-vP1 " &
233 "HIGH " &
234 "-vP2";
236 ----------------------------
237 -- Switches for GNAT BIND --
238 ----------------------------
240 S_Bind_Bind : aliased constant S := "/BIND_FILE=" &
241 "ADA " &
242 "-A " &
243 "C " &
244 "-C";
246 S_Bind_Build : aliased constant S := "/BUILD_LIBRARY=|" &
247 "-L|";
249 S_Bind_Current : aliased constant S := "/CURRENT_DIRECTORY " &
250 "!-I-";
252 S_Bind_Debug : aliased constant S := "/DEBUG=" &
253 "TRACEBACK " &
254 "-g2 " &
255 "ALL " &
256 "-g3 " &
257 "NONE " &
258 "-g0 " &
259 "SYMBOLS " &
260 "-g1 " &
261 "NOSYMBOLS " &
262 "!-g1 " &
263 "LINK " &
264 "-g3 " &
265 "NOTRACEBACK " &
266 "!-g2";
268 S_Bind_DebugX : aliased constant S := "/NODEBUG " &
269 "!-g";
271 S_Bind_Elab : aliased constant S := "/ELABORATION_DEPENDENCIES " &
272 "-e";
274 S_Bind_Error : aliased constant S := "/ERROR_LIMIT=#" &
275 "-m#";
277 S_Bind_Help : aliased constant S := "/HELP " &
278 "-h";
280 S_Bind_Init : aliased constant S := "/INITIALIZE_SCALARS=" &
281 "INVALID " &
282 "-Sin " &
283 "LOW " &
284 "-Slo " &
285 "HIGH " &
286 "-Shi";
288 S_Bind_Library : aliased constant S := "/LIBRARY_SEARCH=*" &
289 "-aO*";
291 S_Bind_Linker : aliased constant S := "/LINKER_OPTION_LIST " &
292 "-K";
294 S_Bind_List : aliased constant S := "/LIST_RESTRICTIONS " &
295 "-r";
297 S_Bind_Main : aliased constant S := "/MAIN " &
298 "!-n";
300 S_Bind_Nostinc : aliased constant S := "/NOSTD_INCLUDES " &
301 "-nostdinc";
303 S_Bind_Nostlib : aliased constant S := "/NOSTD_LIBRARIES " &
304 "-nostdlib";
306 S_Bind_No_Time : aliased constant S := "/NO_TIME_STAMP_CHECK " &
307 "-t";
309 S_Bind_Object : aliased constant S := "/OBJECT_LIST " &
310 "-O";
312 S_Bind_Order : aliased constant S := "/ORDER_OF_ELABORATION " &
313 "-l";
315 S_Bind_Output : aliased constant S := "/OUTPUT=@" &
316 "-o@";
318 S_Bind_OutputX : aliased constant S := "/NOOUTPUT " &
319 "-c";
321 S_Bind_Pess : aliased constant S := "/PESSIMISTIC_ELABORATION " &
322 "-p";
324 S_Bind_Read : aliased constant S := "/READ_SOURCES=" &
325 "ALL " &
326 "-s " &
327 "NONE " &
328 "-x " &
329 "AVAILABLE " &
330 "!-x,!-s";
332 S_Bind_ReadX : aliased constant S := "/NOREAD_SOURCES " &
333 "-x";
335 S_Bind_Rename : aliased constant S := "/RENAME_MAIN=<" &
336 "-M>";
338 S_Bind_Report : aliased constant S := "/REPORT_ERRORS=" &
339 "VERBOSE " &
340 "-v " &
341 "BRIEF " &
342 "-b " &
343 "DEFAULT " &
344 "!-b,!-v";
346 S_Bind_ReportX : aliased constant S := "/NOREPORT_ERRORS " &
347 "!-b,!-v";
349 S_Bind_Restr : aliased constant S := "/RESTRICTION_LIST " &
350 "-r";
352 S_Bind_RTS : aliased constant S := "/RUNTIME_SYSTEM=|" &
353 "--RTS=|";
355 S_Bind_Search : aliased constant S := "/SEARCH=*" &
356 "-I*";
358 S_Bind_Shared : aliased constant S := "/SHARED " &
359 "-shared";
361 S_Bind_Slice : aliased constant S := "/TIME_SLICE=#" &
362 "-T#";
364 S_Bind_Source : aliased constant S := "/SOURCE_SEARCH=*" &
365 "-aI*";
367 S_Bind_Time : aliased constant S := "/TIME_STAMP_CHECK " &
368 "!-t";
370 S_Bind_Verbose : aliased constant S := "/VERBOSE " &
371 "-v";
373 S_Bind_Warn : aliased constant S := "/WARNINGS=" &
374 "NORMAL " &
375 "!-ws,!-we " &
376 "SUPPRESS " &
377 "-ws " &
378 "ERROR " &
379 "-we";
381 S_Bind_WarnX : aliased constant S := "/NOWARNINGS " &
382 "-ws";
384 Bind_Switches : aliased constant Switches :=
385 (S_Bind_Bind 'Access,
386 S_Bind_Build 'Access,
387 S_Bind_Current 'Access,
388 S_Bind_Debug 'Access,
389 S_Bind_DebugX 'Access,
390 S_Bind_Elab 'Access,
391 S_Bind_Error 'Access,
392 S_Ext_Ref 'Access,
393 S_Bind_Help 'Access,
394 S_Bind_Init 'Access,
395 S_Bind_Library 'Access,
396 S_Bind_Linker 'Access,
397 S_Bind_List 'Access,
398 S_Bind_Main 'Access,
399 S_Bind_Nostinc 'Access,
400 S_Bind_Nostlib 'Access,
401 S_Bind_No_Time 'Access,
402 S_Bind_Object 'Access,
403 S_Bind_Order 'Access,
404 S_Bind_Output 'Access,
405 S_Bind_OutputX 'Access,
406 S_Bind_Pess 'Access,
407 S_Project_File 'Access,
408 S_Project_Verb 'Access,
409 S_Bind_Read 'Access,
410 S_Bind_ReadX 'Access,
411 S_Bind_Rename 'Access,
412 S_Bind_Report 'Access,
413 S_Bind_ReportX 'Access,
414 S_Bind_Restr 'Access,
415 S_Bind_RTS 'Access,
416 S_Bind_Search 'Access,
417 S_Bind_Shared 'Access,
418 S_Bind_Slice 'Access,
419 S_Bind_Source 'Access,
420 S_Bind_Time 'Access,
421 S_Bind_Verbose 'Access,
422 S_Bind_Warn 'Access,
423 S_Bind_WarnX 'Access);
425 ----------------------------
426 -- Switches for GNAT CHOP --
427 ----------------------------
429 S_Chop_Comp : aliased constant S := "/COMPILATION " &
430 "-c";
432 S_Chop_File : aliased constant S := "/FILE_NAME_MAX_LENGTH=#" &
433 "-k#";
435 S_Chop_Help : aliased constant S := "/HELP " &
436 "-h";
438 S_Chop_Over : aliased constant S := "/OVERWRITE " &
439 "-w";
441 S_Chop_Pres : aliased constant S := "/PRESERVE " &
442 "-p";
444 S_Chop_Quiet : aliased constant S := "/QUIET " &
445 "-q";
447 S_Chop_Ref : aliased constant S := "/REFERENCE " &
448 "-r";
450 S_Chop_Verb : aliased constant S := "/VERBOSE " &
451 "-v";
453 Chop_Switches : aliased constant Switches :=
454 (S_Chop_Comp 'Access,
455 S_Chop_File 'Access,
456 S_Chop_Help 'Access,
457 S_Chop_Over 'Access,
458 S_Chop_Pres 'Access,
459 S_Chop_Quiet 'Access,
460 S_Chop_Ref 'Access,
461 S_Chop_Verb 'Access);
463 -------------------------------
464 -- Switches for GNAT COMPILE --
465 -------------------------------
467 S_GCC_Ada_83 : aliased constant S := "/83 " &
468 "-gnat83";
470 S_GCC_Ada_95 : aliased constant S := "/95 " &
471 "!-gnat83";
473 S_GCC_Asm : aliased constant S := "/ASM " &
474 "-S,!-c";
476 S_GCC_Checks : aliased constant S := "/CHECKS=" &
477 "FULL " &
478 "-gnato,!-gnatE,!-gnatp " &
479 "OVERFLOW " &
480 "-gnato " &
481 "ELABORATION " &
482 "-gnatE " &
483 "ASSERTIONS " &
484 "-gnata " &
485 "DEFAULT " &
486 "!-gnato,!-gnatp " &
487 "SUPPRESS_ALL " &
488 "-gnatp";
490 S_GCC_ChecksX : aliased constant S := "/NOCHECKS " &
491 "-gnatp,!-gnato,!-gnatE";
493 S_GCC_Compres : aliased constant S := "/COMPRESS_NAMES " &
494 "-gnatC";
496 S_GCC_Config : aliased constant S := "/CONFIGURATION_PRAGMAS_FILE=<" &
497 "-gnatec>";
499 S_GCC_Current : aliased constant S := "/CURRENT_DIRECTORY " &
500 "!-I-";
502 S_GCC_Debug : aliased constant S := "/DEBUG=" &
503 "SYMBOLS " &
504 "-g2 " &
505 "NOSYMBOLS " &
506 "!-g2 " &
507 "TRACEBACK " &
508 "-g1 " &
509 "ALL " &
510 "-g3 " &
511 "NONE " &
512 "-g0 " &
513 "NOTRACEBACK " &
514 "-g0";
516 S_GCC_DebugX : aliased constant S := "/NODEBUG " &
517 "!-g";
519 S_GCC_Dist : aliased constant S := "/DISTRIBUTION_STUBS=" &
520 "RECEIVER " &
521 "-gnatzr " &
522 "CALLER " &
523 "-gnatzc";
525 S_GCC_DistX : aliased constant S := "/NODISTRIBUTION_STUBS " &
526 "!-gnatzr,!-gnatzc";
528 S_GCC_Error : aliased constant S := "/ERROR_LIMIT=#" &
529 "-gnatm#";
531 S_GCC_ErrorX : aliased constant S := "/NOERROR_LIMIT " &
532 "-gnatm999";
534 S_GCC_Expand : aliased constant S := "/EXPAND_SOURCE " &
535 "-gnatG";
537 S_GCC_Extend : aliased constant S := "/EXTENSIONS_ALLOWED " &
538 "-gnatX";
540 S_GCC_File : aliased constant S := "/FILE_NAME_MAX_LENGTH=#" &
541 "-gnatk#";
543 S_GCC_Force : aliased constant S := "/FORCE_ALI " &
544 "-gnatQ";
546 S_GCC_Help : aliased constant S := "/HELP " &
547 "-gnath";
549 S_GCC_Ident : aliased constant S := "/IDENTIFIER_CHARACTER_SET=" &
550 "DEFAULT " &
551 "-gnati1 " &
552 "1 " &
553 "-gnati1 " &
554 "2 " &
555 "-gnati2 " &
556 "3 " &
557 "-gnati3 " &
558 "4 " &
559 "-gnati4 " &
560 "5 " &
561 "-gnati5 " &
562 "PC " &
563 "-gnatip " &
564 "PC850 " &
565 "-gnati8 " &
566 "FULL_UPPER " &
567 "-gnatif " &
568 "NO_UPPER " &
569 "-gnatin " &
570 "WIDE " &
571 "-gnatiw";
573 S_GCC_IdentX : aliased constant S := "/NOIDENTIFIER_CHARACTER_SET " &
574 "-gnati1";
576 S_GCC_Immed : aliased constant S := "/IMMEDIATE_ERRORS " &
577 "-gnatdO";
579 S_GCC_Inline : aliased constant S := "/INLINE=" &
580 "PRAGMA " &
581 "-gnatn " &
582 "FULL " &
583 "-gnatN " &
584 "SUPPRESS " &
585 "-fno-inline";
587 S_GCC_InlineX : aliased constant S := "/NOINLINE " &
588 "!-gnatn";
590 S_GCC_Jumps : aliased constant S := "/LONGJMP_SETJMP " &
591 "-gnatL";
593 S_GCC_Length : aliased constant S := "/MAX_LINE_LENGTH=#" &
594 "-gnatyM#";
596 S_GCC_List : aliased constant S := "/LIST " &
597 "-gnatl";
599 S_GCC_Noadc : aliased constant S := "/NO_GNAT_ADC " &
600 "-gnatA";
602 S_GCC_Noload : aliased constant S := "/NOLOAD " &
603 "-gnatc";
605 S_GCC_Nostinc : aliased constant S := "/NOSTD_INCLUDES " &
606 "-nostdinc";
608 S_GCC_Opt : aliased constant S := "/OPTIMIZE=" &
609 "ALL " &
610 "-O2,!-O0,!-O1,!-O3 " &
611 "NONE " &
612 "-O0,!-O1,!-O2,!-O3 " &
613 "SOME " &
614 "-O1,!-O0,!-O2,!-O3 " &
615 "DEVELOPMENT " &
616 "-O1,!-O0,!-O2,!-O3 " &
617 "UNROLL_LOOPS " &
618 "-funroll-loops " &
619 "INLINING " &
620 "-O3,!-O0,!-O1,!-O2";
622 S_GCC_OptX : aliased constant S := "/NOOPTIMIZE " &
623 "-O0,!-O1,!-O2,!-O3";
625 S_GCC_Polling : aliased constant S := "/POLLING " &
626 "-gnatP";
628 S_GCC_Report : aliased constant S := "/REPORT_ERRORS=" &
629 "VERBOSE " &
630 "-gnatv " &
631 "BRIEF " &
632 "-gnatb " &
633 "FULL " &
634 "-gnatf " &
635 "IMMEDIATE " &
636 "-gnate " &
637 "DEFAULT " &
638 "!-gnatb,!-gnatv";
640 S_GCC_ReportX : aliased constant S := "/NOREPORT_ERRORS " &
641 "!-gnatb,!-gnatv";
643 S_GCC_Repinfo : aliased constant S := "/REPRESENTATION_INFO=" &
644 "ARRAYS " &
645 "-gnatR1 " &
646 "NONE " &
647 "-gnatR0 " &
648 "OBJECTS " &
649 "-gnatR2 " &
650 "SYMBOLIC " &
651 "-gnatR3 " &
652 "DEFAULT " &
653 "-gnatR";
655 S_GCC_RepinfX : aliased constant S := "/NOREPRESENTATION_INFO " &
656 "!-gnatR";
658 S_GCC_Search : aliased constant S := "/SEARCH=*" &
659 "-I*";
661 S_GCC_Style : aliased constant S := "/STYLE_CHECKS=" &
662 "ALL_BUILTIN " &
663 "-gnaty " &
664 "1 " &
665 "-gnaty1 " &
666 "2 " &
667 "-gnaty2 " &
668 "3 " &
669 "-gnaty3 " &
670 "4 " &
671 "-gnaty4 " &
672 "5 " &
673 "-gnaty5 " &
674 "6 " &
675 "-gnaty6 " &
676 "7 " &
677 "-gnaty7 " &
678 "8 " &
679 "-gnaty8 " &
680 "9 " &
681 "-gnaty9 " &
682 "ATTRIBUTE " &
683 "-gnatya " &
684 "BLANKS " &
685 "-gnatyb " &
686 "COMMENTS " &
687 "-gnatyc " &
688 "END " &
689 "-gnatye " &
690 "VTABS " &
691 "-gnatyf " &
692 "GNAT " &
693 "-gnatg " &
694 "HTABS " &
695 "-gnatyh " &
696 "IF_THEN " &
697 "-gnatyi " &
698 "KEYWORD " &
699 "-gnatyk " &
700 "LAYOUT " &
701 "-gnatyl " &
702 "LINE_LENGTH " &
703 "-gnatym " &
704 "STANDARD_CASING " &
705 "-gnatyn " &
706 "ORDERED_SUBPROGRAMS " &
707 "-gnatyo " &
708 "NONE " &
709 "!-gnatg,!-gnatr " &
710 "PRAGMA " &
711 "-gnatyp " &
712 "RM_COLUMN_LAYOUT " &
713 "-gnatr " &
714 "SPECS " &
715 "-gnatys " &
716 "TOKEN " &
717 "-gnatyt ";
719 S_GCC_StyleX : aliased constant S := "/NOSTYLE_CHECKS " &
720 "!-gnatg,!-gnatr";
722 S_GCC_Syntax : aliased constant S := "/SYNTAX_ONLY " &
723 "-gnats";
725 S_GCC_Trace : aliased constant S := "/TRACE_UNITS " &
726 "-gnatdc";
728 S_GCC_Tree : aliased constant S := "/TREE_OUTPUT " &
729 "-gnatt";
731 S_GCC_Trys : aliased constant S := "/TRY_SEMANTICS " &
732 "-gnatq";
734 S_GCC_Units : aliased constant S := "/UNITS_LIST " &
735 "-gnatu";
737 S_GCC_Unique : aliased constant S := "/UNIQUE_ERROR_TAG " &
738 "-gnatU";
740 S_GCC_Upcase : aliased constant S := "/UPPERCASE_EXTERNALS " &
741 "-gnatF";
743 S_GCC_Valid : aliased constant S := "/VALIDITY_CHECKING=" &
744 "DEFAULT " &
745 "-gnatVd " &
746 "NODEFAULT " &
747 "-gnatVD " &
748 "COPIES " &
749 "-gnatVc " &
750 "NOCOPIES " &
751 "-gnatVC " &
752 "FLOATS " &
753 "-gnatVf " &
754 "NOFLOATS " &
755 "-gnatVF " &
756 "IN_PARAMS " &
757 "-gnatVi " &
758 "NOIN_PARAMS " &
759 "-gnatVI " &
760 "MOD_PARAMS " &
761 "-gnatVm " &
762 "NOMOD_PARAMS " &
763 "-gnatVM " &
764 "OPERANDS " &
765 "-gnatVo " &
766 "NOOPERANDS " &
767 "-gnatVO " &
768 "RETURNS " &
769 "-gnatVr " &
770 "NORETURNS " &
771 "-gnatVR " &
772 "SUBSCRIPTS " &
773 "-gnatVs " &
774 "NOSUBSCRIPTS " &
775 "-gnatVS " &
776 "TESTS " &
777 "-gnatVt " &
778 "NOTESTS " &
779 "-gnatVT " &
780 "ALL " &
781 "-gnatVa " &
782 "NONE " &
783 "-gnatVn";
785 S_GCC_Verbose : aliased constant S := "/VERBOSE " &
786 "-v";
788 S_GCC_Warn : aliased constant S := "/WARNINGS=" &
789 "DEFAULT " &
790 "!-gnatws,!-gnatwe " &
791 "ALL_GCC " &
792 "-Wall " &
793 "BIASED_ROUNDING " &
794 "-gnatwb " &
795 "NOBIASED_ROUNDING " &
796 "-gnatwB " &
797 "CONDITIONALS " &
798 "-gnatwc " &
799 "NOCONDITIONALS " &
800 "-gnatwC " &
801 "IMPLICIT_DEREFERENCE " &
802 "-gnatwd " &
803 "NO_IMPLICIT_DEREFERENCE " &
804 "-gnatwD " &
805 "ELABORATION " &
806 "-gnatwl " &
807 "NOELABORATION " &
808 "-gnatwL " &
809 "ERRORS " &
810 "-gnatwe " &
811 "HIDING " &
812 "-gnatwh " &
813 "NOHIDING " &
814 "-gnatwH " &
815 "IMPLEMENTATION " &
816 "-gnatwi " &
817 "NOIMPLEMENTATION " &
818 "-gnatwI " &
819 "INEFFECTIVE_INLINE " &
820 "-gnatwp " &
821 "NOINEFFECTIVE_INLINE " &
822 "-gnatwP " &
823 "OPTIONAL " &
824 "-gnatwa " &
825 "NOOPTIONAL " &
826 "-gnatwA " &
827 "OVERLAYS " &
828 "-gnatwo " &
829 "NOOVERLAYS " &
830 "-gnatwO " &
831 "REDUNDANT " &
832 "-gnatwr " &
833 "NOREDUNDANT " &
834 "-gnatwR " &
835 "SUPPRESS " &
836 "-gnatws " &
837 "UNINITIALIZED " &
838 "-Wuninitialized " &
839 "UNREFERENCED_FORMALS " &
840 "-gnatwf " &
841 "NOUNREFERENCED_FORMALS " &
842 "-gnatwF " &
843 "UNUSED " &
844 "-gnatwu " &
845 "NOUNUSED " &
846 "-gnatwU";
848 S_GCC_WarnX : aliased constant S := "/NOWARNINGS " &
849 "-gnatws";
851 S_GCC_Wide : aliased constant S := "/WIDE_CHARACTER_ENCODING=" &
852 "BRACKETS " &
853 "-gnatWb " &
854 "NONE " &
855 "-gnatWn " &
856 "HEX " &
857 "-gnatWh " &
858 "UPPER " &
859 "-gnatWu " &
860 "SHIFT_JIS " &
861 "-gnatWs " &
862 "UTF8 " &
863 "-gnatW8 " &
864 "EUC " &
865 "-gnatWe";
867 S_GCC_WideX : aliased constant S := "/NOWIDE_CHARACTER_ENCODING " &
868 "-gnatWn";
870 S_GCC_Xdebug : aliased constant S := "/XDEBUG " &
871 "-gnatD";
873 S_GCC_Xref : aliased constant S := "/XREF=" &
874 "GENERATE " &
875 "!-gnatx " &
876 "SUPPRESS " &
877 "-gnatx";
879 GCC_Switches : aliased constant Switches :=
880 (S_GCC_Ada_83 'Access,
881 S_GCC_Ada_95 'Access,
882 S_GCC_Asm 'Access,
883 S_GCC_Checks 'Access,
884 S_GCC_ChecksX 'Access,
885 S_GCC_Compres 'Access,
886 S_GCC_Config 'Access,
887 S_GCC_Current 'Access,
888 S_GCC_Debug 'Access,
889 S_GCC_DebugX 'Access,
890 S_GCC_Dist 'Access,
891 S_GCC_DistX 'Access,
892 S_GCC_Error 'Access,
893 S_GCC_ErrorX 'Access,
894 S_GCC_Expand 'Access,
895 S_GCC_Extend 'Access,
896 S_Ext_Ref 'Access,
897 S_GCC_File 'Access,
898 S_GCC_Force 'Access,
899 S_GCC_Help 'Access,
900 S_GCC_Ident 'Access,
901 S_GCC_IdentX 'Access,
902 S_GCC_Immed 'Access,
903 S_GCC_Inline 'Access,
904 S_GCC_InlineX 'Access,
905 S_GCC_Jumps 'Access,
906 S_GCC_Length 'Access,
907 S_GCC_List 'Access,
908 S_GCC_Noadc 'Access,
909 S_GCC_Noload 'Access,
910 S_GCC_Nostinc 'Access,
911 S_GCC_Opt 'Access,
912 S_GCC_OptX 'Access,
913 S_GCC_Polling 'Access,
914 S_Project_File'Access,
915 S_Project_Verb'Access,
916 S_GCC_Report 'Access,
917 S_GCC_ReportX 'Access,
918 S_GCC_Repinfo 'Access,
919 S_GCC_RepinfX 'Access,
920 S_GCC_Search 'Access,
921 S_GCC_Style 'Access,
922 S_GCC_StyleX 'Access,
923 S_GCC_Syntax 'Access,
924 S_GCC_Trace 'Access,
925 S_GCC_Tree 'Access,
926 S_GCC_Trys 'Access,
927 S_GCC_Units 'Access,
928 S_GCC_Unique 'Access,
929 S_GCC_Upcase 'Access,
930 S_GCC_Valid 'Access,
931 S_GCC_Verbose 'Access,
932 S_GCC_Warn 'Access,
933 S_GCC_WarnX 'Access,
934 S_GCC_Wide 'Access,
935 S_GCC_WideX 'Access,
936 S_GCC_Xdebug 'Access,
937 S_GCC_Xref 'Access);
939 ----------------------------
940 -- Switches for GNAT ELIM --
941 ----------------------------
943 S_Elim_All : aliased constant S := "/ALL " &
944 "-a";
946 S_Elim_Bind : aliased constant S := "/BIND_FILE=<" &
947 "-b>";
949 S_Elim_Miss : aliased constant S := "/MISSED " &
950 "-m";
952 S_Elim_Quiet : aliased constant S := "/QUIET " &
953 "-q";
955 S_Elim_Tree : aliased constant S := "/TREE_DIRS=*" &
956 "-T*";
958 S_Elim_Verb : aliased constant S := "/VERBOSE " &
959 "-v";
961 Elim_Switches : aliased constant Switches :=
962 (S_Elim_All 'Access,
963 S_Elim_Bind 'Access,
964 S_Elim_Miss 'Access,
965 S_Elim_Quiet 'Access,
966 S_Elim_Tree 'Access,
967 S_Elim_Verb 'Access);
969 ----------------------------
970 -- Switches for GNAT FIND --
971 ----------------------------
973 S_Find_All : aliased constant S := "/ALL_FILES " &
974 "-a";
976 S_Find_Deriv : aliased constant S := "/DERIVED_TYPE_INFORMATION " &
977 "-d";
979 S_Find_Expr : aliased constant S := "/EXPRESSIONS " &
980 "-e";
982 S_Find_Full : aliased constant S := "/FULL_PATHNAME " &
983 "-f";
985 S_Find_Ignore : aliased constant S := "/IGNORE_LOCALS " &
986 "-g";
988 S_Find_Nostinc : aliased constant S := "/NOSTD_INCLUDES " &
989 "-nostdinc";
991 S_Find_Nostlib : aliased constant S := "/NOSTD_LIBRARIES " &
992 "-nostdlib";
994 S_Find_Object : aliased constant S := "/OBJECT_SEARCH=*" &
995 "-aO*";
997 S_Find_Print : aliased constant S := "/PRINT_LINES " &
998 "-s";
1000 S_Find_Project : aliased constant S := "/PROJECT=@" &
1001 "-p@";
1003 S_Find_Ref : aliased constant S := "/REFERENCES " &
1004 "-r";
1006 S_Find_Search : aliased constant S := "/SEARCH=*" &
1007 "-I*";
1009 S_Find_Source : aliased constant S := "/SOURCE_SEARCH=*" &
1010 "-aI*";
1012 S_Find_Types : aliased constant S := "/TYPE_HIERARCHY " &
1013 "-t";
1015 Find_Switches : aliased constant Switches :=
1016 (S_Find_All 'Access,
1017 S_Find_Deriv 'Access,
1018 S_Find_Expr 'Access,
1019 S_Ext_Ref 'Access,
1020 S_Find_Full 'Access,
1021 S_Find_Ignore 'Access,
1022 S_Find_Nostinc 'Access,
1023 S_Find_Nostlib 'Access,
1024 S_Find_Object 'Access,
1025 S_Find_Print 'Access,
1026 S_Find_Project 'Access,
1027 S_Project_File 'Access,
1028 S_Project_Verb 'Access,
1029 S_Find_Ref 'Access,
1030 S_Find_Search 'Access,
1031 S_Find_Source 'Access,
1032 S_Find_Types 'Access);
1034 ------------------------------
1035 -- Switches for GNAT KRUNCH --
1036 ------------------------------
1038 S_Krunch_Count : aliased constant S := "/COUNT=#" &
1039 "`#";
1041 Krunch_Switches : aliased constant Switches :=
1042 (1 .. 1 => S_Krunch_Count 'Access);
1044 -------------------------------
1045 -- Switches for GNAT LIBRARY --
1046 -------------------------------
1048 S_Lbr_Config : aliased constant S := "/CONFIG=@" &
1049 "--config=@";
1051 S_Lbr_Create : aliased constant S := "/CREATE=%" &
1052 "--create=%";
1054 S_Lbr_Delete : aliased constant S := "/DELETE=%" &
1055 "--delete=%";
1057 S_Lbr_Set : aliased constant S := "/SET=%" &
1058 "--set=%";
1060 Lbr_Switches : aliased constant Switches :=
1061 (S_Lbr_Config 'Access,
1062 S_Lbr_Create 'Access,
1063 S_Lbr_Delete 'Access,
1064 S_Lbr_Set 'Access);
1066 ----------------------------
1067 -- Switches for GNAT LINK --
1068 ----------------------------
1070 S_Link_Bind : aliased constant S := "/BIND_FILE=" &
1071 "ADA " &
1072 "-A " &
1073 "C " &
1074 "-C";
1076 S_Link_Debug : aliased constant S := "/DEBUG=" &
1077 "ALL " &
1078 "-g3 " &
1079 "NONE " &
1080 "-g0 " &
1081 "TRACEBACK " &
1082 "-g1 " &
1083 "NOTRACEBACK " &
1084 "-g0";
1086 S_Link_Execut : aliased constant S := "/EXECUTABLE=@" &
1087 "-o@";
1089 S_Link_Force : aliased constant S := "/FORCE_OBJECT_FILE_LIST " &
1090 "-f";
1092 S_Link_Ident : aliased constant S := "/IDENTIFICATION=" & '"' &
1093 "--for-linker=IDENT=" &
1094 '"';
1096 S_Link_Nocomp : aliased constant S := "/NOCOMPILE " &
1097 "-n";
1099 S_Link_Nofiles : aliased constant S := "/NOSTART_FILES " &
1100 "-nostartfiles";
1102 S_Link_Noinhib : aliased constant S := "/NOINHIBIT-EXEC " &
1103 "--for-linker=--noinhibit-exec";
1105 S_Link_Static : aliased constant S := "/STATIC " &
1106 "--for-linker=-static";
1108 S_Link_Verb : aliased constant S := "/VERBOSE " &
1109 "-v";
1111 S_Link_ZZZZZ : aliased constant S := "/<other> " &
1112 "--for-linker=";
1114 Link_Switches : aliased constant Switches :=
1115 (S_Link_Bind 'Access,
1116 S_Link_Debug 'Access,
1117 S_Link_Execut 'Access,
1118 S_Ext_Ref 'Access,
1119 S_Link_Force 'Access,
1120 S_Link_Ident 'Access,
1121 S_Link_Nocomp 'Access,
1122 S_Link_Nofiles 'Access,
1123 S_Link_Noinhib 'Access,
1124 S_Project_File 'Access,
1125 S_Project_Verb 'Access,
1126 S_Link_Static 'Access,
1127 S_Link_Verb 'Access,
1128 S_Link_ZZZZZ 'Access);
1130 ----------------------------
1131 -- Switches for GNAT LIST --
1132 ----------------------------
1134 S_List_All : aliased constant S := "/ALL_UNITS " &
1135 "-a";
1137 S_List_Current : aliased constant S := "/CURRENT_DIRECTORY " &
1138 "!-I-";
1140 S_List_Nostinc : aliased constant S := "/NOSTD_INCLUDES " &
1141 "-nostdinc";
1143 S_List_Object : aliased constant S := "/OBJECT_SEARCH=*" &
1144 "-aO*";
1146 S_List_Output : aliased constant S := "/OUTPUT=" &
1147 "SOURCES " &
1148 "-s " &
1149 "DEPEND " &
1150 "-d " &
1151 "OBJECTS " &
1152 "-o " &
1153 "UNITS " &
1154 "-u " &
1155 "OPTIONS " &
1156 "-h " &
1157 "VERBOSE " &
1158 "-v ";
1160 S_List_Search : aliased constant S := "/SEARCH=*" &
1161 "-I*";
1163 S_List_Source : aliased constant S := "/SOURCE_SEARCH=*" &
1164 "-aI*";
1166 List_Switches : aliased constant Switches :=
1167 (S_List_All 'Access,
1168 S_List_Current 'Access,
1169 S_Ext_Ref 'Access,
1170 S_List_Nostinc 'Access,
1171 S_List_Object 'Access,
1172 S_List_Output 'Access,
1173 S_Project_File 'Access,
1174 S_Project_Verb 'Access,
1175 S_List_Search 'Access,
1176 S_List_Source 'Access);
1178 ----------------------------
1179 -- Switches for GNAT MAKE --
1180 ----------------------------
1182 S_Make_Actions : aliased constant S := "/ACTIONS=" &
1183 "COMPILE " &
1184 "-c " &
1185 "BIND " &
1186 "-b " &
1187 "LINK " &
1188 "-l ";
1190 S_Make_All : aliased constant S := "/ALL_FILES " &
1191 "-a";
1193 S_Make_Bind : aliased constant S := "/BINDER_QUALIFIERS=?" &
1194 "-bargs BIND";
1196 S_Make_Comp : aliased constant S := "/COMPILER_QUALIFIERS=?" &
1197 "-cargs COMPILE";
1199 S_Make_Cond : aliased constant S := "/CONDITIONAL_SOURCE_SEARCH=*" &
1200 "-A*";
1202 S_Make_Cont : aliased constant S := "/CONTINUE_ON_ERROR " &
1203 "-k";
1205 S_Make_Current : aliased constant S := "/CURRENT_DIRECTORY " &
1206 "!-I-";
1208 S_Make_Dep : aliased constant S := "/DEPENDENCIES_LIST " &
1209 "-M";
1211 S_Make_Doobj : aliased constant S := "/DO_OBJECT_CHECK " &
1212 "-n";
1214 S_Make_Execut : aliased constant S := "/EXECUTABLE=@" &
1215 "-o@";
1217 S_Make_Force : aliased constant S := "/FORCE_COMPILE " &
1218 "-f";
1220 S_Make_Inplace : aliased constant S := "/IN_PLACE " &
1221 "-i";
1223 S_Make_Library : aliased constant S := "/LIBRARY_SEARCH=*" &
1224 "-L*";
1226 S_Make_Link : aliased constant S := "/LINKER_QUALIFIERS=?" &
1227 "-largs LINK";
1229 S_Make_Mapping : aliased constant S := "/MAPPING " &
1230 "-C";
1232 S_Make_Minimal : aliased constant S := "/MINIMAL_RECOMPILATION " &
1233 "-m";
1235 S_Make_Nolink : aliased constant S := "/NOLINK " &
1236 "-c";
1238 S_Make_Nomain : aliased constant S := "/NOMAIN " &
1239 "-z";
1241 S_Make_Nostinc : aliased constant S := "/NOSTD_INCLUDES " &
1242 "-nostdinc";
1244 S_Make_Nostlib : aliased constant S := "/NOSTD_LIBRARIES " &
1245 "-nostdlib";
1247 S_Make_Object : aliased constant S := "/OBJECT_SEARCH=*" &
1248 "-aO*";
1250 S_Make_Proc : aliased constant S := "/PROCESSES=#" &
1251 "-j#";
1253 S_Make_Nojobs : aliased constant S := "/NOPROCESSES " &
1254 "-j1";
1256 S_Make_Quiet : aliased constant S := "/QUIET " &
1257 "-q";
1259 S_Make_Reason : aliased constant S := "/REASONS " &
1260 "-v";
1262 S_Make_RTS : aliased constant S := "/RUNTIME_SYSTEM=|" &
1263 "--RTS=|";
1265 S_Make_Search : aliased constant S := "/SEARCH=*" &
1266 "-I*";
1268 S_Make_Skip : aliased constant S := "/SKIP_MISSING=*" &
1269 "-aL*";
1271 S_Make_Source : aliased constant S := "/SOURCE_SEARCH=*" &
1272 "-aI*";
1274 S_Make_Switch : aliased constant S := "/SWITCH_CHECK " &
1275 "-s";
1277 S_Make_Unique : aliased constant S := "/UNIQUE " &
1278 "-u";
1280 S_Make_Verbose : aliased constant S := "/VERBOSE " &
1281 "-v";
1283 Make_Switches : aliased constant Switches :=
1284 (S_Make_Actions 'Access,
1285 S_Make_All 'Access,
1286 S_Make_Bind 'Access,
1287 S_Make_Comp 'Access,
1288 S_Make_Cond 'Access,
1289 S_Make_Cont 'Access,
1290 S_Make_Current 'Access,
1291 S_Make_Dep 'Access,
1292 S_Make_Doobj 'Access,
1293 S_Make_Execut 'Access,
1294 S_Ext_Ref 'Access,
1295 S_Make_Force 'Access,
1296 S_Make_Inplace 'Access,
1297 S_Make_Library 'Access,
1298 S_Make_Link 'Access,
1299 S_Make_Mapping 'Access,
1300 S_Make_Minimal 'Access,
1301 S_Make_Nolink 'Access,
1302 S_Make_Nomain 'Access,
1303 S_Make_Nostinc 'Access,
1304 S_Make_Nostlib 'Access,
1305 S_Make_Object 'Access,
1306 S_Make_Proc 'Access,
1307 S_Project_File 'Access,
1308 S_Project_Verb 'Access,
1309 S_Make_Nojobs 'Access,
1310 S_Make_Quiet 'Access,
1311 S_Make_Reason 'Access,
1312 S_Make_RTS 'Access,
1313 S_Make_Search 'Access,
1314 S_Make_Skip 'Access,
1315 S_Make_Source 'Access,
1316 S_Make_Switch 'Access,
1317 S_Make_Unique 'Access,
1318 S_Make_Verbose 'Access);
1320 ----------------------------
1321 -- Switches for GNAT Name --
1322 ----------------------------
1324 S_Name_Conf : aliased constant S := "/CONFIG_FILE=<" &
1325 "-c>";
1327 S_Name_Dirs : aliased constant S := "/SOURCE_DIRS=*" &
1328 "-d*";
1330 S_Name_Dfile : aliased constant S := "/DIRS_FILE=<" &
1331 "-D>";
1333 S_Name_Help : aliased constant S := "/HELP" &
1334 " -h";
1336 S_Name_Proj : aliased constant S := "/PROJECT_FILE=<" &
1337 "-P>";
1339 S_Name_Verbose : aliased constant S := "/VERBOSE" &
1340 " -v";
1342 Name_Switches : aliased constant Switches :=
1343 (S_Name_Conf 'Access,
1344 S_Name_Dirs 'Access,
1345 S_Name_Dfile 'Access,
1346 S_Name_Help 'Access,
1347 S_Name_Proj 'Access,
1348 S_Name_Verbose 'Access);
1350 ----------------------------------
1351 -- Switches for GNAT PREPROCESS --
1352 ----------------------------------
1354 S_Prep_Assoc : aliased constant S := "/ASSOCIATE=" & '"' &
1355 "-D" & '"';
1357 S_Prep_Blank : aliased constant S := "/BLANK_LINES " &
1358 "-b";
1360 S_Prep_Com : aliased constant S := "/COMMENTS " &
1361 "-c";
1363 S_Prep_Ref : aliased constant S := "/REFERENCE " &
1364 "-r";
1366 S_Prep_Remove : aliased constant S := "/REMOVE " &
1367 "!-b,!-c";
1369 S_Prep_Symbols : aliased constant S := "/SYMBOLS " &
1370 "-s";
1372 S_Prep_Undef : aliased constant S := "/UNDEFINED " &
1373 "-u";
1375 Prep_Switches : aliased constant Switches :=
1376 (S_Prep_Assoc 'Access,
1377 S_Prep_Blank 'Access,
1378 S_Prep_Com 'Access,
1379 S_Prep_Ref 'Access,
1380 S_Prep_Remove 'Access,
1381 S_Prep_Symbols 'Access,
1382 S_Prep_Undef 'Access);
1384 ------------------------------
1385 -- Switches for GNAT SHARED --
1386 ------------------------------
1388 S_Shared_Debug : aliased constant S := "/DEBUG=" &
1389 "ALL " &
1390 "-g3 " &
1391 "NONE " &
1392 "-g0 " &
1393 "TRACEBACK " &
1394 "-g1 " &
1395 "NOTRACEBACK " &
1396 "-g0";
1398 S_Shared_Image : aliased constant S := "/IMAGE=@" &
1399 "-o@";
1401 S_Shared_Ident : aliased constant S := "/IDENTIFICATION=" & '"' &
1402 "--for-linker=IDENT=" &
1403 '"';
1405 S_Shared_Nofiles : aliased constant S := "/NOSTART_FILES " &
1406 "-nostartfiles";
1408 S_Shared_Noinhib : aliased constant S := "/NOINHIBIT-IMAGE " &
1409 "--for-linker=--noinhibit-exec";
1411 S_Shared_Verb : aliased constant S := "/VERBOSE " &
1412 "-v";
1414 S_Shared_ZZZZZ : aliased constant S := "/<other> " &
1415 "--for-linker=";
1417 Shared_Switches : aliased constant Switches :=
1418 (S_Shared_Debug 'Access,
1419 S_Shared_Image 'Access,
1420 S_Shared_Ident 'Access,
1421 S_Shared_Nofiles 'Access,
1422 S_Shared_Noinhib 'Access,
1423 S_Shared_Verb 'Access,
1424 S_Shared_ZZZZZ 'Access);
1426 --------------------------------
1427 -- Switches for GNAT STANDARD --
1428 --------------------------------
1430 Standard_Switches : aliased constant Switches := (1 .. 0 => null);
1432 ----------------------------
1433 -- Switches for GNAT STUB --
1434 ----------------------------
1436 S_Stub_Current : aliased constant S := "/CURRENT_DIRECTORY " &
1437 "!-I-";
1439 S_Stub_Full : aliased constant S := "/FULL " &
1440 "-f";
1442 S_Stub_Header : aliased constant S := "/HEADER=" &
1443 "GENERAL " &
1444 "-hg " &
1445 "SPEC " &
1446 "-hs";
1448 S_Stub_Indent : aliased constant S := "/INDENTATION=#" &
1449 "-i#";
1451 S_Stub_Length : aliased constant S := "/LINE_LENGTH=#" &
1452 "-l#";
1454 S_Stub_Quiet : aliased constant S := "/QUIET " &
1455 "-q";
1457 S_Stub_Search : aliased constant S := "/SEARCH=*" &
1458 "-I*";
1460 S_Stub_Tree : aliased constant S := "/TREE_FILE=" &
1461 "OVERWRITE " &
1462 "-t " &
1463 "SAVE " &
1464 "-k " &
1465 "REUSE " &
1466 "-r";
1468 S_Stub_Verbose : aliased constant S := "/VERBOSE " &
1469 "-v";
1471 Stub_Switches : aliased constant Switches :=
1472 (S_Stub_Current 'Access,
1473 S_Stub_Full 'Access,
1474 S_Stub_Header 'Access,
1475 S_Stub_Indent 'Access,
1476 S_Stub_Length 'Access,
1477 S_Stub_Quiet 'Access,
1478 S_Stub_Search 'Access,
1479 S_Stub_Tree 'Access,
1480 S_Stub_Verbose 'Access);
1482 ----------------------------
1483 -- Switches for GNAT XREF --
1484 ----------------------------
1486 S_Xref_All : aliased constant S := "/ALL_FILES " &
1487 "-a";
1489 S_Xref_Deriv : aliased constant S := "/DERIVED_TYPES " &
1490 "-d";
1492 S_Xref_Full : aliased constant S := "/FULL_PATHNAME " &
1493 "-f";
1495 S_Xref_Global : aliased constant S := "/IGNORE_LOCALS " &
1496 "-g";
1498 S_Xref_Nostinc : aliased constant S := "/NOSTD_INCLUDES " &
1499 "-nostdinc";
1501 S_Xref_Nostlib : aliased constant S := "/NOSTD_LIBRARIES " &
1502 "-nostdlib";
1504 S_Xref_Object : aliased constant S := "/OBJECT_SEARCH=*" &
1505 "-aO*";
1507 S_Xref_Project : aliased constant S := "/PROJECT=@" &
1508 "-p@";
1510 S_Xref_Search : aliased constant S := "/SEARCH=*" &
1511 "-I*";
1513 S_Xref_Source : aliased constant S := "/SOURCE_SEARCH=*" &
1514 "-aI*";
1516 S_Xref_Output : aliased constant S := "/UNUSED " &
1517 "-u";
1519 S_Xref_Tags : aliased constant S := "/TAGS " &
1520 "-v";
1522 Xref_Switches : aliased constant Switches :=
1523 (S_Xref_All 'Access,
1524 S_Xref_Deriv 'Access,
1525 S_Ext_Ref 'Access,
1526 S_Xref_Full 'Access,
1527 S_Xref_Global 'Access,
1528 S_Xref_Nostinc 'Access,
1529 S_Xref_Nostlib 'Access,
1530 S_Xref_Object 'Access,
1531 S_Xref_Project 'Access,
1532 S_Project_File 'Access,
1533 S_Project_Verb 'Access,
1534 S_Xref_Search 'Access,
1535 S_Xref_Source 'Access,
1536 S_Xref_Output 'Access,
1537 S_Xref_Tags 'Access);
1539 -------------------
1540 -- COMMAND TABLE --
1541 -------------------
1543 -- The command table contains an entry for each command recognized by
1544 -- GNATCmd. The entries are represented by an array of records.
1546 type Parameter_Type is
1547 -- A parameter is defined as a whitespace bounded string, not begining
1548 -- with a slash. (But see note under FILES_OR_WILDCARD).
1549 (File,
1550 -- A required file or directory parameter.
1552 Optional_File,
1553 -- An optional file or directory parameter.
1555 Other_As_Is,
1556 -- A parameter that's passed through as is (not canonicalized)
1558 Unlimited_Files,
1559 -- An unlimited number of whitespace separate file or directory
1560 -- parameters including wildcard specifications.
1562 Unlimited_As_Is,
1563 -- Un unlimited number of whitespace separated paameters that are
1564 -- passed through as is (not canonicalized).
1566 Files_Or_Wildcard);
1567 -- A comma separated list of files and/or wildcard file specifications.
1568 -- A comma preceded by or followed by whitespace is considered as a
1569 -- single comma character w/o whitespace.
1571 type Parameter_Array is array (Natural range <>) of Parameter_Type;
1572 type Parameter_Ref is access all Parameter_Array;
1574 type Command_Type is
1575 (Bind, Chop, Compile, Elim, Find, Krunch, Library, Link, List,
1576 Make, Name, Preprocess, Shared, Standard, Stub, Xref, Undefined);
1578 type Alternate_Command is (Comp, Ls, Kr, Prep, Psta);
1579 -- Alternate command libel for non VMS system
1581 Corresponding_To : constant array (Alternate_Command) of Command_Type :=
1582 (Comp => Compile,
1583 Ls => List,
1584 Kr => Krunch,
1585 Prep => Preprocess,
1586 Psta => Standard);
1587 -- Mapping of alternate commands to commands
1589 subtype Real_Command_Type is Command_Type range Bind .. Xref;
1591 type Command_Entry is record
1592 Cname : String_Ptr;
1593 -- Command name for GNAT xxx command
1595 Usage : String_Ptr;
1596 -- A usage string, used for error messages
1598 Unixcmd : String_Ptr;
1599 -- Corresponding Unix command
1601 Unixsws : Argument_List_Access;
1602 -- Switches for the Unix command
1604 VMS_Only : Boolean;
1605 -- When True, the command can only be used on VMS
1607 Switches : Switches_Ptr;
1608 -- Pointer to array of switch strings
1610 Params : Parameter_Ref;
1611 -- Describes the allowable types of parameters.
1612 -- Params (1) is the type of the first parameter, etc.
1613 -- An empty parameter array means this command takes no parameters.
1615 Defext : String (1 .. 3);
1616 -- Default extension. If non-blank, then this extension is supplied by
1617 -- default as the extension for any file parameter which does not have
1618 -- an extension already.
1619 end record;
1621 -------------------------
1622 -- INTERNAL STRUCTURES --
1623 -------------------------
1625 -- The switches and commands are defined by strings in the previous
1626 -- section so that they are easy to modify, but internally, they are
1627 -- kept in a more conveniently accessible form described in this
1628 -- section.
1630 -- Commands, command qualifers and options have a similar common format
1631 -- so that searching for matching names can be done in a common manner.
1633 type Item_Id is (Id_Command, Id_Switch, Id_Option);
1635 type Translation_Type is
1637 T_Direct,
1638 -- A qualifier with no options.
1639 -- Example: GNAT MAKE /VERBOSE
1641 T_Directories,
1642 -- A qualifier followed by a list of directories
1643 -- Example: GNAT COMPILE /SEARCH=([], [.FOO], [.BAR])
1645 T_Directory,
1646 -- A qualifier followed by one directory
1647 -- Example: GNAT LIBRARY /SET=[.VAXFLOATLIB]
1649 T_File,
1650 -- A qualifier followed by a filename
1651 -- Example: GNAT LINK /EXECUTABLE=FOO.EXE
1653 T_No_Space_File,
1654 -- A qualifier followed by a filename
1655 -- Example: GNAT MAKE /PROJECT_FILE=PRJ.GPR
1657 T_Numeric,
1658 -- A qualifier followed by a numeric value.
1659 -- Example: GNAT CHOP /FILE_NAME_MAX_LENGTH=39
1661 T_String,
1662 -- A qualifier followed by a quoted string. Only used by
1663 -- /IDENTIFICATION qualfier.
1664 -- Example: GNAT LINK /IDENTIFICATION="3.14a1 version"
1666 T_Options,
1667 -- A qualifier followed by a list of options.
1668 -- Example: GNAT COMPILE /REPRESENTATION_INFO=(ARRAYS,OBJECTS)
1670 T_Commands,
1671 -- A qualifier followed by a list. Only used for
1672 -- MAKE /COMPILER_QUALIFIERS /BINDER_QUALIFIERS /LINKER_QUALIFIERS
1673 -- (gnatmake -cargs -bargs -largs )
1674 -- Example: GNAT MAKE ... /LINKER_QUALIFIERS /VERBOSE FOOBAR.OBJ
1676 T_Other,
1677 -- A qualifier passed directly to the linker. Only used
1678 -- for LINK and SHARED if no other match is found.
1679 -- Example: GNAT LINK FOO.ALI /SYSSHR
1681 T_Alphanumplus
1682 -- A qualifier followed by a legal linker symbol prefix. Only used
1683 -- for BIND /BUILD_LIBRARY (gnatbind -Lxyz).
1684 -- Example: GNAT BIND /BUILD_LIBRARY=foobar
1687 type Item (Id : Item_Id);
1688 type Item_Ptr is access all Item;
1690 type Item (Id : Item_Id) is record
1691 Name : String_Ptr;
1692 -- Name of the command, switch (with slash) or option
1694 Next : Item_Ptr;
1695 -- Pointer to next item on list, always has the same Id value
1697 Command : Command_Type := Undefined;
1699 Unix_String : String_Ptr := null;
1700 -- Corresponding Unix string. For a command, this is the unix command
1701 -- name and possible default switches. For a switch or option it is
1702 -- the unix switch string.
1704 case Id is
1706 when Id_Command =>
1708 Switches : Item_Ptr;
1709 -- Pointer to list of switch items for the command, linked
1710 -- through the Next fields with null terminating the list.
1712 Usage : String_Ptr;
1713 -- Usage information, used only for errors and the default
1714 -- list of commands output.
1716 Params : Parameter_Ref;
1717 -- Array of parameters
1719 Defext : String (1 .. 3);
1720 -- Default extension. If non-blank, then this extension is
1721 -- supplied by default as the extension for any file parameter
1722 -- which does not have an extension already.
1724 when Id_Switch =>
1726 Translation : Translation_Type;
1727 -- Type of switch translation. For all cases, except Options,
1728 -- this is the only field needed, since the Unix translation
1729 -- is found in Unix_String.
1731 Options : Item_Ptr;
1732 -- For the Options case, this field is set to point to a list
1733 -- of options item (for this case Unix_String is null in the
1734 -- main switch item). The end of the list is marked by null.
1736 when Id_Option =>
1738 null;
1739 -- No special fields needed, since Name and Unix_String are
1740 -- sufficient to completely described an option.
1742 end case;
1743 end record;
1745 subtype Command_Item is Item (Id_Command);
1746 subtype Switch_Item is Item (Id_Switch);
1747 subtype Option_Item is Item (Id_Option);
1749 ----------------------------------
1750 -- Declarations for GNATCMD use --
1751 ----------------------------------
1753 Commands : Item_Ptr;
1754 -- Pointer to head of list of command items, one for each command, with
1755 -- the end of the list marked by a null pointer.
1757 Last_Command : Item_Ptr;
1758 -- Pointer to last item in Commands list
1760 Normal_Exit : exception;
1761 -- Raise this exception for normal program termination
1763 Error_Exit : exception;
1764 -- Raise this exception if error detected
1766 Errors : Natural := 0;
1767 -- Count errors detected
1769 Command_Arg : Positive := 1;
1771 Command : Item_Ptr;
1772 -- Pointer to command item for current command
1774 Make_Commands_Active : Item_Ptr := null;
1775 -- Set to point to Command entry for COMPILE, BIND, or LINK as appropriate
1776 -- if a COMMANDS_TRANSLATION switch has been encountered while processing
1777 -- a MAKE Command.
1779 My_Exit_Status : Exit_Status := Success;
1781 package Buffer is new Table.Table
1782 (Table_Component_Type => Character,
1783 Table_Index_Type => Integer,
1784 Table_Low_Bound => 1,
1785 Table_Initial => 4096,
1786 Table_Increment => 2,
1787 Table_Name => "Buffer");
1789 Param_Count : Natural := 0;
1790 -- Number of parameter arguments so far
1792 Arg_Num : Natural;
1793 -- Argument number
1795 Display_Command : Boolean := False;
1796 -- Set true if /? switch causes display of generated command (on VMS)
1798 The_Command : Command_Type;
1799 -- The command used
1801 -----------------------
1802 -- Local Subprograms --
1803 -----------------------
1805 function Index (Char : Character; Str : String) return Natural;
1806 -- Returns the first occurrence of Char in Str.
1807 -- Returns 0 if Char is not in Str.
1809 function Init_Object_Dirs return Argument_List;
1811 function Invert_Sense (S : String) return String_Ptr;
1812 -- Given a unix switch string S, computes the inverse (adding or
1813 -- removing ! characters as required), and returns a pointer to
1814 -- the allocated result on the heap.
1816 function Is_Extensionless (F : String) return Boolean;
1817 -- Returns true if the filename has no extension.
1819 function Match (S1, S2 : String) return Boolean;
1820 -- Determines whether S1 and S2 match. This is a case insensitive match.
1822 function Match_Prefix (S1, S2 : String) return Boolean;
1823 -- Determines whether S1 matches a prefix of S2. This is also a case
1824 -- insensitive match (for example Match ("AB","abc") is True).
1826 function Matching_Name
1827 (S : String;
1828 Itm : Item_Ptr;
1829 Quiet : Boolean := False)
1830 return Item_Ptr;
1831 -- Determines if the item list headed by Itm and threaded through the
1832 -- Next fields (with null marking the end of the list), contains an
1833 -- entry that uniquely matches the given string. The match is case
1834 -- insensitive and permits unique abbreviation. If the match succeeds,
1835 -- then a pointer to the matching item is returned. Otherwise, an
1836 -- appropriate error message is written. Note that the discriminant
1837 -- of Itm is used to determine the appropriate form of this message.
1838 -- Quiet is normally False as shown, if it is set to True, then no
1839 -- error message is generated in a not found situation (null is still
1840 -- returned to indicate the not-found situation).
1842 procedure Non_VMS_Usage;
1843 -- Display usage for platforms other than VMS
1845 function OK_Alphanumerplus (S : String) return Boolean;
1846 -- Checks that S is a string of alphanumeric characters,
1847 -- returning True if all alphanumeric characters,
1848 -- False if empty or a non-alphanumeric character is present.
1850 function OK_Integer (S : String) return Boolean;
1851 -- Checks that S is a string of digits, returning True if all digits,
1852 -- False if empty or a non-digit is present.
1854 procedure Output_Version;
1855 -- Output the version of this program
1857 procedure Place (C : Character);
1858 -- Place a single character in the buffer, updating Ptr
1860 procedure Place (S : String);
1861 -- Place a string character in the buffer, updating Ptr
1863 procedure Place_Lower (S : String);
1864 -- Place string in buffer, forcing letters to lower case, updating Ptr
1866 procedure Place_Unix_Switches (S : String_Ptr);
1867 -- Given a unix switch string, place corresponding switches in Buffer,
1868 -- updating Ptr appropriatelly. Note that in the case of use of ! the
1869 -- result may be to remove a previously placed switch.
1871 procedure Set_Library_For
1872 (Project : Project_Id;
1873 There_Are_Libraries : in out Boolean);
1874 -- If Project is a library project, add the correct
1875 -- -L and -l switches to the linker invocation.
1877 procedure Set_Libraries is
1878 new For_Every_Project_Imported (Boolean, Set_Library_For);
1879 -- Add the -L and -l switches to the linker for all
1880 -- of the library projects.
1882 procedure Validate_Command_Or_Option (N : String_Ptr);
1883 -- Check that N is a valid command or option name, i.e. that it is of the
1884 -- form of an Ada identifier with upper case letters and underscores.
1886 procedure Validate_Unix_Switch (S : String_Ptr);
1887 -- Check that S is a valid switch string as described in the syntax for
1888 -- the switch table item UNIX_SWITCH or else begins with a backquote.
1890 procedure VMS_Conversion (The_Command : out Command_Type);
1891 -- Converts VMS command line to equivalent Unix command line
1893 -----------
1894 -- Index --
1895 -----------
1897 function Index (Char : Character; Str : String) return Natural is
1898 begin
1899 for Index in Str'Range loop
1900 if Str (Index) = Char then
1901 return Index;
1902 end if;
1903 end loop;
1905 return 0;
1906 end Index;
1908 ----------------------
1909 -- Init_Object_Dirs --
1910 ----------------------
1912 function Init_Object_Dirs return Argument_List is
1913 Object_Dirs : Integer;
1914 Object_Dir : Argument_List (1 .. 256);
1915 Object_Dir_Name : String_Access;
1917 begin
1918 Object_Dirs := 0;
1919 Object_Dir_Name := String_Access (Object_Dir_Default_Name);
1920 Get_Next_Dir_In_Path_Init (Object_Dir_Name);
1922 loop
1923 declare
1924 Dir : String_Access := String_Access
1925 (Get_Next_Dir_In_Path (Object_Dir_Name));
1926 begin
1927 exit when Dir = null;
1928 Object_Dirs := Object_Dirs + 1;
1929 Object_Dir (Object_Dirs) :=
1930 new String'("-L" &
1931 To_Canonical_Dir_Spec
1932 (To_Host_Dir_Spec
1933 (Normalize_Directory_Name (Dir.all).all,
1934 True).all, True).all);
1935 end;
1936 end loop;
1938 Object_Dirs := Object_Dirs + 1;
1939 Object_Dir (Object_Dirs) := new String'("-lgnat");
1941 if Hostparm.OpenVMS then
1942 Object_Dirs := Object_Dirs + 1;
1943 Object_Dir (Object_Dirs) := new String'("-ldecgnat");
1944 end if;
1946 return Object_Dir (1 .. Object_Dirs);
1947 end Init_Object_Dirs;
1949 ------------------
1950 -- Invert_Sense --
1951 ------------------
1953 function Invert_Sense (S : String) return String_Ptr is
1954 Sinv : String (1 .. S'Length * 2);
1955 -- Result (for sure long enough)
1957 Sinvp : Natural := 0;
1958 -- Pointer to output string
1960 begin
1961 for Sp in S'Range loop
1962 if Sp = S'First or else S (Sp - 1) = ',' then
1963 if S (Sp) = '!' then
1964 null;
1965 else
1966 Sinv (Sinvp + 1) := '!';
1967 Sinv (Sinvp + 2) := S (Sp);
1968 Sinvp := Sinvp + 2;
1969 end if;
1971 else
1972 Sinv (Sinvp + 1) := S (Sp);
1973 Sinvp := Sinvp + 1;
1974 end if;
1975 end loop;
1977 return new String'(Sinv (1 .. Sinvp));
1978 end Invert_Sense;
1980 ----------------------
1981 -- Is_Extensionless --
1982 ----------------------
1984 function Is_Extensionless (F : String) return Boolean is
1985 begin
1986 for J in reverse F'Range loop
1987 if F (J) = '.' then
1988 return False;
1989 elsif F (J) = '/' or else F (J) = ']' or else F (J) = ':' then
1990 return True;
1991 end if;
1992 end loop;
1994 return True;
1995 end Is_Extensionless;
1997 -----------
1998 -- Match --
1999 -----------
2001 function Match (S1, S2 : String) return Boolean is
2002 Dif : constant Integer := S2'First - S1'First;
2004 begin
2006 if S1'Length /= S2'Length then
2007 return False;
2009 else
2010 for J in S1'Range loop
2011 if To_Lower (S1 (J)) /= To_Lower (S2 (J + Dif)) then
2012 return False;
2013 end if;
2014 end loop;
2016 return True;
2017 end if;
2018 end Match;
2020 ------------------
2021 -- Match_Prefix --
2022 ------------------
2024 function Match_Prefix (S1, S2 : String) return Boolean is
2025 begin
2026 if S1'Length > S2'Length then
2027 return False;
2028 else
2029 return Match (S1, S2 (S2'First .. S2'First + S1'Length - 1));
2030 end if;
2031 end Match_Prefix;
2033 -------------------
2034 -- Matching_Name --
2035 -------------------
2037 function Matching_Name
2038 (S : String;
2039 Itm : Item_Ptr;
2040 Quiet : Boolean := False)
2041 return Item_Ptr
2043 P1, P2 : Item_Ptr;
2045 procedure Err;
2046 -- Little procedure to output command/qualifier/option as appropriate
2047 -- and bump error count.
2049 ---------
2050 -- Err --
2051 ---------
2053 procedure Err is
2054 begin
2055 if Quiet then
2056 return;
2057 end if;
2059 Errors := Errors + 1;
2061 if Itm /= null then
2062 case Itm.Id is
2063 when Id_Command =>
2064 Put (Standard_Error, "command");
2066 when Id_Switch =>
2067 if OpenVMS then
2068 Put (Standard_Error, "qualifier");
2069 else
2070 Put (Standard_Error, "switch");
2071 end if;
2073 when Id_Option =>
2074 Put (Standard_Error, "option");
2076 end case;
2077 else
2078 Put (Standard_Error, "input");
2080 end if;
2082 Put (Standard_Error, ": ");
2083 Put (Standard_Error, S);
2084 end Err;
2086 -- Start of processing for Matching_Name
2088 begin
2089 -- If exact match, that's the one we want
2091 P1 := Itm;
2092 while P1 /= null loop
2093 if Match (S, P1.Name.all) then
2094 return P1;
2095 else
2096 P1 := P1.Next;
2097 end if;
2098 end loop;
2100 -- Now check for prefix matches
2102 P1 := Itm;
2103 while P1 /= null loop
2104 if P1.Name.all = "/<other>" then
2105 return P1;
2107 elsif not Match_Prefix (S, P1.Name.all) then
2108 P1 := P1.Next;
2110 else
2111 -- Here we have found one matching prefix, so see if there is
2112 -- another one (which is an ambiguity)
2114 P2 := P1.Next;
2115 while P2 /= null loop
2116 if Match_Prefix (S, P2.Name.all) then
2117 if not Quiet then
2118 Put (Standard_Error, "ambiguous ");
2119 Err;
2120 Put (Standard_Error, " (matches ");
2121 Put (Standard_Error, P1.Name.all);
2123 while P2 /= null loop
2124 if Match_Prefix (S, P2.Name.all) then
2125 Put (Standard_Error, ',');
2126 Put (Standard_Error, P2.Name.all);
2127 end if;
2129 P2 := P2.Next;
2130 end loop;
2132 Put_Line (Standard_Error, ")");
2133 end if;
2135 return null;
2136 end if;
2138 P2 := P2.Next;
2139 end loop;
2141 -- If we fall through that loop, then there was only one match
2143 return P1;
2144 end if;
2145 end loop;
2147 -- If we fall through outer loop, there was no match
2149 if not Quiet then
2150 Put (Standard_Error, "unrecognized ");
2151 Err;
2152 New_Line (Standard_Error);
2153 end if;
2155 return null;
2156 end Matching_Name;
2158 -----------------------
2159 -- OK_Alphanumerplus --
2160 -----------------------
2162 function OK_Alphanumerplus (S : String) return Boolean is
2163 begin
2164 if S'Length = 0 then
2165 return False;
2167 else
2168 for J in S'Range loop
2169 if not (Is_Alphanumeric (S (J)) or else
2170 S (J) = '_' or else S (J) = '$')
2171 then
2172 return False;
2173 end if;
2174 end loop;
2176 return True;
2177 end if;
2178 end OK_Alphanumerplus;
2180 ----------------
2181 -- OK_Integer --
2182 ----------------
2184 function OK_Integer (S : String) return Boolean is
2185 begin
2186 if S'Length = 0 then
2187 return False;
2189 else
2190 for J in S'Range loop
2191 if not Is_Digit (S (J)) then
2192 return False;
2193 end if;
2194 end loop;
2196 return True;
2197 end if;
2198 end OK_Integer;
2200 --------------------
2201 -- Output_Version --
2202 --------------------
2204 procedure Output_Version is
2205 begin
2206 Put ("GNAT ");
2207 Put (Gnatvsn.Gnat_Version_String);
2208 Put_Line (" Copyright 1996-2002 Free Software Foundation, Inc.");
2209 end Output_Version;
2211 -----------
2212 -- Place --
2213 -----------
2215 procedure Place (C : Character) is
2216 begin
2217 Buffer.Increment_Last;
2218 Buffer.Table (Buffer.Last) := C;
2220 -- Do not put a space as the first character in the buffer
2221 if C = ' ' and then Buffer.Last = 1 then
2222 Buffer.Decrement_Last;
2223 end if;
2224 end Place;
2226 procedure Place (S : String) is
2227 begin
2228 for J in S'Range loop
2229 Place (S (J));
2230 end loop;
2231 end Place;
2233 -----------------
2234 -- Place_Lower --
2235 -----------------
2237 procedure Place_Lower (S : String) is
2238 begin
2239 for J in S'Range loop
2240 Place (To_Lower (S (J)));
2241 end loop;
2242 end Place_Lower;
2244 -------------------------
2245 -- Place_Unix_Switches --
2246 -------------------------
2248 procedure Place_Unix_Switches (S : String_Ptr) is
2249 P1, P2, P3 : Natural;
2250 Remove : Boolean;
2251 Slen : Natural;
2253 begin
2254 P1 := S'First;
2255 while P1 <= S'Last loop
2256 if S (P1) = '!' then
2257 P1 := P1 + 1;
2258 Remove := True;
2259 else
2260 Remove := False;
2261 end if;
2263 P2 := P1;
2264 pragma Assert (S (P1) = '-' or else S (P1) = '`');
2266 while P2 < S'Last and then S (P2 + 1) /= ',' loop
2267 P2 := P2 + 1;
2268 end loop;
2270 -- Switch is now in S (P1 .. P2)
2272 Slen := P2 - P1 + 1;
2274 if Remove then
2275 P3 := 2;
2276 while P3 <= Buffer.Last - Slen loop
2277 if Buffer.Table (P3) = ' '
2278 and then String (Buffer.Table (P3 + 1 .. P3 + Slen)) =
2279 S (P1 .. P2)
2280 and then (P3 + Slen = Buffer.Last
2281 or else
2282 Buffer.Table (P3 + Slen + 1) = ' ')
2283 then
2284 Buffer.Table (P3 .. Buffer.Last - Slen - 1) :=
2285 Buffer.Table (P3 + Slen + 1 .. Buffer.Last);
2286 Buffer.Set_Last (Buffer.Last - Slen - 1);
2288 else
2289 P3 := P3 + 1;
2290 end if;
2291 end loop;
2293 else
2294 Place (' ');
2296 if S (P1) = '`' then
2297 P1 := P1 + 1;
2298 end if;
2300 Place (S (P1 .. P2));
2301 end if;
2303 P1 := P2 + 2;
2304 end loop;
2305 end Place_Unix_Switches;
2307 ---------------------
2308 -- Set_Library_For --
2309 ---------------------
2311 procedure Set_Library_For
2312 (Project : Project_Id;
2313 There_Are_Libraries : in out Boolean)
2315 begin
2316 -- Case of library project
2318 if Projects.Table (Project).Library then
2319 There_Are_Libraries := True;
2321 -- Add the -L switch
2323 Last_Switches.Increment_Last;
2324 Last_Switches.Table (Last_Switches.Last) :=
2325 new String'("-L" &
2326 Get_Name_String
2327 (Projects.Table (Project).Library_Dir));
2329 -- Add the -l switch
2331 Last_Switches.Increment_Last;
2332 Last_Switches.Table (Last_Switches.Last) :=
2333 new String'("-l" &
2334 Get_Name_String
2335 (Projects.Table (Project).Library_Name));
2337 -- Add the Wl,-rpath switch if library non static
2339 if Projects.Table (Project).Library_Kind /= Static then
2340 declare
2341 Option : constant String_Access :=
2342 MLib.Tgt.Linker_Library_Path_Option
2343 (Get_Name_String
2344 (Projects.Table (Project).Library_Dir));
2346 begin
2347 if Option /= null then
2348 Last_Switches.Increment_Last;
2349 Last_Switches.Table (Last_Switches.Last) :=
2350 Option;
2351 end if;
2353 end;
2355 end if;
2357 end if;
2358 end Set_Library_For;
2360 --------------------------------
2361 -- Validate_Command_Or_Option --
2362 --------------------------------
2364 procedure Validate_Command_Or_Option (N : String_Ptr) is
2365 begin
2366 pragma Assert (N'Length > 0);
2368 for J in N'Range loop
2369 if N (J) = '_' then
2370 pragma Assert (N (J - 1) /= '_');
2371 null;
2372 else
2373 pragma Assert (Is_Upper (N (J)) or else Is_Digit (N (J)));
2374 null;
2375 end if;
2376 end loop;
2377 end Validate_Command_Or_Option;
2379 --------------------------
2380 -- Validate_Unix_Switch --
2381 --------------------------
2383 procedure Validate_Unix_Switch (S : String_Ptr) is
2384 begin
2385 if S (S'First) = '`' then
2386 return;
2387 end if;
2389 pragma Assert (S (S'First) = '-' or else S (S'First) = '!');
2391 for J in S'First + 1 .. S'Last loop
2392 pragma Assert (S (J) /= ' ');
2394 if S (J) = '!' then
2395 pragma Assert (S (J - 1) = ',' and then S (J + 1) = '-');
2396 null;
2397 end if;
2398 end loop;
2399 end Validate_Unix_Switch;
2401 ----------------------
2402 -- List of Commands --
2403 ----------------------
2405 -- Note that we put this after all the local bodies (except Non_VMS_Usage
2406 -- and VMS_Conversion that use Command_List) to avoid some access before
2407 -- elaboration problems.
2409 Command_List : constant array (Real_Command_Type) of Command_Entry :=
2410 (Bind =>
2411 (Cname => new S'("BIND"),
2412 Usage => new S'("GNAT BIND file[.ali] /qualifiers"),
2413 VMS_Only => False,
2414 Unixcmd => new S'("gnatbind"),
2415 Unixsws => null,
2416 Switches => Bind_Switches'Access,
2417 Params => new Parameter_Array'(1 => File),
2418 Defext => "ali"),
2420 Chop =>
2421 (Cname => new S'("CHOP"),
2422 Usage => new S'("GNAT CHOP file [directory] /qualifiers"),
2423 VMS_Only => False,
2424 Unixcmd => new S'("gnatchop"),
2425 Unixsws => null,
2426 Switches => Chop_Switches'Access,
2427 Params => new Parameter_Array'(1 => File, 2 => Optional_File),
2428 Defext => " "),
2430 Compile =>
2431 (Cname => new S'("COMPILE"),
2432 Usage => new S'("GNAT COMPILE filespec[,...] /qualifiers"),
2433 VMS_Only => False,
2434 Unixcmd => new S'("gnatmake"),
2435 Unixsws => new Argument_List' (1 => new String'("-f"),
2436 2 => new String'("-u"),
2437 3 => new String'("-c")),
2438 Switches => GCC_Switches'Access,
2439 Params => new Parameter_Array'(1 => Files_Or_Wildcard),
2440 Defext => " "),
2442 Elim =>
2443 (Cname => new S'("ELIM"),
2444 Usage => new S'("GNAT ELIM name /qualifiers"),
2445 VMS_Only => False,
2446 Unixcmd => new S'("gnatelim"),
2447 Unixsws => null,
2448 Switches => Elim_Switches'Access,
2449 Params => new Parameter_Array'(1 => Other_As_Is),
2450 Defext => "ali"),
2452 Find =>
2453 (Cname => new S'("FIND"),
2454 Usage => new S'("GNAT FIND pattern[:sourcefile[:line"
2455 & "[:column]]] filespec[,...] /qualifiers"),
2456 VMS_Only => False,
2457 Unixcmd => new S'("gnatfind"),
2458 Unixsws => null,
2459 Switches => Find_Switches'Access,
2460 Params => new Parameter_Array'(1 => Other_As_Is,
2461 2 => Files_Or_Wildcard),
2462 Defext => "ali"),
2464 Krunch =>
2465 (Cname => new S'("KRUNCH"),
2466 Usage => new S'("GNAT KRUNCH file [/COUNT=nnn]"),
2467 VMS_Only => False,
2468 Unixcmd => new S'("gnatkr"),
2469 Unixsws => null,
2470 Switches => Krunch_Switches'Access,
2471 Params => new Parameter_Array'(1 => File),
2472 Defext => " "),
2474 Library =>
2475 (Cname => new S'("LIBRARY"),
2476 Usage => new S'("GNAT LIBRARY /[CREATE | SET | DELETE]"
2477 & "=directory [/CONFIG=file]"),
2478 VMS_Only => True,
2479 Unixcmd => new S'("gnatlbr"),
2480 Unixsws => null,
2481 Switches => Lbr_Switches'Access,
2482 Params => new Parameter_Array'(1 .. 0 => File),
2483 Defext => " "),
2485 Link =>
2486 (Cname => new S'("LINK"),
2487 Usage => new S'("GNAT LINK file[.ali]"
2488 & " [extra obj_&_lib_&_exe_&_opt files]"
2489 & " /qualifiers"),
2490 VMS_Only => False,
2491 Unixcmd => new S'("gnatlink"),
2492 Unixsws => null,
2493 Switches => Link_Switches'Access,
2494 Params => new Parameter_Array'(1 => Unlimited_Files),
2495 Defext => "ali"),
2497 List =>
2498 (Cname => new S'("LIST"),
2499 Usage => new S'("GNAT LIST /qualifiers object_or_ali_file"),
2500 VMS_Only => False,
2501 Unixcmd => new S'("gnatls"),
2502 Unixsws => null,
2503 Switches => List_Switches'Access,
2504 Params => new Parameter_Array'(1 => File),
2505 Defext => "ali"),
2507 Make =>
2508 (Cname => new S'("MAKE"),
2509 Usage => new S'("GNAT MAKE file /qualifiers (includes "
2510 & "COMPILE /qualifiers)"),
2511 VMS_Only => False,
2512 Unixcmd => new S'("gnatmake"),
2513 Unixsws => null,
2514 Switches => Make_Switches'Access,
2515 Params => new Parameter_Array'(1 => File),
2516 Defext => " "),
2518 Name =>
2519 (Cname => new S'("NAME"),
2520 Usage => new S'("GNAT NAME /qualifiers naming-pattern "
2521 & "[naming-patterns]"),
2522 VMS_Only => False,
2523 Unixcmd => new S'("gnatname"),
2524 Unixsws => null,
2525 Switches => Name_Switches'Access,
2526 Params => new Parameter_Array'(1 => Unlimited_As_Is),
2527 Defext => " "),
2529 Preprocess =>
2530 (Cname => new S'("PREPROCESS"),
2531 Usage => new S'("GNAT PREPROCESS ifile ofile dfile /qualifiers"),
2532 VMS_Only => False,
2533 Unixcmd => new S'("gnatprep"),
2534 Unixsws => null,
2535 Switches => Prep_Switches'Access,
2536 Params => new Parameter_Array'(1 .. 3 => File),
2537 Defext => " "),
2539 Shared =>
2540 (Cname => new S'("SHARED"),
2541 Usage => new S'("GNAT SHARED [obj_&_lib_&_exe_&_opt"
2542 & "files] /qualifiers"),
2543 VMS_Only => True,
2544 Unixcmd => new S'("gcc"),
2545 Unixsws => new Argument_List'(new String'("-shared")
2546 & Init_Object_Dirs),
2547 Switches => Shared_Switches'Access,
2548 Params => new Parameter_Array'(1 => Unlimited_Files),
2549 Defext => " "),
2551 Standard =>
2552 (Cname => new S'("STANDARD"),
2553 Usage => new S'("GNAT STANDARD"),
2554 VMS_Only => False,
2555 Unixcmd => new S'("gnatpsta"),
2556 Unixsws => null,
2557 Switches => Standard_Switches'Access,
2558 Params => new Parameter_Array'(1 .. 0 => File),
2559 Defext => " "),
2561 Stub =>
2562 (Cname => new S'("STUB"),
2563 Usage => new S'("GNAT STUB file [directory]/qualifiers"),
2564 VMS_Only => False,
2565 Unixcmd => new S'("gnatstub"),
2566 Unixsws => null,
2567 Switches => Stub_Switches'Access,
2568 Params => new Parameter_Array'(1 => File, 2 => Optional_File),
2569 Defext => " "),
2571 Xref =>
2572 (Cname => new S'("XREF"),
2573 Usage => new S'("GNAT XREF filespec[,...] /qualifiers"),
2574 VMS_Only => False,
2575 Unixcmd => new S'("gnatxref"),
2576 Unixsws => null,
2577 Switches => Xref_Switches'Access,
2578 Params => new Parameter_Array'(1 => Files_Or_Wildcard),
2579 Defext => "ali")
2582 -------------------
2583 -- Non_VMS_Usage --
2584 -------------------
2586 procedure Non_VMS_Usage is
2587 begin
2588 Output_Version;
2589 New_Line;
2590 Put_Line ("List of available commands");
2591 New_Line;
2593 for C in Command_List'Range loop
2594 if not Command_List (C).VMS_Only then
2595 Put ("GNAT " & Command_List (C).Cname.all);
2596 Set_Col (25);
2597 Put (Command_List (C).Unixcmd.all);
2599 declare
2600 Sws : Argument_List_Access renames Command_List (C).Unixsws;
2601 begin
2602 if Sws /= null then
2603 for J in Sws'Range loop
2604 Put (' ');
2605 Put (Sws (J).all);
2606 end loop;
2607 end if;
2608 end;
2610 New_Line;
2611 end if;
2612 end loop;
2614 New_Line;
2615 Put_Line ("Commands FIND, LIST and XREF accept project file " &
2616 "switches -vPx, -Pprj and -Xnam=val");
2617 New_Line;
2618 end Non_VMS_Usage;
2620 --------------------
2621 -- VMS_Conversion --
2622 --------------------
2624 procedure VMS_Conversion (The_Command : out Command_Type) is
2625 begin
2626 Buffer.Init;
2628 -- First we must preprocess the string form of the command and options
2629 -- list into the internal form that we use.
2631 for C in Real_Command_Type loop
2633 declare
2634 Command : Item_Ptr := new Command_Item;
2636 Last_Switch : Item_Ptr;
2637 -- Last switch in list
2639 begin
2640 -- Link new command item into list of commands
2642 if Last_Command = null then
2643 Commands := Command;
2644 else
2645 Last_Command.Next := Command;
2646 end if;
2648 Last_Command := Command;
2650 -- Fill in fields of new command item
2652 Command.Name := Command_List (C).Cname;
2653 Command.Usage := Command_List (C).Usage;
2654 Command.Command := C;
2656 if Command_List (C).Unixsws = null then
2657 Command.Unix_String := Command_List (C).Unixcmd;
2658 else
2659 declare
2660 Cmd : String (1 .. 5_000);
2661 Last : Natural := 0;
2662 Sws : Argument_List_Access := Command_List (C).Unixsws;
2664 begin
2665 Cmd (1 .. Command_List (C).Unixcmd'Length) :=
2666 Command_List (C).Unixcmd.all;
2667 Last := Command_List (C).Unixcmd'Length;
2669 for J in Sws'Range loop
2670 Last := Last + 1;
2671 Cmd (Last) := ' ';
2672 Cmd (Last + 1 .. Last + Sws (J)'Length) :=
2673 Sws (J).all;
2674 Last := Last + Sws (J)'Length;
2675 end loop;
2677 Command.Unix_String := new String'(Cmd (1 .. Last));
2678 end;
2679 end if;
2681 Command.Params := Command_List (C).Params;
2682 Command.Defext := Command_List (C).Defext;
2684 Validate_Command_Or_Option (Command.Name);
2686 -- Process the switch list
2688 for S in Command_List (C).Switches'Range loop
2689 declare
2690 SS : constant String_Ptr := Command_List (C).Switches (S);
2692 P : Natural := SS'First;
2693 Sw : Item_Ptr := new Switch_Item;
2695 Last_Opt : Item_Ptr;
2696 -- Pointer to last option
2698 begin
2699 -- Link new switch item into list of switches
2701 if Last_Switch = null then
2702 Command.Switches := Sw;
2703 else
2704 Last_Switch.Next := Sw;
2705 end if;
2707 Last_Switch := Sw;
2709 -- Process switch string, first get name
2711 while SS (P) /= ' ' and SS (P) /= '=' loop
2712 P := P + 1;
2713 end loop;
2715 Sw.Name := new String'(SS (SS'First .. P - 1));
2717 -- Direct translation case
2719 if SS (P) = ' ' then
2720 Sw.Translation := T_Direct;
2721 Sw.Unix_String := new String'(SS (P + 1 .. SS'Last));
2722 Validate_Unix_Switch (Sw.Unix_String);
2724 if SS (P - 1) = '>' then
2725 Sw.Translation := T_Other;
2727 elsif SS (P + 1) = '`' then
2728 null;
2730 -- Create the inverted case (/NO ..)
2732 elsif SS (SS'First + 1 .. SS'First + 2) /= "NO" then
2733 Sw := new Switch_Item;
2734 Last_Switch.Next := Sw;
2735 Last_Switch := Sw;
2737 Sw.Name :=
2738 new String'("/NO" & SS (SS'First + 1 .. P - 1));
2739 Sw.Translation := T_Direct;
2740 Sw.Unix_String := Invert_Sense (SS (P + 1 .. SS'Last));
2741 Validate_Unix_Switch (Sw.Unix_String);
2742 end if;
2744 -- Directories translation case
2746 elsif SS (P + 1) = '*' then
2747 pragma Assert (SS (SS'Last) = '*');
2748 Sw.Translation := T_Directories;
2749 Sw.Unix_String := new String'(SS (P + 2 .. SS'Last - 1));
2750 Validate_Unix_Switch (Sw.Unix_String);
2752 -- Directory translation case
2754 elsif SS (P + 1) = '%' then
2755 pragma Assert (SS (SS'Last) = '%');
2756 Sw.Translation := T_Directory;
2757 Sw.Unix_String := new String'(SS (P + 2 .. SS'Last - 1));
2758 Validate_Unix_Switch (Sw.Unix_String);
2760 -- File translation case
2762 elsif SS (P + 1) = '@' then
2763 pragma Assert (SS (SS'Last) = '@');
2764 Sw.Translation := T_File;
2765 Sw.Unix_String := new String'(SS (P + 2 .. SS'Last - 1));
2766 Validate_Unix_Switch (Sw.Unix_String);
2768 -- No space file translation case
2770 elsif SS (P + 1) = '<' then
2771 pragma Assert (SS (SS'Last) = '>');
2772 Sw.Translation := T_No_Space_File;
2773 Sw.Unix_String := new String'(SS (P + 2 .. SS'Last - 1));
2774 Validate_Unix_Switch (Sw.Unix_String);
2776 -- Numeric translation case
2778 elsif SS (P + 1) = '#' then
2779 pragma Assert (SS (SS'Last) = '#');
2780 Sw.Translation := T_Numeric;
2781 Sw.Unix_String := new String'(SS (P + 2 .. SS'Last - 1));
2782 Validate_Unix_Switch (Sw.Unix_String);
2784 -- Alphanumerplus translation case
2786 elsif SS (P + 1) = '|' then
2787 pragma Assert (SS (SS'Last) = '|');
2788 Sw.Translation := T_Alphanumplus;
2789 Sw.Unix_String := new String'(SS (P + 2 .. SS'Last - 1));
2790 Validate_Unix_Switch (Sw.Unix_String);
2792 -- String translation case
2794 elsif SS (P + 1) = '"' then
2795 pragma Assert (SS (SS'Last) = '"');
2796 Sw.Translation := T_String;
2797 Sw.Unix_String := new String'(SS (P + 2 .. SS'Last - 1));
2798 Validate_Unix_Switch (Sw.Unix_String);
2800 -- Commands translation case
2802 elsif SS (P + 1) = '?' then
2803 Sw.Translation := T_Commands;
2804 Sw.Unix_String := new String'(SS (P + 2 .. SS'Last));
2806 -- Options translation case
2808 else
2809 Sw.Translation := T_Options;
2810 Sw.Unix_String := new String'("");
2812 P := P + 1; -- bump past =
2813 while P <= SS'Last loop
2814 declare
2815 Opt : Item_Ptr := new Option_Item;
2816 Q : Natural;
2818 begin
2819 -- Link new option item into options list
2821 if Last_Opt = null then
2822 Sw.Options := Opt;
2823 else
2824 Last_Opt.Next := Opt;
2825 end if;
2827 Last_Opt := Opt;
2829 -- Fill in fields of new option item
2831 Q := P;
2832 while SS (Q) /= ' ' loop
2833 Q := Q + 1;
2834 end loop;
2836 Opt.Name := new String'(SS (P .. Q - 1));
2837 Validate_Command_Or_Option (Opt.Name);
2839 P := Q + 1;
2840 Q := P;
2842 while Q <= SS'Last and then SS (Q) /= ' ' loop
2843 Q := Q + 1;
2844 end loop;
2846 Opt.Unix_String := new String'(SS (P .. Q - 1));
2847 Validate_Unix_Switch (Opt.Unix_String);
2848 P := Q + 1;
2849 end;
2850 end loop;
2851 end if;
2852 end;
2853 end loop;
2854 end;
2855 end loop;
2857 -- If no parameters, give complete list of commands
2859 if Argument_Count = 0 then
2860 Output_Version;
2861 New_Line;
2862 Put_Line ("List of available commands");
2863 New_Line;
2865 while Commands /= null loop
2866 Put (Commands.Usage.all);
2867 Set_Col (53);
2868 Put_Line (Commands.Unix_String.all);
2869 Commands := Commands.Next;
2870 end loop;
2872 raise Normal_Exit;
2873 end if;
2875 Arg_Num := 1;
2877 -- Loop through arguments
2879 while Arg_Num <= Argument_Count loop
2881 Process_Argument : declare
2882 Argv : String_Access;
2883 Arg_Idx : Integer;
2885 function Get_Arg_End
2886 (Argv : String;
2887 Arg_Idx : Integer)
2888 return Integer;
2889 -- Begins looking at Arg_Idx + 1 and returns the index of the
2890 -- last character before a slash or else the index of the last
2891 -- character in the string Argv.
2893 -----------------
2894 -- Get_Arg_End --
2895 -----------------
2897 function Get_Arg_End
2898 (Argv : String;
2899 Arg_Idx : Integer)
2900 return Integer
2902 begin
2903 for J in Arg_Idx + 1 .. Argv'Last loop
2904 if Argv (J) = '/' then
2905 return J - 1;
2906 end if;
2907 end loop;
2909 return Argv'Last;
2910 end Get_Arg_End;
2912 -- Start of processing for Process_Argument
2914 begin
2915 Argv := new String'(Argument (Arg_Num));
2916 Arg_Idx := Argv'First;
2918 <<Tryagain_After_Coalesce>>
2919 loop
2920 declare
2921 Next_Arg_Idx : Integer;
2922 Arg : String_Access;
2924 begin
2925 Next_Arg_Idx := Get_Arg_End (Argv.all, Arg_Idx);
2926 Arg := new String'(Argv (Arg_Idx .. Next_Arg_Idx));
2928 -- The first one must be a command name
2930 if Arg_Num = 1 and then Arg_Idx = Argv'First then
2932 Command := Matching_Name (Arg.all, Commands);
2934 if Command = null then
2935 raise Error_Exit;
2936 end if;
2938 The_Command := Command.Command;
2940 -- Give usage information if only command given
2942 if Argument_Count = 1 and then Next_Arg_Idx = Argv'Last
2943 and then Command.Command /= Standard
2944 then
2945 Output_Version;
2946 New_Line;
2947 Put_Line
2948 ("List of available qualifiers and options");
2949 New_Line;
2951 Put (Command.Usage.all);
2952 Set_Col (53);
2953 Put_Line (Command.Unix_String.all);
2955 declare
2956 Sw : Item_Ptr := Command.Switches;
2958 begin
2959 while Sw /= null loop
2960 Put (" ");
2961 Put (Sw.Name.all);
2963 case Sw.Translation is
2965 when T_Other =>
2966 Set_Col (53);
2967 Put_Line (Sw.Unix_String.all &
2968 "/<other>");
2970 when T_Direct =>
2971 Set_Col (53);
2972 Put_Line (Sw.Unix_String.all);
2974 when T_Directories =>
2975 Put ("=(direc,direc,..direc)");
2976 Set_Col (53);
2977 Put (Sw.Unix_String.all);
2978 Put (" direc ");
2979 Put (Sw.Unix_String.all);
2980 Put_Line (" direc ...");
2982 when T_Directory =>
2983 Put ("=directory");
2984 Set_Col (53);
2985 Put (Sw.Unix_String.all);
2987 if Sw.Unix_String (Sw.Unix_String'Last)
2988 /= '='
2989 then
2990 Put (' ');
2991 end if;
2993 Put_Line ("directory ");
2995 when T_File | T_No_Space_File =>
2996 Put ("=file");
2997 Set_Col (53);
2998 Put (Sw.Unix_String.all);
3000 if Sw.Translation = T_File
3001 and then Sw.Unix_String
3002 (Sw.Unix_String'Last)
3003 /= '='
3004 then
3005 Put (' ');
3006 end if;
3008 Put_Line ("file ");
3010 when T_Numeric =>
3011 Put ("=nnn");
3012 Set_Col (53);
3014 if Sw.Unix_String (Sw.Unix_String'First)
3015 = '`'
3016 then
3017 Put (Sw.Unix_String
3018 (Sw.Unix_String'First + 1
3019 .. Sw.Unix_String'Last));
3020 else
3021 Put (Sw.Unix_String.all);
3022 end if;
3024 Put_Line ("nnn");
3026 when T_Alphanumplus =>
3027 Put ("=xyz");
3028 Set_Col (53);
3030 if Sw.Unix_String (Sw.Unix_String'First)
3031 = '`'
3032 then
3033 Put (Sw.Unix_String
3034 (Sw.Unix_String'First + 1
3035 .. Sw.Unix_String'Last));
3036 else
3037 Put (Sw.Unix_String.all);
3038 end if;
3040 Put_Line ("xyz");
3042 when T_String =>
3043 Put ("=");
3044 Put ('"');
3045 Put ("<string>");
3046 Put ('"');
3047 Set_Col (53);
3049 Put (Sw.Unix_String.all);
3051 if Sw.Unix_String (Sw.Unix_String'Last)
3052 /= '='
3053 then
3054 Put (' ');
3055 end if;
3057 Put ("<string>");
3058 New_Line;
3060 when T_Commands =>
3061 Put (" (switches for ");
3062 Put (Sw.Unix_String
3063 (Sw.Unix_String'First + 7
3064 .. Sw.Unix_String'Last));
3065 Put (')');
3066 Set_Col (53);
3067 Put (Sw.Unix_String
3068 (Sw.Unix_String'First
3069 .. Sw.Unix_String'First + 5));
3070 Put_Line (" switches");
3072 when T_Options =>
3073 declare
3074 Opt : Item_Ptr := Sw.Options;
3076 begin
3077 Put_Line ("=(option,option..)");
3079 while Opt /= null loop
3080 Put (" ");
3081 Put (Opt.Name.all);
3083 if Opt = Sw.Options then
3084 Put (" (D)");
3085 end if;
3087 Set_Col (53);
3088 Put_Line (Opt.Unix_String.all);
3089 Opt := Opt.Next;
3090 end loop;
3091 end;
3093 end case;
3095 Sw := Sw.Next;
3096 end loop;
3097 end;
3099 raise Normal_Exit;
3100 end if;
3102 -- Place (Command.Unix_String.all);
3104 -- Special handling for internal debugging switch /?
3106 elsif Arg.all = "/?" then
3107 Display_Command := True;
3109 -- Copy -switch unchanged
3111 elsif Arg (Arg'First) = '-' then
3112 Place (' ');
3113 Place (Arg.all);
3115 -- Copy quoted switch with quotes stripped
3117 elsif Arg (Arg'First) = '"' then
3118 if Arg (Arg'Last) /= '"' then
3119 Put (Standard_Error, "misquoted argument: ");
3120 Put_Line (Standard_Error, Arg.all);
3121 Errors := Errors + 1;
3123 else
3124 Place (' ');
3125 Place (Arg (Arg'First + 1 .. Arg'Last - 1));
3126 end if;
3128 -- Parameter Argument
3130 elsif Arg (Arg'First) /= '/'
3131 and then Make_Commands_Active = null
3132 then
3133 Param_Count := Param_Count + 1;
3135 if Param_Count <= Command.Params'Length then
3137 case Command.Params (Param_Count) is
3139 when File | Optional_File =>
3140 declare
3141 Normal_File : String_Access
3142 := To_Canonical_File_Spec (Arg.all);
3143 begin
3144 Place (' ');
3145 Place_Lower (Normal_File.all);
3147 if Is_Extensionless (Normal_File.all)
3148 and then Command.Defext /= " "
3149 then
3150 Place ('.');
3151 Place (Command.Defext);
3152 end if;
3153 end;
3155 when Unlimited_Files =>
3156 declare
3157 Normal_File : String_Access
3158 := To_Canonical_File_Spec (Arg.all);
3160 File_Is_Wild : Boolean := False;
3161 File_List : String_Access_List_Access;
3162 begin
3163 for I in Arg'Range loop
3164 if Arg (I) = '*'
3165 or else Arg (I) = '%'
3166 then
3167 File_Is_Wild := True;
3168 end if;
3169 end loop;
3171 if File_Is_Wild then
3172 File_List := To_Canonical_File_List
3173 (Arg.all, False);
3175 for I in File_List.all'Range loop
3176 Place (' ');
3177 Place_Lower (File_List.all (I).all);
3178 end loop;
3179 else
3180 Place (' ');
3181 Place_Lower (Normal_File.all);
3183 if Is_Extensionless (Normal_File.all)
3184 and then Command.Defext /= " "
3185 then
3186 Place ('.');
3187 Place (Command.Defext);
3188 end if;
3189 end if;
3191 Param_Count := Param_Count - 1;
3192 end;
3194 when Other_As_Is =>
3195 Place (' ');
3196 Place (Arg.all);
3198 when Unlimited_As_Is =>
3199 Place (' ');
3200 Place (Arg.all);
3201 Param_Count := Param_Count - 1;
3203 when Files_Or_Wildcard =>
3205 -- Remove spaces from a comma separated list
3206 -- of file names and adjust control variables
3207 -- accordingly.
3209 while Arg_Num < Argument_Count and then
3210 (Argv (Argv'Last) = ',' xor
3211 Argument (Arg_Num + 1)
3212 (Argument (Arg_Num + 1)'First) = ',')
3213 loop
3214 Argv := new String'
3215 (Argv.all & Argument (Arg_Num + 1));
3216 Arg_Num := Arg_Num + 1;
3217 Arg_Idx := Argv'First;
3218 Next_Arg_Idx :=
3219 Get_Arg_End (Argv.all, Arg_Idx);
3220 Arg := new String'
3221 (Argv (Arg_Idx .. Next_Arg_Idx));
3222 end loop;
3224 -- Parse the comma separated list of VMS
3225 -- filenames and place them on the command
3226 -- line as space separated Unix style
3227 -- filenames. Lower case and add default
3228 -- extension as appropriate.
3230 declare
3231 Arg1_Idx : Integer := Arg'First;
3233 function Get_Arg1_End
3234 (Arg : String; Arg_Idx : Integer)
3235 return Integer;
3236 -- Begins looking at Arg_Idx + 1 and
3237 -- returns the index of the last character
3238 -- before a comma or else the index of the
3239 -- last character in the string Arg.
3241 function Get_Arg1_End
3242 (Arg : String; Arg_Idx : Integer)
3243 return Integer
3245 begin
3246 for I in Arg_Idx + 1 .. Arg'Last loop
3247 if Arg (I) = ',' then
3248 return I - 1;
3249 end if;
3250 end loop;
3252 return Arg'Last;
3253 end Get_Arg1_End;
3255 begin
3256 loop
3257 declare
3258 Next_Arg1_Idx : Integer :=
3259 Get_Arg1_End (Arg.all, Arg1_Idx);
3261 Arg1 : String :=
3262 Arg (Arg1_Idx .. Next_Arg1_Idx);
3264 Normal_File : String_Access :=
3265 To_Canonical_File_Spec (Arg1);
3267 begin
3268 Place (' ');
3269 Place_Lower (Normal_File.all);
3271 if Is_Extensionless (Normal_File.all)
3272 and then Command.Defext /= " "
3273 then
3274 Place ('.');
3275 Place (Command.Defext);
3276 end if;
3278 Arg1_Idx := Next_Arg1_Idx + 1;
3279 end;
3281 exit when Arg1_Idx > Arg'Last;
3283 -- Don't allow two or more commas in
3284 -- a row
3286 if Arg (Arg1_Idx) = ',' then
3287 Arg1_Idx := Arg1_Idx + 1;
3288 if Arg1_Idx > Arg'Last or else
3289 Arg (Arg1_Idx) = ','
3290 then
3291 Put_Line
3292 (Standard_Error,
3293 "Malformed Parameter: " &
3294 Arg.all);
3295 Put (Standard_Error, "usage: ");
3296 Put_Line (Standard_Error,
3297 Command.Usage.all);
3298 raise Error_Exit;
3299 end if;
3300 end if;
3302 end loop;
3303 end;
3304 end case;
3305 end if;
3307 -- Qualifier argument
3309 else
3310 declare
3311 Sw : Item_Ptr;
3312 SwP : Natural;
3313 P2 : Natural;
3314 Endp : Natural := 0; -- avoid warning!
3315 Opt : Item_Ptr;
3317 begin
3318 SwP := Arg'First;
3319 while SwP < Arg'Last
3320 and then Arg (SwP + 1) /= '='
3321 loop
3322 SwP := SwP + 1;
3323 end loop;
3325 -- At this point, the switch name is in
3326 -- Arg (Arg'First..SwP) and if that is not the
3327 -- whole switch, then there is an equal sign at
3328 -- Arg (SwP + 1) and the rest of Arg is what comes
3329 -- after the equal sign.
3331 -- If make commands are active, see if we have
3332 -- another COMMANDS_TRANSLATION switch belonging
3333 -- to gnatmake.
3335 if Make_Commands_Active /= null then
3336 Sw :=
3337 Matching_Name
3338 (Arg (Arg'First .. SwP),
3339 Command.Switches,
3340 Quiet => True);
3342 if Sw /= null
3343 and then Sw.Translation = T_Commands
3344 then
3345 null;
3347 else
3348 Sw :=
3349 Matching_Name
3350 (Arg (Arg'First .. SwP),
3351 Make_Commands_Active.Switches,
3352 Quiet => False);
3353 end if;
3355 -- For case of GNAT MAKE or CHOP, if we cannot
3356 -- find the switch, then see if it is a
3357 -- recognized compiler switch instead, and if
3358 -- so process the compiler switch.
3360 elsif Command.Name.all = "MAKE"
3361 or else Command.Name.all = "CHOP" then
3362 Sw :=
3363 Matching_Name
3364 (Arg (Arg'First .. SwP),
3365 Command.Switches,
3366 Quiet => True);
3368 if Sw = null then
3369 Sw :=
3370 Matching_Name
3371 (Arg (Arg'First .. SwP),
3372 Matching_Name
3373 ("COMPILE", Commands).Switches,
3374 Quiet => False);
3375 end if;
3377 -- For all other cases, just search the relevant
3378 -- command.
3380 else
3381 Sw :=
3382 Matching_Name
3383 (Arg (Arg'First .. SwP),
3384 Command.Switches,
3385 Quiet => False);
3386 end if;
3388 if Sw /= null then
3389 case Sw.Translation is
3391 when T_Direct =>
3392 Place_Unix_Switches (Sw.Unix_String);
3393 if SwP < Arg'Last
3394 and then Arg (SwP + 1) = '='
3395 then
3396 Put (Standard_Error,
3397 "qualifier options ignored: ");
3398 Put_Line (Standard_Error, Arg.all);
3399 end if;
3401 when T_Directories =>
3402 if SwP + 1 > Arg'Last then
3403 Put (Standard_Error,
3404 "missing directories for: ");
3405 Put_Line (Standard_Error, Arg.all);
3406 Errors := Errors + 1;
3408 elsif Arg (SwP + 2) /= '(' then
3409 SwP := SwP + 2;
3410 Endp := Arg'Last;
3412 elsif Arg (Arg'Last) /= ')' then
3414 -- Remove spaces from a comma separated
3415 -- list of file names and adjust
3416 -- control variables accordingly.
3418 if Arg_Num < Argument_Count and then
3419 (Argv (Argv'Last) = ',' xor
3420 Argument (Arg_Num + 1)
3421 (Argument (Arg_Num + 1)'First) = ',')
3422 then
3423 Argv :=
3424 new String'(Argv.all
3425 & Argument
3426 (Arg_Num + 1));
3427 Arg_Num := Arg_Num + 1;
3428 Arg_Idx := Argv'First;
3429 Next_Arg_Idx
3430 := Get_Arg_End (Argv.all, Arg_Idx);
3431 Arg := new String'
3432 (Argv (Arg_Idx .. Next_Arg_Idx));
3433 goto Tryagain_After_Coalesce;
3434 end if;
3436 Put (Standard_Error,
3437 "incorrectly parenthesized " &
3438 "or malformed argument: ");
3439 Put_Line (Standard_Error, Arg.all);
3440 Errors := Errors + 1;
3442 else
3443 SwP := SwP + 3;
3444 Endp := Arg'Last - 1;
3445 end if;
3447 while SwP <= Endp loop
3448 declare
3449 Dir_Is_Wild : Boolean := False;
3450 Dir_Maybe_Is_Wild : Boolean := False;
3451 Dir_List : String_Access_List_Access;
3452 begin
3453 P2 := SwP;
3455 while P2 < Endp
3456 and then Arg (P2 + 1) /= ','
3457 loop
3459 -- A wildcard directory spec on
3460 -- VMS will contain either * or
3461 -- % or ...
3463 if Arg (P2) = '*' then
3464 Dir_Is_Wild := True;
3466 elsif Arg (P2) = '%' then
3467 Dir_Is_Wild := True;
3469 elsif Dir_Maybe_Is_Wild
3470 and then Arg (P2) = '.'
3471 and then Arg (P2 + 1) = '.'
3472 then
3473 Dir_Is_Wild := True;
3474 Dir_Maybe_Is_Wild := False;
3476 elsif Dir_Maybe_Is_Wild then
3477 Dir_Maybe_Is_Wild := False;
3479 elsif Arg (P2) = '.'
3480 and then Arg (P2 + 1) = '.'
3481 then
3482 Dir_Maybe_Is_Wild := True;
3484 end if;
3486 P2 := P2 + 1;
3487 end loop;
3489 if (Dir_Is_Wild) then
3490 Dir_List := To_Canonical_File_List
3491 (Arg (SwP .. P2), True);
3493 for I in Dir_List.all'Range loop
3494 Place_Unix_Switches
3495 (Sw.Unix_String);
3496 Place_Lower
3497 (Dir_List.all (I).all);
3498 end loop;
3499 else
3500 Place_Unix_Switches
3501 (Sw.Unix_String);
3502 Place_Lower
3503 (To_Canonical_Dir_Spec
3504 (Arg (SwP .. P2), False).all);
3505 end if;
3507 SwP := P2 + 2;
3508 end;
3509 end loop;
3511 when T_Directory =>
3512 if SwP + 1 > Arg'Last then
3513 Put (Standard_Error,
3514 "missing directory for: ");
3515 Put_Line (Standard_Error, Arg.all);
3516 Errors := Errors + 1;
3518 else
3519 Place_Unix_Switches (Sw.Unix_String);
3521 -- Some switches end in "=". No space
3522 -- here
3524 if Sw.Unix_String
3525 (Sw.Unix_String'Last) /= '='
3526 then
3527 Place (' ');
3528 end if;
3530 Place_Lower
3531 (To_Canonical_Dir_Spec
3532 (Arg (SwP + 2 .. Arg'Last),
3533 False).all);
3534 end if;
3536 when T_File | T_No_Space_File =>
3537 if SwP + 1 > Arg'Last then
3538 Put (Standard_Error,
3539 "missing file for: ");
3540 Put_Line (Standard_Error, Arg.all);
3541 Errors := Errors + 1;
3543 else
3544 Place_Unix_Switches (Sw.Unix_String);
3546 -- Some switches end in "=". No space
3547 -- here.
3549 if Sw.Translation = T_File
3550 and then Sw.Unix_String
3551 (Sw.Unix_String'Last) /= '='
3552 then
3553 Place (' ');
3554 end if;
3556 Place_Lower
3557 (To_Canonical_File_Spec
3558 (Arg (SwP + 2 .. Arg'Last)).all);
3559 end if;
3561 when T_Numeric =>
3563 OK_Integer (Arg (SwP + 2 .. Arg'Last))
3564 then
3565 Place_Unix_Switches (Sw.Unix_String);
3566 Place (Arg (SwP + 2 .. Arg'Last));
3568 else
3569 Put (Standard_Error, "argument for ");
3570 Put (Standard_Error, Sw.Name.all);
3571 Put_Line
3572 (Standard_Error, " must be numeric");
3573 Errors := Errors + 1;
3574 end if;
3576 when T_Alphanumplus =>
3578 OK_Alphanumerplus
3579 (Arg (SwP + 2 .. Arg'Last))
3580 then
3581 Place_Unix_Switches (Sw.Unix_String);
3582 Place (Arg (SwP + 2 .. Arg'Last));
3584 else
3585 Put (Standard_Error, "argument for ");
3586 Put (Standard_Error, Sw.Name.all);
3587 Put_Line (Standard_Error,
3588 " must be alphanumeric");
3589 Errors := Errors + 1;
3590 end if;
3592 when T_String =>
3594 -- A String value must be extended to the
3595 -- end of the Argv, otherwise strings like
3596 -- "foo/bar" get split at the slash.
3598 -- The begining and ending of the string
3599 -- are flagged with embedded nulls which
3600 -- are removed when building the Spawn
3601 -- call. Nulls are use because they won't
3602 -- show up in a /? output. Quotes aren't
3603 -- used because that would make it
3604 -- difficult to embed them.
3606 Place_Unix_Switches (Sw.Unix_String);
3607 if Next_Arg_Idx /= Argv'Last then
3608 Next_Arg_Idx := Argv'Last;
3609 Arg := new String'
3610 (Argv (Arg_Idx .. Next_Arg_Idx));
3612 SwP := Arg'First;
3613 while SwP < Arg'Last and then
3614 Arg (SwP + 1) /= '=' loop
3615 SwP := SwP + 1;
3616 end loop;
3617 end if;
3618 Place (ASCII.NUL);
3619 Place (Arg (SwP + 2 .. Arg'Last));
3620 Place (ASCII.NUL);
3622 when T_Commands =>
3624 -- Output -largs/-bargs/-cargs
3626 Place (' ');
3627 Place (Sw.Unix_String
3628 (Sw.Unix_String'First ..
3629 Sw.Unix_String'First + 5));
3631 -- Set source of new commands, also
3632 -- setting this non-null indicates that
3633 -- we are in the special commands mode
3634 -- for processing the -xargs case.
3636 Make_Commands_Active :=
3637 Matching_Name
3638 (Sw.Unix_String
3639 (Sw.Unix_String'First + 7 ..
3640 Sw.Unix_String'Last),
3641 Commands);
3643 when T_Options =>
3644 if SwP + 1 > Arg'Last then
3645 Place_Unix_Switches
3646 (Sw.Options.Unix_String);
3647 SwP := Endp + 1;
3649 elsif Arg (SwP + 2) /= '(' then
3650 SwP := SwP + 2;
3651 Endp := Arg'Last;
3653 elsif Arg (Arg'Last) /= ')' then
3655 (Standard_Error,
3656 "incorrectly parenthesized " &
3657 "argument: ");
3658 Put_Line (Standard_Error, Arg.all);
3659 Errors := Errors + 1;
3660 SwP := Endp + 1;
3662 else
3663 SwP := SwP + 3;
3664 Endp := Arg'Last - 1;
3665 end if;
3667 while SwP <= Endp loop
3668 P2 := SwP;
3670 while P2 < Endp
3671 and then Arg (P2 + 1) /= ','
3672 loop
3673 P2 := P2 + 1;
3674 end loop;
3676 -- Option name is in Arg (SwP .. P2)
3678 Opt := Matching_Name (Arg (SwP .. P2),
3679 Sw.Options);
3681 if Opt /= null then
3682 Place_Unix_Switches
3683 (Opt.Unix_String);
3684 end if;
3686 SwP := P2 + 2;
3687 end loop;
3689 when T_Other =>
3690 Place_Unix_Switches
3691 (new String'(Sw.Unix_String.all &
3692 Arg.all));
3694 end case;
3695 end if;
3696 end;
3697 end if;
3699 Arg_Idx := Next_Arg_Idx + 1;
3700 end;
3702 exit when Arg_Idx > Argv'Last;
3704 end loop;
3705 end Process_Argument;
3707 Arg_Num := Arg_Num + 1;
3708 end loop;
3710 if Display_Command then
3711 Put (Standard_Error, "generated command -->");
3712 Put (Standard_Error, Command_List (The_Command).Unixcmd.all);
3714 if Command_List (The_Command).Unixsws /= null then
3715 for J in Command_List (The_Command).Unixsws'Range loop
3716 Put (Standard_Error, " ");
3717 Put (Standard_Error,
3718 Command_List (The_Command).Unixsws (J).all);
3719 end loop;
3720 end if;
3722 Put (Standard_Error, " ");
3723 Put (Standard_Error, String (Buffer.Table (1 .. Buffer.Last)));
3724 Put (Standard_Error, "<--");
3725 New_Line (Standard_Error);
3726 raise Normal_Exit;
3727 end if;
3729 -- Gross error checking that the number of parameters is correct.
3730 -- Not applicable to Unlimited_Files parameters.
3732 if (Param_Count = Command.Params'Length - 1
3733 and then Command.Params (Param_Count + 1) = Unlimited_Files)
3734 or else Param_Count <= Command.Params'Length
3735 then
3736 null;
3738 else
3739 Put_Line (Standard_Error,
3740 "Parameter count of "
3741 & Integer'Image (Param_Count)
3742 & " not equal to expected "
3743 & Integer'Image (Command.Params'Length));
3744 Put (Standard_Error, "usage: ");
3745 Put_Line (Standard_Error, Command.Usage.all);
3746 Errors := Errors + 1;
3747 end if;
3749 if Errors > 0 then
3750 raise Error_Exit;
3751 else
3752 -- Prepare arguments for a call to spawn, filtering out
3753 -- embedded nulls place there to delineate strings.
3755 declare
3756 P1, P2 : Natural;
3757 Inside_Nul : Boolean := False;
3758 Arg : String (1 .. 1024);
3759 Arg_Ctr : Natural;
3761 begin
3762 P1 := 1;
3764 while P1 <= Buffer.Last and then Buffer.Table (P1) = ' ' loop
3765 P1 := P1 + 1;
3766 end loop;
3768 Arg_Ctr := 1;
3769 Arg (Arg_Ctr) := Buffer.Table (P1);
3771 while P1 <= Buffer.Last loop
3773 if Buffer.Table (P1) = ASCII.NUL then
3774 if Inside_Nul then
3775 Inside_Nul := False;
3776 else
3777 Inside_Nul := True;
3778 end if;
3779 end if;
3781 if Buffer.Table (P1) = ' ' and then not Inside_Nul then
3782 P1 := P1 + 1;
3783 Arg_Ctr := Arg_Ctr + 1;
3784 Arg (Arg_Ctr) := Buffer.Table (P1);
3786 else
3787 Last_Switches.Increment_Last;
3788 P2 := P1;
3790 while P2 < Buffer.Last
3791 and then (Buffer.Table (P2 + 1) /= ' ' or else
3792 Inside_Nul)
3793 loop
3794 P2 := P2 + 1;
3795 Arg_Ctr := Arg_Ctr + 1;
3796 Arg (Arg_Ctr) := Buffer.Table (P2);
3797 if Buffer.Table (P2) = ASCII.NUL then
3798 Arg_Ctr := Arg_Ctr - 1;
3799 if Inside_Nul then
3800 Inside_Nul := False;
3801 else
3802 Inside_Nul := True;
3803 end if;
3804 end if;
3805 end loop;
3807 Last_Switches.Table (Last_Switches.Last) :=
3808 new String'(String (Arg (1 .. Arg_Ctr)));
3809 P1 := P2 + 2;
3810 Arg_Ctr := 1;
3811 Arg (Arg_Ctr) := Buffer.Table (P1);
3812 end if;
3813 end loop;
3814 end;
3815 end if;
3816 end VMS_Conversion;
3818 -------------------------------------
3819 -- Start of processing for GNATCmd --
3820 -------------------------------------
3822 begin
3823 -- Initializations
3825 Namet.Initialize;
3826 Csets.Initialize;
3828 Snames.Initialize;
3830 Prj.Initialize;
3832 Last_Switches.Init;
3833 Last_Switches.Set_Last (0);
3835 First_Switches.Init;
3836 First_Switches.Set_Last (0);
3838 -- If on VMS, or if VMS emulation is on, convert VMS style /qualifiers,
3839 -- filenames and pathnames to Unix style.
3841 if Hostparm.OpenVMS
3842 or else To_Lower (Getenv ("EMULATE_VMS").all) = "true"
3843 then
3844 VMS_Conversion (The_Command);
3846 -- If not on VMS, scan the command line directly
3848 else
3849 if Argument_Count = 0 then
3850 Non_VMS_Usage;
3851 return;
3852 else
3853 begin
3854 if Argument_Count > 1 and then Argument (1) = "-v" then
3855 Opt.Verbose_Mode := True;
3856 Command_Arg := 2;
3857 end if;
3859 The_Command := Real_Command_Type'Value (Argument (Command_Arg));
3861 if Command_List (The_Command).VMS_Only then
3862 Non_VMS_Usage;
3863 Fail ("Command """ & Command_List (The_Command).Cname.all &
3864 """ can only be used on VMS");
3865 end if;
3866 exception
3867 when Constraint_Error =>
3869 -- Check if it is an alternate command
3870 declare
3871 Alternate : Alternate_Command;
3873 begin
3874 Alternate := Alternate_Command'Value
3875 (Argument (Command_Arg));
3876 The_Command := Corresponding_To (Alternate);
3878 exception
3879 when Constraint_Error =>
3880 Non_VMS_Usage;
3881 Fail ("Unknown command: " & Argument (Command_Arg));
3882 end;
3883 end;
3885 for Arg in Command_Arg + 1 .. Argument_Count loop
3886 Last_Switches.Increment_Last;
3887 Last_Switches.Table (Last_Switches.Last) :=
3888 new String'(Argument (Arg));
3889 end loop;
3890 end if;
3891 end if;
3893 declare
3894 Program : constant String :=
3895 Program_Name (Command_List (The_Command).Unixcmd.all).all;
3897 Exec_Path : String_Access;
3899 begin
3900 -- Locate the executable for the command
3902 Exec_Path := Locate_Exec_On_Path (Program);
3904 if Exec_Path = null then
3905 Put_Line (Standard_Error, "Couldn't locate " & Program);
3906 raise Error_Exit;
3907 end if;
3909 -- If there are switches for the executable, put them as first switches
3911 if Command_List (The_Command).Unixsws /= null then
3912 for J in Command_List (The_Command).Unixsws'Range loop
3913 First_Switches.Increment_Last;
3914 First_Switches.Table (First_Switches.Last) :=
3915 Command_List (The_Command).Unixsws (J);
3916 end loop;
3917 end if;
3919 -- For BIND, FIND, LINK, LIST and XREF, look for project file related
3920 -- switches.
3922 if The_Command = Bind
3923 or else The_Command = Find
3924 or else The_Command = Link
3925 or else The_Command = List
3926 or else The_Command = Xref
3927 then
3928 case The_Command is
3929 when Bind =>
3930 Tool_Package_Name := Name_Binder;
3931 when Find =>
3932 Tool_Package_Name := Name_Finder;
3933 when Link =>
3934 Tool_Package_Name := Name_Linker;
3935 when List =>
3936 Tool_Package_Name := Name_Gnatls;
3937 when Xref =>
3938 Tool_Package_Name := Name_Cross_Reference;
3939 when others =>
3940 null;
3941 end case;
3943 declare
3944 Arg_Num : Positive := 1;
3945 Argv : String_Access;
3947 procedure Remove_Switch (Num : Positive);
3948 -- Remove a project related switch from table Last_Switches
3950 -------------------
3951 -- Remove_Switch --
3952 -------------------
3954 procedure Remove_Switch (Num : Positive) is
3955 begin
3956 Last_Switches.Table (Num .. Last_Switches.Last - 1) :=
3957 Last_Switches.Table (Num + 1 .. Last_Switches.Last);
3958 Last_Switches.Decrement_Last;
3959 end Remove_Switch;
3961 -- Start of processing for ??? (need block name here)
3963 begin
3964 while Arg_Num <= Last_Switches.Last loop
3965 Argv := Last_Switches.Table (Arg_Num);
3967 if Argv (Argv'First) = '-' then
3968 if Argv'Length = 1 then
3969 Fail ("switch character cannot be followed by a blank");
3970 end if;
3972 -- The two style project files (-p and -P) cannot be used
3973 -- together
3975 if (The_Command = Find or else The_Command = Xref)
3976 and then Argv (2) = 'p'
3977 then
3978 Old_Project_File_Used := True;
3979 if Project_File /= null then
3980 Fail ("-P and -p cannot be used together");
3981 end if;
3982 end if;
3984 -- -vPx Specify verbosity while parsing project files
3986 if Argv'Length = 4
3987 and then Argv (Argv'First + 1 .. Argv'First + 2) = "vP"
3988 then
3989 case Argv (Argv'Last) is
3990 when '0' =>
3991 Current_Verbosity := Prj.Default;
3992 when '1' =>
3993 Current_Verbosity := Prj.Medium;
3994 when '2' =>
3995 Current_Verbosity := Prj.High;
3996 when others =>
3997 Fail ("Invalid switch: " & Argv.all);
3998 end case;
4000 Remove_Switch (Arg_Num);
4002 -- -Pproject_file Specify project file to be used
4004 elsif Argv'Length >= 3
4005 and then Argv (Argv'First + 1) = 'P'
4006 then
4008 -- Only one -P switch can be used
4010 if Project_File /= null then
4011 Fail (Argv.all &
4012 ": second project file forbidden (first is """ &
4013 Project_File.all & """)");
4015 -- The two style project files (-p and -P) cannot be
4016 -- used together.
4018 elsif Old_Project_File_Used then
4019 Fail ("-p and -P cannot be used together");
4021 else
4022 Project_File :=
4023 new String'(Argv (Argv'First + 2 .. Argv'Last));
4024 end if;
4026 Remove_Switch (Arg_Num);
4028 -- -Xexternal=value Specify an external reference to be
4029 -- used in project files
4031 elsif Argv'Length >= 5
4032 and then Argv (Argv'First + 1) = 'X'
4033 then
4034 declare
4035 Equal_Pos : constant Natural :=
4036 Index ('=', Argv (Argv'First + 2 .. Argv'Last));
4037 begin
4038 if Equal_Pos >= Argv'First + 3 and then
4039 Equal_Pos /= Argv'Last then
4040 Add (External_Name =>
4041 Argv (Argv'First + 2 .. Equal_Pos - 1),
4042 Value => Argv (Equal_Pos + 1 .. Argv'Last));
4043 else
4044 Fail (Argv.all &
4045 " is not a valid external assignment.");
4046 end if;
4047 end;
4049 Remove_Switch (Arg_Num);
4051 else
4052 Arg_Num := Arg_Num + 1;
4053 end if;
4055 else
4056 Arg_Num := Arg_Num + 1;
4057 end if;
4058 end loop;
4059 end;
4060 end if;
4062 -- If there is a project file specified, parse it, get the switches
4063 -- for the tool and setup PATH environment variables.
4065 if Project_File /= null then
4066 Prj.Pars.Set_Verbosity (To => Current_Verbosity);
4068 Prj.Pars.Parse
4069 (Project => Project,
4070 Project_File_Name => Project_File.all);
4072 if Project = Prj.No_Project then
4073 Fail ("""" & Project_File.all & """ processing failed");
4074 end if;
4076 -- Check if a package with the name of the tool is in the project
4077 -- file and if there is one, get the switches, if any, and scan them.
4079 declare
4080 Data : Prj.Project_Data := Prj.Projects.Table (Project);
4081 Pkg : Prj.Package_Id :=
4082 Prj.Util.Value_Of
4083 (Name => Tool_Package_Name,
4084 In_Packages => Data.Decl.Packages);
4086 Element : Package_Element;
4088 Default_Switches_Array : Array_Element_Id;
4090 The_Switches : Prj.Variable_Value;
4091 Current : Prj.String_List_Id;
4092 The_String : String_Element;
4094 begin
4095 if Pkg /= No_Package then
4096 Element := Packages.Table (Pkg);
4098 -- Packages Gnatls has a single attribute Switches, that is
4099 -- not an associative array.
4101 if The_Command = List then
4102 The_Switches :=
4103 Prj.Util.Value_Of
4104 (Variable_Name => Snames.Name_Switches,
4105 In_Variables => Element.Decl.Attributes);
4107 -- Packages Binder (for gnatbind), Cross_Reference (for
4108 -- gnatxref), Linker (for gnatlink) and Finder
4109 -- (for gnatfind) have an attributed Default_Switches,
4110 -- an associative array, indexed by the name of the
4111 -- programming language.
4112 else
4113 Default_Switches_Array :=
4114 Prj.Util.Value_Of
4115 (Name => Name_Default_Switches,
4116 In_Arrays => Packages.Table (Pkg).Decl.Arrays);
4117 The_Switches := Prj.Util.Value_Of
4118 (Index => Name_Ada,
4119 In_Array => Default_Switches_Array);
4121 end if;
4123 -- If there are switches specified in the package of the
4124 -- project file corresponding to the tool, scan them.
4126 case The_Switches.Kind is
4127 when Prj.Undefined =>
4128 null;
4130 when Prj.Single =>
4131 if String_Length (The_Switches.Value) > 0 then
4132 String_To_Name_Buffer (The_Switches.Value);
4133 First_Switches.Increment_Last;
4134 First_Switches.Table (First_Switches.Last) :=
4135 new String'(Name_Buffer (1 .. Name_Len));
4136 end if;
4138 when Prj.List =>
4139 Current := The_Switches.Values;
4140 while Current /= Prj.Nil_String loop
4141 The_String := String_Elements.Table (Current);
4143 if String_Length (The_String.Value) > 0 then
4144 String_To_Name_Buffer (The_String.Value);
4145 First_Switches.Increment_Last;
4146 First_Switches.Table (First_Switches.Last) :=
4147 new String'(Name_Buffer (1 .. Name_Len));
4148 end if;
4150 Current := The_String.Next;
4151 end loop;
4152 end case;
4153 end if;
4154 end;
4156 -- Set up the environment variables ADA_INCLUDE_PATH and
4157 -- ADA_OBJECTS_PATH.
4159 Setenv
4160 (Name => Ada_Include_Path,
4161 Value => Prj.Env.Ada_Include_Path (Project).all);
4162 Setenv
4163 (Name => Ada_Objects_Path,
4164 Value => Prj.Env.Ada_Objects_Path
4165 (Project, Including_Libraries => False).all);
4167 if The_Command = Bind or else The_Command = Link then
4168 Change_Dir
4169 (Get_Name_String
4170 (Projects.Table (Project).Object_Directory));
4171 end if;
4173 if The_Command = Link then
4175 -- Add the default search directories, to be able to find
4176 -- libgnat in call to MLib.Utl.Lib_Directory.
4178 Add_Default_Search_Dirs;
4180 declare
4181 There_Are_Libraries : Boolean := False;
4183 begin
4184 -- Check if there are library project files
4186 if MLib.Tgt.Libraries_Are_Supported then
4187 Set_Libraries (Project, There_Are_Libraries);
4188 end if;
4190 -- If there are, add the necessary additional switches
4192 if There_Are_Libraries then
4194 -- Add -L<lib_dir> -lgnarl -lgnat -Wl,-rpath,<lib_dir>
4196 Last_Switches.Increment_Last;
4197 Last_Switches.Table (Last_Switches.Last) :=
4198 new String'("-L" & MLib.Utl.Lib_Directory);
4199 Last_Switches.Increment_Last;
4200 Last_Switches.Table (Last_Switches.Last) :=
4201 new String'("-lgnarl");
4202 Last_Switches.Increment_Last;
4203 Last_Switches.Table (Last_Switches.Last) :=
4204 new String'("-lgnat");
4206 declare
4207 Option : constant String_Access :=
4208 MLib.Tgt.Linker_Library_Path_Option
4209 (MLib.Utl.Lib_Directory);
4211 begin
4212 if Option /= null then
4213 Last_Switches.Increment_Last;
4214 Last_Switches.Table (Last_Switches.Last) :=
4215 Option;
4216 end if;
4217 end;
4218 end if;
4219 end;
4220 end if;
4221 end if;
4223 -- Gather all the arguments and invoke the executable
4225 declare
4226 The_Args : Argument_List
4227 (1 .. First_Switches.Last + Last_Switches.Last);
4228 Arg_Num : Natural := 0;
4229 begin
4230 for J in 1 .. First_Switches.Last loop
4231 Arg_Num := Arg_Num + 1;
4232 The_Args (Arg_Num) := First_Switches.Table (J);
4233 end loop;
4235 for J in 1 .. Last_Switches.Last loop
4236 Arg_Num := Arg_Num + 1;
4237 The_Args (Arg_Num) := Last_Switches.Table (J);
4238 end loop;
4240 if Opt.Verbose_Mode then
4241 Output.Write_Str (Exec_Path.all);
4243 for Arg in The_Args'Range loop
4244 Output.Write_Char (' ');
4245 Output.Write_Str (The_Args (Arg).all);
4246 end loop;
4248 Output.Write_Eol;
4249 end if;
4251 My_Exit_Status
4252 := Exit_Status (Spawn (Exec_Path.all, The_Args));
4253 raise Normal_Exit;
4254 end;
4255 end;
4257 exception
4258 when Error_Exit =>
4259 Set_Exit_Status (Failure);
4261 when Normal_Exit =>
4262 Set_Exit_Status (My_Exit_Status);
4264 end GNATCmd;