[SV 41983] Support omitting the text argument to $(file ...)
authorPaul Smith <psmith@gnu.org>
Tue, 8 Apr 2014 22:25:27 +0000 (18:25 -0400)
committerPaul Smith <psmith@gnu.org>
Mon, 7 Jul 2014 05:59:03 +0000 (01:59 -0400)
Reported by Tim Murphy <tnmurphy@gmail.com>
* function.c (func_file): Only write TEXT if it is not NULL.
* NEWS, doc/make.texi: Document the new feature
* tests/scripts/functions/file: Verify that the no-text version of
  $(file ...) works and doesn't add a newline.

NEWS
doc/make.texi
function.c
tests/scripts/functions/file

diff --git a/NEWS b/NEWS
index 05f4e8d4389bfd46c822e7e3fba37f262c95da47..ae725fc10a5875d1400e088345f4bb0f52ff1343 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -15,6 +15,10 @@ A complete list of bugs fixed in this version is available here:
 
 http://sv.gnu.org/bugs/index.php?group=make&report_id=111&fix_release_id=105&set=custom
 
+* Allow a no-text-argument form of the $(file ...) function.  Without a text
+  argument nothing is written to the file: it is simply opened in the
+  requested mode, then closed again.
+
 * Change the fatal error for mixed explicit and implicit rules, that was
   introduced in GNU make 3.82, to a non-fatal error.  However, this syntax is
   still deprecated and may return to being illegal in a future version of GNU
@@ -771,7 +775,7 @@ Version 3.69 (07 Nov 1993)
   have reversed the change made in version 3.68 because it turned out to
   cause a paradoxical situation in cases like:
 
-       export variable = $(shell echo value)
+        export variable = $(shell echo value)
 
   When Make attempted to put this variable in the environment for a
   recipe, it would try expand the value by running the shell command
@@ -794,8 +798,8 @@ Version 3.68 (28 Jul 1993)
   foo.a(b.o) bar.a(c.o) bar.a(d.o)'.
 
 * A suffix rule `.X.a' now produces two pattern rules:
-       (%.o): %.X      # Previous versions produced only this.
-       %.a: %.X        # Now produces this as well, just like other suffixes.
+        (%.o): %.X     # Previous versions produced only this.
+        %.a: %.X       # Now produces this as well, just like other suffixes.
 
 * The new flag `--warn-undefined-variables' says to issue a warning message
   whenever Make expands a reference to an undefined variable.
@@ -865,15 +869,15 @@ Version 3.63 (22 Jan 1993)
   no longer automatically put into the environments of the recipe lines that
   Make runs.  Instead, only variables specified on the command line or in
   the environment are exported by default.  To export others, use:
-       export VARIABLE
+        export VARIABLE
   or you can define variables with:
-       export VARIABLE = VALUE
+        export VARIABLE = VALUE
   or:
-       export VARIABLE := VALUE
+        export VARIABLE := VALUE
   You can use just:
-       export
+        export
   or:
-       .EXPORT_ALL_VARIABLES:
+        .EXPORT_ALL_VARIABLES:
   to get the old behavior.  See the node `Variables/Recursion' in the manual
   for a full description.
 
@@ -893,9 +897,9 @@ Version 3.63 (22 Jan 1993)
 
 * A single `include' directive can now specify more than one makefile to
   include, like this:
-       include file1 file2
+        include file1 file2
   You can also use shell file name patterns in an `include' directive:
-       include *.mk
+        include *.mk
 
 * The default directories to search for included makefiles, and for
   libraries specified with `-lNAME', are now set by configuration.
@@ -1031,7 +1035,7 @@ Version 3.49
 * The `wildcard' variable expansion function now expands ~ and ~USER.
 
 * Messages indicating failed recipe lines now contain the target name:
-       make: *** [target] Error 1
+        make: *** [target] Error 1
 
 * The `-p' output format has been changed somewhat to look more like
   makefile rules and to give all information that Make has about files.
index 8fbdb614f5b5b597fcf10e06e788c152aa0ec2b8..21e32de25274e191d4be52ba187cc99eab057f99 100644 (file)
@@ -1528,7 +1528,7 @@ A rule is always expanded the same way, regardless of the form:
 
 @example
 @var{immediate} : @var{immediate} ; @var{deferred}
-       @var{deferred}
+        @var{deferred}
 @end example
 
 That is, the target and prerequisite sections are expanded immediately,
@@ -7516,7 +7516,7 @@ exist.
 The syntax of the @code{file} function is:
 
 @example
-$(file @var{op} @var{filename},@var{text})
+$(file @var{op} @var{filename}[,@var{text}])
 @end example
 
 The operator @var{op} can be either @code{>} which indicates overwrite
@@ -7528,8 +7528,9 @@ When the @code{file} function is expanded all its arguments are
 expanded first, then the file indicated by @var{filename} will be
 opened in the mode described by @var{op}.  Finally @var{text} will be
 written to the file.  If @var{text} does not already end in a newline,
-a final newline will be written.  The result of evaluating the
-@code{file} function is always the empty string.
+even if empty, a final newline will be written.  If the @var{text}
+argument is not given, nothing will be written.  The result of
+evaluating the @code{file} function is always the empty string.
 
 It is a fatal error if the file cannot be opened for writing, or if
 the write operation fails.
@@ -7556,7 +7557,7 @@ input file, you might write your recipe like this:
 @example
 @group
 program: $(OBJECTS)
-        $(file >$@@.in,) $(foreach O,$^,$(file >>$@@.in,$O))
+        $(file >$@@.in) $(foreach O,$^,$(file >>$@@.in,$O))
         $(CMD) $(CMDFLAGS) @@$@@.in
         @@rm $@@.in
 @end group
index 72ecb7ff9d51df72a439c7bbe42e7c047989d15e..bb62187d4f3562994dd9bcef75ee22eae1d20827 100644 (file)
@@ -2154,18 +2154,18 @@ func_file (char *o, char **argv, const char *funcname UNUSED)
           const char *err = strerror (errno);
           OSS (fatal, reading_file, _("open: %s: %s"), fn, err);
         }
-      else
+      if (argv[1])
         {
           int l = strlen (argv[1]);
-          int nl = (l == 0 || argv[1][l-1] != '\n');
+          int nl = l == 0 || argv[1][l-1] != '\n';
 
           if (fputs (argv[1], fp) == EOF || (nl && fputc ('\n', fp) == EOF))
             {
               const char *err = strerror (errno);
               OSS (fatal, reading_file, _("write: %s: %s"), fn, err);
             }
-          fclose (fp);
         }
+      fclose (fp);
     }
   else
     OS (fatal, reading_file, _("Invalid file operation: %s"), fn);
index 9a4cd024a1d5940288d7387549d2c0283f67cf8f..55eb58a0e4ae8dad9495a997f9f2853da6a781e5 100644 (file)
@@ -30,6 +30,23 @@ x:;@cat file.out
 
 unlink('file.out');
 
+# Test > with no content
+run_make_test(q!
+$(file >4touch)
+.PHONY:x
+x:;@cat 4touch
+!,
+              '', '');
+
+# Test >> with no content
+run_make_test(q!
+$(file >>4touch)
+.PHONY:x
+x:;@cat 4touch
+!,
+              '', '');
+unlink('4touch');
+
 # Test > to a read-only file
 touch('file.out');
 chmod(0444, 'file.out');