aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--libbutl/buildfile5
-rw-r--r--libbutl/manifest-parser.bash.in5
-rw-r--r--libbutl/manifest-serializer.bash.in69
-rw-r--r--libbutl/utility.bash.in2
-rw-r--r--tests/manifest-serializer/buildfile7
-rw-r--r--tests/manifest-serializer/driver.in37
-rw-r--r--tests/manifest-serializer/testscript35
7 files changed, 155 insertions, 5 deletions
diff --git a/libbutl/buildfile b/libbutl/buildfile
index cd2643e..1255424 100644
--- a/libbutl/buildfile
+++ b/libbutl/buildfile
@@ -4,5 +4,6 @@
./: bash{$path.base($path.base(*.bash.in))}
-bash{utility}: in{utility}
-bash{manifest-parser}: in{manifest-parser} bash{utility}
+bash{utility}: in{utility}
+bash{manifest-parser}: in{manifest-parser} bash{utility}
+bash{manifest-serializer}: in{manifest-serializer} bash{utility}
diff --git a/libbutl/manifest-parser.bash.in b/libbutl/manifest-parser.bash.in
index e40791e..3ac2fc7 100644
--- a/libbutl/manifest-parser.bash.in
+++ b/libbutl/manifest-parser.bash.in
@@ -2,7 +2,7 @@
# copyright : Copyright (c) 2014-2018 Code Synthesis Ltd
# license : MIT; see accompanying LICENSE file
-if [ "$butl_manifest_parser" = true ]; then
+if [ "$butl_manifest_parser" ]; then
return 0
else
butl_manifest_parser=true
@@ -10,7 +10,8 @@ fi
@import libbutl/utility@
-# Parse the manifest from stdin writing the binary representation to stdout.
+# Parse the manifest reading from stdin and writing the binary representation
+# to stdout.
#
# Normally you would use the start/finish functions below. But if you don't
# care about errors, the following would be the typical usage:
diff --git a/libbutl/manifest-serializer.bash.in b/libbutl/manifest-serializer.bash.in
new file mode 100644
index 0000000..c180a4b
--- /dev/null
+++ b/libbutl/manifest-serializer.bash.in
@@ -0,0 +1,69 @@
+# file : libbutl/manifest-serializer.bash.in
+# copyright : Copyright (c) 2014-2018 Code Synthesis Ltd
+# license : MIT; see accompanying LICENSE file
+
+if [ "$butl_manifest_serializer" ]; then
+ return 0
+else
+ butl_manifest_serializer=true
+fi
+
+@import libbutl/utility@
+
+# Serialize the manifest reading the binary representation from stdin and
+# writing to stdout.
+#
+# Normally you would use the start/finish functions below.
+#
+function butl_serialize_manifest ()
+{
+ local n v
+ while IFS=: read -r -d '' n v; do
+ printf "$n: $v\n"
+ done
+}
+
+# Start the manifest serialization co-process setting the following "return"
+# variables:
+#
+# butl_manifest_serializer_ifd
+# butl_manifest_serializer_ofd
+# butl_manifest_serializer_pid
+#
+# If <file> is not specified, then write to stdout.
+#
+# The typical usage:
+#
+# butl_manifest_serializer_start
+#
+# fd="$butl_manifest_serializer_ifd"
+#
+# printf ":1\0" >&"$fd"
+# printf "name:foo\0" >&"$fd"
+# printf "version:1.2.3\0" >&"$fd"
+#
+# butl_manifest_serializer_finish
+#
+function butl_manifest_serializer_start () # [<file>]
+{
+ if [ "$#" -gt 0 ]; then
+ exec {butl_manifest_serializer_ofd}>"$1"
+ else
+ exec {butl_manifest_serializer_ofd}>&1
+ fi
+
+ # See notes in butl_manifest_parser_start() on bash co-process issues.
+ #
+ coproc { butl_serialize_manifest; } >&"$butl_manifest_serializer_ofd"
+ butl_manifest_serializer_ifd="${COPROC[1]}"
+ butl_manifest_serializer_pid="$COPROC_PID"
+}
+
+# Finish the manifest serialization co-process.
+#
+function butl_manifest_serializer_finish ()
+{
+ exec {butl_manifest_serializer_ifd}<&-
+ wait "$butl_manifest_serializer_pid"
+ exec {butl_manifest_serializer_ofd}<&-
+}
diff --git a/libbutl/utility.bash.in b/libbutl/utility.bash.in
index bcc0f1b..e284c55 100644
--- a/libbutl/utility.bash.in
+++ b/libbutl/utility.bash.in
@@ -2,7 +2,7 @@
# copyright : Copyright (c) 2014-2018 Code Synthesis Ltd
# license : MIT; see accompanying LICENSE file
-if [ "$butl_utility" = true ]; then
+if [ "$butl_utility" ]; then
return 0
else
butl_utility=true
diff --git a/tests/manifest-serializer/buildfile b/tests/manifest-serializer/buildfile
new file mode 100644
index 0000000..f881ee9
--- /dev/null
+++ b/tests/manifest-serializer/buildfile
@@ -0,0 +1,7 @@
+# file : tests/manifest-serializer/buildfile
+# copyright : Copyright (c) 2014-2018 Code Synthesis Ltd
+# license : MIT; see accompanying LICENSE file
+
+import mods = libbutl.bash%bash{manifest-serializer}
+
+exe{driver}: in{driver} $mods testscript
diff --git a/tests/manifest-serializer/driver.in b/tests/manifest-serializer/driver.in
new file mode 100644
index 0000000..9e619e5
--- /dev/null
+++ b/tests/manifest-serializer/driver.in
@@ -0,0 +1,37 @@
+#!/usr/bin/env bash
+
+# file : tests/manifest-serializer/driver.in
+# copyright : Copyright (c) 2014-2018 Code Synthesis Ltd
+# license : MIT; see accompanying LICENSE file
+
+trap "{ exit 1; }" ERR
+set -o errtrace # Trap ERR in functions.
+
+@import libbutl/manifest-serializer@
+
+butl_manifest_serializer_start "$@"
+
+fd="$butl_manifest_serializer_ifd"
+
+while read -r n; do
+
+ printf "%s:" "$n" >&"$fd"
+
+ f=true
+ while read -r v; do
+ if [ -z "$v" ]; then
+ printf "\0" >&"$fd"
+ break
+ else
+ if [ "$f" ]; then
+ f=
+ else
+ printf "\n" >&"$fd"
+ fi
+ printf "%s" "$v" >&"$fd"
+ fi
+ done
+
+done
+
+butl_manifest_serializer_finish
diff --git a/tests/manifest-serializer/testscript b/tests/manifest-serializer/testscript
new file mode 100644
index 0000000..af96cc0
--- /dev/null
+++ b/tests/manifest-serializer/testscript
@@ -0,0 +1,35 @@
+# file : tests/manifest-serializer/testscript
+# copyright : Copyright (c) 2014-2018 Code Synthesis Ltd
+# license : MIT; see accompanying LICENSE file
+
+$* <<EOI >>EOO
+
+1
+
+name
+foo
+
+version
+1.2.3
+
+description
+foo
+executable
+
+depends
+libfoo
+
+depends
+libbar
+
+EOI
+: 1
+name: foo
+version: 1.2.3
+description: foo
+executable
+depends: libfoo
+depends: libbar
+EOO
+
+#@@ TODO: test writing to file instead of stdout.