On Tue, Nov 01, 2016 at 08:29:10PM +0100, Jean-Marc Lasgouttes wrote:

> I am surprised that addArg does not need to add a space to the current
> argument.

It appears I got away with this because splitArg() handles double-quotes:

  // Extracts arguments from str into args. Arguments are delimted by
  // whitespace or by double quotes.

I've changed addArg() to add a space between arguments.

> I assume that one should also escape double quptes in the string.
> If I am not mistaken, they are handled when parsing the arguments.

Attached are two patches. The first allows for spaces in branch names.
The second allows for double-quotes.

For the first patch, I changed the write() routine to add quotes around
the branch name. Otherwise, read() gets confused. But should I instead
have changed the read routine()?

I'm not sure the second patch is correct. The branch name won't work
with a backslash at the end. I don't know how to fix this, because we
don't store how many arguments there are. Ideally, we would have an
argument class, right?

Scott
From ab3400821f8b01fcf78128352ff33d525f447199 Mon Sep 17 00:00:00 2001
From: Scott Kostyshak <skost...@lyx.org>
Date: Thu, 20 Oct 2016 22:41:31 -0400
Subject: [PATCH 1/2] Fix color when branch name has a space

The arguments are now double-quoted. This is handled by a new helper
function, FuncRequest::addArg().
---
 src/Buffer.cpp                       |  6 ++++--
 src/FuncRequest.cpp                  | 11 +++++++++++
 src/FuncRequest.h                    |  2 ++
 src/frontends/qt4/GuiApplication.cpp |  4 ++--
 src/frontends/qt4/GuiDocument.cpp    | 12 ++++++++----
 src/insets/InsetBranch.cpp           |  3 ++-
 6 files changed, 29 insertions(+), 9 deletions(-)

diff --git a/src/Buffer.cpp b/src/Buffer.cpp
index 86da237..fc68d30 100644
--- a/src/Buffer.cpp
+++ b/src/Buffer.cpp
@@ -2776,10 +2776,12 @@ void Buffer::dispatch(FuncRequest const & func, 
DispatchResult & dr)
                        } else {
                                undo().recordUndoBufferParams(CursorData());
                                branch_list.add(branch_name);
+                               FuncRequest fr(LFUN_SET_COLOR);
                                branch = branch_list.find(branch_name);
+                               fr.addArg(branch_name);
                                string const x11hexname = 
X11hexname(branch->color());
-                               docstring const str = branch_name + ' ' + 
from_ascii(x11hexname);
-                               lyx::dispatch(FuncRequest(LFUN_SET_COLOR, str));
+                               fr.addArg(from_ascii(x11hexname));
+                               lyx::dispatch(fr);
                                dr.setError(false);
                                dr.screenUpdate(Update::Force);
                        }
diff --git a/src/FuncRequest.cpp b/src/FuncRequest.cpp
index 224ba27..db1b940 100644
--- a/src/FuncRequest.cpp
+++ b/src/FuncRequest.cpp
@@ -119,6 +119,17 @@ string FuncRequest::getLongArg(unsigned int i) const
 }
 
 
+void FuncRequest::addArg(docstring const & str)
+{
+       // adding spaces between arguments is not necessary if arguments have
+       // double-quotes (see splitArg()). But even in this case it makes the
+       // argument more readable.
+       if (!argument_.empty())
+               argument_ = argument_ + ' ';
+       argument_ = argument_ + '"' + str + '"';
+}
+
+
 bool operator==(FuncRequest const & lhs, FuncRequest const & rhs)
 {
        return lhs.action() == rhs.action() && lhs.argument() == rhs.argument();
diff --git a/src/FuncRequest.h b/src/FuncRequest.h
index a5822f4..dc5895e 100644
--- a/src/FuncRequest.h
+++ b/src/FuncRequest.h
@@ -85,6 +85,8 @@ public:
        /// argument parsing, extract argument i as std::string,
        /// eating all characters up to the end of the command line
        std::string getLongArg(unsigned int i) const;
+       /// Adds an argument
+       void addArg(docstring const &);
 
        /// 
        static FuncRequest const unknown;
diff --git a/src/frontends/qt4/GuiApplication.cpp 
b/src/frontends/qt4/GuiApplication.cpp
index 0eb55ba..048ce0f 100644
--- a/src/frontends/qt4/GuiApplication.cpp
+++ b/src/frontends/qt4/GuiApplication.cpp
@@ -1738,8 +1738,8 @@ void GuiApplication::dispatch(FuncRequest const & cmd, 
DispatchResult & dr)
        }
 
        case LFUN_SET_COLOR: {
-               string lyx_name;
-               string const x11_name = split(to_utf8(cmd.argument()), 
lyx_name, ' ');
+               string lyx_name = cmd.getArg(0);
+               string x11_name = cmd.getArg(1);
                if (lyx_name.empty() || x11_name.empty()) {
                        if (current_view_)
                                current_view_->message(
diff --git a/src/frontends/qt4/GuiDocument.cpp 
b/src/frontends/qt4/GuiDocument.cpp
index 2293ce3..25594cd 100644
--- a/src/frontends/qt4/GuiDocument.cpp
+++ b/src/frontends/qt4/GuiDocument.cpp
@@ -4129,8 +4129,10 @@ void GuiDocument::dispatchParams()
                        Branch const * branch = branchlist.find(current_branch);
                        string const x11hexname = X11hexname(branch->color());
                        // display the new color
-                       docstring const str = current_branch + ' ' + 
from_ascii(x11hexname);
-                       dispatch(FuncRequest(LFUN_SET_COLOR, str));
+                       FuncRequest fr(LFUN_SET_COLOR);
+                       fr.addArg(current_branch);
+                       fr.addArg(from_ascii(x11hexname));
+                       dispatch(fr);
                }
 
                // Open insets of selected branches, close deselected ones
@@ -4152,8 +4154,10 @@ void GuiDocument::dispatchParams()
                        Index const * index = 
indiceslist.findShortcut(current_index);
                        string const x11hexname = X11hexname(index->color());
                        // display the new color
-                       docstring const str = current_index + ' ' + 
from_ascii(x11hexname);
-                       dispatch(FuncRequest(LFUN_SET_COLOR, str));
+                       FuncRequest fr(LFUN_SET_COLOR);
+                       fr.addArg(current_index);
+                       fr.addArg(from_ascii(x11hexname));
+                       dispatch(fr);
                }
        }
        // FIXME LFUN
diff --git a/src/insets/InsetBranch.cpp b/src/insets/InsetBranch.cpp
index 3cde061..1c7aefd 100644
--- a/src/insets/InsetBranch.cpp
+++ b/src/insets/InsetBranch.cpp
@@ -394,7 +394,8 @@ void InsetBranch::updateBuffer(ParIterator const & it, 
UpdateType utype)
 
 void InsetBranchParams::write(ostream & os) const
 {
-       os << to_utf8(branch) 
+       // double-quotes allow for branch names with spaces
+       os << '"' << to_utf8(branch) << '"'
           << '\n' 
           << "inverted " 
           << inverted;
-- 
2.7.4

From 77b27192d61a6afd13c172dbec5cd022d8fec21e Mon Sep 17 00:00:00 2001
From: Scott Kostyshak <skost...@lyx.org>
Date: Sat, 4 Mar 2017 14:39:46 -0500
Subject: [PATCH 2/2] Allow escaped quotes in arguments

This allows for, e.g., branch names to have double-quotes in them.

Note that a backslash cannot be at the end of an argument, unless
the first character of the argument is not a double-quote (in which
case the argument will be interpreted as space-delimited).
---
 src/FuncRequest.cpp | 16 ++++++++++++++--
 1 file changed, 14 insertions(+), 2 deletions(-)

diff --git a/src/FuncRequest.cpp b/src/FuncRequest.cpp
index db1b940..b69b54d 100644
--- a/src/FuncRequest.cpp
+++ b/src/FuncRequest.cpp
@@ -88,9 +88,20 @@ void splitArg(vector<string> & args, string const & str,
                string s;
                is >> c;
                if (is) {
-                       if (c == '"')
+                       if (c == '"') {
                                // get quote delimited argument
                                getline(is, s, '"');
+                               char lastch = *s.rbegin();
+                               // allow for escaped double-quotes
+                               while (lastch == '\\') {
+                                       s.pop_back();
+                                       s.append("\"");
+                                       string s2;
+                                       getline(is, s2, '"');
+                                       s.append(s2);
+                                       lastch = *s.rbegin();
+                               }
+                       }
                        else {
                                // get whitespace delimited argument
                                is.putback(c);
@@ -126,7 +137,8 @@ void FuncRequest::addArg(docstring const & str)
        // argument more readable.
        if (!argument_.empty())
                argument_ = argument_ + ' ';
-       argument_ = argument_ + '"' + str + '"';
+       docstring const strQuoted = subst(str, from_ascii("\""), 
from_ascii("\\\""));
+       argument_ = argument_ + '"' + strQuoted + '"';
 }
 
 
-- 
2.7.4

Attachment: signature.asc
Description: PGP signature

Reply via email to