g-comlin.ads 51.2 KB
Newer Older
Richard Kenner committed
1 2 3 4 5 6 7 8
------------------------------------------------------------------------------
--                                                                          --
--                         GNAT COMPILER COMPONENTS                         --
--                                                                          --
--                    G N A T . C O M M A N D _ L I N E                     --
--                                                                          --
--                                 S p e c                                  --
--                                                                          --
Arnaud Charlet committed
9
--                     Copyright (C) 1999-2015, AdaCore                     --
Richard Kenner committed
10 11 12
--                                                                          --
-- GNAT is free software;  you can  redistribute it  and/or modify it under --
-- terms of the  GNU General Public License as published  by the Free Soft- --
Arnaud Charlet committed
13
-- ware  Foundation;  either version 3,  or (at your option) any later ver- --
Richard Kenner committed
14 15
-- sion.  GNAT is distributed in the hope that it will be useful, but WITH- --
-- OUT ANY WARRANTY;  without even the  implied warranty of MERCHANTABILITY --
Arnaud Charlet committed
16 17 18 19 20 21 22 23 24 25
-- or FITNESS FOR A PARTICULAR PURPOSE.                                     --
--                                                                          --
-- As a special exception under Section 7 of GPL version 3, you are granted --
-- additional permissions described in the GCC Runtime Library Exception,   --
-- version 3.1, as published by the Free Software Foundation.               --
--                                                                          --
-- You should have received a copy of the GNU General Public License and    --
-- a copy of the GCC Runtime Library Exception along with this program;     --
-- see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see    --
-- <http://www.gnu.org/licenses/>.                                          --
Richard Kenner committed
26
--                                                                          --
27 28
-- GNAT was originally developed  by the GNAT team at  New York University. --
-- Extensive contributions were provided by Ada Core Technologies Inc.      --
Richard Kenner committed
29 30 31
--                                                                          --
------------------------------------------------------------------------------

32
--  High level package for command line parsing and manipulation
Richard Kenner committed
33

Arnaud Charlet committed
34 35 36
----------------------------------------
-- Simple Parsing of the Command Line --
----------------------------------------
37 38 39 40 41 42

--  This package provides an interface for parsing command line arguments,
--  when they are either read from Ada.Command_Line or read from a string list.
--  As shown in the example below, one should first retrieve the switches
--  (special command line arguments starting with '-' by default) and their
--  parameters, and then the rest of the command line arguments.
43 44 45 46 47 48 49 50 51
--
--  While it may appear easy to parse the command line arguments with
--  Ada.Command_Line, there are in fact lots of special cases to handle in some
--  applications. Those are fully managed by GNAT.Command_Line. Among these are
--  switches with optional parameters, grouping switches (for instance "-ab"
--  might mean the same as "-a -b"), various characters to separate a switch
--  and its parameter (or none: "-a 1" and "-a1" are generally the same, which
--  can introduce confusion with grouped switches),...
--
Richard Kenner committed
52 53 54 55
--  begin
--     loop
--        case Getopt ("a b: ad") is  -- Accepts '-a', '-ad', or '-b argument'
--           when ASCII.NUL => exit;
56

Richard Kenner committed
57 58 59 60 61 62
--           when 'a' =>
--                 if Full_Switch = "a" then
--                    Put_Line ("Got a");
--                 else
--                    Put_Line ("Got ad");
--                 end if;
63

64
--           when 'b' => Put_Line ("Got b + " & Parameter);
65

Richard Kenner committed
66
--           when others =>
67
--              raise Program_Error; -- cannot occur
Richard Kenner committed
68 69
--        end case;
--     end loop;
70

Richard Kenner committed
71 72 73 74 75 76 77 78
--     loop
--        declare
--           S : constant String := Get_Argument (Do_Expansion => True);
--        begin
--           exit when S'Length = 0;
--           Put_Line ("Got " & S);
--        end;
--     end loop;
79

Richard Kenner committed
80 81 82 83
--  exception
--     when Invalid_Switch    => Put_Line ("Invalid Switch " & Full_Switch);
--     when Invalid_Parameter => Put_Line ("No parameter for " & Full_Switch);
--  end;
84

Arnaud Charlet committed
85 86 87
--------------
-- Sections --
--------------
Arnaud Charlet committed
88

Richard Kenner committed
89
--  A more complicated example would involve the use of sections for the
90 91
--  switches, as for instance in gnatmake. The same command line is used to
--  provide switches for several tools. Each tool recognizes its switches by
Arnaud Charlet committed
92
--  separating them with special switches that act as section separators.
93
--  Each section acts as a command line of its own.
94

Richard Kenner committed
95 96 97
--  begin
--     Initialize_Option_Scan ('-', False, "largs bargs cargs");
--     loop
98
--        --  Same loop as above to get switches and arguments
Richard Kenner committed
99
--     end loop;
100

Richard Kenner committed
101 102
--     Goto_Section ("bargs");
--     loop
103
--        --  Same loop as above to get switches and arguments
Arnaud Charlet committed
104
--        --  The supported switches in Getopt might be different
Richard Kenner committed
105
--     end loop;
106

Richard Kenner committed
107 108
--     Goto_Section ("cargs");
--     loop
109
--        --  Same loop as above to get switches and arguments
Arnaud Charlet committed
110
--        --  The supported switches in Getopt might be different
111 112 113
--     end loop;
--  end;

Arnaud Charlet committed
114 115 116
-------------------------------
-- Parsing a List of Strings --
-------------------------------
Arnaud Charlet committed
117

Arnaud Charlet committed
118 119 120 121 122 123
--  The examples above show how to parse the command line when the arguments
--  are read directly from Ada.Command_Line. However, these arguments can also
--  be read from a list of strings. This can be useful in several contexts,
--  either because your system does not support Ada.Command_Line, or because
--  you are manipulating other tools and creating their command lines by hand,
--  or for any other reason.
Arnaud Charlet committed
124

125 126 127 128 129 130 131 132 133 134 135 136 137
--  To create the list of strings, it is recommended to use
--  GNAT.OS_Lib.Argument_String_To_List.

--  The example below shows how to get the parameters from such a list. Note
--  also the use of '*' to get all the switches, and not report errors when an
--  unexpected switch was used by the user

--  declare
--     Parser : Opt_Parser;
--     Args : constant Argument_List_Access :=
--        GNAT.OS_Lib.Argument_String_To_List ("-g -O1 -Ipath");
--  begin
--     Initialize_Option_Scan (Parser, Args);
Arnaud Charlet committed
138
--     while Getopt ("* g O! I=", Parser) /= ASCII.NUL loop
139 140
--        Put_Line ("Switch " & Full_Switch (Parser)
--                  & " param=" & Parameter (Parser));
Richard Kenner committed
141
--     end loop;
142
--     Free (Parser);
Richard Kenner committed
143
--  end;
Arnaud Charlet committed
144

Arnaud Charlet committed
145 146 147
-------------------------------------------
-- High-Level Command Line Configuration --
-------------------------------------------
148

