Commit 1b72a563 by Justin Squirek Committed by Pierre-Marie de Rodat

[Ada] Argument_String_To_List creates empty items from whitespace

This patch corrects an issue whereby leading whitespace in a non-quoted
argument list passed to Argument_String_To_List caused extraneous empty
arguments to be returned.

2018-07-17  Justin Squirek  <squirek@adacore.com>

gcc/ada/

	* libgnat/s-os_lib.adb (Argument_String_To_List): Fix trimming of
	whitespace.

gcc/testsuite/

	* gnat.dg/split_args.adb: New testcase.

From-SVN: r262783
parent e6bc029a
2018-07-17 Justin Squirek <squirek@adacore.com>
* libgnat/s-os_lib.adb (Argument_String_To_List): Fix trimming of
whitespace.
2018-07-17 Hristian Kirtchev <kirtchev@adacore.com> 2018-07-17 Hristian Kirtchev <kirtchev@adacore.com>
* sem_prag.adb (Has_Visible_State): Do not consider constants as * sem_prag.adb (Has_Visible_State): Do not consider constants as
......
...@@ -178,7 +178,6 @@ package body System.OS_Lib is ...@@ -178,7 +178,6 @@ package body System.OS_Lib is
return Len; return Len;
end Args_Length; end Args_Length;
----------------------------- -----------------------------
-- Argument_String_To_List -- -- Argument_String_To_List --
----------------------------- -----------------------------
...@@ -191,6 +190,9 @@ package body System.OS_Lib is ...@@ -191,6 +190,9 @@ package body System.OS_Lib is
Idx : Integer; Idx : Integer;
New_Argc : Natural := 0; New_Argc : Natural := 0;
Backqd : Boolean := False;
Quoted : Boolean := False;
Cleaned : String (1 .. Arg_String'Length); Cleaned : String (1 .. Arg_String'Length);
Cleaned_Idx : Natural; Cleaned_Idx : Natural;
-- A cleaned up version of the argument. This function is taking -- A cleaned up version of the argument. This function is taking
...@@ -205,75 +207,71 @@ package body System.OS_Lib is ...@@ -205,75 +207,71 @@ package body System.OS_Lib is
Idx := Arg_String'First; Idx := Arg_String'First;
loop loop
exit when Idx > Arg_String'Last; -- Skip extraneous spaces
declare while Idx <= Arg_String'Last and then Arg_String (Idx) = ' ' loop
Backqd : Boolean := False; Idx := Idx + 1;
Quoted : Boolean := False; end loop;
begin
Cleaned_Idx := Cleaned'First;
loop exit when Idx > Arg_String'Last;
-- An unquoted space is the end of an argument
if not (Backqd or Quoted) Cleaned_Idx := Cleaned'First;
and then Arg_String (Idx) = ' ' Backqd := False;
then Quoted := False;
exit;
-- Start of a quoted string loop
-- An unquoted space is the end of an argument
elsif not (Backqd or Quoted) if not (Backqd or Quoted)
and then Arg_String (Idx) = '"' and then Arg_String (Idx) = ' '
then then
Quoted := True; exit;
Cleaned (Cleaned_Idx) := Arg_String (Idx);
Cleaned_Idx := Cleaned_Idx + 1;
-- End of a quoted string and end of an argument -- Start of a quoted string
elsif (Quoted and not Backqd) elsif not (Backqd or Quoted)
and then Arg_String (Idx) = '"' and then Arg_String (Idx) = '"'
then then
Cleaned (Cleaned_Idx) := Arg_String (Idx); Quoted := True;
Cleaned_Idx := Cleaned_Idx + 1; Cleaned (Cleaned_Idx) := Arg_String (Idx);
Idx := Idx + 1; Cleaned_Idx := Cleaned_Idx + 1;
exit;
-- Turn off backquoting after advancing one character -- End of a quoted string and end of an argument
elsif Backqd then elsif (Quoted and not Backqd)
Backqd := False; and then Arg_String (Idx) = '"'
Cleaned (Cleaned_Idx) := Arg_String (Idx); then
Cleaned_Idx := Cleaned_Idx + 1; Cleaned (Cleaned_Idx) := Arg_String (Idx);
Cleaned_Idx := Cleaned_Idx + 1;
Idx := Idx + 1;
exit;
-- Following character is backquoted -- Turn off backquoting after advancing one character
elsif not Backslash_Is_Sep and then Arg_String (Idx) = '\' then elsif Backqd then
Backqd := True; Backqd := False;
Cleaned (Cleaned_Idx) := Arg_String (Idx);
Cleaned_Idx := Cleaned_Idx + 1;
else -- Following character is backquoted
Cleaned (Cleaned_Idx) := Arg_String (Idx);
Cleaned_Idx := Cleaned_Idx + 1;
end if;
Idx := Idx + 1; elsif not Backslash_Is_Sep and then Arg_String (Idx) = '\' then
exit when Idx > Arg_String'Last; Backqd := True;
end loop;
-- Found an argument else
Cleaned (Cleaned_Idx) := Arg_String (Idx);
Cleaned_Idx := Cleaned_Idx + 1;
end if;
New_Argc := New_Argc + 1; Idx := Idx + 1;
New_Argv (New_Argc) := exit when Idx > Arg_String'Last;
new String'(Cleaned (Cleaned'First .. Cleaned_Idx - 1)); end loop;
-- Skip extraneous spaces -- Found an argument
while Idx <= Arg_String'Last and then Arg_String (Idx) = ' ' loop New_Argc := New_Argc + 1;
Idx := Idx + 1; New_Argv (New_Argc) :=
end loop; new String'(Cleaned (Cleaned'First .. Cleaned_Idx - 1));
end;
end loop; end loop;
return new Argument_List'(New_Argv (1 .. New_Argc)); return new Argument_List'(New_Argv (1 .. New_Argc));
......
2018-07-17 Justin Squirek <squirek@adacore.com>
* gnat.dg/split_args.adb: New testcase.
2018-07-17 Ed Schonberg <schonberg@adacore.com> 2018-07-17 Ed Schonberg <schonberg@adacore.com>
* gnat.dg/discr54.adb, gnat.dg/discr54_pkg.ads: New testcase. * gnat.dg/discr54.adb, gnat.dg/discr54_pkg.ads: New testcase.
......
-- { dg-do run }
-- { dg-options "-gnatws" }
with System.OS_Lib; use System.OS_Lib;
procedure Split_Args is
X : constant Argument_List_Access :=
Argument_String_To_List (" -v");
begin
if X'Length /= 1 then
raise Program_Error;
end if;
end Split_Args;
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment