aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKaren Arutyunov <karen@codesynthesis.com>2017-05-02 00:14:47 +0300
committerBoris Kolpackov <boris@codesynthesis.com>2017-05-02 07:04:47 +0200
commit3da13703991d05ab97639e7db52a92846e68f31a (patch)
treed2efd75871ca838a6ea685dac8921f424dcb1161
parent502c34c80d80791d04a8b79bc9e877dc0f32e33d (diff)
Fix manifest serializer not to break line after backslash
-rw-r--r--libbutl/manifest-serializer.cxx66
-rw-r--r--tests/manifest-serializer/driver.cxx11
2 files changed, 49 insertions, 28 deletions
diff --git a/libbutl/manifest-serializer.cxx b/libbutl/manifest-serializer.cxx
index b152882..96661df 100644
--- a/libbutl/manifest-serializer.cxx
+++ b/libbutl/manifest-serializer.cxx
@@ -158,49 +158,59 @@ namespace butl
//
for (const char* e (s + n); s != e; s++, cl++)
{
+ char pc (c);
c = *s;
bool br (false); // Break the line.
- // If this is a whitespace, see if it's a good place to break the
- // line.
+ // Note that even the "hard" break (see below) is not that hard when it
+ // comes to breaking the line right after the backslash. Doing so would
+ // inject the redundant newline character, as the line-terminating
+ // backslash would be escaped. So we delay breaking till the next
+ // non-backslash character.
//
- if (c == ' ' || c == '\t')
+ if (pc != '\\')
{
- // Find the next whitespace (or the end) and see if it is a better
- // place.
+ // If this is a whitespace, see if it's a good place to break the
+ // line.
//
- for (const char* w (s + 1); ; w++)
+ if (c == ' ' || c == '\t')
{
- if (w == e || *w == ' ' || *w == '\t')
+ // Find the next whitespace (or the end) and see if it is a better
+ // place.
+ //
+ for (const char* w (s + 1); ; w++)
{
- // Is this whitespace past where we need to break? Also see
- // below the "hard" break case for why we use 78 at the end.
- //
- if (cl + static_cast<size_t> (w - s) > (w != e ? 77 : 78))
+ if (w == e || *w == ' ' || *w == '\t')
{
- // Only break if this whitespace is close enough to
- // the end of the line.
+ // Is this whitespace past where we need to break? Also see
+ // below the "hard" break case for why we use 78 at the end.
//
- br = (cl > 57);
- }
+ if (cl + static_cast<size_t> (w - s) > (w != e ? 77 : 78))
+ {
+ // Only break if this whitespace is close enough to
+ // the end of the line.
+ //
+ br = (cl > 57);
+ }
- break;
+ break;
+ }
}
}
- }
- // Do we have to do a "hard" break (i.e., without a whitespace)?
- // If there is just one character left, then instead of writing
- // '\' and then the character on the next line, we might as well
- // write it on this line.
- //
- if (cl == (s + 1 != e ? 77 : 78))
- br = true;
+ // Do we have to do a "hard" break (i.e., without a whitespace)?
+ // If there is just one character left, then instead of writing
+ // '\' and then the character on the next line, we might as well
+ // write it on this line.
+ //
+ if (cl >= (s + 1 != e ? 77 : 78))
+ br = true;
- if (br)
- {
- os_ << '\\' << endl;
- cl = 0;
+ if (br)
+ {
+ os_ << '\\' << endl;
+ cl = 0;
+ }
}
os_ << c;
diff --git a/tests/manifest-serializer/driver.cxx b/tests/manifest-serializer/driver.cxx
index 147ce48..d148f12 100644
--- a/tests/manifest-serializer/driver.cxx
+++ b/tests/manifest-serializer/driver.cxx
@@ -147,10 +147,21 @@ main ()
" Zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz"
"zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz");
+ // Hard break after the backslash/delayed hard break.
+ //
+ string l5 ("xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
+ "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\\"
+ "Yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy");
+
+ string e5 ("xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
+ "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\\Y\\\n"
+ "yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy");
+
assert (test ({{"","1"},{"a",l1},{"",""},{"",""}}, ": 1\na: " + e1 + "\n"));
assert (test ({{"","1"},{"a",l2},{"",""},{"",""}}, ": 1\na: " + e2 + "\n"));
assert (test ({{"","1"},{"a",l3},{"",""},{"",""}}, ": 1\na: " + e3 + "\n"));
assert (test ({{"","1"},{"a",l4},{"",""},{"",""}}, ": 1\na: " + e4 + "\n"));
+ assert (test ({{"","1"},{"a",l5},{"",""},{"",""}}, ": 1\na: " + e5 + "\n"));
// Multi-line value.