Ok, I think I got it figured out.
The code in wordfile() blindly assumed that read() would always return
exactly the number of bytes requested. This is NOT garanteed by the
specification. It's perfectly valid for read() to return less, but
never more data than requested.
Windows is doing something very reasonable here. When the requested
read size would split up a CRNL, then it stops reading one byte earlier.
This ensures that the next read() will be able to correctly convert the
CRNL into a single NL.
The consequence for us is that counting back from the end of MAXWLEN
will
give us the wrong position in the data. We need to save the value of n
right after the read(), and use that instead of MAXWLEN in the
memmove().
Reading in binary mode is unnecessary.
I've checked a working version into CVS.
Cheers
-schorsch
Am 2016-05-13 02:06, schrieb Gregory J. Ward:
I agree the code in wordfile.c is a bit over-complex and confusing.
Hopefully, it will make more sense to you tomorrow.
Meanwhile, you can try running the following code on the attached
files:
#include <stdio.h>
#include "platform.h"
int
main(int argc, char *argv[])
{
char rdbuf[40];
int n;
while ((n = read(0, rdbuf, sizeof(rdbuf))) > 0) {
char *cp = rdbuf;
printf("Read %d characters:\n\"", n);
while (n--)
fputc(*cp++, stdout);
fputs("\"\n", stdout);
}
return 0;
}
Running "checkread < testfile_unix.txt" gives me the following on Mac
OS X:
Read 40 characters:
"123456789
123456789
123456789
123456789
"
Read 20 characters:
"123456789
123456789
"
You should get the same result on Windows using this file. However,
using the "testfile_dos.txt" as your input, you might get:
Read 37 characters:
"123456789
123456789
123456789
1234567"
Read 23 characters:
"89
123456789
123456789
"
Using "testfile_dos2.txt", I get:
Read 40 characters:
"12345678
12345678
12345678
12345678
"
Read 20 characters:
"12345678
12345678
"
You should get the same, but with different character counts -- 36 in
the first read and 18 in the second as it removes the '\r' characters
from the result in the default _O_TEXT mode. Now, try adding an extra
character to the beginning of the "testfile_dos2.txt" file, so that
the "\r\n" sequence splits the read calls. I'm hoping this will
demonstrate the bug, or else I'm still confused about what's going
wrong in Windows.
Cheers,
-Greg
From: Georg Mischler <[email protected]>
Subject: Re: [Radiance-dev] NREL Radiance re-distribution
Date: May 12, 2016 4:17:50 PM PDT
Hmmm... I really seem to be tired.
That null byte is the one we just wrote ourselfes...
But something in the counting is definitively off.
"buf+MAXWLEN-crem" will point to the second character of the next
word,
and memmove() probably reads one beyond the buffer.
More tomorrow.
Cheers
-schorsch
Am 2016-05-13 00:53, schrieb Georg Mischler:
The problem is that in wordfile(), crem still gets incremented even
after
passing the null byte in buf. I must admit that I don't quite
understand
the counting logic in there yet, the function looks unnecessarily
complicated
to me. Maybe I'll see clearer tomorrow when I'm fully awake again...
Cheers
-schorsch
Am 2016-05-13 00:02, schrieb Gregory J. Ward:
Should be reproducible with a sequence of read calls on a file with
one or two printing characters per line, followed by "\r\n" as
usual.
If a character gets eaten, then it must be the _O_TEXT processing at
fault, somehow.
-Greg
_______________________________________________
Radiance-dev mailing list
[email protected]
http://www.radiance-online.org/mailman/listinfo/radiance-dev
--
Georg Mischler -- simulations developer -- schorsch at schorsch com
+schorsch.com+ -- lighting design tools -- http://www.schorsch.com/
_______________________________________________
Radiance-dev mailing list
[email protected]
http://www.radiance-online.org/mailman/listinfo/radiance-dev