aboutsummaryrefslogtreecommitdiff
path: root/common
diff options
context:
space:
mode:
authorEugene Sandulenko2004-10-18 21:22:10 +0000
committerEugene Sandulenko2004-10-18 21:22:10 +0000
commitacf6e4a12f0e676c9a33cb8f96b6d95f83f1b77a (patch)
tree384c6994161bcb56288b2fbddc5170693b042e59 /common
parent83560e5110c2ea52702b731c8ad97d7a6557a06f (diff)
downloadscummvm-rg350-acf6e4a12f0e676c9a33cb8f96b6d95f83f1b77a.tar.gz
scummvm-rg350-acf6e4a12f0e676c9a33cb8f96b6d95f83f1b77a.tar.bz2
scummvm-rg350-acf6e4a12f0e676c9a33cb8f96b6d95f83f1b77a.zip
Accepted patch #1048693 -- Making File::gets() more well-defined.
svn-id: r15608
Diffstat (limited to 'common')
-rw-r--r--common/file.cpp54
1 files changed, 50 insertions, 4 deletions
diff --git a/common/file.cpp b/common/file.cpp
index 9376749866..63073239df 100644
--- a/common/file.cpp
+++ b/common/file.cpp
@@ -268,19 +268,65 @@ uint32 File::write(const void *ptr, uint32 len) {
return len;
}
+#define LF 0x0A
+#define CR 0x0D
+
char *File::gets(void *ptr, uint32 len) {
char *ptr2 = (char *)ptr;
- char *res;
+ char *res = ptr2;
+ uint32 read_chars = 1;
if (_handle == NULL) {
error("File::gets: File is not open!");
return 0;
}
- if (len == 0)
- return 0;
+ if (len == 0 || !ptr)
+ return NULL;
+
+ // We don't include the newline character(s) in the buffer, and we
+ // always terminate it - we never read more than len-1 characters.
+
+ // EOF is treated as a line break, unless it was the first character
+ // that was read.
+
+ // 0 is treated as a line break, even though it should never occur in
+ // a text file.
+
+ // DOS and Windows use CRLF line breaks
+ // Unix and OS X use LF line breaks
+ // Macintosh before OS X uses CR line breaks
+
+ bool first = true;
+
+ while (read_chars < len) {
+ int c = getc(_handle);
- res = fgets(ptr2, len, _handle);
+ if (c == EOF) {
+ if (first)
+ return NULL;
+ break;
+ }
+
+ first = false;
+
+ if (c == 0)
+ break;
+
+ if (c == LF)
+ break;
+
+ if (c == CR) {
+ c = getc(_handle);
+ if (c != LF)
+ ungetc(c, _handle);
+ break;
+ }
+
+ *ptr2++ = (char) c;
+ read_chars++;
+ }
+ *ptr2 = 0;
return res;
}