summaryrefslogtreecommitdiffstats
path: root/generic/tclIO.c
diff options
context:
space:
mode:
authordgp <dgp@users.sourceforge.net>2014-03-10 19:00:19 (GMT)
committerdgp <dgp@users.sourceforge.net>2014-03-10 19:00:19 (GMT)
commitdd5ac1c6419faed6fedef71a19409cb52335353c (patch)
treea086b48ece22286ad20d0a2c2a7664f089f47d32 /generic/tclIO.c
parent091096d315755aa89f28bd063b426e16a4c16e51 (diff)
downloadtcl-dd5ac1c6419faed6fedef71a19409cb52335353c.zip
tcl-dd5ac1c6419faed6fedef71a19409cb52335353c.tar.gz
tcl-dd5ac1c6419faed6fedef71a19409cb52335353c.tar.bz2
Rewrite CRLF translation to use more system calls.
Diffstat (limited to 'generic/tclIO.c')
-rw-r--r--generic/tclIO.c46
1 files changed, 28 insertions, 18 deletions
diff --git a/generic/tclIO.c b/generic/tclIO.c
index 2971838..1070f0a 100644
--- a/generic/tclIO.c
+++ b/generic/tclIO.c
@@ -5645,28 +5645,38 @@ TranslateInputEOL(
dstLen = srcLen;
break;
case TCL_TRANSLATE_CRLF: {
- const char *srcEnd = srcStart + srcLen;
- const char *dstEnd = dstStart + dstLen;
- const char *src = srcStart;
+ const char *crFound, *src = srcStart;
char *dst = dstStart;
-
- for ( ; dst < dstEnd && src < srcEnd; ) {
- if (*src == '\r') {
- src++;
- if (src == srcEnd) {
- src--;
- break;
- } else if (*src == '\n') {
- *dst++ = *src++;
- } else {
- *dst++ = '\r';
- }
+ int lesser = (dstLen < srcLen) ? dstLen : srcLen;
+
+ while ((crFound = memchr(src, '\r', lesser))) {
+ int numBytes = crFound - src;
+ memmove(dst, src, numBytes);
+
+ dst += numBytes;
+ src += numBytes;
+ dstLen -= numBytes;
+ srcLen -= numBytes;
+ if (srcLen == 1) {
+ /* valid src bytes end in \r */
+ lesser = 0;
+ break;
+ }
+ if (src[1] == '\n') {
+ *dst++ = '\n';
+ srcLen -= 2;
+ src += 2;
} else {
- *dst++ = *src++;
+ *dst++ = '\r';
+ srcLen--;
+ src++;
}
+ dstLen++;
+ lesser = (dstLen < srcLen) ? dstLen : srcLen;
}
- srcLen = src - srcStart;
- dstLen = dst - dstStart;
+ memmove(dst, src, lesser);
+ srcLen = src + lesser - srcStart;
+ dstLen = dst + lesser - dstStart;
break;
}
case TCL_TRANSLATE_AUTO: {