From 03ff256dc44228c9465cd2040593a72b2d084d1e Mon Sep 17 00:00:00 2001 From: Boris Kolpackov Date: Sat, 21 Jul 2018 12:30:38 +0200 Subject: Add manifest serializer module --- libbutl/buildfile | 5 +-- libbutl/manifest-parser.bash.in | 5 +-- libbutl/manifest-serializer.bash.in | 69 ++++++++++++++++++++++++++++++++++++ libbutl/utility.bash.in | 2 +- tests/manifest-serializer/buildfile | 7 ++++ tests/manifest-serializer/driver.in | 37 +++++++++++++++++++ tests/manifest-serializer/testscript | 35 ++++++++++++++++++ 7 files changed, 155 insertions(+), 5 deletions(-) create mode 100644 libbutl/manifest-serializer.bash.in create mode 100644 tests/manifest-serializer/buildfile create mode 100644 tests/manifest-serializer/driver.in create mode 100644 tests/manifest-serializer/testscript 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 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 () # [] +{ + 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 + +$* <>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. -- cgit v1.1