------------------------------------------------------------------------------
--                                                                          --
--                         GNAT COMPILER COMPONENTS                         --
--                                                                          --
--                    G N A T . C O M M A N D _ L I N E                     --
--                                                                          --
--                                 B o d y                                  --
--                                                                          --
--          Copyright (C) 1999-2021, Free Software Foundation, Inc.         --
--                                                                          --
-- 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- --
-- ware  Foundation;  either version 3,  or (at your option) any later ver- --
-- sion.  GNAT is distributed in the hope that it will be useful, but WITH- --
-- OUT ANY WARRANTY;  without even the  implied warranty of MERCHANTABILITY --
-- 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/>.                                          --
--                                                                          --
-- GNAT was originally developed  by the GNAT team at  New York University. --
-- Extensive contributions were provided by Ada Core Technologies Inc.      --
--                                                                          --
------------------------------------------------------------------------------

with Ada.Characters.Handling;    use Ada.Characters.Handling;
with Ada.Strings.Unbounded;
with Ada.Text_IO;                use Ada.Text_IO;
with Ada.Unchecked_Deallocation;

with GNAT.Directory_Operations; use GNAT.Directory_Operations;
with GNAT.OS_Lib;               use GNAT.OS_Lib;

package body GNAT.Command_Line is

   --  General note: this entire body could use much more commenting. There
   --  are large sections of uncommented code throughout, and many formal
   --  parameters of local subprograms are not documented at all ???

   package CL renames Ada.Command_Line;

   type Switch_Parameter_Type is
     (Parameter_None,
      Parameter_With_Optional_Space,  --  ':' in getopt
      Parameter_With_Space_Or_Equal,  --  '=' in getopt
      Parameter_No_Space,             --  '!' in getopt
      Parameter_Optional);            --  '?' in getopt

   procedure Set_Parameter
     (Variable : out Parameter_Type;
      Arg_Num  : Positive;
      First    : Positive;
      Last     : Natural;
      Extra    : Character := ASCII.NUL);
   pragma Inline (Set_Parameter);
   --  Set the parameter that will be returned by Parameter below
   --
   --  Extra is a character that needs to be added when reporting Full_Switch.
   --  (it will in general be the switch character, for instance '-').
   --  Otherwise, Full_Switch will report 'f' instead of '-f'. In particular,
   --  it needs to be set when reporting an invalid switch or handling '*'.
   --
   --  Parameters need to be defined ???

   function Goto_Next_Argument_In_Section (Parser : Opt_Parser) return Boolean;
   --  Go to the next argument on the command line. If we are at the end of
   --  the current section, we want to make sure there is no other identical
   --  section on the command line (there might be multiple instances of
   --  -largs). Returns True iff there is another argument.

   function Get_File_Names_Case_Sensitive return Integer;
   pragma Import (C, Get_File_Names_Case_Sensitive,
                  "__gnat_get_file_names_case_sensitive");

   File_Names_Case_Sensitive : constant Boolean :=
                                 Get_File_Names_Case_Sensitive /= 0;

   procedure Canonical_Case_File_Name (S : in out String);
   --  Given a file name, converts it to canonical case form. For systems where
   --  file names are case sensitive, this procedure has no effect. If file
   --  names are not case sensitive (i.e. for example if you have the file
   --  "xyz.adb", you can refer to it as XYZ.adb or XyZ.AdB), then this call
   --  converts the given string to canonical all lower case form, so that two
   --  file names compare equal if they refer to the same file.

   procedure Internal_Initialize_Option_Scan
     (Parser                   : Opt_Parser;
      Switch_Char              : Character;
      Stop_At_First_Non_Switch : Boolean;
      Section_Delimiters       : String);
   --  Initialize Parser, which must have been allocated already

   function Argument (Parser : Opt_Parser; Index : Integer) return String;
   --  Return the index-th command line argument

   procedure Find_Longest_Matching_Switch
     (Switches          : String;
      Arg               : String;
      Index_In_Switches : out Integer;
      Switch_Length     : out Integer;
      Param             : out Switch_Parameter_Type);
   --  Return the Longest switch from Switches that at least partially matches
   --  Arg. Index_In_Switches is set to 0 if none matches. What are other
   --  parameters??? in particular Param is not always set???

   procedure Unchecked_Free is new Ada.Unchecked_Deallocation
     (Argument_List, Argument_List_Access);

   procedure Unchecked_Free is new Ada.Unchecked_Deallocation
     (Command_Line_Configuration_Record, Command_Line_Configuration);

   procedure Remove (Line : in out Argument_List_Access; Index : Integer);
   --  Remove a specific element from Line

   procedure Add
     (Line   : in out Argument_List_Access;
      Str    : String_Access;
      Before : Boolean := False);
   --  Add a new element to Line. If Before is True, the item is inserted at
   --  the beginning, else it is appended.

   procedure Add
     (Config : in out Command_Line_Configuration;
      Switch : Switch_Definition);
   procedure Add
     (Def   : in out Alias_Definitions_List;
      Alias : Alias_Definition);
   --  Add a new element to Def

   procedure Initialize_Switch_Def
     (Def         : out Switch_Definition;
      Switch      : String := "";
      Long_Switch : String := "";
      Help        : String := "";
      Section     : String := "";
      Argument    : String := "ARG");
   --  Initialize [Def] with the contents of the other parameters.
   --  This also checks consistency of the switch parameters, and will raise
   --  Invalid_Switch if they do not match.

   procedure Decompose_Switch
     (Switch         : String;
      Parameter_Type : out Switch_Parameter_Type;
      Switch_Last    : out Integer);
   --  Given a switch definition ("name:" for instance), extracts the type of
   --  parameter that is expected, and the name of the switch

   function Can_Have_Parameter (S : String) return Boolean;
   --  True if S can have a parameter

   function Require_Parameter (S : String) return Boolean;
   --  True if S requires a parameter

   function Actual_Switch (S : String) return String;
   --  Remove any possible trailing '!', ':', '?' and '='

   generic
      with procedure Callback
        (Simple_Switch : String;
         Separator     : String;
         Parameter     : String;
         Index         : Integer);  --  Index in Config.Switches, or -1
   procedure For_Each_Simple_Switch
     (Config    : Command_Line_Configuration;
      Section   : String;
      Switch    : String;
      Parameter : String  := "";
      Unalias   : Boolean := True);
   --  Breaks Switch into as simple switches as possible (expanding aliases and
   --  ungrouping common prefixes when possible), and call Callback for each of
   --  these.

   procedure Sort_Sections
     (Line     : not null GNAT.OS_Lib.Argument_List_Access;
      Sections : GNAT.OS_Lib.Argument_List_Access;
      Params   : GNAT.OS_Lib.Argument_List_Access);
   --  Reorder the command line switches so that the switches belonging to a
   --  section are grouped together.

   procedure Group_Switches
     (Cmd      : Command_Line;
      Result   : Argument_List_Access;
      Sections : Argument_List_Access;
      Params   : Argument_List_Access);
   --  Group switches with common prefixes whenever possible. Once they have
   --  been grouped, we also check items for possible aliasing.

   procedure Alias_Switches
     (Cmd    : Command_Line;
      Result : Argument_List_Access;
      Params : Argument_List_Access);
   --  When possible, replace one or more switches by an alias, i.e. a shorter
   --  version.

   function Looking_At
     (Type_Str  : String;
      Index     : Natural;
      Substring : String) return Boolean;
   --  Return True if the characters starting at Index in Type_Str are
   --  equivalent to Substring.

   generic
      with function Callback (S : String; Index : Integer) return Boolean;
   procedure Foreach_Switch
     (Config   : Command_Line_Configuration;
      Section  : String);
   --  Iterate over all switches defined in Config, for a specific section.
   --  Index is set to the index in Config.Switches. Stop iterating when
   --  Callback returns False.

   --------------
   -- Argument --
   --------------

   function Argument (Parser : Opt_Parser; Index : Integer) return String is
   begin
      if Parser.Arguments /= null then
         return Parser.Arguments (Index + Parser.Arguments'First - 1).all;
      else
         return CL.Argument (Index);
      end if;
   end Argument;

   ------------------------------
   -- Canonical_Case_File_Name --
   ------------------------------

   procedure Canonical_Case_File_Name (S : in out String) is
   begin
      if not File_Names_Case_Sensitive then
         for J in S'Range loop
            if S (J) in 'A' .. 'Z' then
               S (J) := Character'Val
                          (Character'Pos (S (J)) +
                            (Character'Pos ('a') - Character'Pos ('A')));
            end if;
         end loop;
      end if;
   end Canonical_Case_File_Name;

   ---------------
   -- Expansion --
   ---------------

   function Expansion (Iterator : Expansion_Iterator) return String is
      type Pointer is access all Expansion_Iterator;

      It   : constant Pointer := Iterator'Unrestricted_Access;
      S    : String (1 .. 1024);
      Last : Natural;

      Current : Depth := It.Current_Depth;
      NL      : Positive;

   begin
      --  It is assumed that a directory is opened at the current level.
      --  Otherwise GNAT.Directory_Operations.Directory_Error will be raised
      --  at the first call to Read.

      loop
         Read (It.Levels (Current).Dir, S, Last);

         --  If we have exhausted the directory, close it and go back one level

         if Last = 0 then
            Close (It.Levels (Current).Dir);

            --  If we are at level 1, we are finished; return an empty string

            if Current = 1 then
               return String'(1 .. 0 => ' ');

            --  Otherwise continue with the directory at the previous level

            else
               Current := Current - 1;
               It.Current_Depth := Current;
            end if;

         --  If this is a directory, that is neither "." or "..", attempt to
         --  go to the next level.

         elsif Is_Directory
                 (It.Dir_Name (1 .. It.Levels (Current).Name_Last) &
                    S (1 .. Last))
             and then S (1 .. Last) /= "."
             and then S (1 .. Last) /= ".."
         then
            --  We can go to the next level only if we have not reached the
            --  maximum depth,

            if Current < It.Maximum_Depth then
               NL := It.Levels (Current).Name_Last;

               --  And if relative path of this new directory is not too long

               if NL + Last + 1 < Max_Path_Length then
                  Current := Current + 1;
                  It.Current_Depth := Current;
                  It.Dir_Name (NL + 1 .. NL + Last) := S (1 .. Last);
                  NL := NL + Last + 1;
                  It.Dir_Name (NL) := Directory_Separator;
                  It.Levels (Current).Name_Last := NL;
                  Canonical_Case_File_Name (It.Dir_Name (1 .. NL));

                  --  Open the new directory, and read from it

                  GNAT.Directory_Operations.Open
                    (It.Levels (Current).Dir, It.Dir_Name (1 .. NL));
               end if;
            end if;
         end if;

         --  Check the relative path against the pattern

         --  Note that we try to match also against directory names, since
         --  clients of this function may expect to retrieve directories.

         declare
            Name : String :=
                     It.Dir_Name (It.Start .. It.Levels (Current).Name_Last)
                       & S (1 .. Last);

         begin
            Canonical_Case_File_Name (Name);

            --  If it matches return the relative path

            if GNAT.Regexp.Match (Name, Iterator.Regexp) then
               return Name;
            end if;
         end;
      end loop;
   end Expansion;

   ---------------------
   -- Current_Section --
   ---------------------

   function Current_Section
     (Parser : Opt_Parser := Command_Line_Parser) return String
   is
   begin
      if Parser.Current_Section = 1 then
         return "";
      end if;

      for Index in reverse 1 .. Integer'Min (Parser.Current_Argument - 1,
                                             Parser.Section'Last)
      loop
         if Parser.Section (Index) = 0 then
            return Argument (Parser, Index);
         end if;
      end loop;

      return "";
   end Current_Section;

   -----------------
   -- Full_Switch --
   -----------------

   function Full_Switch
     (Parser : Opt_Parser := Command_Line_Parser) return String
   is
   begin
      if Parser.The_Switch.Extra = ASCII.NUL then
         return Argument (Parser, Parser.The_Switch.Arg_Num)
           (Parser.The_Switch.First .. Parser.The_Switch.Last);
      else
         return Parser.The_Switch.Extra
           & Argument (Parser, Parser.The_Switch.Arg_Num)
           (Parser.The_Switch.First .. Parser.The_Switch.Last);
      end if;
   end Full_Switch;

   ------------------
   -- Get_Argument --
   ------------------

   function Get_Argument
     (Do_Expansion : Boolean := False;
      Parser       : Opt_Parser := Command_Line_Parser) return String
   is
      End_Of_Args : Boolean;
   begin
      return Get_Argument (Do_Expansion, Parser, End_Of_Args);
   end Get_Argument;

   ------------------
   -- Get_Argument --
   ------------------

   function Get_Argument
     (Do_Expansion     : Boolean    := False;
      Parser           : Opt_Parser := Command_Line_Parser;
      End_Of_Arguments : out Boolean) return String is
   begin
      End_Of_Arguments := False;

      if Parser.In_Expansion then
         declare
            S : constant String := Expansion (Parser.Expansion_It);
         begin
            if S'Length /= 0 then
               return S;
            else
               Parser.In_Expansion := False;
            end if;
         end;
      end if;

      if Parser.Current_Argument > Parser.Arg_Count then

         --  If this is the first time this function is called

         if Parser.Current_Index = 1 then
            Parser.Current_Argument := 1;
            while Parser.Current_Argument <= Parser.Arg_Count
              and then Parser.Section (Parser.Current_Argument) /=
                                                      Parser.Current_Section
            loop
               Parser.Current_Argument := Parser.Current_Argument + 1;
            end loop;

         else
            End_Of_Arguments := True;
            return String'(1 .. 0 => ' ');
         end if;

      elsif Parser.Section (Parser.Current_Argument) = 0 then
         while Parser.Current_Argument <= Parser.Arg_Count
           and then Parser.Section (Parser.Current_Argument) /=
                                                      Parser.Current_Section
         loop
            Parser.Current_Argument := Parser.Current_Argument + 1;
         end loop;
      end if;

      Parser.Current_Index := Integer'Last;

      while Parser.Current_Argument <= Parser.Arg_Count
        and then Parser.Is_Switch (Parser.Current_Argument)
      loop
         Parser.Current_Argument := Parser.Current_Argument + 1;
      end loop;

      if Parser.Current_Argument > Parser.Arg_Count then
         End_Of_Arguments := True;
         return String'(1 .. 0 => ' ');

      elsif Parser.Section (Parser.Current_Argument) = 0 then
         return Get_Argument (Do_Expansion, Parser, End_Of_Arguments);
      end if;

      Parser.Current_Argument := Parser.Current_Argument + 1;

      --  Could it be a file name with wildcards to expand?

      if Do_Expansion then
         declare
            Arg   : constant String :=
                      Argument (Parser, Parser.Current_Argument - 1);
         begin
            for Index in Arg'Range loop
               if Arg (Index) in '*' | '?' | '[' then
                  Parser.In_Expansion := True;
                  Start_Expansion (Parser.Expansion_It, Arg);
                  return Get_Argument (Do_Expansion, Parser, End_Of_Arguments);
               end if;
            end loop;
         end;
      end if;

      return Argument (Parser, Parser.Current_Argument - 1);
   end Get_Argument;

   ----------------------
   -- Decompose_Switch --
   ----------------------

   procedure Decompose_Switch
     (Switch         : String;
      Parameter_Type : out Switch_Parameter_Type;
      Switch_Last    : out Integer)
   is
   begin
      if Switch = "" then
         Parameter_Type := Parameter_None;
         Switch_Last := Switch'Last;
         return;
      end if;

      case Switch (Switch'Last) is
         when ':' =>
            Parameter_Type := Parameter_With_Optional_Space;
            Switch_Last    := Switch'Last - 1;

         when '=' =>
            Parameter_Type := Parameter_With_Space_Or_Equal;
            Switch_Last    := Switch'Last - 1;

         when '!' =>
            Parameter_Type := Parameter_No_Space;
            Switch_Last    := Switch'Last - 1;

         when '?' =>
            Parameter_Type := Parameter_Optional;
            Switch_Last    := Switch'Last - 1;

         when others =>
            Parameter_Type := Parameter_None;
            Switch_Last    := Switch'Last;
      end case;
   end Decompose_Switch;

   ----------------------------------
   -- Find_Longest_Matching_Switch --
   ----------------------------------

   procedure Find_Longest_Matching_Switch
     (Switches          : String;
      Arg               : String;
      Index_In_Switches : out Integer;
      Switch_Length     : out Integer;
      Param             : out Switch_Parameter_Type)
   is
      Index  : Natural;
      Length : Natural := 1;
      Last   : Natural;
      P      : Switch_Parameter_Type;

   begin
      Param             := Parameter_None;
      Index_In_Switches := 0;
      Switch_Length     := 0;

      --  Remove all leading spaces first to make sure that Index points
      --  at the start of the first switch.

      Index := Switches'First;
      while Index <= Switches'Last and then Switches (Index) = ' ' loop
         Index := Index + 1;
      end loop;

      while Index <= Switches'Last loop

         --  Search the length of the parameter at this position in Switches

         Length := Index;
         while Length <= Switches'Last
           and then Switches (Length) /= ' '
         loop
            Length := Length + 1;
         end loop;

         --  Length now marks the separator after the current switch. Last will
         --  mark the last character of the name of the switch.

         if Length = Index + 1 then
            P := Parameter_None;
            Last := Index;
         else
            Decompose_Switch (Switches (Index .. Length - 1), P, Last);
         end if;

         --  If it is the one we searched, it may be a candidate

         if Arg'First + Last - Index <= Arg'Last
           and then Switches (Index .. Last) =
                      Arg (Arg'First .. Arg'First + Last - Index)
           and then Last - Index + 1 > Switch_Length
           and then
             (P /= Parameter_With_Space_Or_Equal
               or else Arg'Last = Arg'First + Last - Index
               or else Arg (Arg'First + Last - Index + 1) = '=')
         then
            Param             := P;
            Index_In_Switches := Index;
            Switch_Length     := Last - Index + 1;
         end if;

         --  Look for the next switch in Switches

         while Index <= Switches'Last
           and then Switches (Index) /= ' '
         loop
            Index := Index + 1;
         end loop;

         Index := Index + 1;
      end loop;
   end Find_Longest_Matching_Switch;

   ------------
   -- Getopt --
   ------------

   function Getopt
     (Switches    : String;
      Concatenate : Boolean := True;
      Parser      : Opt_Parser := Command_Line_Parser) return Character
   is
      Dummy : Boolean;

   begin
      <<Restart>>

      --  If we have finished parsing the current command line item (there
      --  might be multiple switches in a single item), then go to the next
      --  element.

      if Parser.Current_Argument > Parser.Arg_Count
        or else (Parser.Current_Index >
                   Argument (Parser, Parser.Current_Argument)'Last
                 and then not Goto_Next_Argument_In_Section (Parser))
      then
         return ASCII.NUL;
      end if;

      --  By default, the switch will not have a parameter

      Parser.The_Parameter :=
        (Integer'Last, Integer'Last, Integer'Last - 1, ASCII.NUL);
      Parser.The_Separator := ASCII.NUL;

      declare
         Arg            : constant String :=
                            Argument (Parser, Parser.Current_Argument);
         Index_Switches : Natural := 0;
         Max_Length     : Natural := 0;
         End_Index      : Natural;
         Param          : Switch_Parameter_Type;
      begin
         --  If we are on a new item, test if this might be a switch

         if Parser.Current_Index = Arg'First then
            if Arg = "" or else Arg (Arg'First) /= Parser.Switch_Character then

               --  If it isn't a switch, return it immediately. We also know it
               --  isn't the parameter to a previous switch, since that has
               --  already been handled.

               if Switches (Switches'First) = '*' then
                  Set_Parameter
                    (Parser.The_Switch,
                     Arg_Num => Parser.Current_Argument,
                     First   => Arg'First,
                     Last    => Arg'Last);
                  Parser.Is_Switch (Parser.Current_Argument) := True;
                  Dummy := Goto_Next_Argument_In_Section (Parser);
                  return '*';
               end if;

               if Parser.Stop_At_First then
                  Parser.Current_Argument := Positive'Last;
                  return ASCII.NUL;

               elsif not Goto_Next_Argument_In_Section (Parser) then
                  return ASCII.NUL;

               else
                  --  Recurse to get the next switch on the command line

                  goto Restart;
               end if;
            end if;

            --  We are on the first character of a new command line argument,
            --  which starts with Switch_Character. Further analysis is needed.

            Parser.Current_Index := Parser.Current_Index + 1;
            Parser.Is_Switch (Parser.Current_Argument) := True;
         end if;

         Find_Longest_Matching_Switch
           (Switches          => Switches,
            Arg               => Arg (Parser.Current_Index .. Arg'Last),
            Index_In_Switches => Index_Switches,
            Switch_Length     => Max_Length,
            Param             => Param);

         --  If switch is not accepted, it is either invalid or is returned
         --  in the context of '*'.

         if Index_Switches = 0 then

            --  Find the current switch that we did not recognize. This is in
            --  fact difficult because Getopt does not know explicitly about
            --  short and long switches. Ideally, we would want the following
            --  behavior:

            --      * for short switches, with Concatenate:
            --        if -a is not recognized, and the command line has -daf
            --        we should report the invalid switch as "-a".

            --      * for short switches, wihtout Concatenate:
            --        we should report the invalid switch as "-daf".

            --      * for long switches:
            --        if the commadn line is "--long" we should report --long
            --        as unrecongized.

            --  Unfortunately, the fact that long switches start with a
            --  duplicate switch character is just a convention (so we could
            --  have a long switch "-long" for instance). We'll still rely on
            --  this convention here to try and get as helpful an error message
            --  as possible.

            --  Long switch case (starting with double switch character)

            if Arg (Arg'First + 1) = Parser.Switch_Character then
               End_Index := Arg'Last;

            --  Short switch case

            else
               End_Index :=
                 (if Concatenate then Parser.Current_Index else Arg'Last);
            end if;

            if Switches /= "" and then Switches (Switches'First) = '*' then

               --  Always prepend the switch character, so that users know
               --  that this comes from a switch on the command line. This
               --  is especially important when Concatenate is False, since
               --  otherwise the current argument first character is lost.

               if Parser.Section (Parser.Current_Argument) = 0 then

                  --  A section transition should not be returned to the user

                  Dummy := Goto_Next_Argument_In_Section (Parser);
                  goto Restart;

               else
                  Set_Parameter
                    (Parser.The_Switch,
                     Arg_Num => Parser.Current_Argument,
                     First   => Parser.Current_Index,
                     Last    => Arg'Last,
                     Extra   => Parser.Switch_Character);
                  Parser.Is_Switch (Parser.Current_Argument) := True;
                  Dummy := Goto_Next_Argument_In_Section (Parser);
                  return '*';
               end if;
            end if;

            if Parser.Current_Index = Arg'First then
               Set_Parameter
                 (Parser.The_Switch,
                  Arg_Num => Parser.Current_Argument,
                  First   => Parser.Current_Index,
                  Last    => End_Index);
            else
               Set_Parameter
                 (Parser.The_Switch,
                  Arg_Num => Parser.Current_Argument,
                  First   => Parser.Current_Index,
                  Last    => End_Index,
                  Extra   => Parser.Switch_Character);
            end if;

            Parser.Current_Index := End_Index + 1;

            raise Invalid_Switch with
              "Unrecognized option '" & Full_Switch (Parser) & ''';
         end if;

         End_Index := Parser.Current_Index + Max_Length - 1;
         Set_Parameter
           (Parser.The_Switch,
            Arg_Num => Parser.Current_Argument,
            First   => Parser.Current_Index,
            Last    => End_Index);

         case Param is
            when Parameter_With_Optional_Space =>
               if End_Index < Arg'Last then
                  Set_Parameter
                    (Parser.The_Parameter,
                     Arg_Num => Parser.Current_Argument,
                     First   => End_Index + 1,
                     Last    => Arg'Last);
                  Dummy := Goto_Next_Argument_In_Section (Parser);

               elsif Parser.Current_Argument < Parser.Arg_Count
                 and then Parser.Section (Parser.Current_Argument + 1) /= 0
               then
                  Parser.Current_Argument := Parser.Current_Argument + 1;
                  Parser.The_Separator := ' ';
                  Set_Parameter
                    (Parser.The_Parameter,
                     Arg_Num => Parser.Current_Argument,
                     First => Argument (Parser, Parser.Current_Argument)'First,
                     Last  => Argument (Parser, Parser.Current_Argument)'Last);
                  Parser.Is_Switch (Parser.Current_Argument) := True;
                  Dummy := Goto_Next_Argument_In_Section (Parser);

               else
                  Parser.Current_Index := End_Index + 1;
                  raise Invalid_Parameter;
               end if;

            when Parameter_With_Space_Or_Equal =>

               --  If the switch is of the form <switch>=xxx

               if End_Index < Arg'Last then
                  if Arg (End_Index + 1) = '='
                    and then End_Index + 1 < Arg'Last
                  then
                     Parser.The_Separator := '=';
                     Set_Parameter
                       (Parser.The_Parameter,
                        Arg_Num => Parser.Current_Argument,
                        First   => End_Index + 2,
                        Last    => Arg'Last);
                     Dummy := Goto_Next_Argument_In_Section (Parser);

                  else
                     Parser.Current_Index := End_Index + 1;
                     raise Invalid_Parameter;
                  end if;

               --  Case of switch of the form <switch> xxx

               elsif Parser.Current_Argument < Parser.Arg_Count
                 and then Parser.Section (Parser.Current_Argument + 1) /= 0
               then
                  Parser.Current_Argument := Parser.Current_Argument + 1;
                  Parser.The_Separator := ' ';
                  Set_Parameter
                    (Parser.The_Parameter,
                     Arg_Num => Parser.Current_Argument,
                     First => Argument (Parser, Parser.Current_Argument)'First,
                     Last  => Argument (Parser, Parser.Current_Argument)'Last);
                  Parser.Is_Switch (Parser.Current_Argument) := True;
                  Dummy := Goto_Next_Argument_In_Section (Parser);

               else
                  Parser.Current_Index := End_Index + 1;
                  raise Invalid_Parameter;
               end if;

            when Parameter_No_Space =>
               if End_Index < Arg'Last then
                  Set_Parameter
                    (Parser.The_Parameter,
                     Arg_Num => Parser.Current_Argument,
                     First   => End_Index + 1,
                     Last    => Arg'Last);
                  Dummy := Goto_Next_Argument_In_Section (Parser);

               else
                  Parser.Current_Index := End_Index + 1;
                  raise Invalid_Parameter;
               end if;

            when Parameter_Optional =>
               if End_Index < Arg'Last then
                  Set_Parameter
                    (Parser.The_Parameter,
                     Arg_Num => Parser.Current_Argument,
                     First   => End_Index + 1,
                     Last    => Arg'Last);
               end if;

               Dummy := Goto_Next_Argument_In_Section (Parser);

            when Parameter_None =>
               if Concatenate or else End_Index = Arg'Last then
                  Parser.Current_Index := End_Index + 1;

               else
                  --  If Concatenate is False and the full argument is not
                  --  recognized as a switch, this is an invalid switch.

                  if Switches (Switches'First) = '*' then
                     Set_Parameter
                       (Parser.The_Switch,
                        Arg_Num => Parser.Current_Argument,
                        First   => Arg'First,
                        Last    => Arg'Last);
                     Parser.Is_Switch (Parser.Current_Argument) := True;
                     Dummy := Goto_Next_Argument_In_Section (Parser);
                     return '*';
                  end if;

                  Set_Parameter
                    (Parser.The_Switch,
                     Arg_Num => Parser.Current_Argument,
                     First   => Parser.Current_Index,
                     Last    => Arg'Last,
                     Extra   => Parser.Switch_Character);
                  Parser.Current_Index := Arg'Last + 1;
                  raise Invalid_Switch with
                    "Unrecognized option '" & Full_Switch (Parser) & ''';
               end if;
         end case;

         return Switches (Index_Switches);
      end;
   end Getopt;

   -----------------------------------
   -- Goto_Next_Argument_In_Section --
   -----------------------------------

   function Goto_Next_Argument_In_Section
     (Parser : Opt_Parser) return Boolean
   is
   begin
      Parser.Current_Argument := Parser.Current_Argument + 1;

      if Parser.Current_Argument > Parser.Arg_Count
        or else Parser.Section (Parser.Current_Argument) = 0
      then
         loop
            Parser.Current_Argument := Parser.Current_Argument + 1;

            if Parser.Current_Argument > Parser.Arg_Count then
               Parser.Current_Index := 1;
               return False;
            end if;

            exit when Parser.Section (Parser.Current_Argument) =
                                                  Parser.Current_Section;
         end loop;
      end if;

      Parser.Current_Index :=
        Argument (Parser, Parser.Current_Argument)'First;

      return True;
   end Goto_Next_Argument_In_Section;

   ------------------
   -- Goto_Section --
   ------------------

   procedure Goto_Section
     (Name   : String := "";
      Parser : Opt_Parser := Command_Line_Parser)
   is
      Index : Integer;

   begin
      Parser.In_Expansion := False;

      if Name = "" then
         Parser.Current_Argument := 1;
         Parser.Current_Index    := 1;
         Parser.Current_Section  := 1;
         return;
      end if;

      Index := 1;
      while Index <= Parser.Arg_Count loop
         if Parser.Section (Index) = 0
           and then Argument (Parser, Index) = Parser.Switch_Character & Name
         then
            Parser.Current_Argument := Index + 1;
            Parser.Current_Index    := 1;

            if Parser.Current_Argument <= Parser.Arg_Count then
               Parser.Current_Section :=
                 Parser.Section (Parser.Current_Argument);
            end if;

            --  Exit from loop if we have the start of another section

            if Index = Parser.Section'Last
               or else Parser.Section (Index + 1) /= 0
            then
               return;
            end if;
         end if;

         Index := Index + 1;
      end loop;

      Parser.Current_Argument := Positive'Last;
      Parser.Current_Index := 2;   --  so that Get_Argument returns nothing
   end Goto_Section;

   ----------------------------
   -- Initialize_Option_Scan --
   ----------------------------

   procedure Initialize_Option_Scan
     (Switch_Char              : Character := '-';
      Stop_At_First_Non_Switch : Boolean   := False;
      Section_Delimiters       : String    := "")
   is
   begin
      Internal_Initialize_Option_Scan
        (Parser                   => Command_Line_Parser,
         Switch_Char              => Switch_Char,
         Stop_At_First_Non_Switch => Stop_At_First_Non_Switch,
         Section_Delimiters       => Section_Delimiters);
   end Initialize_Option_Scan;

   ----------------------------
   -- Initialize_Option_Scan --
   ----------------------------

   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 := "")
   is
   begin
      Free (Parser);

      if Command_Line = null then
         Parser := new Opt_Parser_Data (CL.Argument_Count);
         Internal_Initialize_Option_Scan
           (Parser                   => Parser,
            Switch_Char              => Switch_Char,
            Stop_At_First_Non_Switch => Stop_At_First_Non_Switch,
            Section_Delimiters       => Section_Delimiters);
      else
         Parser := new Opt_Parser_Data (Command_Line'Length);
         Parser.Arguments := Command_Line;
         Internal_Initialize_Option_Scan
           (Parser                   => Parser,
            Switch_Char              => Switch_Char,
            Stop_At_First_Non_Switch => Stop_At_First_Non_Switch,
            Section_Delimiters       => Section_Delimiters);
      end if;
   end Initialize_Option_Scan;

   -------------------------------------
   -- Internal_Initialize_Option_Scan --
   -------------------------------------

   procedure Internal_Initialize_Option_Scan
     (Parser                   : Opt_Parser;
      Switch_Char              : Character;
      Stop_At_First_Non_Switch : Boolean;
      Section_Delimiters       : String)
   is
      Section_Num     : Section_Number;
      Section_Index   : Integer;
      Last            : Integer;
      Delimiter_Found : Boolean;

      Discard : Boolean;
      pragma Warnings (Off, Discard);

   begin
      Parser.Current_Argument := 0;
      Parser.Current_Index    := 0;
      Parser.In_Expansion     := False;
      Parser.Switch_Character := Switch_Char;
      Parser.Stop_At_First    := Stop_At_First_Non_Switch;
      Parser.Section          := (others => 1);

      --  If we are using sections, we have to preprocess the command line to
      --  delimit them. A section can be repeated, so we just give each item
      --  on the command line a section number

      Section_Num   := 1;
      Section_Index := Section_Delimiters'First;
      while Section_Index <= Section_Delimiters'Last loop
         Last := Section_Index;
         while Last <= Section_Delimiters'Last
           and then Section_Delimiters (Last) /= ' '
         loop
            Last := Last + 1;
         end loop;

         Delimiter_Found := False;
         Section_Num := Section_Num + 1;

         for Index in 1 .. Parser.Arg_Count loop
            pragma Assert (Argument (Parser, Index)'First = 1);
            if Argument (Parser, Index) /= ""
              and then Argument (Parser, Index)(1) = Parser.Switch_Character
              and then
                Argument (Parser, Index) = Parser.Switch_Character &
                                             Section_Delimiters
                                               (Section_Index .. Last - 1)
            then
               Parser.Section (Index) := 0;
               Delimiter_Found := True;

            elsif Parser.Section (Index) = 0 then

               --  A previous section delimiter

               Delimiter_Found := False;

            elsif Delimiter_Found then
               Parser.Section (Index) := Section_Num;
            end if;
         end loop;

         Section_Index := Last + 1;
         while Section_Index <= Section_Delimiters'Last
           and then Section_Delimiters (Section_Index) = ' '
         loop
            Section_Index := Section_Index + 1;
         end loop;
      end loop;

      Discard := Goto_Next_Argument_In_Section (Parser);
   end Internal_Initialize_Option_Scan;

   ---------------
   -- Parameter --
   ---------------

   function Parameter
     (Parser : Opt_Parser := Command_Line_Parser) return String
   is
   begin
      if Parser.The_Parameter.First > Parser.The_Parameter.Last then
         return String'(1 .. 0 => ' ');
      else
         return Argument (Parser, Parser.The_Parameter.Arg_Num)
           (Parser.The_Parameter.First .. Parser.The_Parameter.Last);
      end if;
   end Parameter;

   ---------------
   -- Separator --
   ---------------

   function Separator
     (Parser : Opt_Parser := Command_Line_Parser) return Character
   is
   begin
      return Parser.The_Separator;
   end Separator;

   -------------------
   -- Set_Parameter --
   -------------------

   procedure Set_Parameter
     (Variable : out Parameter_Type;
      Arg_Num  : Positive;
      First    : Positive;
      Last     : Natural;
      Extra    : Character := ASCII.NUL)
   is
   begin
      Variable.Arg_Num := Arg_Num;
      Variable.First   := First;
      Variable.Last    := Last;
      Variable.Extra   := Extra;
   end Set_Parameter;

   ---------------------
   -- Start_Expansion --
   ---------------------

   procedure Start_Expansion
     (Iterator     : out Expansion_Iterator;
      Pattern      : String;
      Directory    : String := "";
      Basic_Regexp : Boolean := True)
   is
      Directory_Separator : Character;
      pragma Import (C, Directory_Separator, "__gnat_dir_separator");

      First : Positive := Pattern'First;
      Pat   : String := Pattern;

   begin
      Canonical_Case_File_Name (Pat);
      Iterator.Current_Depth := 1;

      --  If Directory is unspecified, use the current directory ("./" or ".\")

      if Directory = "" then
         Iterator.Dir_Name (1 .. 2) := "." & Directory_Separator;
         Iterator.Start := 3;

      else
         Iterator.Dir_Name (1 .. Directory'Length) := Directory;
         Iterator.Start := Directory'Length + 1;
         Canonical_Case_File_Name (Iterator.Dir_Name (1 .. Directory'Length));

         --  Make sure that the last character is a directory separator

         if Directory (Directory'Last) /= Directory_Separator then
            Iterator.Dir_Name (Iterator.Start) := Directory_Separator;
            Iterator.Start := Iterator.Start + 1;
         end if;
      end if;

      Iterator.Levels (1).Name_Last := Iterator.Start - 1;

      --  Open the initial Directory, at depth 1

      GNAT.Directory_Operations.Open
        (Iterator.Levels (1).Dir, Iterator.Dir_Name (1 .. Iterator.Start - 1));

      --  If in the current directory and the pattern starts with "./" or ".\",
      --  drop the "./" or ".\" from the pattern.

      if Directory = "" and then Pat'Length > 2
        and then Pat (Pat'First) = '.'
        and then Pat (Pat'First + 1) = Directory_Separator
      then
         First := Pat'First + 2;
      end if;

      Iterator.Regexp :=
        GNAT.Regexp.Compile (Pat (First .. Pat'Last), Basic_Regexp, True);

      Iterator.Maximum_Depth := 1;

      --  Maximum_Depth is equal to 1 plus the number of directory separators
      --  in the pattern.

      for Index in First .. Pat'Last loop
         if Pat (Index) = Directory_Separator then
            Iterator.Maximum_Depth := Iterator.Maximum_Depth + 1;
            exit when Iterator.Maximum_Depth = Max_Depth;
         end if;
      end loop;
   end Start_Expansion;

   ----------
   -- Free --
   ----------

   procedure Free (Parser : in out Opt_Parser) is
      procedure Unchecked_Free is new
        Ada.Unchecked_Deallocation (Opt_Parser_Data, Opt_Parser);
   begin
      if Parser /= null and then Parser /= Command_Line_Parser then
         Free (Parser.Arguments);
         Unchecked_Free (Parser);
      end if;
   end Free;

   ------------------
   -- Define_Alias --
   ------------------

   procedure Define_Alias
     (Config   : in out Command_Line_Configuration;
      Switch   : String;
      Expanded : String;
      Section  : String := "")
   is
      Def    : Alias_Definition;

   begin
      if Config = null then
         Config := new Command_Line_Configuration_Record;
      end if;

      Def.Alias     := new String'(Switch);
      Def.Expansion := new String'(Expanded);
      Def.Section   := new String'(Section);
      Add (Config.Aliases, Def);
   end Define_Alias;

   -------------------
   -- Define_Prefix --
   -------------------

   procedure Define_Prefix
     (Config : in out Command_Line_Configuration;
      Prefix : String)
   is
   begin
      if Config = null then
         Config := new Command_Line_Configuration_Record;
      end if;

      Add (Config.Prefixes, new String'(Prefix));
   end Define_Prefix;

   ---------
   -- Add --
   ---------

   procedure Add
     (Config : in out Command_Line_Configuration;
      Switch : Switch_Definition)
   is
      procedure Unchecked_Free is new Ada.Unchecked_Deallocation
        (Switch_Definitions, Switch_Definitions_List);

      Tmp : Switch_Definitions_List;

   begin
      if Config = null then
         Config := new Command_Line_Configuration_Record;
      end if;

      Tmp := Config.Switches;

      if Tmp = null then
         Config.Switches := new Switch_Definitions (1 .. 1);
      else
         Config.Switches := new Switch_Definitions (1 .. Tmp'Length + 1);
         Config.Switches (1 .. Tmp'Length) := Tmp.all;
         Unchecked_Free (Tmp);
      end if;

      if Switch.Switch /= null and then Switch.Switch.all = "*" then
         Config.Star_Switch := True;
      end if;

      Config.Switches (Config.Switches'Last) := Switch;
   end Add;

   ---------
   -- Add --
   ---------

   procedure Add
     (Def   : in out Alias_Definitions_List;
      Alias : Alias_Definition)
   is
      procedure Unchecked_Free is new
        Ada.Unchecked_Deallocation
          (Alias_Definitions, Alias_Definitions_List);

      Tmp : Alias_Definitions_List := Def;

   begin
      if Tmp = null then
         Def := new Alias_Definitions (1 .. 1);
      else
         Def := new Alias_Definitions (1 .. Tmp'Length + 1);
         Def (1 .. Tmp'Length) := Tmp.all;
         Unchecked_Free (Tmp);
      end if;

      Def (Def'Last) := Alias;
   end Add;

   ---------------------------
   -- Initialize_Switch_Def --
   ---------------------------

   procedure Initialize_Switch_Def
     (Def         : out Switch_Definition;
      Switch      : String := "";
      Long_Switch : String := "";
      Help        : String := "";
      Section     : String := "";
      Argument    : String := "ARG")
   is
      P1, P2       : Switch_Parameter_Type := Parameter_None;
      Last1, Last2 : Integer;

   begin
      if Switch /= "" then
         Def.Switch := new String'(Switch);
         Decompose_Switch (Switch, P1, Last1);
      end if;

      if Long_Switch /= "" then
         Def.Long_Switch := new String'(Long_Switch);
         Decompose_Switch (Long_Switch, P2, Last2);
      end if;

      if Switch /= "" and then Long_Switch /= "" then
         if (P1 = Parameter_None and then P2 /= P1)
           or else (P2 = Parameter_None and then P1 /= P2)
           or else (P1 = Parameter_Optional and then P2 /= P1)
           or else (P2 = Parameter_Optional and then P2 /= P1)
         then
            raise Invalid_Switch
              with "Inconsistent parameter types for "
                & Switch & " and " & Long_Switch;
         end if;
      end if;

      if Section /= "" then
         Def.Section := new String'(Section);
      end if;

      if Argument /= "ARG" then
         Def.Argument := new String'(Argument);
      end if;

      if Help /= "" then
         Def.Help := new String'(Help);
      end if;
   end Initialize_Switch_Def;

   -------------------
   -- Define_Switch --
   -------------------

   procedure Define_Switch
     (Config      : in out Command_Line_Configuration;
      Switch      : String := "";
      Long_Switch : String := "";
      Help        : String := "";
      Section     : String := "";
      Argument    : String := "ARG")
   is
      Def : Switch_Definition;
   begin
      if Switch /= "" or else Long_Switch /= "" then
         Initialize_Switch_Def
           (Def, Switch, Long_Switch, Help, Section, Argument);
         Add (Config, Def);
      end if;
   end Define_Switch;

   -------------------
   -- Define_Switch --
   -------------------

   procedure Define_Switch
     (Config      : in out Command_Line_Configuration;
      Output      : access Boolean;
      Switch      : String := "";
      Long_Switch : String := "";
      Help        : String := "";
      Section     : String := "";
      Value       : Boolean := True)
   is
      Def : Switch_Definition (Switch_Boolean);
   begin
      if Switch /= "" or else Long_Switch /= "" then
         Initialize_Switch_Def (Def, Switch, Long_Switch, Help, Section);
         Def.Boolean_Output := Output.all'Unchecked_Access;
         Def.Boolean_Value  := Value;
         Add (Config, Def);
      end if;
   end Define_Switch;

   -------------------
   -- Define_Switch --
   -------------------

   procedure Define_Switch
     (Config      : in out Command_Line_Configuration;
      Output      : access Integer;
      Switch      : String := "";
      Long_Switch : String := "";
      Help        : String := "";
      Section     : String := "";
      Initial     : Integer := 0;
      Default     : Integer := 1;
      Argument    : String := "ARG")
   is
      Def : Switch_Definition (Switch_Integer);
   begin
      if Switch /= "" or else Long_Switch /= "" then
         Initialize_Switch_Def
           (Def, Switch, Long_Switch, Help, Section, Argument);
         Def.Integer_Output  := Output.all'Unchecked_Access;
         Def.Integer_Default := Default;
         Def.Integer_Initial := Initial;
         Add (Config, Def);
      end if;
   end Define_Switch;

   -------------------
   -- Define_Switch --
   -------------------

   procedure Define_Switch
     (Config      : in out Command_Line_Configuration;
      Output      : access GNAT.Strings.String_Access;
      Switch      : String := "";
      Long_Switch : String := "";
      Help        : String := "";
      Section     : String := "";
      Argument    : String := "ARG")
   is
      Def : Switch_Definition (Switch_String);
   begin
      if Switch /= "" or else Long_Switch /= "" then
         Initialize_Switch_Def
           (Def, Switch, Long_Switch, Help, Section, Argument);
         Def.String_Output  := Output.all'Unchecked_Access;
         Add (Config, Def);
      end if;
   end Define_Switch;

   -------------------
   -- Define_Switch --
   -------------------

   procedure Define_Switch
     (Config      : in out Command_Line_Configuration;
      Callback    : not null Value_Callback;
      Switch      : String := "";
      Long_Switch : String := "";
      Help        : String := "";
      Section     : String := "";
      Argument    : String := "ARG")
   is
      Def : Switch_Definition (Switch_Callback);
   begin
      if Switch /= "" or else Long_Switch /= "" then
         Initialize_Switch_Def
           (Def, Switch, Long_Switch, Help, Section, Argument);
         Def.Callback := Callback;
         Add (Config, Def);
      end if;
   end Define_Switch;

   --------------------
   -- Define_Section --
   --------------------

   procedure Define_Section
     (Config : in out Command_Line_Configuration;
      Section : String)
   is
   begin
      if Config = null then
         Config := new Command_Line_Configuration_Record;
      end if;

      Add (Config.Sections, new String'(Section));
   end Define_Section;

   --------------------
   -- Foreach_Switch --
   --------------------

   procedure Foreach_Switch
     (Config   : Command_Line_Configuration;
      Section  : String)
   is
   begin
      if Config /= null and then Config.Switches /= null then
         for J in Config.Switches'Range loop
            if (Section = "" and then Config.Switches (J).Section = null)
              or else
                (Config.Switches (J).Section /= null
                  and then Config.Switches (J).Section.all = Section)
            then
               exit when Config.Switches (J).Switch /= null
                 and then not Callback (Config.Switches (J).Switch.all, J);

               exit when Config.Switches (J).Long_Switch /= null
                 and then
                   not Callback (Config.Switches (J).Long_Switch.all, J);
            end if;
         end loop;
      end if;
   end Foreach_Switch;

   ------------------
   -- Get_Switches --
   ------------------

   function Get_Switches
     (Config      : Command_Line_Configuration;
      Switch_Char : Character := '-';
      Section     : String := "") return String
   is
      Ret : Ada.Strings.Unbounded.Unbounded_String;
      use Ada.Strings.Unbounded;

      function Add_Switch (S : String; Index : Integer) return Boolean;
      --  Add a switch to Ret

      ----------------
      -- Add_Switch --
      ----------------

      function Add_Switch (S : String; Index : Integer) return Boolean is
         pragma Unreferenced (Index);
      begin
         if S = "*" then
            Ret := "*" & Ret;  --  Always first
         elsif S (S'First) = Switch_Char then
            Append (Ret, " " & S (S'First + 1 .. S'Last));
         else
            Append (Ret, " " & S);
         end if;

         return True;
      end Add_Switch;

      Tmp : Boolean;
      pragma Unreferenced (Tmp);

      procedure Foreach is new Foreach_Switch (Add_Switch);

   --  Start of processing for Get_Switches

   begin
      if Config = null then
         return "";
      end if;

      Foreach (Config, Section => Section);

      --  Add relevant aliases

      if Config.Aliases /= null then
         for A in Config.Aliases'Range loop
            if Config.Aliases (A).Section.all = Section then
               Tmp := Add_Switch (Config.Aliases (A).Alias.all, -1);
            end if;
         end loop;
      end if;

      return To_String (Ret);
   end Get_Switches;

   ------------------------
   -- Section_Delimiters --
   ------------------------

   function Section_Delimiters
     (Config : Command_Line_Configuration) return String
   is
      use Ada.Strings.Unbounded;
      Result : Unbounded_String;

   begin
      if Config /= null and then Config.Sections /= null then
         for S in Config.Sections'Range loop
            Append (Result, " " & Config.Sections (S).all);
         end loop;
      end if;

      return To_String (Result);
   end Section_Delimiters;

   -----------------------
   -- Set_Configuration --
   -----------------------

   procedure Set_Configuration
     (Cmd    : in out Command_Line;
      Config : Command_Line_Configuration)
   is
   begin
      Cmd.Config := Config;
   end Set_Configuration;

   -----------------------
   -- Get_Configuration --
   -----------------------

   function Get_Configuration
     (Cmd : Command_Line) return Command_Line_Configuration
   is
   begin
      return Cmd.Config;
   end Get_Configuration;

   ----------------------
   -- Set_Command_Line --
   ----------------------

   procedure Set_Command_Line
     (Cmd                : in out Command_Line;
      Switches           : String;
      Getopt_Description : String := "";
      Switch_Char        : Character := '-')
   is
      Tmp     : Argument_List_Access;
      Parser  : Opt_Parser;
      S       : Character;
      Section : String_Access := null;

      function Real_Full_Switch
        (S      : Character;
         Parser : Opt_Parser) return String;
      --  Ensure that the returned switch value contains the Switch_Char prefix
      --  if needed.

      ----------------------
      -- Real_Full_Switch --
      ----------------------

      function Real_Full_Switch
        (S      : Character;
         Parser : Opt_Parser) return String
      is
      begin
         if S = '*' then
            return Full_Switch (Parser);
         else
            return Switch_Char & Full_Switch (Parser);
         end if;
      end Real_Full_Switch;

   --  Start of processing for Set_Command_Line

   begin
      Free (Cmd.Expanded);
      Free (Cmd.Params);

      if Switches /= "" then
         Tmp := Argument_String_To_List (Switches);
         Initialize_Option_Scan (Parser, Tmp, Switch_Char);

         loop
            begin
               if Cmd.Config /= null then

                  --  Do not use Getopt_Description in this case. Otherwise,
                  --  if we have defined a prefix -gnaty, and two switches
                  --  -gnatya and -gnatyL!, we would have a different behavior
                  --  depending on the order of switches:

                  --      -gnatyL1a   =>  -gnatyL with argument "1a"
                  --      -gnatyaL1   =>  -gnatya and -gnatyL with argument "1"

                  --  This is because the call to Getopt below knows nothing
                  --  about prefixes, and in the first case finds a valid
                  --  switch with arguments, so returns it without analyzing
                  --  the argument. In the second case, the switch matches "*",
                  --  and is then decomposed below.

                  --  Note: When a Command_Line object is associated with a
                  --  Command_Line_Config (which is mostly the case for tools
                  --  that let users choose the command line before spawning
                  --  other tools, for instance IDEs), the configuration of
                  --  the switches must be taken from the Command_Line_Config.

                  S := Getopt (Switches    => "* " & Get_Switches (Cmd.Config),
                               Concatenate => False,
                               Parser      => Parser);

               else
                  S := Getopt (Switches    => "* " & Getopt_Description,
                               Concatenate => False,
                               Parser      => Parser);
               end if;

               exit when S = ASCII.NUL;

               declare
                  Sw         : constant String := Real_Full_Switch (S, Parser);
                  Is_Section : Boolean         := False;

               begin
                  if Cmd.Config /= null
                    and then Cmd.Config.Sections /= null
                  then
                     Section_Search :
                     for S in Cmd.Config.Sections'Range loop
                        if Sw = Cmd.Config.Sections (S).all then
                           Section := Cmd.Config.Sections (S);
                           Is_Section := True;

                           exit Section_Search;
                        end if;
                     end loop Section_Search;
                  end if;

                  if not Is_Section then
                     if Section = null then
                        Add_Switch (Cmd, Sw, Parameter (Parser));
                     else
                        Add_Switch
                          (Cmd, Sw, Parameter (Parser),
                           Section => Section.all);
                     end if;
                  end if;
               end;

            exception
               when Invalid_Parameter =>

                  --  Add it with no parameter, if that's the way the user
                  --  wants it.

                  --  Specify the separator in all cases, as the switch might
                  --  need to be unaliased, and the alias might contain
                  --  switches with parameters.

                  if Section = null then
                     Add_Switch
                       (Cmd, Switch_Char & Full_Switch (Parser));
                  else
                     Add_Switch
                       (Cmd, Switch_Char & Full_Switch (Parser),
                        Section   => Section.all);
                  end if;
            end;
         end loop;

         Free (Parser);
      end if;
   end Set_Command_Line;

   ----------------
   -- Looking_At --
   ----------------

   function Looking_At
     (Type_Str  : String;
      Index     : Natural;
      Substring : String) return Boolean
   is
   begin
      return Index + Substring'Length - 1 <= Type_Str'Last
        and then Type_Str (Index .. Index + Substring'Length - 1) = Substring;
   end Looking_At;

   ------------------------
   -- Can_Have_Parameter --
   ------------------------

   function Can_Have_Parameter (S : String) return Boolean is
   begin
      if S'Length <= 1 then
         return False;
      end if;

      case S (S'Last) is
         when '!' | ':' | '?' | '=' =>
            return True;
         when others =>
            return False;
      end case;
   end Can_Have_Parameter;

   -----------------------
   -- Require_Parameter --
   -----------------------

   function Require_Parameter (S : String) return Boolean is
   begin
      if S'Length <= 1 then
         return False;
      end if;

      case S (S'Last) is
         when '!' | ':' | '=' =>
            return True;
         when others =>
            return False;
      end case;
   end Require_Parameter;

   -------------------
   -- Actual_Switch --
   -------------------

   function Actual_Switch (S : String) return String is
   begin
      if S'Length <= 1 then
         return S;
      end if;

      case S (S'Last) is
         when '!' | ':' | '?' | '=' =>
            return S (S'First .. S'Last - 1);
         when others =>
            return S;
      end case;
   end Actual_Switch;

   ----------------------------
   -- For_Each_Simple_Switch --
   ----------------------------

   procedure For_Each_Simple_Switch
     (Config    : Command_Line_Configuration;
      Section   : String;
      Switch    : String;
      Parameter : String := "";
      Unalias   : Boolean := True)
   is
      function Group_Analysis
        (Prefix : String;
         Group  : String) return Boolean;
      --  Perform the analysis of a group of switches

      Found_In_Config : Boolean := False;
      function Is_In_Config
        (Config_Switch : String; Index : Integer) return Boolean;
      --  If Switch is the same as Config_Switch, run the callback and sets
      --  Found_In_Config to True.

      function Starts_With
        (Config_Switch : String; Index : Integer) return Boolean;
      --  if Switch starts with Config_Switch, sets Found_In_Config to True.
      --  The return value is for the Foreach_Switch iterator.

      --------------------
      -- Group_Analysis --
      --------------------

      function Group_Analysis
        (Prefix : String;
         Group  : String) return Boolean
      is
         Idx   : Natural;
         Found : Boolean;

         function Analyze_Simple_Switch
           (Switch : String; Index : Integer) return Boolean;
         --  "Switches" is one of the switch definitions passed to the
         --  configuration, not one of the switches found on the command line.

         ---------------------------
         -- Analyze_Simple_Switch --
         ---------------------------

         function Analyze_Simple_Switch
           (Switch : String; Index : Integer) return Boolean
         is
            pragma Unreferenced (Index);

            Full : constant String := Prefix & Group (Idx .. Group'Last);

            Sw : constant String := Actual_Switch (Switch);
            --  Switches definition minus argument definition

            Last  : Natural;
            Param : Natural;

         begin
            --  Verify that sw starts with Prefix

            if Looking_At (Sw, Sw'First, Prefix)

              --  Verify that the group starts with sw

              and then Looking_At (Full, Full'First, Sw)
            then
               Last  := Idx + Sw'Length - Prefix'Length - 1;
               Param := Last + 1;

               if Can_Have_Parameter (Switch) then

                  --  Include potential parameter to the recursive call. Only
                  --  numbers are allowed.

                  while Last < Group'Last
                    and then Group (Last + 1) in '0' .. '9'
                  loop
                     Last := Last + 1;
                  end loop;
               end if;

               if not Require_Parameter (Switch) or else Last >= Param then
                  if Idx = Group'First
                    and then Last = Group'Last
                    and then Last < Param
                  then
                     --  The group only concerns a single switch. Do not
                     --  perform recursive call.

                     --  Note that we still perform a recursive call if
                     --  a parameter is detected in the switch, as this
                     --  is a way to correctly identify such a parameter
                     --  in aliases.

                     return False;
                  end if;

                  Found := True;

                  --  Recursive call, using the detected parameter if any

                  if Last >= Param then
                     For_Each_Simple_Switch
                       (Config,
                        Section,
                        Prefix & Group (Idx .. Param - 1),
                        Group (Param .. Last));

                  else
                     For_Each_Simple_Switch
                       (Config, Section, Prefix & Group (Idx .. Last), "");
                  end if;

                  Idx := Last + 1;
                  return False;
               end if;
            end if;

            return True;
         end Analyze_Simple_Switch;

         procedure Foreach is new Foreach_Switch (Analyze_Simple_Switch);

      --  Start of processing for Group_Analysis

      begin
         Idx := Group'First;
         while Idx <= Group'Last loop
            Found := False;
            Foreach (Config, Section);

            if not Found then
               For_Each_Simple_Switch
                 (Config, Section, Prefix & Group (Idx), "");
               Idx := Idx + 1;
            end if;
         end loop;

         return True;
      end Group_Analysis;

      ------------------
      -- Is_In_Config --
      ------------------

      function Is_In_Config
        (Config_Switch : String; Index : Integer) return Boolean
      is
         Last : Natural;
         P    : Switch_Parameter_Type;

      begin
         Decompose_Switch (Config_Switch, P, Last);

         if Config_Switch (Config_Switch'First .. Last) = Switch then
            case P is
               when Parameter_None =>
                  if Parameter = "" then
                     Callback (Switch, "", "", Index => Index);
                     Found_In_Config := True;
                     return False;
                  end if;

               when Parameter_With_Optional_Space =>
                  Callback (Switch, " ", Parameter, Index => Index);
                  Found_In_Config := True;
                  return False;

               when Parameter_With_Space_Or_Equal =>
                  Callback (Switch, "=", Parameter, Index => Index);
                  Found_In_Config := True;
                  return False;

               when Parameter_No_Space
                  | Parameter_Optional
               =>
                  Callback (Switch, "", Parameter, Index);
                  Found_In_Config := True;
                  return False;
            end case;
         end if;

         return True;
      end Is_In_Config;

      -----------------
      -- Starts_With --
      -----------------

      function Starts_With
        (Config_Switch : String; Index : Integer) return Boolean
      is
         Last  : Natural;
         Param : Natural;
         P     : Switch_Parameter_Type;

      begin
         --  This function is called when we believe the parameter was
         --  specified as part of the switch, instead of separately. Thus we
         --  look in the config to find all possible switches.

         Decompose_Switch (Config_Switch, P, Last);

         if Looking_At
              (Switch, Switch'First,
               Config_Switch (Config_Switch'First .. Last))
         then
            --  Set first char of Param, and last char of Switch

            Param := Switch'First + Last;
            Last  := Switch'First + Last - Config_Switch'First;

            case P is

               --  None is already handled in Is_In_Config

               when Parameter_None =>
                  null;

               when Parameter_With_Space_Or_Equal =>
                  if Param <= Switch'Last
                    and then
                      (Switch (Param) = ' ' or else Switch (Param) = '=')
                  then
                     Callback (Switch (Switch'First .. Last),
                               "=", Switch (Param + 1 .. Switch'Last), Index);
                     Found_In_Config := True;
                     return False;
                  end if;

               when Parameter_With_Optional_Space =>
                  if Param <= Switch'Last and then Switch (Param) = ' '  then
                     Param := Param + 1;
                  end if;

                  Callback (Switch (Switch'First .. Last),
                            " ", Switch (Param .. Switch'Last), Index);
                  Found_In_Config := True;
                  return False;

               when Parameter_No_Space
                  | Parameter_Optional
               =>
                  Callback (Switch (Switch'First .. Last),
                            "", Switch (Param .. Switch'Last), Index);
                  Found_In_Config := True;
                  return False;
            end case;
         end if;
         return True;
      end Starts_With;

      procedure Foreach_In_Config is new Foreach_Switch (Is_In_Config);
      procedure Foreach_Starts_With is new Foreach_Switch (Starts_With);

   --  Start of processing for For_Each_Simple_Switch

   begin
      --  First determine if the switch corresponds to one belonging to the
      --  configuration. If so, run callback and exit.

      --  ??? Is this necessary. On simple tests, we seem to have the same
      --  results with or without this call.

      Foreach_In_Config (Config, Section);

      if Found_In_Config then
         return;
      end if;

      --  If adding a switch that can in fact be expanded through aliases,
      --  add separately each of its expansions.

      --  This takes care of expansions like "-T" -> "-gnatwrs", where the
      --  alias and its expansion do not have the same prefix. Given the order
      --  in which we do things here, the expansion of the alias will itself
      --  be checked for a common prefix and split into simple switches.

      if Unalias
        and then Config /= null
        and then Config.Aliases /= null
      then
         for A in Config.Aliases'Range loop
            if Config.Aliases (A).Section.all = Section
              and then Config.Aliases (A).Alias.all = Switch
              and then Parameter = ""
            then
               For_Each_Simple_Switch
                 (Config, Section, Config.Aliases (A).Expansion.all, "");
               return;
            end if;
         end loop;
      end if;

      --  If adding a switch grouping several switches, add each of the simple
      --  switches instead.

      if Config /= null and then Config.Prefixes /= null then
         for P in Config.Prefixes'Range loop
            if Switch'Length > Config.Prefixes (P)'Length + 1
              and then
                Looking_At (Switch, Switch'First, Config.Prefixes (P).all)
            then
               --  Alias expansion will be done recursively

               if Config.Switches = null then
                  for S in Switch'First + Config.Prefixes (P)'Length
                            .. Switch'Last
                  loop
                     For_Each_Simple_Switch
                       (Config, Section,
                        Config.Prefixes (P).all & Switch (S), "");
                  end loop;

                  return;

               elsif Group_Analysis
                 (Config.Prefixes (P).all,
                  Switch
                    (Switch'First + Config.Prefixes (P)'Length .. Switch'Last))
               then
                  --  Recursive calls already done on each switch of the group:
                  --  Return without executing Callback.

                  return;
               end if;
            end if;
         end loop;
      end if;

      --  Test if added switch is a known switch with parameter attached
      --  instead of being specified separately

      if Parameter = ""
        and then Config /= null
        and then Config.Switches /= null
      then
         Found_In_Config := False;
         Foreach_Starts_With (Config, Section);

         if Found_In_Config then
            return;
         end if;
      end if;

      --  The switch is invalid in the config, but we still want to report it.
      --  The config could, for instance, include "*" to specify it accepts
      --  all switches.

      Callback (Switch, " ", Parameter, Index => -1);
   end For_Each_Simple_Switch;

   ----------------
   -- Add_Switch --
   ----------------

   procedure Add_Switch
     (Cmd        : in out Command_Line;
      Switch     : String;
      Parameter  : String    := "";
      Separator  : Character := ASCII.NUL;
      Section    : String    := "";
      Add_Before : Boolean   := False)
   is
      Success : Boolean;
      pragma Unreferenced (Success);
   begin
      Add_Switch (Cmd, Switch, Parameter, Separator,
                  Section, Add_Before, Success);
   end Add_Switch;

   ----------------
   -- Add_Switch --
   ----------------

   procedure Add_Switch
     (Cmd        : in out Command_Line;
      Switch     : String;
      Parameter  : String := "";
      Separator  : Character := ASCII.NUL;
      Section    : String := "";
      Add_Before : Boolean := False;
      Success    : out Boolean)
   is
      procedure Add_Simple_Switch
        (Simple : String;
         Sepa   : String;
         Param  : String;
         Index  : Integer);
      --  Add a new switch that has had all its aliases expanded, and switches
      --  ungrouped. We know there are no more aliases in Switches.

      -----------------------
      -- Add_Simple_Switch --
      -----------------------

      procedure Add_Simple_Switch
        (Simple : String;
         Sepa   : String;
         Param  : String;
         Index  : Integer)
      is
         Sep : Character;

      begin
         if Index = -1
           and then Cmd.Config /= null
           and then not Cmd.Config.Star_Switch
         then
            raise Invalid_Switch
              with "Invalid switch " & Simple;
         end if;

         if Separator /= ASCII.NUL then
            Sep := Separator;

         elsif Sepa = "" then
            Sep := ASCII.NUL;
         else
            Sep := Sepa (Sepa'First);
         end if;

         if Cmd.Expanded = null then
            Cmd.Expanded := new Argument_List'(1 .. 1 => new String'(Simple));

            if Param /= "" then
               Cmd.Params :=
                 new Argument_List'(1 .. 1 => new String'(Sep & Param));
            else
               Cmd.Params := new Argument_List'(1 .. 1 => null);
            end if;

            if Section = "" then
               Cmd.Sections := new Argument_List'(1 .. 1 => null);
            else
               Cmd.Sections :=
                 new Argument_List'(1 .. 1 => new String'(Section));
            end if;

         else
            --  Do we already have this switch?

            for C in Cmd.Expanded'Range loop
               if Cmd.Expanded (C).all = Simple
                 and then
                   ((Cmd.Params (C) = null and then Param = "")
                     or else
                       (Cmd.Params (C) /= null
                         and then Cmd.Params (C).all = Sep & Param))
                 and then
                   ((Cmd.Sections (C) = null and then Section = "")
                     or else
                       (Cmd.Sections (C) /= null
                         and then Cmd.Sections (C).all = Section))
               then
                  return;
               end if;
            end loop;

            --  Inserting at least one switch

            Success := True;
            Add (Cmd.Expanded, new String'(Simple), Add_Before);

            if Param /= "" then
               Add
                 (Cmd.Params,
                  new String'(Sep & Param),
                  Add_Before);
            else
               Add
                 (Cmd.Params,
                  null,
                  Add_Before);
            end if;

            if Section = "" then
               Add
                 (Cmd.Sections,
                  null,
                  Add_Before);
            else
               Add
                 (Cmd.Sections,
                  new String'(Section),
                  Add_Before);
            end if;
         end if;
      end Add_Simple_Switch;

      procedure Add_Simple_Switches is
        new For_Each_Simple_Switch (Add_Simple_Switch);

      --  Local Variables

      Section_Valid : Boolean := False;

   --  Start of processing for Add_Switch

   begin
      if Section /= "" and then Cmd.Config /= null then
         for S in Cmd.Config.Sections'Range loop
            if Section = Cmd.Config.Sections (S).all then
               Section_Valid := True;
               exit;
            end if;
         end loop;

         if not Section_Valid then
            raise Invalid_Section;
         end if;
      end if;

      Success := False;
      Add_Simple_Switches (Cmd.Config, Section, Switch, Parameter);
      Free (Cmd.Coalesce);
   end Add_Switch;

   ------------
   -- Remove --
   ------------

   procedure Remove (Line : in out Argument_List_Access; Index : Integer) is
      Tmp : Argument_List_Access := Line;

   begin
      Line := new Argument_List (Tmp'First .. Tmp'Last - 1);

      if Index /= Tmp'First then
         Line (Tmp'First .. Index - 1) := Tmp (Tmp'First .. Index - 1);
      end if;

      Free (Tmp (Index));

      if Index /= Tmp'Last then
         Line (Index .. Tmp'Last - 1) := Tmp (Index + 1 .. Tmp'Last);
      end if;

      Unchecked_Free (Tmp);
   end Remove;

   ---------
   -- Add --
   ---------

   procedure Add
     (Line   : in out Argument_List_Access;
      Str    : String_Access;
      Before : Boolean := False)
   is
      Tmp : Argument_List_Access := Line;

   begin
      if Tmp /= null then
         Line := new Argument_List (Tmp'First .. Tmp'Last + 1);

         if Before then
            Line (Tmp'First)                     := Str;
            Line (Tmp'First + 1 .. Tmp'Last + 1) := Tmp.all;
         else
            Line (Tmp'Range)    := Tmp.all;
            Line (Tmp'Last + 1) := Str;
         end if;

         Unchecked_Free (Tmp);

      else
         Line := new Argument_List'(1 .. 1 => Str);
      end if;
   end Add;

   -------------------
   -- Remove_Switch --
   -------------------

   procedure Remove_Switch
     (Cmd           : in out Command_Line;
      Switch        : String;
      Remove_All    : Boolean := False;
      Has_Parameter : Boolean := False;
      Section       : String := "")
   is
      Success : Boolean;
      pragma Unreferenced (Success);
   begin
      Remove_Switch (Cmd, Switch, Remove_All, Has_Parameter, Section, Success);
   end Remove_Switch;

   -------------------
   -- Remove_Switch --
   -------------------

   procedure Remove_Switch
     (Cmd           : in out Command_Line;
      Switch        : String;
      Remove_All    : Boolean := False;
      Has_Parameter : Boolean := False;
      Section       : String  := "";
      Success       : out Boolean)
   is
      procedure Remove_Simple_Switch
        (Simple, Separator, Param : String; Index : Integer);
      --  Removes a simple switch, with no aliasing or grouping

      --------------------------
      -- Remove_Simple_Switch --
      --------------------------

      procedure Remove_Simple_Switch
        (Simple, Separator, Param : String; Index : Integer)
      is
         C : Integer;
         pragma Unreferenced (Param, Separator, Index);

      begin
         if Cmd.Expanded /= null then
            C := Cmd.Expanded'First;
            while C <= Cmd.Expanded'Last loop
               if Cmd.Expanded (C).all = Simple
                 and then
                   (Remove_All
                     or else (Cmd.Sections (C) = null
                               and then Section = "")
                     or else (Cmd.Sections (C) /= null
                               and then Section = Cmd.Sections (C).all))
                 and then (not Has_Parameter or else Cmd.Params (C) /= null)
               then
                  Remove (Cmd.Expanded, C);
                  Remove (Cmd.Params, C);
                  Remove (Cmd.Sections, C);
                  Success := True;

                  if not Remove_All then
                     return;
                  end if;

               else
                  C := C + 1;
               end if;
            end loop;
         end if;
      end Remove_Simple_Switch;

      procedure Remove_Simple_Switches is
        new For_Each_Simple_Switch (Remove_Simple_Switch);

   --  Start of processing for Remove_Switch

   begin
      Success := False;
      Remove_Simple_Switches
        (Cmd.Config, Section, Switch, "", Unalias => not Has_Parameter);
      Free (Cmd.Coalesce);
   end Remove_Switch;

   -------------------
   -- Remove_Switch --
   -------------------

   procedure Remove_Switch
     (Cmd       : in out Command_Line;
      Switch    : String;
      Parameter : String;
      Section   : String  := "")
   is
      procedure Remove_Simple_Switch
        (Simple, Separator, Param : String; Index : Integer);
      --  Removes a simple switch, with no aliasing or grouping

      --------------------------
      -- Remove_Simple_Switch --
      --------------------------

      procedure Remove_Simple_Switch
        (Simple, Separator, Param : String; Index : Integer)
      is
         pragma Unreferenced (Separator, Index);
         C : Integer;

      begin
         if Cmd.Expanded /= null then
            C := Cmd.Expanded'First;
            while C <= Cmd.Expanded'Last loop
               if Cmd.Expanded (C).all = Simple
                 and then
                   ((Cmd.Sections (C) = null
                      and then Section = "")
                    or else
                      (Cmd.Sections (C) /= null
                        and then Section = Cmd.Sections (C).all))
                 and then
                   ((Cmd.Params (C) = null and then Param = "")
                      or else
                        (Cmd.Params (C) /= null

                          --  Ignore the separator stored in Parameter

                          and then
                             Cmd.Params (C) (Cmd.Params (C)'First + 1
                                             .. Cmd.Params (C)'Last) = Param))
               then
                  Remove (Cmd.Expanded, C);
                  Remove (Cmd.Params, C);
                  Remove (Cmd.Sections, C);

                  --  The switch is necessarily unique by construction of
                  --  Add_Switch.

                  return;

               else
                  C := C + 1;
               end if;
            end loop;
         end if;
      end Remove_Simple_Switch;

      procedure Remove_Simple_Switches is
        new For_Each_Simple_Switch (Remove_Simple_Switch);

   --  Start of processing for Remove_Switch

   begin
      Remove_Simple_Switches (Cmd.Config, Section, Switch, Parameter);
      Free (Cmd.Coalesce);
   end Remove_Switch;

   --------------------
   -- Group_Switches --
   --------------------

   procedure Group_Switches
     (Cmd      : Command_Line;
      Result   : Argument_List_Access;
      Sections : Argument_List_Access;
      Params   : Argument_List_Access)
   is
      function Compatible_Parameter (Param : String_Access) return Boolean;
      --  True when the parameter can be part of a group

      --------------------------
      -- Compatible_Parameter --
      --------------------------

      function Compatible_Parameter (Param : String_Access) return Boolean is
      begin
         --  No parameter OK

         if Param = null then
            return True;

         --  We need parameters without separators

         elsif Param (Param'First) /= ASCII.NUL then
            return False;

         --  Parameters must be all digits

         else
            for J in Param'First + 1 .. Param'Last loop
               if Param (J) not in '0' .. '9' then
                  return False;
               end if;
            end loop;

            return True;
         end if;
      end Compatible_Parameter;

      --  Local declarations

      Group : Ada.Strings.Unbounded.Unbounded_String;
      First : Natural;
      use type Ada.Strings.Unbounded.Unbounded_String;

   --  Start of processing for Group_Switches

   begin
      if Cmd.Config = null or else Cmd.Config.Prefixes = null then
         return;
      end if;

      for P in Cmd.Config.Prefixes'Range loop
         Group   := Ada.Strings.Unbounded.Null_Unbounded_String;
         First   := 0;

         for C in Result'Range loop
            if Result (C) /= null
              and then Compatible_Parameter (Params (C))
              and then Looking_At
                         (Result (C).all,
                          Result (C)'First,
                          Cmd.Config.Prefixes (P).all)
            then
               --  If we are still in the same section, group the switches

               if First = 0
                 or else
                   (Sections (C) = null
                     and then Sections (First) = null)
                 or else
                   (Sections (C) /= null
                     and then Sections (First) /= null
                     and then Sections (C).all = Sections (First).all)
               then
                  Group :=
                    Group &
                      Result (C)
                        (Result (C)'First + Cmd.Config.Prefixes (P)'Length ..
                         Result (C)'Last);

                  if Params (C) /= null then
                     Group :=
                       Group &
                         Params (C) (Params (C)'First + 1 .. Params (C)'Last);
                     Free (Params (C));
                  end if;

                  if First = 0 then
                     First := C;
                  end if;

                  Free (Result (C));

               --  We changed section: we put the grouped switches to the first
               --  place, on continue with the new section.

               else
                  Result (First) :=
                    new String'
                      (Cmd.Config.Prefixes (P).all &
                       Ada.Strings.Unbounded.To_String (Group));
                  Group :=
                    Ada.Strings.Unbounded.To_Unbounded_String
                      (Result (C)
                         (Result (C)'First + Cmd.Config.Prefixes (P)'Length ..
                          Result (C)'Last));
                  First := C;
               end if;
            end if;
         end loop;

         if First > 0 then
            Result (First) :=
              new String'
                (Cmd.Config.Prefixes (P).all &
                 Ada.Strings.Unbounded.To_String (Group));
         end if;
      end loop;
   end Group_Switches;

   --------------------
   -- Alias_Switches --
   --------------------

   procedure Alias_Switches
     (Cmd    : Command_Line;
      Result : Argument_List_Access;
      Params : Argument_List_Access)
   is
      Found : Boolean;
      First : Natural;

      procedure Check_Cb (Switch, Separator, Param : String; Index : Integer);
      --  Checks whether the command line contains [Switch]. Sets the global
      --  variable [Found] appropriately. This is called for each simple switch
      --  that make up an alias, to know whether the alias should be applied.

      procedure Remove_Cb (Switch, Separator, Param : String; Index : Integer);
      --  Remove the simple switch [Switch] from the command line, since it is
      --  part of a simpler alias

      --------------
      -- Check_Cb --
      --------------

      procedure Check_Cb
        (Switch, Separator, Param : String; Index : Integer)
      is
         pragma Unreferenced (Separator, Index);

      begin
         if Found then
            for E in Result'Range loop
               if Result (E) /= null
                 and then
                   (Params (E) = null
                     or else Params (E) (Params (E)'First + 1 ..
                                         Params (E)'Last) = Param)
                 and then Result (E).all = Switch
               then
                  return;
               end if;
            end loop;

            Found := False;
         end if;
      end Check_Cb;

      ---------------
      -- Remove_Cb --
      ---------------

      procedure Remove_Cb (Switch, Separator, Param : String; Index : Integer)
      is
         pragma Unreferenced (Separator, Index);

      begin
         for E in Result'Range loop
            if Result (E) /= null
                 and then
                   (Params (E) = null
                     or else Params (E) (Params (E)'First + 1
                                             .. Params (E)'Last) = Param)
              and then Result (E).all = Switch
            then
               if First > E then
                  First := E;
               end if;

               Free (Result (E));
               Free (Params (E));
               return;
            end if;
         end loop;
      end Remove_Cb;

      procedure Check_All is new For_Each_Simple_Switch (Check_Cb);
      procedure Remove_All is new For_Each_Simple_Switch (Remove_Cb);

   --  Start of processing for Alias_Switches

   begin
      if Cmd.Config = null or else Cmd.Config.Aliases = null then
         return;
      end if;

      for A in Cmd.Config.Aliases'Range loop

         --  Compute the various simple switches that make up the alias. We
         --  split the expansion into as many simple switches as possible, and
         --  then check whether the expanded command line has all of them.

         Found := True;
         Check_All (Cmd.Config,
                    Switch  => Cmd.Config.Aliases (A).Expansion.all,
                    Section => Cmd.Config.Aliases (A).Section.all);

         if Found then
            First := Integer'Last;
            Remove_All (Cmd.Config,
                        Switch  => Cmd.Config.Aliases (A).Expansion.all,
                        Section => Cmd.Config.Aliases (A).Section.all);
            Result (First) := new String'(Cmd.Config.Aliases (A).Alias.all);
         end if;
      end loop;
   end Alias_Switches;

   -------------------
   -- Sort_Sections --
   -------------------

   procedure Sort_Sections
     (Line     : not null GNAT.OS_Lib.Argument_List_Access;
      Sections : GNAT.OS_Lib.Argument_List_Access;
      Params   : GNAT.OS_Lib.Argument_List_Access)
   is
      Sections_List : Argument_List_Access :=
                        new Argument_List'(1 .. 1 => null);
      Found         : Boolean;
      Old_Line      : constant Argument_List := Line.all;
      Old_Sections  : constant Argument_List := Sections.all;
      Old_Params    : constant Argument_List := Params.all;
      Index         : Natural;

   begin
      --  First construct a list of all sections

      for E in Line'Range loop
         if Sections (E) /= null then
            Found := False;
            for S in Sections_List'Range loop
               if (Sections_List (S) = null and then Sections (E) = null)
                 or else
                   (Sections_List (S) /= null
                     and then Sections (E) /= null
                     and then Sections_List (S).all = Sections (E).all)
               then
                  Found := True;
                  exit;
               end if;
            end loop;

            if not Found then
               Add (Sections_List, Sections (E));
            end if;
         end if;
      end loop;

      Index := Line'First;

      for S in Sections_List'Range loop
         for E in Old_Line'Range loop
            if (Sections_List (S) = null and then Old_Sections (E) = null)
              or else
                (Sections_List (S) /= null
                  and then Old_Sections (E) /= null
                  and then Sections_List (S).all = Old_Sections (E).all)
            then
               Line (Index) := Old_Line (E);
               Sections (Index) := Old_Sections (E);
               Params (Index) := Old_Params (E);
               Index := Index + 1;
            end if;
         end loop;
      end loop;

      Unchecked_Free (Sections_List);
   end Sort_Sections;

   -----------
   -- Start --
   -----------

   procedure Start
     (Cmd      : in out Command_Line;
      Iter     : in out Command_Line_Iterator;
      Expanded : Boolean := False)
   is
   begin
      if Cmd.Expanded = null then
         Iter.List := null;
         return;
      end if;

      --  Reorder the expanded line so that sections are grouped

      Sort_Sections (Cmd.Expanded, Cmd.Sections, Cmd.Params);

      --  Coalesce the switches as much as possible

      if not Expanded
        and then Cmd.Coalesce = null
      then
         Cmd.Coalesce := new Argument_List (Cmd.Expanded'Range);
         for E in Cmd.Expanded'Range loop
            Cmd.Coalesce (E) := new String'(Cmd.Expanded (E).all);
         end loop;

         Free (Cmd.Coalesce_Sections);
         Cmd.Coalesce_Sections := new Argument_List (Cmd.Sections'Range);
         for E in Cmd.Sections'Range loop
            Cmd.Coalesce_Sections (E) :=
              (if Cmd.Sections (E) = null then null
               else new String'(Cmd.Sections (E).all));
         end loop;

         Free (Cmd.Coalesce_Params);
         Cmd.Coalesce_Params := new Argument_List (Cmd.Params'Range);
         for E in Cmd.Params'Range loop
            Cmd.Coalesce_Params (E) :=
              (if Cmd.Params (E) = null then null
               else new String'(Cmd.Params (E).all));
         end loop;

         --  Not a clone, since we will not modify the parameters anyway

         Alias_Switches (Cmd, Cmd.Coalesce, Cmd.Coalesce_Params);
         Group_Switches
           (Cmd, Cmd.Coalesce, Cmd.Coalesce_Sections, Cmd.Coalesce_Params);
      end if;

      if Expanded then
         Iter.List     := Cmd.Expanded;
         Iter.Params   := Cmd.Params;
         Iter.Sections := Cmd.Sections;
      else
         Iter.List     := Cmd.Coalesce;
         Iter.Params   := Cmd.Coalesce_Params;
         Iter.Sections := Cmd.Coalesce_Sections;
      end if;

      if Iter.List = null then
         Iter.Current := Integer'Last;
      else
         Iter.Current := Iter.List'First - 1;
         Next (Iter);
      end if;
   end Start;

   --------------------
   -- Current_Switch --
   --------------------

   function Current_Switch (Iter : Command_Line_Iterator) return String is
   begin
      return Iter.List (Iter.Current).all;
   end Current_Switch;

   --------------------
   -- Is_New_Section --
   --------------------

   function Is_New_Section    (Iter : Command_Line_Iterator) return Boolean is
      Section : constant String := Current_Section (Iter);

   begin
      if Iter.Sections = null then
         return False;

      elsif Iter.Current = Iter.Sections'First
        or else Iter.Sections (Iter.Current - 1) = null
      then
         return Section /= "";

      else
         return Section /= Iter.Sections (Iter.Current - 1).all;
      end if;
   end Is_New_Section;

   ---------------------
   -- Current_Section --
   ---------------------

   function Current_Section (Iter : Command_Line_Iterator) return String is
   begin
      if Iter.Sections = null
        or else Iter.Current > Iter.Sections'Last
        or else Iter.Sections (Iter.Current) = null
      then
         return "";
      end if;

      return Iter.Sections (Iter.Current).all;
   end Current_Section;

   -----------------------
   -- Current_Separator --
   -----------------------

   function Current_Separator (Iter : Command_Line_Iterator) return String is
   begin
      if Iter.Params = null
        or else Iter.Current > Iter.Params'Last
        or else Iter.Params (Iter.Current) = null
      then
         return "";

      else
         declare
            Sep : constant Character :=
              Iter.Params (Iter.Current) (Iter.Params (Iter.Current)'First);
         begin
            if Sep = ASCII.NUL then
               return "";
            else
               return "" & Sep;
            end if;
         end;
      end if;
   end Current_Separator;

   -----------------------
   -- Current_Parameter --
   -----------------------

   function Current_Parameter (Iter : Command_Line_Iterator) return String is
   begin
      if Iter.Params = null
        or else Iter.Current > Iter.Params'Last
        or else Iter.Params (Iter.Current) = null
      then
         return "";

      else
         --  Return result, skipping separator

         declare
            P : constant String := Iter.Params (Iter.Current).all;
         begin
            return P (P'First + 1 .. P'Last);
         end;
      end if;
   end Current_Parameter;

   --------------
   -- Has_More --
   --------------

   function Has_More (Iter : Command_Line_Iterator) return Boolean is
   begin
      return Iter.List /= null and then Iter.Current <= Iter.List'Last;
   end Has_More;

   ----------
   -- Next --
   ----------

   procedure Next (Iter : in out Command_Line_Iterator) is
   begin
      Iter.Current := Iter.Current + 1;
      while Iter.Current <= Iter.List'Last
        and then Iter.List (Iter.Current) = null
      loop
         Iter.Current := Iter.Current + 1;
      end loop;
   end Next;

   ----------
   -- Free --
   ----------

   procedure Free (Config : in out Command_Line_Configuration) is
      procedure Unchecked_Free is new
        Ada.Unchecked_Deallocation
          (Switch_Definitions, Switch_Definitions_List);

      procedure Unchecked_Free is new
        Ada.Unchecked_Deallocation
          (Alias_Definitions, Alias_Definitions_List);

   begin
      if Config /= null then
         Free (Config.Prefixes);
         Free (Config.Sections);
         Free (Config.Usage);
         Free (Config.Help);
         Free (Config.Help_Msg);

         if Config.Aliases /= null then
            for A in Config.Aliases'Range loop
               Free (Config.Aliases (A).Alias);
               Free (Config.Aliases (A).Expansion);
               Free (Config.Aliases (A).Section);
            end loop;

            Unchecked_Free (Config.Aliases);
         end if;

         if Config.Switches /= null then
            for S in Config.Switches'Range loop
               Free (Config.Switches (S).Switch);
               Free (Config.Switches (S).Long_Switch);
               Free (Config.Switches (S).Help);
               Free (Config.Switches (S).Section);
               Free (Config.Switches (S).Argument);
            end loop;

            Unchecked_Free (Config.Switches);
         end if;

         Unchecked_Free (Config);
      end if;
   end Free;

   ----------
   -- Free --
   ----------

   procedure Free (Cmd : in out Command_Line) is
   begin
      Free (Cmd.Expanded);
      Free (Cmd.Coalesce);
      Free (Cmd.Coalesce_Sections);
      Free (Cmd.Coalesce_Params);
      Free (Cmd.Params);
      Free (Cmd.Sections);
   end Free;

   ---------------
   -- Set_Usage --
   ---------------

   procedure Set_Usage
     (Config   : in out Command_Line_Configuration;
      Usage    : String := "[switches] [arguments]";
      Help     : String := "";
      Help_Msg : String := "")
   is
   begin
      if Config = null then
         Config := new Command_Line_Configuration_Record;
      end if;

      Free (Config.Usage);
      Free (Config.Help);
      Free (Config.Help_Msg);

      Config.Usage    := new String'(Usage);
      Config.Help     := new String'(Help);
      Config.Help_Msg := new String'(Help_Msg);
   end Set_Usage;

   ------------------
   -- Display_Help --
   ------------------

   procedure Display_Help (Config : Command_Line_Configuration) is
      function Switch_Name
        (Def     : Switch_Definition;
         Section : String) return String;
      --  Return the "-short, --long=ARG" string for Def.
      --  Returns "" if the switch is not in the section.

      function Param_Name
        (P    : Switch_Parameter_Type;
         Name : String := "ARG") return String;
      --  Return the display for a switch parameter

      procedure Display_Section_Help (Section : String);
      --  Display the help for a specific section ("" is the default section)

      --------------------------
      -- Display_Section_Help --
      --------------------------

      procedure Display_Section_Help (Section : String) is
         Max_Len : Natural := 0;

      begin
         --  ??? Special display for "*"

         New_Line;

         if Section /= "" then
            Put_Line ("Switches after " & Section);
         end if;

         --  Compute size of the switches column

         for S in Config.Switches'Range loop
            Max_Len := Natural'Max
              (Max_Len, Switch_Name (Config.Switches (S), Section)'Length);
         end loop;

         if Config.Aliases /= null then
            for A in Config.Aliases'Range loop
               if Config.Aliases (A).Section.all = Section then
                  Max_Len := Natural'Max
                    (Max_Len, Config.Aliases (A).Alias'Length);
               end if;
            end loop;
         end if;

         --  Display the switches

         for S in Config.Switches'Range loop
            declare
               N : constant String :=
                     Switch_Name (Config.Switches (S), Section);

            begin
               if N /= "" then
                  Put (" ");
                  Put (N);
                  Put ((1 .. Max_Len - N'Length + 1 => ' '));

                  if Config.Switches (S).Help /= null then
                     Put (Config.Switches (S).Help.all);
                  end if;

                  New_Line;
               end if;
            end;
         end loop;

         --  Display the aliases

         if Config.Aliases /= null then
            for A in Config.Aliases'Range loop
               if Config.Aliases (A).Section.all = Section then
                  Put (" ");
                  Put (Config.Aliases (A).Alias.all);
                  Put ((1 .. Max_Len - Config.Aliases (A).Alias'Length + 1
                       => ' '));
                  Put ("Equivalent to " & Config.Aliases (A).Expansion.all);
                  New_Line;
               end if;
            end loop;
         end if;
      end Display_Section_Help;

      ----------------
      -- Param_Name --
      ----------------

      function Param_Name
        (P    : Switch_Parameter_Type;
         Name : String := "ARG") return String
      is
      begin
         case P is
            when Parameter_None =>
               return "";

            when Parameter_With_Optional_Space =>
               return " " & To_Upper (Name);

            when Parameter_With_Space_Or_Equal =>
               return "=" & To_Upper (Name);

            when Parameter_No_Space =>
               return To_Upper (Name);

            when Parameter_Optional =>
               return '[' & To_Upper (Name) & ']';
         end case;
      end Param_Name;

      -----------------
      -- Switch_Name --
      -----------------

      function Switch_Name
        (Def     : Switch_Definition;
         Section : String) return String
      is
         use Ada.Strings.Unbounded;
         Result       : Unbounded_String;
         P1, P2       : Switch_Parameter_Type;
         Last1, Last2 : Integer := 0;

      begin
         if (Section = "" and then Def.Section = null)
           or else (Def.Section /= null and then Def.Section.all = Section)
         then
            if Def.Switch /= null and then Def.Switch.all = "*" then
               return "[any switch]";
            end if;

            if Def.Switch /= null then
               Decompose_Switch (Def.Switch.all, P1, Last1);
               Append (Result, Def.Switch (Def.Switch'First .. Last1));

               if Def.Long_Switch /= null then
                  Decompose_Switch (Def.Long_Switch.all, P2, Last2);
                  Append (Result, ", "
                          & Def.Long_Switch (Def.Long_Switch'First .. Last2));

                  if Def.Argument = null then
                     Append (Result, Param_Name (P2, "ARG"));
                  else
                     Append (Result, Param_Name (P2, Def.Argument.all));
                  end if;

               else
                  if Def.Argument = null then
                     Append (Result, Param_Name (P1, "ARG"));
                  else
                     Append (Result, Param_Name (P1, Def.Argument.all));
                  end if;
               end if;

            --  Def.Switch is null (Long_Switch must be non-null)

            else
               Decompose_Switch (Def.Long_Switch.all, P2, Last2);
               Append (Result,
                       Def.Long_Switch (Def.Long_Switch'First .. Last2));

               if Def.Argument = null then
                  Append (Result, Param_Name (P2, "ARG"));
               else
                  Append (Result, Param_Name (P2, Def.Argument.all));
               end if;
            end if;
         end if;

         return To_String (Result);
      end Switch_Name;

   --  Start of processing for Display_Help

   begin
      if Config = null then
         return;
      end if;

      if Config.Help /= null and then Config.Help.all /= "" then
         Put_Line (Config.Help.all);
      end if;

      if Config.Usage /= null then
         Put_Line ("Usage: "
                   & Base_Name
                     (Ada.Command_Line.Command_Name) & " " & Config.Usage.all);
      else
         Put_Line ("Usage: " & Base_Name (Ada.Command_Line.Command_Name)
                   & " [switches] [arguments]");
      end if;

      if Config.Help_Msg /= null and then Config.Help_Msg.all /= "" then
         Put_Line (Config.Help_Msg.all);

      else
         Display_Section_Help ("");

         if Config.Sections /= null and then Config.Switches /= null then
            for S in Config.Sections'Range loop
               Display_Section_Help (Config.Sections (S).all);
            end loop;
         end if;
      end if;
   end Display_Help;

   ------------
   -- Getopt --
   ------------

   procedure Getopt
     (Config      : Command_Line_Configuration;
      Callback    : Switch_Handler := null;
      Parser      : Opt_Parser := Command_Line_Parser;
      Concatenate : Boolean := True;
      Quiet       : Boolean := False)
   is
      Local_Config    : Command_Line_Configuration := Config;
      Getopt_Switches : String_Access;
      C               : Character := ASCII.NUL;

      Empty_Name      : aliased constant String := "";
      Current_Section : Integer := -1;
      Section_Name    : not null access constant String := Empty_Name'Access;

      procedure Simple_Callback
        (Simple_Switch : String;
         Separator     : String;
         Parameter     : String;
         Index         : Integer);
      --  Needs comments ???

      procedure Do_Callback (Switch, Parameter : String; Index : Integer);

      -----------------
      -- Do_Callback --
      -----------------

      procedure Do_Callback (Switch, Parameter : String; Index : Integer) is
      begin
         --  Do automatic handling when possible

         if Index /= -1 then
            case Local_Config.Switches (Index).Typ is
               when Switch_Untyped =>
                  null;   --  no automatic handling

               when Switch_Boolean =>
                  Local_Config.Switches (Index).Boolean_Output.all :=
                    Local_Config.Switches (Index).Boolean_Value;
                  return;

               when Switch_Integer =>
                  begin
                     if Parameter = "" then
                        Local_Config.Switches (Index).Integer_Output.all :=
                          Local_Config.Switches (Index).Integer_Default;
                     else
                        Local_Config.Switches (Index).Integer_Output.all :=
                          Integer'Value (Parameter);
                     end if;

                  exception
                     when Constraint_Error =>
                        raise Invalid_Parameter
                          with "Expected integer parameter for '"
                            & Switch & "'";
                  end;

                  return;

               when Switch_String =>
                  Free (Local_Config.Switches (Index).String_Output.all);
                  Local_Config.Switches (Index).String_Output.all :=
                    new String'(Parameter);
                  return;

               when Switch_Callback =>
                  Local_Config.Switches (Index).Callback (Switch, Parameter);
                  return;
            end case;
         end if;

         --  Otherwise calls the user callback if one was defined

         if Callback /= null then
            Callback (Switch    => Switch,
                      Parameter => Parameter,
                      Section   => Section_Name.all);
         end if;
      end Do_Callback;

      procedure For_Each_Simple
        is new For_Each_Simple_Switch (Simple_Callback);

      ---------------------
      -- Simple_Callback --
      ---------------------

      procedure Simple_Callback
        (Simple_Switch : String;
         Separator     : String;
         Parameter     : String;
         Index         : Integer)
      is
         pragma Unreferenced (Separator);
      begin
         Do_Callback (Switch    => Simple_Switch,
                      Parameter => Parameter,
                      Index     => Index);
      end Simple_Callback;

   --  Start of processing for Getopt

   begin
      --  We work with a local copy of Config, because Config can be null, for
      --  example if Define_Switch was never called. We could modify Config
      --  itself, but then we would have to make it into an 'in out' parameter,
      --  which would be incompatible.

      if Local_Config = null then
         Local_Config := new Command_Line_Configuration_Record;
      end if;

      if Local_Config.Switches = null then
         Local_Config.Switches := new Switch_Definitions (1 .. 0);
      end if;

      --  Initialize sections

      if Local_Config.Sections = null then
         Local_Config.Sections := new Argument_List'(1 .. 0 => null);
      end if;

      Internal_Initialize_Option_Scan
        (Parser                   => Parser,
         Switch_Char              => Parser.Switch_Character,
         Stop_At_First_Non_Switch => Parser.Stop_At_First,
         Section_Delimiters       => Section_Delimiters (Local_Config));

      Getopt_Switches := new String'
        (Get_Switches (Local_Config, Parser.Switch_Character, Section_Name.all)
         & " h -help");

      --  Initialize output values for automatically handled switches

      for S in Local_Config.Switches'Range loop
         case Local_Config.Switches (S).Typ is
            when Switch_Untyped | Switch_Callback =>
               null;   --  Nothing to do

            when Switch_Boolean =>
               Local_Config.Switches (S).Boolean_Output.all :=
                 not Local_Config.Switches (S).Boolean_Value;

            when Switch_Integer =>
               Local_Config.Switches (S).Integer_Output.all :=
                 Local_Config.Switches (S).Integer_Initial;

            when Switch_String =>
               if Local_Config.Switches (S).String_Output.all = null then
                  Local_Config.Switches (S).String_Output.all :=
                    new String'("");
               end if;
         end case;
      end loop;

      --  For all sections, and all switches within those sections

      loop
         C := Getopt (Switches    => Getopt_Switches.all,
                      Concatenate => Concatenate,
                      Parser      => Parser);

         if C = '*' then
            --  Full_Switch already includes the leading '-'

            Do_Callback (Switch    => Full_Switch (Parser),
                         Parameter => Parameter (Parser),
                         Index     => -1);

         elsif C /= ASCII.NUL then
            if Full_Switch (Parser) = "h"
                 or else
               Full_Switch (Parser) = "-help"
            then
               Display_Help (Local_Config);
               raise Exit_From_Command_Line;
            end if;

            --  Do switch expansion if needed

            For_Each_Simple
              (Local_Config,
               Section   => Section_Name.all,
               Switch    => Parser.Switch_Character & Full_Switch (Parser),
               Parameter => Parameter (Parser));

         else
            if Current_Section = -1 then
               Current_Section := Local_Config.Sections'First;
            else
               Current_Section := Current_Section + 1;
            end if;

            exit when Current_Section > Local_Config.Sections'Last;

            Section_Name := Local_Config.Sections (Current_Section);
            Goto_Section (Section_Name.all, Parser);

            Free (Getopt_Switches);
            Getopt_Switches := new String'
              (Get_Switches
                 (Local_Config, Parser.Switch_Character, Section_Name.all));
         end if;
      end loop;

      Free (Getopt_Switches);

   exception
      when Invalid_Switch =>
         Free (Getopt_Switches);

         --  Message inspired by "ls" on Unix

         if not Quiet then
            Put_Line (Standard_Error,
                      Base_Name (Ada.Command_Line.Command_Name)
                      & ": unrecognized option '"
                      & Full_Switch (Parser)
                      & "'");
            Try_Help;
         end if;

         raise;

      when others =>
         Free (Getopt_Switches);
         raise;
   end Getopt;

   -----------
   -- Build --
   -----------

   procedure Build
     (Line        : in out Command_Line;
      Args        : out GNAT.OS_Lib.Argument_List_Access;
      Expanded    : Boolean := False;
      Switch_Char : Character := '-')
   is
      Iter  : Command_Line_Iterator;
      Count : Natural := 0;

   begin
      Start (Line, Iter, Expanded => Expanded);
      while Has_More (Iter) loop
         if Is_New_Section (Iter) then
            Count := Count + 1;
         end if;

         Count := Count + 1;
         Next (Iter);
      end loop;

      Args := new Argument_List (1 .. Count);
      Count := Args'First;

      Start (Line, Iter, Expanded => Expanded);
      while Has_More (Iter) loop
         if Is_New_Section (Iter) then
            Args (Count) := new String'(Switch_Char & Current_Section (Iter));
            Count := Count + 1;
         end if;

         Args (Count) := new String'(Current_Switch (Iter)
                                     & Current_Separator (Iter)
                                     & Current_Parameter (Iter));
         Count := Count + 1;
         Next (Iter);
      end loop;
   end Build;

   --------------
   -- Try_Help --
   --------------

   --  Note: Any change to the message displayed should also be done in
   --  gnatbind.adb that does not use this interface.

   procedure Try_Help is
   begin
      Put_Line
        (Standard_Error,
         "try """ & Base_Name (Ada.Command_Line.Command_Name, Suffix => ".exe")
         & " --help"" for more information.");
   end Try_Help;

end GNAT.Command_Line;
