Write a program or function that alters the file at a user-specified filename via replacing all instances of UNIX line endings with Windows line endings and vice versa.
Clarifications:
For the purposes of this problem, a UNIX line ending consists of the octet
0A
in hexadecimal, except when it is immediately preceded by the octet0D
. A Windows line ending consists of the two octets0D 0A
.As usual, your program only has to run on one (pre-existing) interpreter on one (pre-existing) operating system; this is particularly important for this question, where I imagine many submissions will succeed on UNIX but fail on Windows, or vice versa, due to line ending conversions built into the language.
To alter a file, you can either edit the file "in-place", or read the file, then save the contents of the file back over the original. However, the program must alter a file on disk; just taking a string as an argument and returning a string specifying the result is not acceptable for this challenge, because the challenge is partially about testing the ability to handle files.
The program's user must have some method of specifying the filename to change without needing to alter the program itself (i.e. you can't use hardcoded filenames). For example, you could read the name of the file to modify from a command-line argument, or from standard input. If you're submitting a function rather than a full program, making it take a filename as argument would be acceptable.
The input to the program must be specified as a filename specifically; you can't take input other than strings (assuming that you're using an operating system in which filenames are strings; in most, they are), and you can't place restrictions on what filenames you accept (you must accept all filenames that the operating system would accept, and that refer to a file that the user running the program has permission to read and write). For example, you can't write a function that takes a UNIX file descriptor as an argument and requires the file to already be open, and you can't write an editor macro that assumes the file has already been opened in the current buffer.
If the file is missing a trailing newline before you alter it, it should continue to be missing a trailing newline after you alter it. Likewise, if the file does have a trailing newline, you should preserve that (leaving the file with the other sort of trailing newline).
If the input file has mixed line ending conventions, you should nonetheless translate each of the line endings to the opposite sort of line ending (so the resulting line will still have mixed line ending conventions, but each individual line will have been converted).
The program is intended for use converting text files, and as such, you don't have to be able to handle nonprintable control codes in the input (although you can if you wish). The nonprintable control codes are the octets from
00
to1F
(hexadecimal) inclusive except for09
,0A
,0B
,0C
,0D
. It's also acceptable for your program to fail on input that cannot be decoded as UTF-8 (however, there is no requirement to place a UTF-8 interpretation on the input; programs which handle all the high-bit-set octets are also acceptable).As an exception from the specification, it's acceptable for the program to do anything upon seeing the octet sequence
0D 0D 0A
in the input (because it's impossible to comply with the spec when this sequence appears in the input: you'd have to generate0D
followed by an0A
which is not immediately preceded by0D
, which is a contradiction).
The shortest program wins, under usual code-golf rules (i.e. fewest bytes in the program you submit). Good luck!
Test cases
Here are some hex dumps of files you can use to test your program. All these test cases are reversible; swapping the input and output gives another valid test case. Note that your program should work for cases other than the given test-cases; these are just some examples to help testing:
Input
30 31 32 0A 33 34 35 0A 36 37 38 0A
Output
30 31 32 0D 0A 33 34 35 0D 0A 36 37 38 0D 0A
Input
30 31 0A 0D 0A 32 0A 0A 0A 33 34
Output
30 31 0D 0A 0A 32 0D 0A 0D 0A 0D 0A 33 34
Input and Output both a zero-byte file.
0A 0D 0A
, the transform is0A
->0D 0A
and0D 0A
->0A
resulting in0D 0A 0A
? \$\endgroup\$