149 150 151 152
--  As shown above, the code is still relatively low-level. For instance, there
--  is no way to indicate which switches are related (thus if "-l" and "--long"
--  should have the same effect, your code will need to test for both cases).
--  Likewise, it is difficult to handle more advanced constructs, like:
153 154 155 156 157 158 159 160 161

--    * Specifying -gnatwa is the same as specifying -gnatwu -gnatwv, but
--      shorter and more readable

--    * All switches starting with -gnatw can be grouped, for instance one
--      can write -gnatwcd instead of -gnatwc -gnatwd.
--      Of course, this can be combined with the above and -gnatwacd is the
--      same as -gnatwc -gnatwd -gnatwu -gnatwv

162
--    * The switch -T is the same as -gnatwAB (same as -gnatwA -gnatwB)
163

164 165 166
--  With the above form of Getopt, you would receive "-gnatwa", "-T" or
--  "-gnatwcd" in the examples above, and thus you require additional manual
--  parsing of the switch.
167

168 169
--  Instead, this package provides the type Command_Line_Configuration, which
--  stores all the knowledge above. For instance:
170 171

--     Config : Command_Line_Configuration;
172
--     Define_Alias  (Config, "-gnatwa", "-gnatwu -gnatwv");
173 174 175
--     Define_Prefix (Config, "-gnatw");
--     Define_Alias  (Config, "-T",      "-gnatwAB");

176 177 178 179 180 181 182 183
--  You then need to specify all possible switches in your application by
--  calling Define_Switch, for instance:

--     Define_Switch (Config, "-gnatwu", Help => "warn on unused entities");
--     Define_Switch (Config, "-gnatwv", Help => "warn on unassigned var");
--     ...

--  Specifying the help message is optional, but makes it easy to then call
Arnaud Charlet committed
184 185
--  the function:

186
--     Display_Help (Config);
Arnaud Charlet committed
187

188 189
--  that will display a properly formatted help message for your application,
--  listing all possible switches. That way you have a single place in which
Ralf Wildenhues committed
190
--  to maintain the list of switches and their meaning, rather than maintaining
191 192 193
--  both the string to pass to Getopt and a subprogram to display the help.
--  Both will properly stay synchronized.

Arnaud Charlet committed
194 195
--  Once you have this Config, you just have to call:

