]> git.ipfire.org Git - thirdparty/autoconf.git/commitdiff
config.status: handle CRLF line endings in AC_CONFIG_HEADERS input
authorZack Weinberg <zack@owlfolio.org>
Fri, 15 Dec 2023 15:59:38 +0000 (10:59 -0500)
committerZack Weinberg <zack@owlfolio.org>
Fri, 15 Dec 2023 15:59:38 +0000 (10:59 -0500)
On systems that normally use Unix line endings, if config.h.in has
somehow been generated with DOS line endings, then awk will treat
each CR character as part of the line.  This breaks the regular
expressions used to edit config.h.in into config.h

To fix, manually strip trailing CRs from each “input record” before
any other processing.  For consistency I also made this change to the
code dealing with AC_CONFIG_FILES substitutions.  On systems that use
DOS line endings, both changes should be no-ops.

Reported by David Allsopp in <https://savannah.gnu.org/support/?110554>.
He offered a different patch, which also worked on my machine, but it
used a regular expression as the third argument to ‘split’, which
might not be portable across awk implementations (the gawk manual is
unclear).  Also, it could produce a config.h with _inconsistent_ line
endings.

* lib/autoconf/status.m4 (_AC_OUTPUT_HEADERS_PREPARE): In the awk
  script, strip a trailing CR from each record as the first action.
  (_AC_OUTPUT_FILES_PREPARE): Likewise.
* tests/torture.at (CRLF line endings in .in files): New test.

Co-authored-by: David Allsopp <david@davidallsopp.com>
lib/autoconf/status.m4
tests/torture.at

index 2bfaf32bccd0a72773e5fd7d87c37b3835a559a2..e5eb67bff663f7ed0365a388c99c17c3c096b381 100644 (file)
@@ -503,6 +503,7 @@ cat >>"\$ac_tmp/subs1.awk" <<_ACAWK &&
 }
 {
   line = $ 0
+  sub(/\r\$/, "", line)
   nfields = split(line, field, "@")
   substed = 0
   len = length(field[1])
@@ -824,6 +825,7 @@ cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
   for (key in D) D_is_set[key] = 1
   FS = "\a"
 }
+{ sub(/\r\$/, "", \$ 0) }
 /^[\t ]*#[\t ]*(define|undef)[\t ]+$ac_word_re([\t (]|\$)/ {
   line = \$ 0
   split(line, arg, " ")
index ba52e12dc8c64d74ee5a89a7f1b5dee9e372e5d1..4e81d0dce1449dcff6a6040e7295995c147d7116 100644 (file)
@@ -1093,6 +1093,35 @@ AT_CHECK_DEFINES([[#define foo one
 
 AT_CLEANUP
 
+## ------------------- ##
+## CRLF line endings.  ##
+## ------------------- ##
+
+AT_SETUP([CRLF line endings in .in files])
+
+AT_CONFIGURE_AC([[
+AC_DEFINE([MACRO], [1], [Define MACRO as 1 always.])
+AC_SUBST([VARIABLE], [value])
+AC_CONFIG_FILES([config.out:config.oin])
+]])
+
+# Shell `printf` should understand \r.
+AT_CHECK([printf '%s\r\n' \
+  '/* Define MACRO as 1 always. */' \
+  '#undef MACRO' \
+  > config.hin])
+AT_CHECK([printf '%s\r\n' \
+  'VARIABLE=@VARIABLE@' \
+  > config.oin])
+
+AT_SKIP_IF([grep '\\r' config.hin > /dev/null])
+
+AT_CHECK_AUTOCONF
+AT_CHECK_CONFIGURE
+AT_CHECK([grep '#define MACRO 1' config.h > /dev/null])
+AT_CHECK([grep 'VARIABLE=value' config.out > /dev/null])
+
+AT_CLEANUP
 
 ## ------------------------------------ ##
 ## AC_SUBST: variable name validation.  ##