jcs
/amend
/amendments
/70
diffreg: Open files as binary to get expected newline handling
Unbeknownst to me, THINK C's file stream library transparently
converts \r newlines to \n. By opening files as binary, this is
disabled and we get \r newlines as expected.
jcs made amendment 70 over 2 years ago
--- committer.c Sat Apr 16 13:30:03 2022
+++ committer.c Mon Jun 6 22:50:22 2022
@@ -550,12 +550,11 @@ diff_output(const char *format, ...)
if (cur_committer->diff_line_pos >= DIFF_LINE_SIZE)
err(1, "diff line overflow!");
- if (len == 1 && (*(cur_committer->diff_line))[last_pos] != '\n')
+ if (len == 1 && (*(cur_committer->diff_line))[last_pos] != '\r')
return 1;
for (i = last_pos; i < cur_committer->diff_line_pos; i++) {
- if (((char *)*(cur_committer->diff_line))[i] == '\n') {
- ((char *)*(cur_committer->diff_line))[i] = '\r';
+ if (((char *)*(cur_committer->diff_line))[i] == '\r') {
diff_append_line(*(cur_committer->diff_line) + last_line,
i - last_line + 1, false);
last_line = i + 1;
--- diffreg.c Thu Jun 2 15:17:37 2022
+++ diffreg.c Mon Jun 6 21:51:39 2022
@@ -300,14 +300,14 @@ diffreg(char *file1, char *file2, int flags)
if (strcmp(file1, "-") == 0 && strcmp(file2, "-") == 0)
goto closem;
- f1 = fopen(file1, "r");
+ f1 = fopen(file1, "rb");
if (f1 == NULL) {
warn("%s", file1);
status |= 2;
goto closem;
}
- f2 = fopen(file2, "r");
+ f2 = fopen(file2, "rb");
if (f2 == NULL) {
warn("%s", file2);
status |= 2;
@@ -634,10 +634,10 @@ check(FILE *f1, FILE *f2, int flags)
* in one file for -b or -w.
*/
if (flags & (D_FOLDBLANKS|D_IGNOREBLANKS)) {
- if (c == EOF && d == '\n') {
+ if (c == EOF && d == '\r') {
ctnew++;
break;
- } else if (c == '\n' && d == EOF) {
+ } else if (c == '\r' && d == EOF) {
ctold++;
break;
}
@@ -647,21 +647,21 @@ check(FILE *f1, FILE *f2, int flags)
if ((flags & D_FOLDBLANKS) && isspace(c) &&
isspace(d)) {
do {
- if (c == '\n')
+ if (c == '\r')
break;
ctold++;
} while (isspace(c = getc(f1)));
do {
- if (d == '\n')
+ if (d == '\r')
break;
ctnew++;
} while (isspace(d = getc(f2)));
} else if ((flags & D_IGNOREBLANKS)) {
- while (isspace(c) && c != '\n') {
+ while (isspace(c) && c != '\r') {
c = getc(f1);
ctold++;
}
- while (isspace(d) && d != '\n') {
+ while (isspace(d) && d != '\r') {
d = getc(f2);
ctnew++;
}
@@ -669,13 +669,13 @@ check(FILE *f1, FILE *f2, int flags)
if (chrtran[c] != chrtran[d]) {
jackpot++;
J[i] = 0;
- if (c != '\n' && c != EOF)
+ if (c != '\r' && c != EOF)
ctold += skipline(f1);
- if (d != '\n' && c != EOF)
+ if (d != '\r' && c != EOF)
ctnew += skipline(f2);
break;
}
- if (c == '\n' || c == EOF)
+ if (c == '\r' || c == EOF)
break;
}
} else {
@@ -685,13 +685,13 @@ check(FILE *f1, FILE *f2, int flags)
if ((c = getc(f1)) != (d = getc(f2))) {
/* jackpot++; */
J[i] = 0;
- if (c != '\n' && c != EOF)
+ if (c != '\r' && c != EOF)
ctold += skipline(f1);
- if (d != '\n' && c != EOF)
+ if (d != '\r' && c != EOF)
ctnew += skipline(f2);
break;
}
- if (c == '\n' || c == EOF)
+ if (c == '\r' || c == EOF)
break;
}
}
@@ -758,7 +758,7 @@ skipline(FILE *f)
{
int i, c;
- for (i = 1; (c = getc(f)) != '\n' && c != EOF; i++)
+ for (i = 1; (c = getc(f)) != '\r' && c != EOF; i++)
continue;
return (i);
}
@@ -849,7 +849,7 @@ preadline(int fd, size_t rlen, off_t off)
if ((nr = read(fd, line, rlen)) == -1)
err(2, "preadline");
lseek(fd, pos, SEEK_SET);
- if (nr > 0 && line[nr-1] == '\n')
+ if (nr > 0 && line[nr-1] == '\r')
nr--;
line[nr] = '\0';
return (line);
@@ -912,7 +912,7 @@ restart:
}
proceed:
if (*pflags & D_HEADER) {
- diff_output("%s %s\n", file1, file2);
+ diff_output("%s %s\r", file1, file2);
*pflags &= ~D_HEADER;
}
if (diff_format == D_CONTEXT || diff_format == D_UNIFIED) {
@@ -962,28 +962,28 @@ proceed:
diff_output("%c", a > b ? 'a' : c > d ? 'd' : 'c');
if (diff_format == D_NORMAL)
range(c, d, ",");
- diff_output("\n");
+ diff_output("\r");
break;
case D_REVERSE:
diff_output("%c", a > b ? 'a' : c > d ? 'd' : 'c');
range(a, b, " ");
- diff_output("\n");
+ diff_output("\r");
break;
case D_NREVERSE:
if (a > b)
- diff_output("a%d %d\n", b, d - c + 1);
+ diff_output("a%d %d\r", b, d - c + 1);
else {
- diff_output("d%d %d\n", a, b - a + 1);
+ diff_output("d%d %d\r", a, b - a + 1);
if (!(c > d))
/* add changed lines */
- diff_output("a%d %d\n", b, d - c + 1);
+ diff_output("a%d %d\r", b, d - c + 1);
}
break;
}
if (diff_format == D_NORMAL || diff_format == D_IFDEF) {
fetch(ixold, a, b, f1, '<', 1, *pflags);
if (a <= b && c <= d && diff_format == D_NORMAL)
- diff_output("---\n");
+ diff_output("---\r");
}
i = fetch(ixnew, c, d, f2, diff_format == D_NORMAL ? '>' : '\0', 0, *pflags);
if (i != 0 && diff_format == D_EDIT) {
@@ -994,17 +994,17 @@ proceed:
* it. We have to add a substitute command to change this
* back and restart where we left off.
*/
- diff_output(".\n");
- diff_output("%ds/.//\n", a + i - 1);
+ diff_output(".\r");
+ diff_output("%ds/.//\r", a + i - 1);
b = a + i - 1;
a = b + 1;
c += i;
goto restart;
}
if ((diff_format == D_EDIT || diff_format == D_REVERSE) && c <= d)
- diff_output(".\n");
+ diff_output(".\r");
if (inifdef) {
- diff_output("#endif /* %s */\n", ifdefname);
+ diff_output("#endif /* %s */\r", ifdefname);
inifdef = 0;
}
}
@@ -1029,13 +1029,13 @@ fetch(long *f, int a, int b, FILE *lb, int ch, int old
return (0);
if (diff_format == D_IFDEF) {
if (inifdef) {
- diff_output("#else /* %s%s */\n",
+ diff_output("#else /* %s%s */\r",
oldfile == 1 ? "!" : "", ifdefname);
} else {
if (oldfile)
- diff_output("#ifndef %s\n", ifdefname);
+ diff_output("#ifndef %s\r", ifdefname);
else
- diff_output("#ifdef %s\n", ifdefname);
+ diff_output("#ifdef %s\r", ifdefname);
}
inifdef = 1 + oldfile;
}
@@ -1061,19 +1061,21 @@ fetch(long *f, int a, int b, FILE *lb, int ch, int old
warnx("No newline at end of file");
else
#if 0
- diff_output("\n\\ No newline at end of "
- "file\n");
+ diff_output("\r\\ No newline at end of "
+ "file\r");
#else
- diff_output("\n");
+ diff_output("\r");
#endif
return (0);
}
+ if (c == '\n')
+ c = '\n';
if (c == '\t' && (flags & D_EXPANDTABS)) {
do {
diff_output(" ");
} while (++col & 7);
} else {
- if (diff_format == D_EDIT && j == 1 && c == '\n'
+ if (diff_format == D_EDIT && j == 1 && c == '\r'
&& lastc == '.') {
/*
* Don't print a bare "." line
@@ -1082,7 +1084,7 @@ fetch(long *f, int a, int b, FILE *lb, int ch, int old
* giving the caller an offset
* from which to restart.
*/
- diff_output(".\n");
+ diff_output(".\r");
return (i - a + 1);
}
diff_output("%c", c);
@@ -1106,7 +1108,7 @@ readhash(FILE *f, int flags)
space = 0;
if ((flags & (D_FOLDBLANKS|D_IGNOREBLANKS)) == 0) {
if (flags & D_IGNORECASE)
- for (i = 0; (t = getc(f)) != '\n'; i++) {
+ for (i = 0; (t = getc(f)) != '\r'; i++) {
if (t == EOF) {
if (i == 0)
return (0);
@@ -1115,7 +1117,7 @@ readhash(FILE *f, int flags)
sum = sum * 127 + chrtran[t];
}
else
- for (i = 0; (t = getc(f)) != '\n'; i++) {
+ for (i = 0; (t = getc(f)) != '\r'; i++) {
if (t == EOF) {
if (i == 0)
return (0);
@@ -1127,7 +1129,7 @@ readhash(FILE *f, int flags)
for (i = 0;;) {
switch (t = getc(f)) {
case '\t':
- case '\r':
+ case '\n':
case '\v':
case '\f':
case ' ':
@@ -1145,7 +1147,7 @@ readhash(FILE *f, int flags)
if (i == 0)
return (0);
/* FALLTHROUGH */
- case '\n':
+ case '\r':
break;
}
break;
@@ -1240,9 +1242,9 @@ dump_context_vec(FILE *f1, FILE *f2, int flags)
if (f != NULL)
diff_output(" %s", f);
}
- diff_output("\n*** ");
+ diff_output("\r*** ");
range(lowa, upb, ",");
- diff_output(" ****\n");
+ diff_output(" ****\r");
/*
* Output changes to the "old" file. The first loop suppresses
@@ -1283,7 +1285,7 @@ dump_context_vec(FILE *f1, FILE *f2, int flags)
/* output changes to the "new" file */
diff_output("--- ");
range(lowc, upd, ",");
- diff_output(" ----\n");
+ diff_output(" ----\r");
do_output = 0;
for (cvp = context_vec_start; cvp <= context_vec_ptr; cvp++)
@@ -1347,7 +1349,7 @@ dump_unified_vec(FILE *f1, FILE *f2, int flags)
if (f != NULL)
diff_output(" %s", f);
}
- diff_output("\n");
+ diff_output("\r");
/*
* Output changes in "unified" diff format--the old and new lines
@@ -1396,13 +1398,13 @@ static void
print_header(const char *file1, const char *file2)
{
if (label[0] != NULL)
- diff_output("%s %s\n", diff_format == D_CONTEXT ? "***" : "---",
+ diff_output("%s %s\r", diff_format == D_CONTEXT ? "***" : "---",
label[0]);
else
diff_output("%s %s\t%s", diff_format == D_CONTEXT ? "***" : "---",
file1, ctime(&stb1.st_mtime));
if (label[1] != NULL)
- diff_output("%s %s\n", diff_format == D_CONTEXT ? "---" : "+++",
+ diff_output("%s %s\r", diff_format == D_CONTEXT ? "---" : "+++",
label[1]);
else
diff_output("%s %s\t%s", diff_format == D_CONTEXT ? "---" : "+++",