From 1b72a5637c0de2ee26e9be0e1a0615c8dc655187 Mon Sep 17 00:00:00 2001 From: Justin Squirek Date: Tue, 17 Jul 2018 08:07:42 +0000 Subject: [PATCH] [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 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 --- gcc/ada/ChangeLog | 5 ++ gcc/ada/libgnat/s-os_lib.adb | 104 +++++++++++++-------------- gcc/testsuite/ChangeLog | 4 ++ gcc/testsuite/gnat.dg/split_args.adb | 13 ++++ 4 files changed, 73 insertions(+), 53 deletions(-) create mode 100644 gcc/testsuite/gnat.dg/split_args.adb diff --git a/gcc/ada/ChangeLog b/gcc/ada/ChangeLog index c98f8d31b8e..83196d3b61d 100644 --- a/gcc/ada/ChangeLog +++ b/gcc/ada/ChangeLog @@ -1,3 +1,8 @@ +2018-07-17 Justin Squirek + + * libgnat/s-os_lib.adb (Argument_String_To_List): Fix trimming of + whitespace. + 2018-07-17 Hristian Kirtchev * sem_prag.adb (Has_Visible_State): Do not consider constants as diff --git a/gcc/ada/libgnat/s-os_lib.adb b/gcc/ada/libgnat/s-os_lib.adb index 2569a83a8fd..1464206c83b 100644 --- a/gcc/ada/libgnat/s-os_lib.adb +++ b/gcc/ada/libgnat/s-os_lib.adb @@ -178,7 +178,6 @@ package body System.OS_Lib is return Len; end Args_Length; - ----------------------------- -- Argument_String_To_List -- ----------------------------- @@ -191,6 +190,9 @@ package body System.OS_Lib is Idx : Integer; New_Argc : Natural := 0; + Backqd : Boolean := False; + Quoted : Boolean := False; + Cleaned : String (1 .. Arg_String'Length); Cleaned_Idx : Natural; -- A cleaned up version of the argument. This function is taking @@ -205,75 +207,71 @@ package body System.OS_Lib is Idx := Arg_String'First; loop - exit when Idx > Arg_String'Last; + -- Skip extraneous spaces - declare - Backqd : Boolean := False; - Quoted : Boolean := False; - - begin - Cleaned_Idx := Cleaned'First; + while Idx <= Arg_String'Last and then Arg_String (Idx) = ' ' loop + Idx := Idx + 1; + end loop; - loop - -- An unquoted space is the end of an argument + exit when Idx > Arg_String'Last; - if not (Backqd or Quoted) - and then Arg_String (Idx) = ' ' - then - exit; + Cleaned_Idx := Cleaned'First; + Backqd := False; + Quoted := False; - -- Start of a quoted string + loop + -- An unquoted space is the end of an argument - elsif not (Backqd or Quoted) - and then Arg_String (Idx) = '"' - then - Quoted := True; - Cleaned (Cleaned_Idx) := Arg_String (Idx); - Cleaned_Idx := Cleaned_Idx + 1; + if not (Backqd or Quoted) + and then Arg_String (Idx) = ' ' + then + exit; - -- End of a quoted string and end of an argument + -- Start of a quoted string - elsif (Quoted and not Backqd) - and then Arg_String (Idx) = '"' - then - Cleaned (Cleaned_Idx) := Arg_String (Idx); - Cleaned_Idx := Cleaned_Idx + 1; - Idx := Idx + 1; - exit; + elsif not (Backqd or Quoted) + and then Arg_String (Idx) = '"' + then + Quoted := True; + Cleaned (Cleaned_Idx) := Arg_String (Idx); + Cleaned_Idx := Cleaned_Idx + 1; - -- Turn off backquoting after advancing one character + -- End of a quoted string and end of an argument - elsif Backqd then - Backqd := False; - Cleaned (Cleaned_Idx) := Arg_String (Idx); - Cleaned_Idx := Cleaned_Idx + 1; + elsif (Quoted and not Backqd) + and then Arg_String (Idx) = '"' + then + 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 - Backqd := True; + elsif Backqd then + Backqd := False; + Cleaned (Cleaned_Idx) := Arg_String (Idx); + Cleaned_Idx := Cleaned_Idx + 1; - else - Cleaned (Cleaned_Idx) := Arg_String (Idx); - Cleaned_Idx := Cleaned_Idx + 1; - end if; + -- Following character is backquoted - Idx := Idx + 1; - exit when Idx > Arg_String'Last; - end loop; + elsif not Backslash_Is_Sep and then Arg_String (Idx) = '\' then + Backqd := True; - -- Found an argument + else + Cleaned (Cleaned_Idx) := Arg_String (Idx); + Cleaned_Idx := Cleaned_Idx + 1; + end if; - New_Argc := New_Argc + 1; - New_Argv (New_Argc) := - new String'(Cleaned (Cleaned'First .. Cleaned_Idx - 1)); + Idx := Idx + 1; + exit when Idx > Arg_String'Last; + end loop; - -- Skip extraneous spaces + -- Found an argument - while Idx <= Arg_String'Last and then Arg_String (Idx) = ' ' loop - Idx := Idx + 1; - end loop; - end; + New_Argc := New_Argc + 1; + New_Argv (New_Argc) := + new String'(Cleaned (Cleaned'First .. Cleaned_Idx - 1)); end loop; return new Argument_List'(New_Argv (1 .. New_Argc)); diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 39caa2f7776..eace53c3b35 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,7 @@ +2018-07-17 Justin Squirek + + * gnat.dg/split_args.adb: New testcase. + 2018-07-17 Ed Schonberg * gnat.dg/discr54.adb, gnat.dg/discr54_pkg.ads: New testcase. diff --git a/gcc/testsuite/gnat.dg/split_args.adb b/gcc/testsuite/gnat.dg/split_args.adb new file mode 100644 index 00000000000..3ea39dc2c04 --- /dev/null +++ b/gcc/testsuite/gnat.dg/split_args.adb @@ -0,0 +1,13 @@ +-- { 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; -- 2.30.2