summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorZack Weinberg <zack@owlfolio.org>2023-12-15 10:59:38 -0500
committerZack Weinberg <zack@owlfolio.org>2023-12-15 10:59:38 -0500
commitbfd3894367e4d1c36c514e02c62173cde157f06b (patch)
treecd32a554672615828b83bce5d524eba07cd93299
parentdec7b457b6771588d79190f3f6bd007310fc7fe7 (diff)
downloadautoconf-bfd3894367e4d1c36c514e02c62173cde157f06b.tar.gz
config.status: handle CRLF line endings in AC_CONFIG_HEADERS input
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>
-rw-r--r--lib/autoconf/status.m42
-rw-r--r--tests/torture.at29
2 files changed, 31 insertions, 0 deletions
diff --git a/lib/autoconf/status.m4 b/lib/autoconf/status.m4
index 2bfaf32..e5eb67b 100644
--- a/lib/autoconf/status.m4
+++ b/lib/autoconf/status.m4
@@ -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 = ""
}
+{ sub(/\r\$/, "", \$ 0) }
/^[\t ]*#[\t ]*(define|undef)[\t ]+$ac_word_re([\t (]|\$)/ {
line = \$ 0
split(line, arg, " ")
diff --git a/tests/torture.at b/tests/torture.at
index ba52e12..4e81d0d 100644
--- a/tests/torture.at
+++ b/tests/torture.at
@@ -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. ##