With the following code and a command line "count -n -sargs -zargs", counting the number of arguments in the "-sargs" section was returning 1, ie including the start of the following section. This now properly returns 0
with GNAT.Command_Line; use GNAT.Command_Line; procedure Count is Count : Natural := 0; begin Initialize_Option_Scan (Section_Delimiters => "sargs zargs vargs"); Goto_Section ("sargs"); loop case Getopt ("*") is when '*' => Count := Count + 1; when others => return Count; end case; end loop; pragma Assert (Count = 0); end Count; Tested on x86_64-pc-linux-gnu, committed on trunk 2011-08-02 Emmanuel Briot <br...@adacore.com> * g-comlin.adb (Goto_Section, Getopt): fix handling of "*" when there are empty sections.
Index: g-comlin.adb =================================================================== --- g-comlin.adb (revision 176998) +++ g-comlin.adb (working copy) @@ -673,15 +673,24 @@ -- especially important when Concatenate is False, since -- otherwise the current argument first character is lost. - 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 '*'; + 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; Set_Parameter @@ -891,7 +900,14 @@ Parser.Current_Section := Parser.Section (Parser.Current_Argument); end if; - return; + + -- Until 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; @@ -1004,6 +1020,9 @@ Delimiter_Found := True; elsif Parser.Section (Index) = 0 then + + -- A previous section delimiter + Delimiter_Found := False; elsif Delimiter_Found then @@ -3186,14 +3205,14 @@ procedure Getopt (Config : Command_Line_Configuration; Callback : Switch_Handler := null; - Parser : Opt_Parser := Command_Line_Parser) + Parser : Opt_Parser := Command_Line_Parser) is Getopt_Switches : String_Access; - C : Character := ASCII.NUL; + C : Character := ASCII.NUL; - Empty_Name : aliased constant String := ""; + Empty_Name : aliased constant String := ""; Current_Section : Integer := -1; - Section_Name : not null access constant String := Empty_Name'Access; + Section_Name : not null access constant String := Empty_Name'Access; procedure Simple_Callback (Simple_Switch : String; @@ -3231,6 +3250,7 @@ Config.Switches (Index).Integer_Output.all := Integer'Value (Parameter); end if; + exception when Constraint_Error => raise Invalid_Parameter