}
else if (fn[0] == '<')
{
- char *preo = o;
+ size_t n = 0;
FILE *fp;
++fn;
char buf[1024];
size_t l = fread (buf, 1, sizeof (buf), fp);
if (l > 0)
- o = variable_buffer_output (o, buf, l);
-
+ {
+ o = variable_buffer_output (o, buf, l);
+ n += l;
+ }
if (ferror (fp))
if (errno != EINTR)
OSS (fatal, reading_file, _("read: %s: %s"), fn, strerror (errno));
OSS (fatal, reading_file, _("close: %s: %s"), fn, strerror (errno));
/* Remove trailing newline. */
- if (o > preo && o[-1] == '\n')
- if (--o > preo && o[-1] == '\r')
- --o;
+ if (n && o[-1] == '\n')
+ o -= 1 + (n > 1 && o[-2] == '\r');
}
else
OS (fatal, *expanding_var, _("file: invalid file operation: %s"), fn);
unlink('file.out');
+# Read an empty file.
+touch("file.out");
+run_make_test(q!# empty file
+X1 := x$(file <file.out)y
+x:;@echo '$(X1)'
+!,
+ '', "xy\n");
+
+unlink('file.out');
+
+# Read a file whose full contents is a newline.
+create_file('file.out', "\n");
+run_make_test(q!# <nl>
+X1 := x$(file <file.out)y
+x:;@echo '$(X1)'
+!,
+ '', "xy\n");
+
+unlink('file.out');
+
+# Read a file which does not end with a newline.
+create_file('file.out', "hello");
+# echo prints a trailig newline, because run_make_test appends a newline.
+run_make_test(q!# hello
+X1 := x$(file <file.out)y
+x:;@echo $(X1)
+!,
+ '', "xhelloy\n");
+
+unlink('file.out');
+
+# Read a file which ends with a newline.
+create_file('file.out', "hello\n");
+# echo prints a trailig newline, because run_make_test appends a newline.
+run_make_test(q!# hello<nl>
+X1 := x$(file <file.out)y
+x:;@echo '$(X1)'
+!,
+ '', "xhelloy\n");
+
+
+unlink('file.out');
+
+# Read a file which ends with multiple newlines.
+create_file('file.out', "hello\n\n");
+run_make_test(q!# hello<nl><nl>
+X1 := x$(file <file.out)y
+export X1
+x:;@echo "$$X1"
+!,
+ '', "xhello\ny\n");
+
+unlink('file.out');
+
+# Read a file whose contents exceed 200 bytes.
+# 200 is the initial size of variable_buffer.
+# File bigger than 200 bytes causes a realloc.
+# The size of the file in this test not only exceeds 200 bytes, it exceeds 65k.
+
+my $s = "hello world, hello world, hello world, hello world, hello world";
+my $answer = $s x 2000;
+create_file('file.out', $answer);
+run_make_test(q!# <hugestring>
+X1 := x$(file <file.out)y
+x:;@echo '$(X1)'
+!,
+ '', "x${answer}y\n");
+
+unlink('file.out');
+
# Reading from non-existent file
run_make_test(q!
X1 := $(file <file.out)
# Each step consists of an operator and argument.
#
# It supports the following operators:
-# out <word> : echo <word> to stdout
+# out <word> : echo <word> to stdout with a newline
+# raw <word> : echo <word> to stdout without adding anything
# file <word> : echo <word> to stdout AND create the file <word>
# dir <word> : echo <word> to stdout AND create the directory <word>
# rm <word> : echo <word> to stdout AND delete the file/directory <word>
print "$nm\n";
return 1;
}
+ if ($op eq 'raw') {
+ print "$nm";
+ return 1;
+ }
# Show the output before creating the file
if ($op eq 'file') {