andre@0: /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ andre@0: /* This Source Code Form is subject to the terms of the Mozilla Public andre@0: * License, v. 2.0. If a copy of the MPL was not distributed with this andre@0: * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ andre@0: andre@0: #include "primpl.h" andre@0: andre@0: #include andre@0: andre@0: /* andre@0: ** fprintf to a PRFileDesc andre@0: */ andre@0: PR_IMPLEMENT(PRUint32) PR_fprintf(PRFileDesc* fd, const char *fmt, ...) andre@0: { andre@0: va_list ap; andre@0: PRUint32 rv; andre@0: andre@0: va_start(ap, fmt); andre@0: rv = PR_vfprintf(fd, fmt, ap); andre@0: va_end(ap); andre@0: return rv; andre@0: } andre@0: andre@0: PR_IMPLEMENT(PRUint32) PR_vfprintf(PRFileDesc* fd, const char *fmt, va_list ap) andre@0: { andre@0: /* XXX this could be better */ andre@0: PRUint32 rv, len; andre@0: char* msg = PR_vsmprintf(fmt, ap); andre@0: if (NULL == msg) { andre@0: return -1; andre@0: } andre@0: len = strlen(msg); andre@0: #ifdef XP_OS2 andre@0: /* andre@0: * OS/2 really needs a \r for every \n. andre@0: * In the future we should try to use scatter-gather instead of a andre@0: * succession of PR_Write. andre@0: */ andre@0: if (isatty(PR_FileDesc2NativeHandle(fd))) { andre@0: PRUint32 last = 0, idx; andre@0: PRInt32 tmp; andre@0: rv = 0; andre@0: for (idx = 0; idx < len+1; idx++) { andre@0: if ((idx - last > 0) && (('\n' == msg[idx]) || (idx == len))) { andre@0: tmp = PR_Write(fd, msg + last, idx - last); andre@0: if (tmp >= 0) { andre@0: rv += tmp; andre@0: } andre@0: last = idx; andre@0: } andre@0: /* andre@0: * if current character is \n, and andre@0: * previous character isn't \r, and andre@0: * next character isn't \r andre@0: */ andre@0: if (('\n' == msg[idx]) && andre@0: ((0 == idx) || ('\r' != msg[idx-1])) && andre@0: ('\r' != msg[idx+1])) { andre@0: /* add extra \r */ andre@0: tmp = PR_Write(fd, "\r", 1); andre@0: if (tmp >= 0) { andre@0: rv += tmp; andre@0: } andre@0: } andre@0: } andre@0: } else { andre@0: rv = PR_Write(fd, msg, len); andre@0: } andre@0: #else andre@0: rv = PR_Write(fd, msg, len); andre@0: #endif andre@0: PR_DELETE(msg); andre@0: return rv; andre@0: }