aboutsummaryrefslogtreecommitdiff
path: root/libbuild2/in
diff options
context:
space:
mode:
authorKaren Arutyunov <karen@codesynthesis.com>2021-03-06 00:41:20 +0300
committerKaren Arutyunov <karen@codesynthesis.com>2021-03-08 15:08:45 +0300
commit309d6cfafbd4967660ac3d3045ccc4ebad312175 (patch)
treeff71e48ebde83a16e0c7b20220f1b954659a1f8e /libbuild2/in
parent69586bbccf5b34be18a289d2e063e665bde8967a (diff)
Fix 'in' module to preserve line endings
Diffstat (limited to 'libbuild2/in')
-rw-r--r--libbuild2/in/rule.cxx33
1 files changed, 29 insertions, 4 deletions
diff --git a/libbuild2/in/rule.cxx b/libbuild2/in/rule.cxx
index b64541c..2569948 100644
--- a/libbuild2/in/rule.cxx
+++ b/libbuild2/in/rule.cxx
@@ -276,8 +276,11 @@ namespace build2
const path* whom;
try
{
+ // Open the streams in the binary mode to preserve the .in file line
+ // endings.
+ //
what = "open"; whom = &ip;
- ifdstream ifs (ip, ifdstream::badbit);
+ ifdstream ifs (ip, fdopen_mode::binary, ifdstream::badbit);
what = "open"; whom = &tp;
#ifdef _WIN32
@@ -285,7 +288,7 @@ namespace build2
// remove the file immediately before creating it sometimes can cause
// open to fail with permission denied.
//
- ofdstream ofs (tp);
+ ofdstream ofs (tp, fdopen_mode::binary);
#else
// See fdopen() for details (umask, etc).
//
@@ -302,12 +305,25 @@ namespace build2
//
try_rmfile (tp, true /* ignore_error */);
+ // Note: no binary flag is added since this is noop on POSIX.
+ //
ofdstream ofs (fdopen (tp,
fdopen_mode::out | fdopen_mode::create,
prm));
#endif
auto_rmfile arm (tp);
+ // Note: this default will only be used if the file if empty (i.e.,
+ // does not contain even a newline).
+ //
+ const char* nl (
+#ifdef _WIN32
+ "\r\n"
+#else
+ "\n"
+#endif
+ );
+
string s; // Reuse the buffer.
for (size_t ln (1);; ++ln)
{
@@ -315,6 +331,13 @@ namespace build2
if (!getline (ifs, s))
break; // Could not read anything, not even newline.
+ // Remember the line ending type and, if it is CRLF, strip the
+ // trailing '\r'.
+ //
+ bool crlf (!s.empty () && s.back() == '\r');
+ if (crlf)
+ s.pop_back();
+
// Not tracking column for now (see also depdb above).
//
const location l (ip, ln);
@@ -400,8 +423,10 @@ namespace build2
what = "write"; whom = &tp;
if (ln != 1)
- ofs << '\n'; // See below.
+ ofs << nl; // See below.
ofs << s;
+
+ nl = crlf ? "\r\n" : "\n"; // Preserve the original line ending.
}
// Close depdb before closing the output file so its mtime is not
@@ -410,7 +435,7 @@ namespace build2
dd.close ();
what = "close"; whom = &tp;
- ofs << '\n'; // Last write to make sure our mtime is older than dd.
+ ofs << nl; // Last write to make sure our mtime is older than dd.
ofs.close ();
arm.cancel ();