]> git.draconx.ca Git - dxcommon.git/commitdiff
Update DX_COMMAND_OUTPUT to handle newlines and backslashes.
authorNick Bowler <nbowler@draconx.ca>
Wed, 22 Apr 2015 01:47:44 +0000 (21:47 -0400)
committerNick Bowler <nbowler@draconx.ca>
Wed, 28 Jun 2017 23:24:24 +0000 (19:24 -0400)
The 'read' builtin eats backslashes from the input, so this macro fails
to properly handle output containing backslashes.  Since the -r option
is not portable according to the Autoconf manual, fix up the input by
escaping all backslashes.

While we're at it, remove the "feature" which converts newlines to
spaces because it seems rather silly.

m4/cmdout.m4
tests/macros.at

index 5aa39253b397a67e2a3d9f6c2b4c47c661ba34ae..90aa13ea0c361e2d985add8b11547e29acdd46dd 100644 (file)
@@ -1,4 +1,4 @@
-dnl Copyright © 2014 Nick Bowler
+dnl Copyright © 2014-2015 Nick Bowler
 dnl
 dnl License WTFPL2: Do What The Fuck You Want To Public License, version 2.
 dnl This is free software: you are free to do what the fuck you want to.
@@ -7,30 +7,30 @@ dnl There is NO WARRANTY, to the extent permitted by law.
 dnl DX_COMMAND_OUTPUT(variable, command, [action-if-ok], [action-if-failed])
 dnl
 dnl Helper to capture standard output of a shell command.  If the command
-dnl is successful then variable is assigned with its output (with newlines
-dnl converted to spaces), and action-if-ok is performed.  Otherwise, if
-dnl the command is unsuccessful, then variable is not changed, and
-dnl action-if-failed is performed.
+dnl is successful then variable is assigned with its output, and action-if-ok
+dnl is performed.  Otherwise, if the command is unsuccessful, then variable
+dnl is not changed, and action-if-failed is performed.
 AC_DEFUN([DX_COMMAND_OUTPUT], [AC_REQUIRE([_DX_COMMAND_OUTPUT_SETUP])dnl
-AS_IF([$2 >conftest.out 2>&AS_MESSAGE_LOG_FD],
-       [m4_do([dx_fn_cmdout_collect_output $1],
-               [m4_ifnblank([$3], [m4_newline([$3])])])],
-       [$4])
-rm -f conftest.out
-])
+AS_IF([$2 >conftest.do0 2>&AS_MESSAGE_LOG_FD],
+  [m4_do([dx_fn_cmdout_collect_output $1],
+    [m4_ifnblank([$3], [m4_newline([$3])])])],
+  [$4])
+rm -f conftest.do0 conftest.do1])
 
 AC_DEFUN_ONCE([_DX_COMMAND_OUTPUT_SETUP], [m4_divert_push([INIT_PREPARE])dnl
-# Helper function to store the contents of conftest.out into a shell variable.
+# Helper function to store the contents of conftest.do0 into a shell variable.
 dx_fn_cmdout_collect_output () {
   AS_UNSET([$][1])
-  exec 3<conftest.out
+  # Double up backslashes as they will be stripped by read.
+  sed 's/\\/\\\\/g' conftest.do0 >conftest.do1 || return
+  exec 3<conftest.do1
   _dx_save_IFS=$IFS
   IFS=
   while read _dx_tmp <&3
   do
-AS_VAR_SET_IF([$][1],
-       [AS_VAR_APPEND([$][1], [" $_dx_tmp"])],
-       [AS_VAR_SET([$][1], [$_dx_tmp])])
+    AS_VAR_SET_IF([$][1],
+      [AS_VAR_APPEND([$][1], ["$as_nl$_dx_tmp"])],
+      [AS_VAR_SET([$][1], [$_dx_tmp])])
   done
   IFS=$_dx_save_IFS
   exec 3<&-
index f57ecae23976626ab7e9e8f49effb446dfff2746..a5c8c5d2e4d3e78b5e66b8edd556d197d11edeef 100644 (file)
@@ -78,3 +78,25 @@ TEST_AUTORECONF
 TEST_CONFIGURE
 
 AT_CLEANUP
+
+AT_SETUP([DX_COMMAND_OUTPUT])
+
+AT_DATA([expout],
+[[   leading whitespace
+trailing whitespace     @&t@
+embedded\ backslashes
+      @&t@
+backslash\
+newline
+]])
+
+TEST_CONFIGURE_AC(
+[[DX_COMMAND_OUTPUT([var], [cat expout])
+AS@&t@_ECHO(["$var"]) >test.out
+]])
+TEST_AUTORECONF
+TEST_CONFIGURE
+
+AT_CHECK([cat test.out], [0], [expout])
+
+AT_CLEANUP