aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--libbutl/manifest-parser.cxx35
-rw-r--r--libbutl/manifest-parser.hxx4
-rw-r--r--libbutl/manifest-serializer.cxx3
-rw-r--r--libbutl/manifest-serializer.hxx10
-rw-r--r--tests/manifest-roundtrip/buildfile3
-rw-r--r--tests/manifest-roundtrip/driver.cxx26
-rw-r--r--tests/manifest-roundtrip/manifest32
-rw-r--r--tests/manifest-roundtrip/testscript78
8 files changed, 150 insertions, 41 deletions
diff --git a/libbutl/manifest-parser.cxx b/libbutl/manifest-parser.cxx
index 1cb0ec7..ae0d43d 100644
--- a/libbutl/manifest-parser.cxx
+++ b/libbutl/manifest-parser.cxx
@@ -222,7 +222,8 @@ namespace butl
string& v (r.value);
string::size_type n (0); // Size of last non-space character (simple mode).
- // Detect the multi-line mode introducer.
+ // Detect the old-fashioned multi-line mode introducer (like in
+ // 'foo:\<newline>').
//
bool ml (false);
if (c == '\\')
@@ -245,6 +246,38 @@ namespace butl
unget (c);
}
+ // Detect the new-fashioned multi-line mode introducer (like in
+ // 'foo:<newline>\<newline>').
+ //
+ if (!ml && c == '\n')
+ {
+ get ();
+ xchar p1 (peek ());
+
+ if (p1 == '\\')
+ {
+ get ();
+ xchar p2 (peek ());
+
+ if (p2 == '\n')
+ {
+ get (); // Newline is not part of the value so skip it.
+ c = peek ();
+ ml = true;
+ }
+ else if (eos (p2))
+ {
+ c = p2; // Set to EOF.
+ ml = true;
+ }
+ else
+ unget (p1); // Unget '\\'. Note: '\n' will be ungot below.
+ }
+
+ if (!ml)
+ unget (c); // Unget '\n'.
+ }
+
// Multi-line value starts from the line that follows the name.
//
if (ml)
diff --git a/libbutl/manifest-parser.hxx b/libbutl/manifest-parser.hxx
index d53eb42..601fb2d 100644
--- a/libbutl/manifest-parser.hxx
+++ b/libbutl/manifest-parser.hxx
@@ -37,7 +37,7 @@ namespace butl
};
class LIBBUTL_SYMEXPORT manifest_parser:
- protected char_scanner<utf8_validator>
+ protected char_scanner<utf8_validator, 2>
{
public:
// The filter, if specified, is called by next() prior to returning the
@@ -83,7 +83,7 @@ namespace butl
split_comment (const std::string&);
private:
- using base = char_scanner<utf8_validator>;
+ using base = char_scanner<utf8_validator, 2>;
void
parse_next (manifest_name_value&);
diff --git a/libbutl/manifest-serializer.cxx b/libbutl/manifest-serializer.cxx
index 5875052..b0d0324 100644
--- a/libbutl/manifest-serializer.cxx
+++ b/libbutl/manifest-serializer.cxx
@@ -297,6 +297,9 @@ namespace butl
v.back () == ' ' ||
v.back () == '\t')
{
+ if (multiline_v2_)
+ os_ << endl;
+
os_ << "\\" << endl; // Multi-line mode introducer.
// Chunk the value into fragments separated by newlines.
diff --git a/libbutl/manifest-serializer.hxx b/libbutl/manifest-serializer.hxx
index 43924e7..2159901 100644
--- a/libbutl/manifest-serializer.hxx
+++ b/libbutl/manifest-serializer.hxx
@@ -45,14 +45,19 @@ namespace butl
// Unless long_lines is true, break lines in values (including multi-line)
// so that their length does not exceed 78 codepoints (including '\n').
//
+ // Note that the multiline_v2 flag is temporary and should not be used
+ // except by the implementation for testing.
+ //
manifest_serializer (std::ostream& os,
const std::string& name,
bool long_lines = false,
- std::function<filter_function> filter = {})
+ std::function<filter_function> filter = {},
+ bool multiline_v2 = false)
: os_ (os),
name_ (name),
long_lines_ (long_lines),
- filter_ (std::move (filter))
+ filter_ (std::move (filter)),
+ multiline_v2_ (multiline_v2)
{
}
@@ -123,6 +128,7 @@ namespace butl
const std::string name_;
bool long_lines_;
const std::function<filter_function> filter_;
+ bool multiline_v2_;
};
// Serialize a manifest to a stream adding the leading format version pair
diff --git a/tests/manifest-roundtrip/buildfile b/tests/manifest-roundtrip/buildfile
index 8056f64..7ddcc1f 100644
--- a/tests/manifest-roundtrip/buildfile
+++ b/tests/manifest-roundtrip/buildfile
@@ -3,5 +3,4 @@
import libs = libbutl%lib{butl}
-exe{driver}: {hxx cxx}{*} $libs
-exe{driver}: manifest: test.roundtrip = true
+exe{driver}: {hxx cxx}{*} $libs testscript
diff --git a/tests/manifest-roundtrip/driver.cxx b/tests/manifest-roundtrip/driver.cxx
index 4cf35e9..5dc5862 100644
--- a/tests/manifest-roundtrip/driver.cxx
+++ b/tests/manifest-roundtrip/driver.cxx
@@ -15,17 +15,39 @@
using namespace std;
using namespace butl;
+// Usage: argv[0] [-m]
+//
+// Round-trip a manifest reading it from stdin and printing to stdout.
+//
+// -m
+// Serialize multi-line manifest values using the v2 form.
+//
int
-main ()
+main (int argc, const char* argv[])
try
{
+ bool multiline_v2 (false);
+
+ for (int i (1); i != argc; ++i)
+ {
+ string v (argv[i]);
+
+ if (v == "-m")
+ multiline_v2 = true;
+ }
+
// Read/write in binary mode.
//
stdin_fdmode (fdstream_mode::binary);
stdout_fdmode (fdstream_mode::binary);
manifest_parser p (cin, "stdin");
- manifest_serializer s (cout, "stdout");
+
+ manifest_serializer s (cout,
+ "stdout",
+ false /* long_lines */,
+ {} /* filter */,
+ multiline_v2);
for (bool eom (true), eos (false); !eos; )
{
diff --git a/tests/manifest-roundtrip/manifest b/tests/manifest-roundtrip/manifest
deleted file mode 100644
index 4926e29..0000000
--- a/tests/manifest-roundtrip/manifest
+++ /dev/null
@@ -1,32 +0,0 @@
-: 1
-name: libbpkg
-version: 1.0.1
-summary: build2 package manager library
-license: MIT
-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:\
-1.0.1
- - Fixed a very very very very very very very very very very very very very\
- very annoying bug.
-1.0.0
- - Firts public release
- - Lots of really cool features
-\
-url: http://www.codesynthesis.com/projects/libstudxml/
-email: build-users@codesynthesis.com; Public mailing list, posts by\
- non-members are allowed but moderated.
-package-email: boris@codesynthesis.com; Direct email to the author.
-depends: libbutl
-depends: * build2
-depends: ?* bpkg
-requires: ?* linux | windows
-requires: c++11
-:
-path: c:\windows\\
-path:\
-
-c:\windows\\
-\
diff --git a/tests/manifest-roundtrip/testscript b/tests/manifest-roundtrip/testscript
new file mode 100644
index 0000000..91db8b5
--- /dev/null
+++ b/tests/manifest-roundtrip/testscript
@@ -0,0 +1,78 @@
+# file : tests/manifest-roundtrip/testscript
+# license : MIT; see accompanying LICENSE file
+
+: basics
+:
+$* <<EOF >>EOF
+ : 1
+ name: libbpkg
+ version: 1.0.1
+ summary: build2 package manager library
+ license: MIT
+ 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:\
+ 1.0.1
+ - Fixed a very very very very very very very very very very very very very\
+ very annoying bug.
+ 1.0.0
+ - Firts public release
+ - Lots of really cool features
+ \
+ url: http://www.codesynthesis.com/projects/libstudxml/
+ email: build-users@codesynthesis.com; Public mailing list, posts by\
+ non-members are allowed but moderated.
+ package-email: boris@codesynthesis.com; Direct email to the author.
+ depends: libbutl
+ depends: * build2
+ depends: ?* bpkg
+ requires: ?* linux | windows
+ requires: c++11
+ :
+ path: c:\windows\\
+ path:\
+
+ c:\windows\\
+ \
+ EOF
+
+: multiline-v2
+:
+$* -m <<EOF >>EOF
+ : 1
+ name: libbpkg
+ version: 1.0.1
+ summary: build2 package manager library
+ license: MIT
+ 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:
+ \
+ 1.0.1
+ - Fixed a very very very very very very very very very very very very very\
+ very annoying bug.
+ 1.0.0
+ - Firts public release
+ - Lots of really cool features
+ \
+ url: http://www.codesynthesis.com/projects/libstudxml/
+ email: build-users@codesynthesis.com; Public mailing list, posts by\
+ non-members are allowed but moderated.
+ package-email: boris@codesynthesis.com; Direct email to the author.
+ depends: libbutl
+ depends: * build2
+ depends: ?* bpkg
+ requires: ?* linux | windows
+ requires: c++11
+ :
+ path: c:\windows\\
+ path:
+ \
+
+ c:\windows\\
+ \
+ EOF