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 | 112 +++++++++++++-------------- gcc/testsuite/ChangeLog | 4 + gcc/testsuite/gnat.dg/split_args.adb | 13 ++++ 4 files changed, 77 insertions(+), 57 deletions(-) create mode 100644 gcc/testsuite/gnat.dg/split_args.adb diff --git a/gcc/ada/ChangeLog b/gcc/ada/ChangeLog index c98f8d31b8e7..83196d3b61d3 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 2569a83a8fd2..1464206c83bd 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 + -- Skip extraneous spaces + + while Idx <= Arg_String'Last and then Arg_String (Idx) = ' ' loop + Idx := Idx + 1; + end loop; + exit when Idx > Arg_String'Last; - declare - Backqd : Boolean := False; - Quoted : Boolean := False; + Cleaned_Idx := Cleaned'First; + Backqd := False; + Quoted := False; - begin - Cleaned_Idx := Cleaned'First; + loop + -- An unquoted space is the end of an argument - loop - -- An unquoted space is the end of an argument + if not (Backqd or Quoted) + and then Arg_String (Idx) = ' ' + then + exit; - if not (Backqd or Quoted) - and then Arg_String (Idx) = ' ' - then - exit; + -- Start of a quoted string - -- Start of a quoted string + elsif not (Backqd or Quoted) + and then Arg_String (Idx) = '"' + then + Quoted := True; + Cleaned (Cleaned_Idx) := Arg_String (Idx); + Cleaned_Idx := Cleaned_Idx + 1; - elsif not (Backqd or Quoted) - and then Arg_String (Idx) = '"' - then - Quoted := True; - Cleaned (Cleaned_Idx) := Arg_String (Idx); - Cleaned_Idx := Cleaned_Idx + 1; - - -- End of a quoted string and end of an argument - - 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; - - -- Turn off backquoting after advancing one character - - elsif Backqd then - Backqd := False; - Cleaned (Cleaned_Idx) := Arg_String (Idx); - Cleaned_Idx := Cleaned_Idx + 1; - - -- Following character is backquoted - - elsif not Backslash_Is_Sep and then Arg_String (Idx) = '\' then - Backqd := True; - - else - Cleaned (Cleaned_Idx) := Arg_String (Idx); - Cleaned_Idx := Cleaned_Idx + 1; - end if; + -- End of a quoted string and end of an argument + 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 when Idx > Arg_String'Last; - end loop; + exit; - -- Found an argument + -- Turn off backquoting after advancing one character - New_Argc := New_Argc + 1; - New_Argv (New_Argc) := - new String'(Cleaned (Cleaned'First .. Cleaned_Idx - 1)); + elsif Backqd then + Backqd := False; + Cleaned (Cleaned_Idx) := Arg_String (Idx); + Cleaned_Idx := Cleaned_Idx + 1; - -- Skip extraneous spaces + -- Following character is backquoted - while Idx <= Arg_String'Last and then Arg_String (Idx) = ' ' loop - Idx := Idx + 1; - end loop; - end; + elsif not Backslash_Is_Sep and then Arg_String (Idx) = '\' then + Backqd := True; + + else + Cleaned (Cleaned_Idx) := Arg_String (Idx); + Cleaned_Idx := Cleaned_Idx + 1; + end if; + + Idx := Idx + 1; + exit when Idx > Arg_String'Last; + end loop; + + -- Found an argument + + 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 39caa2f7776f..eace53c3b354 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 000000000000..3ea39dc2c04b --- /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;