aboutsummaryrefslogtreecommitdiff
path: root/libbutl/manifest-parser.bash.in
diff options
context:
space:
mode:
Diffstat (limited to 'libbutl/manifest-parser.bash.in')
-rw-r--r--libbutl/manifest-parser.bash.in83
1 files changed, 83 insertions, 0 deletions
diff --git a/libbutl/manifest-parser.bash.in b/libbutl/manifest-parser.bash.in
new file mode 100644
index 0000000..e40791e
--- /dev/null
+++ b/libbutl/manifest-parser.bash.in
@@ -0,0 +1,83 @@
+# file : libbutl/manifest-parser.bash.in
+# copyright : Copyright (c) 2014-2018 Code Synthesis Ltd
+# license : MIT; see accompanying LICENSE file
+
+if [ "$butl_manifest_parser" = true ]; then
+ return 0
+else
+ butl_manifest_parser=true
+fi
+
+@import libbutl/utility@
+
+# Parse the manifest from stdin 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:
+#
+# while IFS=: read -r -d '' n v; do
+# ...
+# done < <(butl_parse_manifest)
+#
+function butl_parse_manifest ()
+{
+ printf ":1\0"
+ printf "name:foo\0"
+ printf "version:1.2.3\0"
+ printf "description:foo\nexecutable\0"
+ printf "depends:libfoo\0"
+ printf "depends:libbar\0"
+}
+
+# Start the manifest parsing co-process setting the following "return"
+# variables:
+#
+# butl_manifest_parser_ofd
+# butl_manifest_parser_ifd
+# butl_manifest_parser_pid
+#
+# If <file> is not specified, then read from stdin.
+#
+# The typical usage:
+#
+# butl_manifest_parser_start
+#
+# while IFS=: read -ru "$butl_manifest_parser_ofd" -d '' n v; do
+# ...
+# done
+#
+# butl_manifest_parser_finish
+#
+function butl_manifest_parser_start () # [<file>]
+{
+ if [ "$#" -gt 0 ]; then
+ exec {butl_manifest_parser_ifd}<"$1"
+ else
+ exec {butl_manifest_parser_ifd}<&0
+ fi
+
+ # Note that bash co-process facility is racy: as soon as the process
+ # finishes, bash unsets COPROC/COPROC_PID (my guess would be it checks after
+ # each command in the script). This specific sequence of steps (and the one
+ # in *_finish()) seems to work reliably at least from bash 4.3.30 and
+ # up. See the following resources for details:
+ #
+ # http://wiki.bash-hackers.org/syntax/keywords/coproc
+ # http://tldp.org/LDP/abs/html/bashver4.html (coproc section)
+ # https://lists.gnu.org/archive/html/bug-bash/2014-02/msg00017.html
+ # https://lists.gnu.org/archive/html/bug-bash/2012-12/msg00069.html
+ # https://lists.gnu.org/archive/html/bug-bash/2012-10/msg00027.html
+ #
+ coproc { butl_parse_manifest; } <&"$butl_manifest_parser_ifd"
+ exec {butl_manifest_parser_ofd}<&"${COPROC[0]}"
+ butl_manifest_parser_pid="$COPROC_PID"
+}
+
+# Finish the manifest parsing co-process.
+#
+function butl_manifest_parser_finish ()
+{
+ exec {butl_manifest_parser_ofd}<&-
+ wait "$butl_manifest_parser_pid"
+ exec {butl_manifest_parser_ifd}<&-
+}