[Ada] Argument_String_To_List creates empty items from whitespace
authorJustin Squirek <squirek@adacore.com>
Tue, 17 Jul 2018 08:07:42 +0000 (08:07 +0000)
committerPierre-Marie de Rodat <pmderodat@gcc.gnu.org>
Tue, 17 Jul 2018 08:07:42 +0000 (08:07 +0000)
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

gcc/ada/ChangeLog
gcc/ada/libgnat/s-os_lib.adb
gcc/testsuite/ChangeLog
gcc/testsuite/gnat.dg/split_args.adb [new file with mode: 0644]

index c98f8d31b8e7a47d5fd970f0d51d3adf6eee00ff..83196d3b61d36fb338cb47a8a4f7939fcb87c84b 100644 (file)
@@ -1,3 +1,8 @@
+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>
 
        * sem_prag.adb (Has_Visible_State): Do not consider constants as
index 2569a83a8fd2d9db5b3b80cd6b7bb094a0c5dbf9..1464206c83bda28902a43b688673367d19ffabf9 100644 (file)
@@ -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));
index 39caa2f7776ff371b51fdd7b45ccf122301acebf..eace53c3b354625bafc4c61824a34a2f1c4d1b0a 100644 (file)
@@ -1,3 +1,7 @@
+2018-07-17  Justin Squirek  <squirek@adacore.com>
+
+       * gnat.dg/split_args.adb: New testcase.
+
 2018-07-17  Ed Schonberg  <schonberg@adacore.com>
 
        * 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 (file)
index 0000000..3ea39dc
--- /dev/null
@@ -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;