+2019-07-11  Andrew Burgess  <andrew.burgess@embecosm.com>
+
+       * cli/cli-option.c (parse_option): Use extract_string_maybe_quoted
+       to extract string arguments.
+       * common/common-utils.c (extract_string_maybe_quoted): New function.
+       * common/common-utils.h (extract_string_maybe_quoted): Declare.
+
 2019-07-11  Tom Tromey  <tromey@adacore.com>
 
        * main.c (get_init_files): Use GDBINIT, not gdbinit.
 
          }
 
        const char *arg_start = *args;
-       *args = skip_to_space (*args);
-
+       std::string str = extract_string_maybe_quoted (args);
        if (*args == arg_start)
          error (_("-%s requires an argument"), match->name);
 
        option_value val;
-       val.string = savestring (arg_start, *args - arg_start);
+       val.string = xstrdup (str.c_str ());
        return option_def_and_value {*match, match_ctx, val};
       }
 
 
 
 char *savestring (const char *ptr, size_t len);
 
+/* Extract the next word from ARG.  The next word is defined as either,
+   everything up to the next space, or, if the next word starts with either
+   a single or double quote, then everything up to the closing quote.  The
+   enclosing quotes are not returned in the result string.  The pointer in
+   ARG is updated to point to the first character after the end of the
+   word, or, for quoted words, the first character after the closing
+   quote.  */
+
+std::string extract_string_maybe_quoted (const char **arg);
+
 /* The strerror() function can return NULL for errno values that are
    out of range.  Provide a "safe" version that always returns a
    printable string.  */
 
 # test-options xxx", with -string set to $STR.  OPERAND is the
 # expected operand.
 proc expect_string {str operand} {
+    # Dequote the string in the expected output.
+    if { ( [string range $str 0 0] == "\""
+          && [string range $str end end] == "\"")
+        || ([string range $str 0 0] == "'"
+            && [string range $str end end] == "'")} {
+       set str [string range $str 1 end-1]
+    }
     return "-flag 0 -xx1 0 -xx2 0 -bool 0 -enum xxx -uint 0 -zuint-unl 0 -string '$str' -- $operand"
 }
 
            "-string requires an argument"
     }
 
-    res_test_gdb_complete_none \
-       "1 [expect_none ""]" \
-       "$cmd -string STR"
-    gdb_test "$cmd -string STR --" [expect_string "STR" ""]
+    foreach_with_prefix str {
+       "STR"
+       "\"STR\""
+       "\\\"STR"
+       "'STR'"
+       "\\'STR"
+       "\"STR AAA\""
+       "'STR BBB'"
+       "\"STR 'CCC' DDD\""
+       "'STR \"EEE\" FFF'"
+       "\"STR \\\"GGG\\\" HHH\""
+       "'STR \\\'III\\\' JJJ'"
+    } {
+       res_test_gdb_complete_none \
+           "1 [expect_none ""]" \
+           "$cmd -string ${str}"
+       gdb_test "$cmd -string ${str} --" [expect_string "${str}" ""]
 
-    # Completing at "-" after parsing STR should list all options.
-    res_test_gdb_complete_multiple \
-       "1 [expect_string "STR" "-"]" \
-       "$cmd -string STR " "-" "" $all_options
+       # Completing at "-" after parsing STR should list all options.
+       res_test_gdb_complete_multiple \
+           "1 [expect_string "${str}" "-"]" \
+           "$cmd -string ${str} " "-" "" $all_options
 
-    # Check that only FOO is considered part of the string's value.
-    # I.e., that we stop parsing the string at the first whitespace.
-    if {$variant == "require-delimiter"} {
-       res_test_gdb_complete_none \
-           "1 [expect_string "FOO" "BAR"]" \
-           "$cmd -string FOO BAR"
-    } else {
-       res_test_gdb_complete_none "0 BAR" "$cmd -string FOO BAR"
+       # Check that only $STR is considered part of the string's value.
+       # I.e., that we stop parsing the string at the first
+       # whitespace or after the closing quote of $STR.
+       if {$variant == "require-delimiter"} {
+           res_test_gdb_complete_none \
+               "1 [expect_string "${str}" "BAR"]" \
+               "$cmd -string ${str} BAR"
+       } else {
+           res_test_gdb_complete_none "0 BAR" "$cmd -string ${str} BAR"
+       }
+       gdb_test "$cmd -string ${str} BAR --" "Unrecognized option at: BAR --"
     }
-    gdb_test "$cmd -string FOO BAR --" "Unrecognized option at: BAR --"
 }
 
 # Run the options framework tests first.