mirror of
https://github.com/johnkerl/miller.git
synced 2026-07-22 07:30:43 +00:00
166 lines
4.1 KiB
C
166 lines
4.1 KiB
C
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
|
|
// . CR LF CRLF
|
|
// CR - 1 1
|
|
// LF 2 - 2
|
|
// CRLF x x -
|
|
|
|
typedef void line_cvt_func_t(char* line, ssize_t linelen, FILE* output_stream);
|
|
|
|
static void cr_to_crlf(char* line, ssize_t linelen, FILE* output_stream) {
|
|
if (linelen == 1) {
|
|
if (line[0] == '\r') {
|
|
fputc('\r', output_stream);
|
|
fputc('\n', output_stream);
|
|
} else {
|
|
fputc(line[0], output_stream);
|
|
}
|
|
} else {
|
|
if (line[linelen-2] == '\r' && line[linelen-1] == '\n') {
|
|
fputs(line, output_stream);
|
|
} else if (line[linelen-1] == '\r') {
|
|
fputs(line, output_stream);
|
|
fputc('\n', output_stream);
|
|
} else {
|
|
fputs(line, output_stream);
|
|
}
|
|
}
|
|
}
|
|
|
|
static void lf_to_crlf(char* line, ssize_t linelen, FILE* output_stream) {
|
|
if (linelen == 1) {
|
|
if (line[0] == '\n') {
|
|
fputc('\r', output_stream);
|
|
fputc('\n', output_stream);
|
|
} else {
|
|
fputc(line[0], output_stream);
|
|
}
|
|
} else {
|
|
if (line[linelen-2] == '\r' && line[linelen-1] == '\n') {
|
|
fputs(line, output_stream);
|
|
} else if (line[linelen-1] == '\n') {
|
|
line[linelen-1] = '\r';
|
|
fputs(line, output_stream);
|
|
fputc('\n', output_stream);
|
|
} else {
|
|
fputs(line, output_stream);
|
|
}
|
|
}
|
|
}
|
|
|
|
static void crlf_to_cr(char* line, ssize_t linelen, FILE* output_stream) {
|
|
if (linelen >= 2 && line[linelen-2] == '\r' && line[linelen-1] == '\n') {
|
|
line[linelen-2] = '\r';
|
|
line[linelen-1] = '\0';
|
|
}
|
|
fputs(line, output_stream);
|
|
}
|
|
|
|
static void crlf_to_lf(char* line, ssize_t linelen, FILE* output_stream) {
|
|
if (linelen >= 2 && line[linelen-2] == '\r' && line[linelen-1] == '\n') {
|
|
line[linelen-2] = '\n';
|
|
line[linelen-1] = '\0';
|
|
}
|
|
fputs(line, output_stream);
|
|
}
|
|
|
|
static void cr_to_lf(char* line, ssize_t linelen, FILE* output_stream) {
|
|
if (linelen >= 1 && line[linelen-1] == '\r') {
|
|
line[linelen-1] = '\n';
|
|
}
|
|
fputs(line, output_stream);
|
|
}
|
|
|
|
static void lf_to_cr(char* line, ssize_t linelen, FILE* output_stream) {
|
|
if (linelen >= 1 && line[linelen-1] == '\n') {
|
|
line[linelen-1] = '\r';
|
|
}
|
|
fputs(line, output_stream);
|
|
}
|
|
|
|
// ----------------------------------------------------------------
|
|
static int do_stream(FILE* input_stream, FILE* output_stream, char inend, line_cvt_func_t* pcvt_func) {
|
|
while (1) {
|
|
char* line = NULL;
|
|
size_t linecap = 0;
|
|
ssize_t linelen = getdelim(&line, &linecap, inend, input_stream);
|
|
if (linelen <= 0) {
|
|
break;
|
|
}
|
|
|
|
pcvt_func(line, linelen, output_stream);
|
|
|
|
free(line);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
// ================================================================
|
|
static void usage(char* argv0) {
|
|
printf("Usage: %s [option] {zero or more file names}\n", argv0);
|
|
printf("Option (exactly one is required):\n");
|
|
printf("--cr2crlf\n");
|
|
printf("--lf2crlf\n");
|
|
printf("--crlf2cr\n");
|
|
printf("--crlf2lf\n");
|
|
printf("--cr2lf\n");
|
|
printf("--lf2cr\n");
|
|
printf("-h or --help: print this message\n");
|
|
printf("Zero file names means read from standard input.\n");
|
|
printf("Output is always to standard output; files are not written in-place.\n");
|
|
|
|
exit(1);
|
|
}
|
|
|
|
int main(int argc, char** argv) {
|
|
int ok = 1;
|
|
char inend = '\n';
|
|
line_cvt_func_t* pcvt_func = lf_to_crlf;
|
|
|
|
if (argc < 2)
|
|
usage(argv[0]);
|
|
char* opt = argv[1];
|
|
if (!strcmp(opt, "-h")) {
|
|
usage(opt);
|
|
} else if (!strcmp(opt, "--help")) {
|
|
usage(opt);
|
|
} else if (!strcmp(opt, "--cr2crlf")) {
|
|
pcvt_func = cr_to_crlf;
|
|
inend = '\r';
|
|
} else if (!strcmp(opt, "--lf2crlf")) {
|
|
pcvt_func = lf_to_crlf;
|
|
inend = '\n';
|
|
} else if (!strcmp(opt, "--crlf2cr")) {
|
|
pcvt_func = crlf_to_cr;
|
|
inend = '\n';
|
|
} else if (!strcmp(opt, "--crlf2lf")) {
|
|
pcvt_func = crlf_to_lf;
|
|
inend = '\n';
|
|
} else if (!strcmp(opt, "--cr2lf")) {
|
|
pcvt_func = cr_to_lf;
|
|
inend = '\r';
|
|
} else if (!strcmp(opt, "--lf2cr")) {
|
|
pcvt_func = lf_to_cr;
|
|
inend = '\n';
|
|
} else {
|
|
usage(argv[0]);
|
|
}
|
|
|
|
if (argc == 2) {
|
|
ok = ok && do_stream(stdin, stdout, inend, pcvt_func);
|
|
} else {
|
|
for (int argi = 2; argi < argc; argi++) {
|
|
char* file_name = argv[argi];
|
|
FILE* input_stream = fopen(file_name, "r");
|
|
if (input_stream == NULL) {
|
|
perror(file_name);
|
|
exit(1);
|
|
}
|
|
ok = do_stream(input_stream, stdout, inend, pcvt_func);
|
|
fclose(input_stream);
|
|
}
|
|
}
|
|
return ok ? 0 : 1;
|
|
}
|