aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKaren Arutyunov <karen@codesynthesis.com>2019-04-06 23:47:48 +0300
committerKaren Arutyunov <karen@codesynthesis.com>2019-04-08 16:51:41 +0300
commita16982956c5e87d9b2f238522d902df177ece98e (patch)
tree71f049508596a2004b872d8b5fbdeaf473148696
parent89659b66de7611e9a3f33e7354493ac1c540fe70 (diff)
Add support for manifest_serializer long lines mode
-rw-r--r--libbutl/manifest-rewriter.cxx7
-rw-r--r--libbutl/manifest-rewriter.mxx6
-rw-r--r--libbutl/manifest-serializer.cxx12
-rw-r--r--libbutl/manifest-serializer.mxx12
-rw-r--r--tests/manifest-serializer/driver.cxx30
5 files changed, 54 insertions, 13 deletions
diff --git a/libbutl/manifest-rewriter.cxx b/libbutl/manifest-rewriter.cxx
index 2be53f1..e5b4eae 100644
--- a/libbutl/manifest-rewriter.cxx
+++ b/libbutl/manifest-rewriter.cxx
@@ -41,8 +41,9 @@ using namespace std;
namespace butl
{
manifest_rewriter::
- manifest_rewriter (path p)
+ manifest_rewriter (path p, bool long_lines)
: path_ (move (p)),
+ long_lines_ (long_lines),
fd_ (fdopen (path_,
fdopen_mode::in |
fdopen_mode::out |
@@ -99,7 +100,7 @@ namespace butl
{
os << ' ';
- manifest_serializer s (os, path_.string ());
+ manifest_serializer s (os, path_.string (), long_lines_);
s.write_value (nv.value,
static_cast<size_t> (nv.colon_pos - nv.start_pos + 2));
@@ -127,7 +128,7 @@ namespace butl
ofdstream os (move (fd_));
os << '\n';
- manifest_serializer s (os, path_.string ());
+ manifest_serializer s (os, path_.string (), long_lines_);
s.write_name (nv.name);
os << ':';
diff --git a/libbutl/manifest-rewriter.mxx b/libbutl/manifest-rewriter.mxx
index 6cba682..8ad22b3 100644
--- a/libbutl/manifest-rewriter.mxx
+++ b/libbutl/manifest-rewriter.mxx
@@ -50,7 +50,10 @@ LIBBUTL_MODEXPORT namespace butl
class LIBBUTL_SYMEXPORT manifest_rewriter
{
public:
- manifest_rewriter (path);
+ // Unless long_lines is true, break lines in values (see
+ // manifest_serializer for details).
+ //
+ manifest_rewriter (path, bool long_lines = false);
// Replace the existing value at the specified position (specifically,
// between colon_pos and end_pos) with the specified new value. The new
@@ -70,6 +73,7 @@ LIBBUTL_MODEXPORT namespace butl
private:
path path_;
+ bool long_lines_;
auto_fd fd_;
};
}
diff --git a/libbutl/manifest-serializer.cxx b/libbutl/manifest-serializer.cxx
index 2098551..059c374 100644
--- a/libbutl/manifest-serializer.cxx
+++ b/libbutl/manifest-serializer.cxx
@@ -182,7 +182,6 @@ namespace butl
{
char pc (c);
c = *s;
- bool br (false); // 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
@@ -190,8 +189,10 @@ namespace butl
// backslash would be escaped. So we delay breaking till the next
// non-backslash character.
//
- if (pc != '\\')
+ if (pc != '\\' && !long_lines_)
{
+ bool br (false); // Break the line.
+
// If this is a whitespace, see if it's a good place to break the
// line.
//
@@ -238,7 +239,7 @@ namespace butl
os_ << c;
}
- // What comes next is always a newline. I the last character that
+ // What comes next is always a newline. If the last character that
// we have written is a backslash, escape it.
//
if (c == '\\')
@@ -261,6 +262,11 @@ namespace butl
// - value contains newlines
// - value contains leading/trailing whitespaces
//
+ // Should we use the multi-line mode for large column offsets if the long
+ // lines flag is set? Probably yes, as this improves the manifest
+ // 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')
diff --git a/libbutl/manifest-serializer.mxx b/libbutl/manifest-serializer.mxx
index 7df78d5..1b3ace8 100644
--- a/libbutl/manifest-serializer.mxx
+++ b/libbutl/manifest-serializer.mxx
@@ -56,10 +56,19 @@ LIBBUTL_MODEXPORT namespace butl
using filter_function = bool (const std::string& name,
const std::string& value);
+ // Unless long_lines is true, break lines in values (including multi-line)
+ // so that their length does not exceed 78 characters (including '\n').
+ //
manifest_serializer (std::ostream& os,
const std::string& name,
+ bool long_lines = false,
std::function<filter_function> filter = {})
- : os_ (os), name_ (name), filter_ (std::move (filter)) {}
+ : os_ (os),
+ name_ (name),
+ long_lines_ (long_lines),
+ filter_ (std::move (filter))
+ {
+ }
const std::string&
name () const {return name_;}
@@ -124,6 +133,7 @@ LIBBUTL_MODEXPORT namespace butl
private:
std::ostream& os_;
const std::string name_;
+ bool long_lines_;
const std::function<filter_function> filter_;
};
}
diff --git a/tests/manifest-serializer/driver.cxx b/tests/manifest-serializer/driver.cxx
index d6e538d..4cddb57 100644
--- a/tests/manifest-serializer/driver.cxx
+++ b/tests/manifest-serializer/driver.cxx
@@ -32,6 +32,7 @@ using pairs = vector<pair<string, string>>;
static bool
test (const pairs& manifest,
const string& expected,
+ bool long_lines = false,
manifest_serializer::filter_function f = {});
static bool
@@ -178,7 +179,6 @@ main ()
assert (test ({{"","1"},{"a",l4},{"",""},{"",""}}, ": 1\na: " + e4 + "\n"));
assert (test ({{"","1"},{"a",l5},{"",""},{"",""}}, ": 1\na: " + e5 + "\n"));
-
// Multi-line value.
//
string n ("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa");
@@ -199,6 +199,20 @@ main ()
assert (test ({{"","1"},{"a"," x "},{"",""},{"",""}},
": 1\na: \\\n x \n\\\n"));
+ // The long lines mode.
+ //
+ assert (test ({{"","1"},{"a",l1},{"",""},{"",""}},
+ ": 1\na: " + l1 + "\n",
+ true /* long_lines */));
+
+ assert (test ({{"","1"},{"a", " abc\n" + l1 + "\ndef"},{"",""},{"",""}},
+ ": 1\na: \\\n abc\n" + l1 + "\ndef\n\\\n",
+ true /* long_lines */));
+
+ assert (test ({{"","1"},{n,l1},{"",""},{"",""}},
+ ": 1\n" + n + ": \\\n" + l1 + "\n\\\n",
+ true /* long_lines */));
+
// Carriage return character.
//
assert (test ({{"","1"},{"a","x\ry"},{"",""},{"",""}},
@@ -241,15 +255,18 @@ main ()
//
assert (test ({{"","1"},{"a","abc"},{"b","bca"},{"c","cab"},{"",""},{"",""}},
": 1\na: abc\nc: cab\n",
+ false /* long_lines */,
[] (const string& n, const string&) {return n != "b";}));
}
static string
-serialize (const pairs& m, manifest_serializer::filter_function f = {})
+serialize (const pairs& m,
+ bool long_lines = false,
+ manifest_serializer::filter_function f = {})
{
ostringstream os;
os.exceptions (istream::failbit | istream::badbit);
- manifest_serializer s (os, "", f);
+ manifest_serializer s (os, "", long_lines, f);
for (const auto& p: m)
{
@@ -263,9 +280,12 @@ serialize (const pairs& m, manifest_serializer::filter_function f = {})
}
static bool
-test (const pairs& m, const string& e, manifest_serializer::filter_function f)
+test (const pairs& m,
+ const string& e,
+ bool long_lines,
+ manifest_serializer::filter_function f)
{
- string r (serialize (m, f));
+ string r (serialize (m, long_lines, f));
if (r != e)
{