196
--     Getopt (Config, Callback'Access);
Arnaud Charlet committed
197

198 199 200 201 202 203 204 205 206 207 208 209
--  to parse the command line. The Callback will be called for each switch
--  found on the command line (in the case of our example, that is "-gnatwu"
--  and then "-gnatwv", not "-gnatwa" itself). This simplifies command line
--  parsing a lot.

--  In fact, this can be further automated for the most command case where the
--  parameter passed to a switch is stored in a variable in the application.
--  When a switch is defined, you only have to indicate where to store the
--  value, and let Getopt do the rest. For instance:

--     Optimization : aliased Integer;
--     Verbose      : aliased Boolean;
Arnaud Charlet committed
210

211 212 213 214 215
--     Define_Switch (Config, Verbose'Access,
--                    "-v", Long_Switch => "--verbose",
--                    Help => "Output extra verbose information");
--     Define_Switch (Config, Optimization'Access,
--                    "-O?", Help => "Optimization level");
Arnaud Charlet committed
216

217 218 219 220 221 222 223
--     Getopt (Config);  --  No callback

--  Since all switches are handled automatically, we don't even need to pass
--  a callback to Getopt. Once getopt has been called, the two variables
--  Optimization and Verbose have been properly initialized, either to the
--  default value or to the value found on the command line.

Arnaud Charlet committed
224 225 226
------------------------------------------------
-- Creating and Manipulating the Command Line --
------------------------------------------------
227 228 229 230 231 232 233 234 235 236 237

--  This package provides mechanisms to create and modify command lines by
--  adding or removing arguments from them. The resulting command line is kept
--  as short as possible by coalescing arguments whenever possible.

--  Complex command lines can thus be constructed, for example from a GUI
--  (although this package does not by itself depend upon any specific GUI
--  toolkit).

--  Using the configuration defined earlier, one can then construct a command
--  line for the tool with:
Richard Kenner committed
238

239
--     Cmd : Command_Line;
240
--     Set_Configuration (Cmd, Config);   --  Config created earlier
241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269
--     Add_Switch (Cmd, "-bar");
--     Add_Switch (Cmd, "-gnatwu");
--     Add_Switch (Cmd, "-gnatwv");  --  will be grouped with the above
--     Add_Switch (Cmd, "-T");

--  The resulting command line can be iterated over to get all its switches,
--  There are two modes for this iteration: either you want to get the
--  shortest possible command line, which would be:

--      -bar -gnatwaAB

--  or on the other hand you want each individual switch (so that your own
--  tool does not have to do further complex processing), which would be:

--      -bar -gnatwu -gnatwv -gnatwA -gnatwB

--  Of course, we can assume that the tool you want to spawn would understand
--  both of these, since they are both compatible with the description we gave
--  above. However, the first result is useful if you want to show the user
--  what you are spawning (since that keeps the output shorter), and the second
--  output is more useful for a tool that would check whether -gnatwu was
--  passed (which isn't obvious in the first output). Likewise, the second
--  output is more useful if you have a graphical interface since each switch
--  can be associated with a widget, and you immediately know whether -gnatwu
--  was selected.
--
--  Some command line arguments can have parameters, which on a command line
--  appear as a separate argument that must immediately follow the switch.
--  Since the subprograms in this package will reorganize the switches to group
Arnaud Charlet committed
270 271
--  them, you need to indicate what is a command line parameter, and what is a
--  switch argument.
272 273 274

--  This is done by passing an extra argument to Add_Switch, as in:

Arnaud Charlet committed
275
--     Add_Switch (Cmd, "-foo", Parameter => "arg1");
276 277 278 279 280

--  This ensures that "arg1" will always be treated as the argument to -foo,
--  and will not be grouped with other parts of the command line.

with Ada.Command_Line;
Arnaud Charlet committed
281

Richard Kenner committed
282
with GNAT.Directory_Operations;
283
with GNAT.OS_Lib;
Richard Kenner committed
284
with GNAT.Regexp;
285
with GNAT.Strings;
Richard Kenner committed
286 287 288

package GNAT.Command_Line is

289 290 291 292 293 294 295 296 297 298 299 300 301 302 303
   -------------
   -- Parsing --
   -------------

   type Opt_Parser is private;
   Command_Line_Parser : constant Opt_Parser;
   --  This object is responsible for parsing a list of arguments, which by
   --  default are the standard command line arguments from Ada.Command_Line.
   --  This is really a pointer to actual data, which must therefore be
   --  initialized through a call to Initialize_Option_Scan, and must be freed
   --  with a call to Free.
   --
   --  As a special case, Command_Line_Parser does not need to be either
   --  initialized or free-ed.

Richard Kenner committed
304 305 306 307
   procedure Initialize_Option_Scan
     (Switch_Char              : Character := '-';
      Stop_At_First_Non_Switch : Boolean := False;
      Section_Delimiters       : String := "");
308 309 310 311 312 313 314
   procedure Initialize_Option_Scan
     (Parser                   : out Opt_Parser;
      Command_Line             : GNAT.OS_Lib.Argument_List_Access;
      Switch_Char              : Character := '-';
      Stop_At_First_Non_Switch : Boolean := False;
      Section_Delimiters       : String := "");
   --  The first procedure resets the internal state of the package to prepare
Arnaud Charlet committed
315 316 317 318
   --  to rescan the parameters. It does not need to be called before the
   --  first use of Getopt (but it could be), but it must be called if you
   --  want to start rescanning the command line parameters from the start.
   --  The optional parameter Switch_Char can be used to reset the switch
319 320
   --  character, e.g. to '/' for use in DOS-like systems.
   --
Arnaud Charlet committed
321 322 323
   --  The second subprogram initializes a parser that takes its arguments
   --  from an array of strings rather than directly from the command line. In
   --  this case, the parser is responsible for freeing the strings stored in
324 325
   --  Command_Line. If you pass null to Command_Line, this will in fact create
   --  a second parser for Ada.Command_Line, which doesn't share any data with
Arnaud Charlet committed
326
   --  the default parser. This parser must be free'ed.
327 328 329 330
   --
   --  The optional parameter Stop_At_First_Non_Switch indicates if Getopt is
   --  to look for switches on the whole command line, or if it has to stop as
   --  soon as a non-switch argument is found.
Richard Kenner committed
331 332 333 334 335
   --
   --  Example:
   --
   --      Arguments: my_application file1 -c
   --
336
   --      If Stop_At_First_Non_Switch is False, then -c will be considered
Richard Kenner committed
337 338 339
   --      as a switch (returned by getopt), otherwise it will be considered
   --      as a normal argument (returned by Get_Argument).
   --
Arnaud Charlet committed
340
   --  If Section_Delimiters is set, then every following subprogram
Richard Kenner committed
341 342 343 344
   --  (Getopt and Get_Argument) will only operate within a section, which
   --  is delimited by any of these delimiters or the end of the command line.
   --
   --  Example:
345
   --      Initialize_Option_Scan (Section_Delimiters => "largs bargs cargs");
Richard Kenner committed
346 347
   --
   --      Arguments on command line : my_application -c -bargs -d -e -largs -f
Arnaud Charlet committed
348
   --      This line contains three sections, the first one is the default one
Richard Kenner committed
349
   --      and includes only the '-c' switch, the second one is between -bargs
Arnaud Charlet committed
350
   --      and -largs and includes '-d -e' and the last one includes '-f'.
Richard Kenner committed
351

352 353 354 355 356 357 358
   procedure Free (Parser : in out Opt_Parser);
   --  Free the memory used by the parser. Calling this is not mandatory for
   --  the Command_Line_Parser

   procedure Goto_Section
     (Name   : String := "";
      Parser : Opt_Parser := Command_Line_Parser);
359
   --  Change the current section. The next Getopt or Get_Argument will start
360 361
   --  looking at the beginning of the section. An empty name ("") refers to
   --  the first section between the program name and the first section
Arnaud Charlet committed
362 363 364
   --  delimiter. If the section does not exist in Section_Delimiters, then
   --  Invalid_Section is raised. If the section does not appear on the command
   --  line, then it is treated as an empty section.
Richard Kenner committed
365

366 367
   function Full_Switch
     (Parser : Opt_Parser := Command_Line_Parser) return String;
Arnaud Charlet committed
368 369 370
   --  Returns the full name of the last switch found (Getopt only returns the
   --  first character). Does not include the Switch_Char ('-' by default),
   --  unless the "*" option of Getopt is used (see below).
Richard Kenner committed
371

372 373 374 375 376
   function Current_Section
     (Parser : Opt_Parser := Command_Line_Parser) return String;
   --  Return the name of the current section.
   --  The list of valid sections is defined through Initialize_Option_Scan

377 378
   function Getopt
     (Switches    : String;
379 380
      Concatenate : Boolean := True;
      Parser      : Opt_Parser := Command_Line_Parser) return Character;
381 382 383 384
   --  This function moves to the next switch on the command line (defined as
   --  switch character followed by a character within Switches, casing being
   --  significant). The result returned is the first character of the switch
   --  that is located. If there are no more switches in the current section,
Arnaud Charlet committed
385 386 387 388
   --  returns ASCII.NUL. If Concatenate is True (the default), the switches do
   --  not need to be separated by spaces (they can be concatenated if they do
   --  not require an argument, e.g. -ab is the same as two separate arguments
   --  -a -b).
Richard Kenner committed
389
   --
Arnaud Charlet committed
390 391
   --  Switches is a string of all the possible switches, separated by
   --  spaces. A switch can be followed by one of the following characters:
Richard Kenner committed
392 393
   --
   --   ':'  The switch requires a parameter. There can optionally be a space
394 395
   --        on the command line between the switch and its parameter.
   --
396
   --   '='  The switch requires a parameter. There can either be a '=' or a
397 398
   --        space on the command line between the switch and its parameter.
   --
Richard Kenner committed
399
   --   '!'  The switch requires a parameter, but there can be no space on the
400 401
   --        command line between the switch and its parameter.
   --
402
   --   '?'  The switch may have an optional parameter. There can be no space
403 404 405 406 407
   --        between the switch and its argument.
   --
   --        e.g. if Switches has the following value : "a? b",
   --        The command line can be:
   --
Richard Kenner committed
408 409 410 411 412
   --             -afoo    :  -a switch with 'foo' parameter
   --             -a foo   :  -a switch and another element on the
   --                           command line 'foo', returned by Get_Argument
   --
   --     Example: if Switches is "-a: -aO:", you can have the following
413 414
   --              command lines:
   --
Richard Kenner committed
415 416 417 418 419 420 421 422 423 424 425 426 427 428 429
   --                -aarg    :  'a' switch with 'arg' parameter
   --                -a arg   :  'a' switch with 'arg' parameter
   --                -aOarg   :  'aO' switch with 'arg' parameter
   --                -aO arg  :  'aO' switch with 'arg' parameter
   --
   --    Example:
   --
   --       Getopt ("a b: ac ad?")
   --
   --         accept either 'a' or 'ac' with no argument,
   --         accept 'b' with a required argument
   --         accept 'ad' with an optional argument
   --
   --  If the first item in switches is '*', then Getopt will catch
   --  every element on the command line that was not caught by any other
430 431 432 433
   --  switch. The character returned by GetOpt is '*', but Full_Switch
   --  contains the full command line argument, including leading '-' if there
   --  is one. If this character was not returned, there would be no way of
   --  knowing whether it is there or not.
Richard Kenner committed
434 435 436
   --
   --    Example
   --       Getopt ("* a b")
437
   --       If the command line is '-a -c toto.o -b', Getopt will return
Arnaud Charlet committed
438 439
   --       successively 'a', '*', '*' and 'b', with Full_Switch returning
   --       "a", "-c", "toto.o", and "b".
Richard Kenner committed
440 441 442
   --
   --  When Getopt encounters an invalid switch, it raises the exception
   --  Invalid_Switch and sets Full_Switch to return the invalid switch.
443
   --  When Getopt cannot find the parameter associated with a switch, it
Richard Kenner committed
444
   --  raises Invalid_Parameter, and sets Full_Switch to return the invalid
Arnaud Charlet committed
445
   --  switch.
Richard Kenner committed
446 447 448 449 450
   --
   --  Note: in case of ambiguity, e.g. switches a ab abc, then the longest
   --  matching switch is returned.
   --
   --  Arbitrary characters are allowed for switches, although it is
451
   --  strongly recommended to use only letters and digits for portability
Richard Kenner committed
452
   --  reasons.
453 454 455 456 457
   --
   --  When Concatenate is False, individual switches need to be separated by
   --  spaces.
   --
   --    Example
Arnaud Charlet committed
458 459 460
   --      Getopt ("a b", Concatenate => False)
   --      If the command line is '-ab', exception Invalid_Switch will be
   --      raised and Full_Switch will return "ab".
Richard Kenner committed
461

462 463 464
   function Get_Argument
     (Do_Expansion : Boolean := False;
      Parser       : Opt_Parser := Command_Line_Parser) return String;
Arnaud Charlet committed
465 466
   --  Returns the next element on the command line that is not a switch.  This
   --  function should not be called before Getopt has returned ASCII.NUL.
Richard Kenner committed
467
   --
Arnaud Charlet committed
468 469 470 471 472 473
   --  If Do_Expansion is True, then the parameter on the command line will
   --  be considered as a filename with wild cards, and will be expanded. The
   --  matching file names will be returned one at a time. This is useful in
   --  non-Unix systems for obtaining normal expansion of wild card references.
   --  When there are no more arguments on the command line, this function
   --  returns an empty string.
Richard Kenner committed
474

475 476
   function Parameter
     (Parser : Opt_Parser := Command_Line_Parser) return String;
Arnaud Charlet committed
477 478 479 480 481
   --  Returns parameter associated with the last switch returned by Getopt.
   --  If no parameter was associated with the last switch, or no previous call
   --  has been made to Get_Argument, raises Invalid_Parameter. If the last
   --  switch was associated with an optional argument and this argument was
   --  not found on the command line, Parameter returns an empty string.
Richard Kenner committed
482

483 484 485
   function Separator
     (Parser : Opt_Parser := Command_Line_Parser) return Character;
   --  The separator that was between the switch and its parameter. This is
Arnaud Charlet committed
486 487 488 489
   --  useful if you want to know exactly what was on the command line. This
   --  is in general a single character, set to ASCII.NUL if the switch and
   --  the parameter were concatenated. A space is returned if the switch and
   --  its argument were in two separate arguments.
490

Arnaud Charlet committed
491 492 493 494 495 496 497 498
   Invalid_Section : exception;
   --  Raised when an invalid section is selected by Goto_Section

   Invalid_Switch : exception;
   --  Raised when an invalid switch is detected in the command line

   Invalid_Parameter : exception;
   --  Raised when a parameter is missing, or an attempt is made to obtain a
Arnaud Charlet committed
499
   --  parameter for a switch that does not allow a parameter.
Arnaud Charlet committed
500 501 502 503

   -----------------------------------------
   -- Expansion of command line arguments --
   -----------------------------------------
Arnaud Charlet committed
504

Arnaud Charlet committed
505
   --  These subprograms take care of expanding globbing patterns on the
Arnaud Charlet committed
506 507 508 509
   --  command line. On Unix, such expansion is done by the shell before your
   --  application is called. But on Windows you must do this expansion
   --  yourself.

Richard Kenner committed
510 511 512 513 514 515 516 517
   type Expansion_Iterator is limited private;
   --  Type used during expansion of file names

   procedure Start_Expansion
     (Iterator     : out Expansion_Iterator;
      Pattern      : String;
      Directory    : String := "";
      Basic_Regexp : Boolean := True);
518
   --  Initialize a wild card expansion. The next calls to Expansion will
Richard Kenner committed
519 520
   --  return the next file name in Directory which match Pattern (Pattern
   --  is a regular expression, using only the Unix shell and DOS syntax if
521
   --  Basic_Regexp is True). When Directory is an empty string, the current
Richard Kenner committed
522
   --  directory is searched.
523
   --
524
   --  Pattern may contain directory separators (as in "src/*/*.ada").
525 526 527
   --  Subdirectories of Directory will also be searched, up to one
   --  hundred levels deep.
   --
Arnaud Charlet committed
528 529
   --  When Start_Expansion has been called, function Expansion should
   --  be called repeatedly until it returns an empty string, before
530 531
   --  Start_Expansion can be called again with the same Expansion_Iterator
   --  variable.
Richard Kenner committed
532 533

   function Expansion (Iterator : Expansion_Iterator) return String;
534
   --  Returns the next file in the directory matching the parameters given
Richard Kenner committed
535
   --  to Start_Expansion and updates Iterator to point to the next entry.
Arnaud Charlet committed
536
   --  Returns an empty string when there are no more files.
537
   --
Richard Kenner committed
538 539 540
   --  If Expansion is called again after an empty string has been returned,
   --  then the exception GNAT.Directory_Operations.Directory_Error is raised.

541 542 543
   -----------------
   -- Configuring --
   -----------------
Arnaud Charlet committed
544

Arnaud Charlet committed
545 546 547 548 549 550
   --  The following subprograms are used to manipulate a command line
   --  represented as a string (for instance "-g -O2"), as well as parsing
   --  the switches from such a string. They provide high-level configurations
   --  to define aliases (a switch is equivalent to one or more other switches)
   --  or grouping of switches ("-gnatyac" is equivalent to "-gnatya" and
   --  "-gnatyc").
Arnaud Charlet committed
551

Arnaud Charlet committed
552
   --  See the top of this file for examples on how to use these subprograms
553 554 555

   type Command_Line_Configuration is private;

556 557 558 559 560 561
   procedure Define_Section
     (Config  : in out Command_Line_Configuration;
      Section : String);
   --  Indicates a new switch section. All switches belonging to the same
   --  section are ordered together, preceded by the section. They are placed
   --  at the end of the command line (as in "gnatmake somefile.adb -cargs -g")
Arnaud Charlet committed
562 563 564 565
   --
   --  The section name should not include the leading '-'. So for instance in
   --  the case of gnatmake we would use:
   --
Arnaud Charlet committed
566 567
   --    Define_Section (Config, "cargs");
   --    Define_Section (Config, "bargs");
568

569 570 571
   procedure Define_Alias
     (Config   : in out Command_Line_Configuration;
      Switch   : String;
572 573
      Expanded : String;
      Section  : String := "");
574 575 576 577
   --  Indicates that whenever Switch appears on the command line, it should
   --  be expanded as Expanded. For instance, for the GNAT compiler switches,
   --  we would define "-gnatwa" as an alias for "-gnatwcfijkmopruvz", ie some
   --  default warnings to be activated.
Arnaud Charlet committed
578
   --
579 580
   --  This expansion is only done within the specified section, which must
   --  have been defined first through a call to [Define_Section].
581 582

   procedure Define_Prefix
Arnaud Charlet committed
583 584
     (Config : in out Command_Line_Configuration;
      Prefix : String);
585
   --  Indicates that all switches starting with the given prefix should be
Arnaud Charlet committed
586 587 588 589 590
   --  grouped. For instance, for the GNAT compiler we would define "-gnatw" as
   --  a prefix, so that "-gnatwu -gnatwv" can be grouped into "-gnatwuv" It is
   --  assumed that the remainder of the switch ("uv") is a set of characters
   --  whose order is irrelevant. In fact, this package will sort them
   --  alphabetically.
Arnaud Charlet committed
591
   --
Arnaud Charlet committed
592 593 594 595
   --  When grouping switches that accept arguments (for instance "-gnatyL!"
   --  as the definition, and "-gnatyaL12b" as the command line), only
   --  numerical arguments are accepted. The above is equivalent to
   --  "-gnatya -gnatyL12 -gnatyb".
596

597
   procedure Define_Switch
598 599 600 601
     (Config      : in out Command_Line_Configuration;
      Switch      : String := "";
      Long_Switch : String := "";
      Help        : String := "";
Arnaud Charlet committed
602 603
      Section     : String := "";
      Argument    : String := "ARG");
604 605
   --  Indicates a new switch. The format of this switch follows the getopt
   --  format (trailing ':', '?', etc for defining a switch with parameters).
606 607
   --
   --  Switch should also start with the leading '-' (or any other characters).
Arnaud Charlet committed
608 609
   --  If this character is not '-', you need to call Initialize_Option_Scan to
   --  set the proper character for the parser.
610 611
   --
   --  The switches defined in the command_line_configuration object are used
612
   --  when ungrouping switches with more that one character after the prefix.
613 614 615
   --
   --  Switch and Long_Switch (when specified) are aliases and can be used
   --  interchangeably. There is no check that they both take an argument or
Arnaud Charlet committed
616 617 618
   --  both take no argument. Switch can be set to "*" to indicate that any
   --  switch is supported (in which case Getopt will return '*', see its
   --  documentation).
619 620 621 622 623 624
   --
   --  Help is used by the Display_Help procedure to describe the supported
   --  switches.
   --
   --  In_Section indicates in which section the switch is valid (you need to
   --  first define the section through a call to Define_Section).
Arnaud Charlet committed
625 626 627
   --
   --  Argument is the name of the argument, as displayed in the automatic
   --  help message. It is always capitalized for consistency.
628

629 630 631 632 633 634 635 636 637 638 639
   procedure Define_Switch
     (Config      : in out Command_Line_Configuration;
      Output      : access Boolean;
      Switch      : String := "";
      Long_Switch : String := "";
      Help        : String := "";
      Section     : String := "";
      Value       : Boolean := True);
   --  See Define_Switch for a description of the parameters.
   --  When the switch is found on the command line, Getopt will set
   --  Output.all to Value.
Arnaud Charlet committed
640
   --
641 642 643
   --  Output is always initially set to "not Value", so that if the switch is
   --  not found on the command line, Output still has a valid value.
   --  The switch must not take any parameter.
Arnaud Charlet committed
644 645 646
   --
   --  Output must exist at least as long as Config, otherwise an erroneous
   --  memory access may occur.
647 648 649 650 651 652 653 654 655

   procedure Define_Switch
     (Config      : in out Command_Line_Configuration;
      Output      : access Integer;
      Switch      : String := "";
      Long_Switch : String := "";
      Help        : String := "";
      Section     : String := "";
      Initial     : Integer := 0;
Arnaud Charlet committed
656 657
      Default     : Integer := 1;
      Argument    : String := "ARG");
Arnaud Charlet committed
658 659 660 661 662
   --  See Define_Switch for a description of the parameters. When the
   --  switch is found on the command line, Getopt will set Output.all to the
   --  value of the switch's parameter. If the parameter is not an integer,
   --  Invalid_Parameter is raised.

663 664
   --  Output is always initialized to Initial. If the switch has an optional
   --  argument which isn't specified by the user, then Output will be set to
Arnaud Charlet committed
665
   --  Default. The switch must accept an argument.
666 667 668 669 670 671 672

   procedure Define_Switch
     (Config      : in out Command_Line_Configuration;
      Output      : access GNAT.Strings.String_Access;
      Switch      : String := "";
      Long_Switch : String := "";
      Help        : String := "";
Arnaud Charlet committed
673 674
      Section     : String := "";
      Argument    : String := "ARG");
675
   --  Set Output to the value of the switch's parameter when the switch is
Arnaud Charlet committed
676 677 678 679
   --  found on the command line. Output is always initialized to the empty
   --  string if it does not have a value already (otherwise it is left as is
   --  so that you can specify the default value directly in the declaration
   --  of the variable). The switch must accept an argument.
680 681

   procedure Set_Usage
Arnaud Charlet committed
682 683 684 685
     (Config   : in out Command_Line_Configuration;
      Usage    : String := "[switches] [arguments]";
      Help     : String := "";
      Help_Msg : String := "");
686
   --  Defines the general format of the call to the application, and a short
Arnaud Charlet committed
687 688 689
   --  help text. These are both displayed by Display_Help. When a non-empty
   --  Help_Msg is given, it is used by Display_Help instead of the
   --  automatically generated list of supported switches.
690 691 692

   procedure Display_Help (Config : Command_Line_Configuration);
   --  Display the help for the tool (ie its usage, and its supported switches)
693

694 695
   function Get_Switches
     (Config      : Command_Line_Configuration;
Arnaud Charlet committed
696 697
      Switch_Char : Character := '-';
      Section     : String := "") return String;
698 699 700 701 702
   --  Get the switches list as expected by Getopt, for a specific section of
   --  the command line. This list is built using all switches defined
   --  previously via Define_Switch above.

   function Section_Delimiters
Arnaud Charlet committed
703
     (Config : Command_Line_Configuration) return String;
704
   --  Return a string suitable for use in Initialize_Option_Scan
705

706 707 708
   procedure Free (Config : in out Command_Line_Configuration);
   --  Free the memory used by Config

709 710 711 712
   type Switch_Handler is access procedure
     (Switch    : String;
      Parameter : String;
      Section   : String);
Arnaud Charlet committed
713 714 715 716
   --  Called when a switch is found on the command line. Switch includes
   --  any leading '-' that was specified in Define_Switch. This is slightly
   --  different from the functional version of Getopt above, for which
   --  Full_Switch omits the first leading '-'.
717 718

   Exit_From_Command_Line : exception;
Arnaud Charlet committed
719 720
   --  Emitted when the program should exit. This is called when Getopt below
   --  has seen -h, --help or an invalid switch.
721 722

   procedure Getopt
Arnaud Charlet committed
723 724 725 726
     (Config      : Command_Line_Configuration;
      Callback    : Switch_Handler := null;
      Parser      : Opt_Parser := Command_Line_Parser;
      Concatenate : Boolean := True);
Arnaud Charlet committed
727 728 729
   --  Similar to the standard Getopt function. For each switch found on the
   --  command line, this calls Callback, if the switch is not handled
   --  automatically.
730 731 732 733 734 735 736
   --
   --  The list of valid switches are the ones from the configuration. The
   --  switches that were declared through Define_Switch with an Output
   --  parameter are never returned (and result in a modification of the Output
   --  variable). This function will in fact never call [Callback] if all
   --  switches were handled automatically and there is nothing left to do.
   --
Arnaud Charlet committed
737 738 739
   --  The option Concatenate is identical to the one of the standard Getopt
   --  function.
   --
740 741 742 743 744 745
   --  This procedure automatically adds -h and --help to the valid switches,
   --  to display the help message and raises Exit_From_Command_Line.
   --  If an invalid switch is specified on the command line, this procedure
   --  will display an error message and raises Invalid_Switch again.
   --
   --  This function automatically expands switches:
Arnaud Charlet committed
746 747 748 749 750 751 752 753 754
   --
   --    If Define_Prefix was called (for instance "-gnaty") and the user
   --    specifies "-gnatycb" on the command line, then Getopt returns
   --    "-gnatyc" and "-gnatyb" separately.
   --
   --    If Define_Alias was called (for instance "-gnatya = -gnatycb") then
   --    the latter is returned (in this case it also expands -gnaty as per
   --    the above.
   --
755 756 757 758 759 760 761
   --  The goal is to make handling as easy as possible by leaving as much
   --  work as possible to this package.
   --
   --  As opposed to the standard Getopt, this one will analyze all sections
   --  as defined by Define_Section, and automatically jump from one section to
   --  the next.

Arnaud Charlet committed
762 763 764
   ------------------------------
   -- Generating command lines --
   ------------------------------
Arnaud Charlet committed
765

Arnaud Charlet committed
766 767 768
   --  Once the command line configuration has been created, you can build your
   --  own command line. This will be done in general because you need to spawn
   --  external tools from your application.
Arnaud Charlet committed
769

Arnaud Charlet committed
770 771 772 773
   --  Although it could be done by concatenating strings, the following
   --  subprograms will properly take care of grouping switches when possible,
   --  so as to keep the command line as short as possible. They also provide a
   --  way to remove a switch from an existing command line.
Arnaud Charlet committed
774

775
   --  For instance:
Arnaud Charlet committed
776

777 778 779 780
   --      declare
   --         Config : Command_Line_Configuration;
   --         Line : Command_Line;
   --         Args : Argument_List_Access;
Arnaud Charlet committed
781

782 783 784 785
   --      begin
   --         Define_Switch (Config, "-gnatyc");
   --         Define_Switch (Config, ...);  --  for all valid switches
   --         Define_Prefix (Config, "-gnaty");
Arnaud Charlet committed
786

787 788 789 790 791 792 793 794
   --         Set_Configuration (Line, Config);
   --         Add_Switch (Line, "-O2");
   --         Add_Switch (Line, "-gnatyc");
   --         Add_Switch (Line, "-gnatyd");
   --
   --         Build (Line, Args);
   --         --   Args is now  ["-O2", "-gnatycd"]
   --      end;
795 796 797 798

   type Command_Line is private;

   procedure Set_Configuration
799 800 801 802
     (Cmd    : in out Command_Line;
      Config : Command_Line_Configuration);
   function Get_Configuration
     (Cmd : Command_Line) return Command_Line_Configuration;
Arnaud Charlet committed
803 804 805
   --  Set or retrieve the configuration used for that command line. The Config
   --  must have been initialized first, by calling one of the Define_Switches
   --  subprograms.
806

807 808 809 810 811 812 813 814 815
   procedure Set_Command_Line
     (Cmd                : in out Command_Line;
      Switches           : String;
      Getopt_Description : String    := "";
      Switch_Char        : Character := '-');
   --  Set the new content of the command line, by replacing the current
   --  version with Switches.
   --
   --  The parsing of Switches is done through calls to Getopt, by passing
Arnaud Charlet committed
816
   --  Getopt_Description as an argument. (A "*" is automatically prepended so
Arnaud Charlet committed
817 818 819
   --  that all switches and command line arguments are accepted). If a config
   --  was defined via Set_Configuration, the Getopt_Description parameter will
   --  be ignored.
820 821 822 823 824 825 826
   --
   --  To properly handle switches that take parameters, you should document
   --  them in Getopt_Description. Otherwise, the switch and its parameter will
   --  be recorded as two separate command line arguments as returned by a
   --  Command_Line_Iterator (which might be fine depending on your
   --  application).
   --
Arnaud Charlet committed
827 828
   --  If the command line has sections (such as -bargs -cargs), then they
   --  should be listed in the Sections parameter (as "-bargs -cargs").
829
   --
Arnaud Charlet committed
830
   --  This function can be used to reset Cmd by passing an empty string
Arnaud Charlet committed
831 832 833 834 835 836
   --
   --  If an invalid switch is found on the command line (ie wasn't defined in
   --  the configuration via Define_Switch), and the configuration wasn't set
   --  to accept all switches (by defining "*" as a valid switch), then an
   --  exception Invalid_Switch is raised. The exception message indicates the
   --  invalid switch.
837 838

   procedure Add_Switch
839 840 841
     (Cmd        : in out Command_Line;
      Switch     : String;
      Parameter  : String    := "";
842
      Separator  : Character := ASCII.NUL;
843 844
      Section    : String    := "";
      Add_Before : Boolean   := False);
845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861
   --  Add a new switch to the command line, and combine/group it with existing
   --  switches if possible. Nothing is done if the switch already exists with
   --  the same parameter.
   --
   --  If the Switch takes a parameter, the latter should be specified
   --  separately, so that the association between the two is always correctly
   --  recognized even if the order of switches on the command line changes.
   --  For instance, you should pass "--check=full" as ("--check", "full") so
   --  that Remove_Switch below can simply take "--check" in parameter. That
   --  will automatically remove "full" as well. The value of the parameter is
   --  never modified by this package.
   --
   --  On the other hand, you could decide to simply pass "--check=full" as
   --  the Switch above, and then pass no parameter. This means that you need
   --  to pass "--check=full" to Remove_Switch as well.
   --
   --  A Switch with a parameter will never be grouped with another switch to
Arnaud Charlet committed
862
   --  avoid ambiguities as to what the parameter applies to.
863
   --
864 865 866
   --  If the switch is part of a section, then it should be specified so that
   --  the switch is correctly placed in the command line, and the section
   --  added if not already present. For example, to add the -g switch into the
Arnaud Charlet committed
867 868
   --  -cargs section, you need to call (Cmd, "-g", Section => "-cargs").
   --
869 870 871 872 873
   --  [Separator], if specified, overrides the separator that was defined
   --  through Define_Switch. For instance, if the switch was defined as
   --  "-from:", the separator defaults to a space. But if your application
   --  uses unusual separators not supported by GNAT.Command_Line (for instance
   --  it requires ":"), you can specify this separator here.
Arnaud Charlet committed
874
   --
875 876
   --  For instance,
   --     Add_Switch(Cmd, "-from", "bar", ':')
Arnaud Charlet committed
877
   --
878 879
   --  results in
   --     -from:bar
Arnaud Charlet committed
880
   --
881 882 883 884 885 886 887
   --  rather than the default
   --     -from bar
   --
   --  Note however that Getopt doesn't know how to handle ":" as a separator.
   --  So the recommendation is to declare the switch as "-from!" (ie no
   --  space between the switch and its parameter). Then Getopt will return
   --  ":bar" as the parameter, and you can trim the ":" in your application.
Arnaud Charlet committed
888
   --
Arnaud Charlet committed
889 890
   --  Invalid_Section is raised if Section was not defined in the
   --  configuration of the command line.
891
   --
892 893
   --  Add_Before allows insertion of the switch at the beginning of the
   --  command line.
894

895
   procedure Add_Switch
896 897 898
     (Cmd        : in out Command_Line;
      Switch     : String;
      Parameter  : String    := "";
899
      Separator  : Character := ASCII.NUL;
900 901 902
      Section    : String    := "";
      Add_Before : Boolean   := False;
      Success    : out Boolean);
903
   --  Same as above, returning the status of the operation
904

905
   procedure Remove_Switch
906 907 908 909 910
     (Cmd           : in out Command_Line;
      Switch        : String;
      Remove_All    : Boolean := False;
      Has_Parameter : Boolean := False;
      Section       : String := "");
911 912 913 914 915 916 917 918 919
   --  Remove Switch from the command line, and ungroup existing switches if
   --  necessary.
   --
   --  The actual parameter to the switches are ignored. If for instance
   --  you are removing "-foo", then "-foo param1" and "-foo param2" can
   --  be removed.
   --
   --  If Remove_All is True, then all matching switches are removed, otherwise
   --  only the first matching one is removed.
920
   --
921
   --  If Has_Parameter is set to True, then only switches having a parameter
922 923
   --  are removed.
   --
924 925 926 927 928
   --  If the switch belongs to a section, then this section should be
   --  specified: Remove_Switch (Cmd_Line, "-g", Section => "-cargs") called
   --  on the command line "-g -cargs -g" will result in "-g", while if
   --  called with (Cmd_Line, "-g") this will result in "-cargs -g".
   --  If Remove_All is set, then both "-g" will be removed.
929 930

   procedure Remove_Switch
931 932 933 934 935 936 937 938 939 940
     (Cmd           : in out Command_Line;
      Switch        : String;
      Remove_All    : Boolean := False;
      Has_Parameter : Boolean := False;
      Section       : String  := "";
      Success       : out Boolean);
   --  Same as above, reporting the success of the operation (Success is False
   --  if no switch was removed).

   procedure Remove_Switch
941 942
     (Cmd       : in out Command_Line;
      Switch    : String;
943 944
      Parameter : String;
      Section   : String := "");
945 946 947
   --  Remove a switch with a specific parameter. If Parameter is the empty
   --  string, then only a switch with no parameter will be removed.

Arnaud Charlet committed
948 949 950
   procedure Free (Cmd : in out Command_Line);
   --  Free the memory used by Cmd

951
   ---------------
952
   -- Iteration --
953
   ---------------
Arnaud Charlet committed
954

Arnaud Charlet committed
955 956
   --  When a command line was created with the above, you can then iterate
   --  over its contents using the following iterator.
957 958 959 960 961 962

   type Command_Line_Iterator is private;

   procedure Start
     (Cmd      : in out Command_Line;
      Iter     : in out Command_Line_Iterator;
Arnaud Charlet committed
963
      Expanded : Boolean := False);
964 965 966 967 968 969 970 971
   --  Start iterating over the command line arguments. If Expanded is true,
   --  then the arguments are not grouped and no alias is used. For instance,
   --  "-gnatwv" and "-gnatwu" would be returned instead of "-gnatwuv".
   --
   --  The iterator becomes invalid if the command line is changed through a
   --  call to Add_Switch, Remove_Switch or Set_Command_Line.

   function Current_Switch    (Iter : Command_Line_Iterator) return String;
972 973
   function Is_New_Section    (Iter : Command_Line_Iterator) return Boolean;
   function Current_Section   (Iter : Command_Line_Iterator) return String;
974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989
   function Current_Separator (Iter : Command_Line_Iterator) return String;
   function Current_Parameter (Iter : Command_Line_Iterator) return String;
   --  Return the current switch and its parameter (or the empty string if
   --  there is no parameter or the switch was added through Add_Switch
   --  without specifying the parameter.
   --
   --  Separator is the string that goes between the switch and its separator.
   --  It could be the empty string if they should be concatenated, or a space
   --  for instance. When printing, you should not add any other character.

   function Has_More (Iter : Command_Line_Iterator) return Boolean;
   --  Return True if there are more switches to be returned

   procedure Next (Iter : in out Command_Line_Iterator);
   --  Move to the next switch

990 991 992 993 994
   procedure Build
     (Line        : in out Command_Line;
      Args        : out GNAT.OS_Lib.Argument_List_Access;
      Expanded    : Boolean := False;
      Switch_Char : Character := '-');
Arnaud Charlet committed
995 996 997 998 999
   --  This is a wrapper using the Command_Line_Iterator. It provides a simple
   --  way to get all switches (grouped as much as possible), and possibly
   --  create an Opt_Parser.
   --
   --  Args must be freed by the caller.
Arnaud Charlet committed
1000
   --
Arnaud Charlet committed
1001
   --  Expanded has the same meaning as in Start.
1002

Arnaud Charlet committed
1003 1004 1005 1006 1007
   procedure Try_Help;
   --  Output a message on standard error to indicate how to get the usage for
   --  the executable. This procedure should only be called when the executable
   --  accepts switch --help. When this procedure is called by executable xxx,
   --  the following message is displayed on standard error:
Arnaud Charlet committed
1008
   --      try "xxx --help" for more information.
Arnaud Charlet committed
1009

Richard Kenner committed
1010 1011
private

1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026
   Max_Depth : constant := 100;
   --  Maximum depth of subdirectories

   Max_Path_Length : constant := 1024;
   --  Maximum length of relative path

   type Depth is range 1 .. Max_Depth;

   type Level is record
      Name_Last : Natural := 0;
      Dir       : GNAT.Directory_Operations.Dir_Type;
   end record;

   type Level_Array is array (Depth) of Level;

1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042
   type Section_Number is new Natural range 0 .. 65534;
   for Section_Number'Size use 16;

   type Parameter_Type is record
      Arg_Num : Positive;
      First   : Positive;
      Last    : Positive;
      Extra   : Character;
   end record;

   type Is_Switch_Type is array (Natural range <>) of Boolean;
   pragma Pack (Is_Switch_Type);

   type Section_Type is array (Natural range <>) of Section_Number;
   pragma Pack (Section_Type);

Richard Kenner committed
1043
   type Expansion_Iterator is limited record
1044
      Start : Positive := 1;
1045 1046
      --  Position of the first character of the relative path to check against
      --  the pattern.
1047 1048 1049 1050 1051 1052 1053

      Dir_Name : String (1 .. Max_Path_Length);

      Current_Depth : Depth := 1;

      Levels : Level_Array;

Richard Kenner committed
1054
      Regexp : GNAT.Regexp.Regexp;
1055 1056 1057
      --  Regular expression built with the pattern

      Maximum_Depth : Depth := 1;
1058 1059
      --  The maximum depth of directories, reflecting the number of directory
      --  separators in the pattern.
Richard Kenner committed
1060 1061
   end record;

1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103
   type Opt_Parser_Data (Arg_Count : Natural) is record
      Arguments : GNAT.OS_Lib.Argument_List_Access;
      --  null if reading from the command line

      The_Parameter : Parameter_Type;
      The_Separator : Character;
      The_Switch    : Parameter_Type;
      --  This type and this variable are provided to store the current switch
      --  and parameter.

      Is_Switch : Is_Switch_Type (1 .. Arg_Count) := (others => False);
      --  Indicates wich arguments on the command line are considered not be
      --  switches or parameters to switches (leaving e.g. filenames,...)

      Section : Section_Type (1 .. Arg_Count) := (others => 1);
      --  Contains the number of the section associated with the current
      --  switch. If this number is 0, then it is a section delimiter, which is
      --  never returned by GetOpt.

      Current_Argument : Natural := 1;
      --  Number of the current argument parsed on the command line

      Current_Index : Natural := 1;
      --  Index in the current argument of the character to be processed

      Current_Section : Section_Number := 1;

      Expansion_It : aliased Expansion_Iterator;
      --  When Get_Argument is expanding a file name, this is the iterator used

      In_Expansion : Boolean := False;
      --  True if we are expanding a file

      Switch_Character : Character := '-';
      --  The character at the beginning of the command line arguments,
      --  indicating the beginning of a switch.

      Stop_At_First : Boolean := False;
      --  If it is True then Getopt stops at the first non-switch argument
   end record;

   Command_Line_Parser_Data : aliased Opt_Parser_Data
Arnaud Charlet committed
1104
                                        (Ada.Command_Line.Argument_Count);
1105 1106 1107 1108 1109 1110
   --  The internal data used when parsing the command line

   type Opt_Parser is access all Opt_Parser_Data;
   Command_Line_Parser : constant Opt_Parser :=
                           Command_Line_Parser_Data'Access;

1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121
   type Switch_Type is (Switch_Untyped,
                        Switch_Boolean,
                        Switch_Integer,
                        Switch_String);

   type Switch_Definition (Typ : Switch_Type := Switch_Untyped) is record
      Switch      : GNAT.OS_Lib.String_Access;
      Long_Switch : GNAT.OS_Lib.String_Access;
      Section     : GNAT.OS_Lib.String_Access;
      Help        : GNAT.OS_Lib.String_Access;

Arnaud Charlet committed
1122 1123 1124 1125
      Argument    : GNAT.OS_Lib.String_Access;
      --  null if "ARG".
      --  Name of the argument for this switch.

1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144
      case Typ is
         when Switch_Untyped =>
            null;
         when Switch_Boolean =>
            Boolean_Output : access Boolean;
            Boolean_Value  : Boolean;  --  will set Output to that value
         when Switch_Integer =>
            Integer_Output  : access Integer;
            Integer_Initial : Integer;
            Integer_Default : Integer;
         when Switch_String =>
            String_Output   : access GNAT.Strings.String_Access;
      end case;
   end record;
   type Switch_Definitions is array (Natural range <>) of Switch_Definition;
   type Switch_Definitions_List is access all Switch_Definitions;
   --  [Switch] includes the leading '-'

   type Alias_Definition is record
Arnaud Charlet committed
1145 1146 1147
      Alias     : GNAT.OS_Lib.String_Access;
      Expansion : GNAT.OS_Lib.String_Access;
      Section   : GNAT.OS_Lib.String_Access;
1148 1149 1150 1151
   end record;
   type Alias_Definitions is array (Natural range <>) of Alias_Definition;
   type Alias_Definitions_List is access all Alias_Definitions;

1152
   type Command_Line_Configuration_Record is record
Arnaud Charlet committed
1153
      Prefixes : GNAT.OS_Lib.Argument_List_Access;
1154 1155
      --  The list of prefixes

Arnaud Charlet committed
1156
      Sections : GNAT.OS_Lib.Argument_List_Access;
1157 1158
      --  The list of sections

Arnaud Charlet committed
1159 1160 1161 1162 1163
      Star_Switch : Boolean := False;
      --  Whether switches not described in this configuration should be
      --  returned to the user (True). If False, an exception Invalid_Switch
      --  is raised.

Arnaud Charlet committed
1164 1165 1166
      Aliases  : Alias_Definitions_List;
      Usage    : GNAT.OS_Lib.String_Access;
      Help     : GNAT.OS_Lib.String_Access;
Arnaud Charlet committed
1167
      Help_Msg : GNAT.OS_Lib.String_Access;
Arnaud Charlet committed
1168
      Switches : Switch_Definitions_List;
1169
      --  List of expected switches (Used when expanding switch groups)
1170 1171 1172 1173 1174 1175 1176 1177 1178
   end record;
   type Command_Line_Configuration is access Command_Line_Configuration_Record;

   type Command_Line is record
      Config   : Command_Line_Configuration;
      Expanded : GNAT.OS_Lib.Argument_List_Access;

      Params : GNAT.OS_Lib.Argument_List_Access;
      --  Parameter for the corresponding switch in Expanded. The first
1179
      --  character is the separator (or ASCII.NUL if there is no separator).
1180

1181
      Sections : GNAT.OS_Lib.Argument_List_Access;
1182 1183 1184 1185 1186
      --  The list of sections

      Coalesce          : GNAT.OS_Lib.Argument_List_Access;
      Coalesce_Params   : GNAT.OS_Lib.Argument_List_Access;
      Coalesce_Sections : GNAT.OS_Lib.Argument_List_Access;
1187 1188 1189 1190 1191
      --  Cached version of the command line. This is recomputed every time
      --  the command line changes. Switches are grouped as much as possible,
      --  and aliases are used to reduce the length of the command line. The
      --  parameters are not allocated, they point into Params, so they must
      --  not be freed.
1192 1193 1194 1195
   end record;

   type Command_Line_Iterator is record
      List     : GNAT.OS_Lib.Argument_List_Access;
1196
      Sections : GNAT.OS_Lib.Argument_List_Access;
1197 1198 1199 1200
      Params   : GNAT.OS_Lib.Argument_List_Access;
      Current  : Natural;
   end record;

Richard Kenner committed
1201
end GNAT.Command_Line;