// anynl.c -- accept any unix, mac, or windows format text file and convert
// line endings to any of the three conventions. Defaults to
// converting to the current platform's convention.
//
// When compiled on Windows this program must go out of its way to
// disable to normal ASCII translation of newlines done by the C
// runtime to map between C's '\n' and the Windows platform's CR/LF.
//
#include <stdio.h>
#include <fcntl.h>
#if defined(WIN32) || defined(__WIN32__) || defined(_Windows) || defined(_WIN32)
#include <io.h>
#endif
#include <string.h>
#define LF ((char)10)
#define CR ((char)13)
#define CTRLZ ((char)26)
#if defined(_MSC_VER)
#define strcasecmp(a,b) _stricmp(a,b)
#endif
void UnixNewline(void) {
putchar(LF);
}
void MacNewline(void) {
putchar(CR);
}
void DosNewline(void) {
putchar(CR);
putchar(LF);
}
int main(int argc, char **argv)
{
char ch;
int ich;
void (*EmitNewline)(void);
#if defined(WIN32) || defined(__WIN32__) || defined(_Windows) || defined(_WIN32)
// switch stdin/stdout streams to binary mode
_setmode(_fileno(stdin), _O_BINARY);
_setmode(_fileno(stdout), _O_BINARY);
EmitNewline = DosNewline;
#else
// default to targetting this platform.
EmitNewline = UnixNewline;
#endif
while (++argv, --argc) {
if (!strcasecmp(*argv, "-dos")) {
EmitNewline = DosNewline;
} else if (!strcasecmp(*argv, "-mac")) {
EmitNewline = MacNewline;
} else if (!strcasecmp(*argv, "-unix")) {
EmitNewline = UnixNewline;
}
}
while (EOF != (ich = getc(stdin))) {
ch = ich;
if (CR == ch) {
(*EmitNewline)();
// might be mac, with CR only, or dos, with CRLF
if (EOF == (ich = getc(stdin))) {
break;
}
ch = ich;
if (LF != ch) {
ungetc(ch, stdin);
}
} else if (LF == ch) {
(*EmitNewline)();
} else if (CTRLZ == ch) { // DOS sometimes has ^Z to indicate EOF, stop there
break;
} else {
putchar(ch);
}
}
}