[Top][All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[PATCH] Support newlines in cache variables

From: Quinn Grier
Subject: [PATCH] Support newlines in cache variables
Date: Fri, 12 Aug 2016 21:34:29 -0500
User-agent: Mozilla/5.0 (Windows NT 6.3; WOW64; rv:45.0) Gecko/20100101 Thunderbird/45.2.0

The old _AC_CACHE_DUMP code disallowed newlines in cache variables. It
would unset all variables (including non-cache variables) that contain
newlines and output all remaining cache variables. Because unset halts
the (sub)shell when used on a readonly variable, this also disallowed
newlines in all readonly variables (including non-cache variables).

The new code translates newlines to $as_nl expansions and still handles
implementations of set that fail to quote. The important observation is
that bogus variable names in the output of set can be identified using
${name+x} regardless of quoting bugs. The new code works as follows:

      for each line in the output of set
        if the line looks like an assignment
          if the variable name contains _cv_
            if the variable name is not bogus
              if the variable has not been seen yet
                output the variable appropriately
                add the variable to the seen list

The seen list is included to be maximally conservative. Without it,
certain values can cause cache variables to be output multiple times,
which is harmless from a technical perspective but may confuse callers
doing unusual things. For example, ac_cv_x=${as_nl}ac_cv_x= will cause
ac_cv_x to be listed twice. Note that the seen list can be disabled by
removing the ac_seen=$ac_seen$ac_var, assignment.

The $as_nl expansions are double-quoted to handle the Solaris and Ultrix
bugs described in the manual for the ${var=value} syntax. Note that this
syntax is used by AC_CACHE_SAVE, the main caller of _AC_CACHE_DUMP.

* lib/autoconf/general.m4 (_AC_CACHE_DUMP): Support newlines.
This also happens to add support for readonly variables that
contain newlines, which would previously break this code.
 NEWS                    |  3 +++
 doc/autoconf.texi       |  9 ++++-----
 lib/autoconf/general.m4 | 52 +++++++++++++++++++++----------------------------
 3 files changed, 29 insertions(+), 35 deletions(-)

diff --git a/NEWS b/NEWS
index 5f05ad6..d52e8a6 100644
--- a/NEWS
+++ b/NEWS
@@ -27,6 +27,9 @@ GNU Autoconf NEWS - User visible changes.
    is now deprecated.  If you really need that behavior use
+** Newlines are now supported in cache variables.  They are translated
+   to expansions of a M4sh-reserved variable that contains a newline.
 ** Macros
 - New macro AC_C__GENERIC.
diff --git a/doc/autoconf.texi b/doc/autoconf.texi
index 1838d6b..f2b89d6 100644
--- a/doc/autoconf.texi
+++ b/doc/autoconf.texi
@@ -10087,11 +10087,10 @@ For example, @samp{broken} or @samp{set}.  This part 
of the name may
 be omitted if it does not apply.
 @end table
-The values assigned to cache variables may not contain newlines.
-Usually, their values are Boolean (@samp{yes} or @samp{no}) or the
-names of files or functions; so this is not an important restriction.
address@hidden Variable Index} for an index of cache variables with
-documented semantics.
+The values assigned to cache variables may contain newlines, which are
+translated to expansions of a M4sh-reserved variable that contains a
+newline.  For an index of cache variables with documented semantics,
address@hidden Variable Index}.
 @node Cache Files
diff --git a/lib/autoconf/general.m4 b/lib/autoconf/general.m4
index c15fb13..e203092 100644
--- a/lib/autoconf/general.m4
+++ b/lib/autoconf/general.m4
@@ -1978,42 +1978,34 @@ fi
 # --------------
 # Dump the cache to stdout.  It can be in a pipe (this is a requirement).
-[# The following way of writing the cache mishandles newlines in values,
-# but we know of no workaround that is simple, portable, and efficient.
-# So, we kill variables containing newlines.
 # Ultrix sh set writes to stderr and can't be redirected directly,
 # and sets the high bit in the cache file unless we assign to the vars.
+  ac_seen=,
   for ac_var in `(set) 2>&1 | sed -n 
['s/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p']`; do
-    eval ac_val=\$$ac_var
-    case $ac_val in #(
-    *${as_nl}*)
-      case $ac_var in #(
-      *_cv_*) AC_MSG_WARN([cache variable $ac_var contains a newline]) ;;
-      esac
-      case $ac_var in #(
-      _ | IFS | as_nl) ;; #(
-      BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #(
-      *) AS_UNSET([$ac_var]) ;;
+    case $ac_var in #(
+    *_cv_*)
+      eval ac_hit=\$[]{$ac_var+x}
+      case $ac_hit in #(
+      x)
+        case $ac_seen in #(
+        *,$ac_var,*) ;; #(
+        *)
+          eval ac_val=\$$ac_var
+          sed "
+            s/'/'\\\\''/g
+            1s/^/$ac_var='/
+            \$!s/\$/'\"\$as_nl\"'/
+            \$s/\$/'/
+          " <<_ACEOF | tr -d "$as_nl"; echo
+          ac_seen=$ac_seen$ac_var, ;;
+        esac ;;
       esac ;;
-  done
-  (set) 2>&1 |
-    case $as_nl`(ac_space=' '; set) 2>&1` in #(
-    *${as_nl}ac_space=\ *)
-      # `set' does not quote correctly, so add quotes: double-quote
-      # substitution turns \\\\ into \\, and sed turns \\ into \.
-      sed -n \
-       ["s/'/'\\\\''/g;
-         s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p"]
-      ;; #(
-    *)
-      # `set' quotes correctly as required by POSIX, so do not add quotes.
-      sed -n ["/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p"]
-      ;;
-    esac |
-    sort
+  done | sort

reply via email to

[Prev in Thread] Current Thread [Next in Thread]