aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKaren Arutyunov <karen@codesynthesis.com>2021-11-23 21:26:20 +0300
committerKaren Arutyunov <karen@codesynthesis.com>2021-11-24 11:54:40 +0300
commitb90126986fbeec6f42d469e99574096c3f6abc22 (patch)
tree25de68baabd3c51438881478f1ce0c31cb585d2e
parenta1ddd27f217f3ae2664128c72522d76cb0af8c80 (diff)
Don't separate multi-line manifest value introducer from colon with space in manifest serializer
-rw-r--r--libbutl/manifest-rewriter.cxx8
-rw-r--r--libbutl/manifest-serializer.cxx22
-rw-r--r--libbutl/manifest-serializer.hxx10
-rw-r--r--tests/manifest-rewriter/driver.cxx15
-rw-r--r--tests/manifest-roundtrip/manifest4
-rw-r--r--tests/manifest-serializer/driver.cxx38
6 files changed, 55 insertions, 42 deletions
diff --git a/libbutl/manifest-rewriter.cxx b/libbutl/manifest-rewriter.cxx
index 3bddd37..1232e9c 100644
--- a/libbutl/manifest-rewriter.cxx
+++ b/libbutl/manifest-rewriter.cxx
@@ -73,8 +73,6 @@ namespace butl
if (!nv.value.empty ())
{
- os << ' ';
-
manifest_serializer s (os, path_.string (), long_lines_);
// Note that the name can be surrounded with the ASCII whitespace
@@ -86,7 +84,7 @@ namespace butl
//
s.write_value (nv.value,
static_cast<size_t> (nv.colon_pos - nv.start_pos) -
- (nv.name.size () - utf8_length (nv.name)) + 2);
+ (nv.name.size () - utf8_length (nv.name)) + 1);
}
os << suffix;
@@ -118,15 +116,13 @@ namespace butl
if (!nv.value.empty ())
{
- os << ' ';
-
// Note that the name can be surrounded with the ASCII whitespace
// characters and the start_pos refers to the first character in the
// line.
//
s.write_value (nv.value,
static_cast<size_t> (nv.colon_pos - nv.start_pos) -
- (nv.name.size () - n) + 2);
+ (nv.name.size () - n) + 1);
}
os << suffix;
diff --git a/libbutl/manifest-serializer.cxx b/libbutl/manifest-serializer.cxx
index 8f248cf..5875052 100644
--- a/libbutl/manifest-serializer.cxx
+++ b/libbutl/manifest-serializer.cxx
@@ -4,6 +4,7 @@
#include <libbutl/manifest-serializer.hxx>
#include <ostream>
+#include <cassert>
#include <libbutl/utf8.hxx>
#include <libbutl/utility.hxx>
@@ -66,10 +67,7 @@ namespace butl
os_ << ':';
if (!v.empty ())
- {
- os_ << ' ';
- write_value (v, l + 2);
- }
+ write_value (v, l + 1);
os_ << endl;
break;
@@ -272,6 +270,8 @@ namespace butl
void manifest_serializer::
write_value (const string& v, size_t cl)
{
+ assert (!v.empty ());
+
// Consider both \r and \n characters as line separators, and the
// \r\n characters sequence as a single line separator.
//
@@ -290,9 +290,12 @@ namespace butl
// readability, still allowing the user to easily copy the value which
// seems to be the main reason for using the flag.
//
- if (cl > 39 || nl () != string::npos ||
- v.front () == ' ' || v.front () == '\t' ||
- v.back () == ' ' || v.back () == '\t')
+ if (cl + 1 > 39 || // '+ 1' for the space after the colon.
+ nl () != string::npos ||
+ v.front () == ' ' ||
+ v.front () == '\t' ||
+ v.back () == ' ' ||
+ v.back () == '\t')
{
os_ << "\\" << endl; // Multi-line mode introducer.
@@ -317,7 +320,10 @@ namespace butl
os_ << endl << "\\"; // Multi-line mode terminator.
}
else
- write_value (v.c_str (), v.size (), cl);
+ {
+ os_ << ' ';
+ write_value (v.c_str (), v.size (), cl + 1);
+ }
}
// manifest_serialization
diff --git a/libbutl/manifest-serializer.hxx b/libbutl/manifest-serializer.hxx
index dfe37da..43924e7 100644
--- a/libbutl/manifest-serializer.hxx
+++ b/libbutl/manifest-serializer.hxx
@@ -96,10 +96,12 @@ namespace butl
size_t
write_name (const std::string&);
- // Write a value assuming the current line already has the specified
- // codepoint offset. If the resulting line length would be too large then
- // the multi-line representation will be used. It is assumed that the
- // name, followed by the colon, is already written.
+ // Write a non-empty value assuming the current line already has the
+ // specified codepoint offset. If the resulting line length would be too
+ // large then the multi-line representation will be used. For the
+ // single-line representation the space character is written before the
+ // value. It is assumed that the name, followed by the colon, is already
+ // written.
//
void
write_value (const std::string&, std::size_t offset);
diff --git a/tests/manifest-rewriter/driver.cxx b/tests/manifest-rewriter/driver.cxx
index 3e8fecb..3b1dfe9 100644
--- a/tests/manifest-rewriter/driver.cxx
+++ b/tests/manifest-rewriter/driver.cxx
@@ -67,17 +67,26 @@ namespace butl
{{"a", "xyz"}, edit_cmd {"x", "y", "c"}, {"e", "123"}}) ==
":1\na: xyz\nc:d\nx: y\ne: 123");
- assert (edit (":1\na: b", {{"a", "xy\nz"}}) == ":1\na: \\\nxy\nz\n\\");
+ assert (edit (":1\na: b", {{"a", "xy\nz"}}) == ":1\na:\\\nxy\nz\n\\");
+
+ assert (edit (":1\na:\\\nxy\nz\n\\\nb: c", {{"a", "ab\ncd\ne"}}) ==
+ ":1\na:\\\nab\ncd\ne\n\\\nb: c");
+
+ assert (edit (":1\na: \\\nxy\nz\n\\\nb: c", {{"a", "ab\ncd\ne"}}) ==
+ ":1\na:\\\nab\ncd\ne\n\\\nb: c");
+
+ assert (edit (":1\na:\n\\\nxy\nz\n\\\nb: c", {{"a", "ab\ncd\ne"}}) ==
+ ":1\na:\\\nab\ncd\ne\n\\\nb: c");
assert (edit (":1\n", {{"a", "b", ""}}) == ":1\na: b\n");
assert (edit (":1\n abc: b",
{{"abc", "xyz"}}) ==
- ":1\n abc: \\\nxyz\n\\");
+ ":1\n abc:\\\nxyz\n\\");
assert (edit (":1\n a\xD0\xB0g : b",
{{"a\xD0\xB0g", "xyz"}}) ==
- ":1\n a\xD0\xB0g : \\\nxyz\n\\");
+ ":1\n a\xD0\xB0g :\\\nxyz\n\\");
// Test editing of manifests that contains CR characters.
//
diff --git a/tests/manifest-roundtrip/manifest b/tests/manifest-roundtrip/manifest
index 23c2730..4926e29 100644
--- a/tests/manifest-roundtrip/manifest
+++ b/tests/manifest-roundtrip/manifest
@@ -7,7 +7,7 @@ tags: c++, package, manager, bpkg
description: A very very very very very very very very very very very very\
very very very very very very very very very very very very very very very\
very very long description.
-changes: \
+changes:\
1.0.1
- Fixed a very very very very very very very very very very very very very\
very annoying bug.
@@ -26,7 +26,7 @@ requires: ?* linux | windows
requires: c++11
:
path: c:\windows\\
-path: \
+path:\
c:\windows\\
\
diff --git a/tests/manifest-serializer/driver.cxx b/tests/manifest-serializer/driver.cxx
index 4c09038..be3ae25 100644
--- a/tests/manifest-serializer/driver.cxx
+++ b/tests/manifest-serializer/driver.cxx
@@ -189,21 +189,21 @@ main ()
//
string n ("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa");
assert (test ({{"","1"},{n,"x"},{"",""},{"",""}},
- ": 1\n" + n + ": \\\nx\n\\\n"));
+ ": 1\n" + n + ":\\\nx\n\\\n"));
assert (test ({{"","1"},{"a","\n"},{"",""},{"",""}},
- ": 1\na: \\\n\n\n\\\n"));
+ ": 1\na:\\\n\n\n\\\n"));
assert (test ({{"","1"},{"a","\n\n"},{"",""},{"",""}},
- ": 1\na: \\\n\n\n\n\\\n"));
+ ": 1\na:\\\n\n\n\n\\\n"));
assert (test ({{"","1"},{"a","\nx\n"},{"",""},{"",""}},
- ": 1\na: \\\n\nx\n\n\\\n"));
+ ": 1\na:\\\n\nx\n\n\\\n"));
assert (test ({{"","1"},{"a","x\ny\nz"},{"",""},{"",""}},
- ": 1\na: \\\nx\ny\nz\n\\\n"));
+ ": 1\na:\\\nx\ny\nz\n\\\n"));
assert (test ({{"","1"},{"a"," x"},{"",""},{"",""}},
- ": 1\na: \\\n x\n\\\n"));
+ ": 1\na:\\\n x\n\\\n"));
assert (test ({{"","1"},{"a","x "},{"",""},{"",""}},
- ": 1\na: \\\nx \n\\\n"));
+ ": 1\na:\\\nx \n\\\n"));
assert (test ({{"","1"},{"a"," x "},{"",""},{"",""}},
- ": 1\na: \\\n x \n\\\n"));
+ ": 1\na:\\\n x \n\\\n"));
// The long lines mode.
//
@@ -212,42 +212,42 @@ main ()
true /* long_lines */));
assert (test ({{"","1"},{"a", " abc\n" + l1 + "\ndef"},{"",""},{"",""}},
- ": 1\na: \\\n abc\n" + l1 + "\ndef\n\\\n",
+ ": 1\na:\\\n abc\n" + l1 + "\ndef\n\\\n",
true /* long_lines */));
assert (test ({{"","1"},{n,l1},{"",""},{"",""}},
- ": 1\n" + n + ": \\\n" + l1 + "\n\\\n",
+ ": 1\n" + n + ":\\\n" + l1 + "\n\\\n",
true /* long_lines */));
// Carriage return character.
//
assert (test ({{"","1"},{"a","x\ry"},{"",""},{"",""}},
- ": 1\na: \\\nx\ny\n\\\n"));
+ ": 1\na:\\\nx\ny\n\\\n"));
assert (test ({{"","1"},{"a","x\r"},{"",""},{"",""}},
- ": 1\na: \\\nx\n\n\\\n"));
+ ": 1\na:\\\nx\n\n\\\n"));
assert (test ({{"","1"},{"a","x\r\ny"},{"",""},{"",""}},
- ": 1\na: \\\nx\ny\n\\\n"));
+ ": 1\na:\\\nx\ny\n\\\n"));
assert (test ({{"","1"},{"a","x\r\n"},{"",""},{"",""}},
- ": 1\na: \\\nx\n\n\\\n"));
+ ": 1\na:\\\nx\n\n\\\n"));
// Extra three x's are for the leading name part ("a: ") that we
// don't have.
//
assert (test ({{"","1"},{"a","\nxxx" + l1},{"",""},{"",""}},
- ": 1\na: \\\n\nxxx" + e1 + "\n\\\n"));
+ ": 1\na:\\\n\nxxx" + e1 + "\n\\\n"));
assert (test ({{"","1"},{"a","\nxxx" + l2},{"",""},{"",""}},
- ": 1\na: \\\n\nxxx" + e2 + "\n\\\n"));
+ ": 1\na:\\\n\nxxx" + e2 + "\n\\\n"));
assert (test ({{"","1"},{"a","\nxxx" + l3},{"",""},{"",""}},
- ": 1\na: \\\n\nxxx" + e3 + "\n\\\n"));
+ ": 1\na:\\\n\nxxx" + e3 + "\n\\\n"));
assert (test ({{"","1"},{"a","\nxxx" + l4},{"",""},{"",""}},
- ": 1\na: \\\n\nxxx" + e4 + "\n\\\n"));
+ ": 1\na:\\\n\nxxx" + e4 + "\n\\\n"));
// Backslash escaping (simple and multi-line).
//
assert (test ({{"","1"},{"a","c:\\"},{"",""},{"",""}},
": 1\na: c:\\\\\n"));
assert (test ({{"","1"},{"a","c:\\\nd:\\"},{"",""},{"",""}},
- ": 1\na: \\\nc:\\\\\nd:\\\\\n\\\n"));
+ ": 1\na:\\\nc:\\\\\nd:\\\\\n\\\n"));
// Manifest value/comment merging.
//