Fixed flushbuf() so that it works with POSIX conformant Unix versions
This commit is contained in:
parent
e6a017827e
commit
9e9e7db6b4
|
@ -27,7 +27,6 @@ fseek.c
|
|||
fsetpos.c
|
||||
ftell.c
|
||||
fwrite.c
|
||||
gcvt.c
|
||||
getc.c
|
||||
getchar.c
|
||||
gets.c
|
||||
|
|
|
@ -44,7 +44,6 @@ ferror.c
|
|||
fileno.c
|
||||
fltpr.c
|
||||
ecvt.c
|
||||
gcvt.c
|
||||
fillbuf.c
|
||||
fclose.c
|
||||
flushbuf.c
|
||||
|
|
|
@ -111,38 +111,6 @@ o_print(va_list *ap, int flags, char *s, char c, int precision, int is_signed)
|
|||
return s;
|
||||
}
|
||||
|
||||
#ifndef NOFLOAT
|
||||
static char *
|
||||
f_print(va_list *ap, int flags, char *s, char c, int precision)
|
||||
{
|
||||
register char *old_s = s;
|
||||
long double ld_val;
|
||||
|
||||
if (flags & FL_LONGDOUBLE) ld_val = va_arg(*ap, long double);
|
||||
else ld_val = (long double) va_arg(*ap, double);
|
||||
|
||||
switch(c) {
|
||||
case 'f':
|
||||
s = _pfloat(ld_val, s, precision, flags);
|
||||
break;
|
||||
case 'e':
|
||||
case 'E':
|
||||
s = _pscien(ld_val, s, precision , flags);
|
||||
break;
|
||||
case 'g':
|
||||
case 'G':
|
||||
s = _gcvt(ld_val, precision, s, flags);
|
||||
s += strlen(s);
|
||||
break;
|
||||
}
|
||||
if ( c == 'E' || c == 'G') {
|
||||
while (*old_s && *old_s != 'e') old_s++;
|
||||
if (*old_s == 'e') *old_s = 'E';
|
||||
}
|
||||
return s;
|
||||
}
|
||||
#endif /* NOFLOAT */
|
||||
|
||||
int
|
||||
_doprnt(register const char *fmt, va_list ap, FILE *stream)
|
||||
{
|
||||
|
@ -279,7 +247,7 @@ _doprnt(register const char *fmt, va_list ap, FILE *stream)
|
|||
precision = sizeof(buf) - 1;
|
||||
|
||||
flags |= FL_SIGNEDCONV;
|
||||
s = f_print(&ap, flags, s, c, precision);
|
||||
s = _f_print(&ap, flags, s, c, precision);
|
||||
break;
|
||||
#endif /* NOFLOAT */
|
||||
case 'r':
|
||||
|
|
|
@ -1,12 +1,14 @@
|
|||
/*
|
||||
* floatpr.c - print floating point numbers
|
||||
* fltpr.c - print floating point numbers
|
||||
*/
|
||||
/* $Header$ */
|
||||
|
||||
#ifndef NOFLOAT
|
||||
#include <string.h>
|
||||
#include <stdarg.h>
|
||||
#include "loc_incl.h"
|
||||
|
||||
char *
|
||||
static char *
|
||||
_pfloat(long double r, register char *s, int n, int flags)
|
||||
{
|
||||
register char *s1;
|
||||
|
@ -39,7 +41,7 @@ _pfloat(long double r, register char *s, int n, int flags)
|
|||
return s;
|
||||
}
|
||||
|
||||
char *
|
||||
static char *
|
||||
_pscien(long double r, register char *s, int n, int flags)
|
||||
{
|
||||
int sign, dp;
|
||||
|
@ -74,4 +76,103 @@ _pscien(long double r, register char *s, int n, int flags)
|
|||
*s++ = '0' + (dp%10);
|
||||
return s;
|
||||
}
|
||||
|
||||
#define NDIGINEXP(exp) (((exp) >= 100 || (exp) <= -100) ? 3 : 2)
|
||||
#define LOW_EXP -4
|
||||
#define USE_EXP(exp, ndigits) (((exp) < LOW_EXP + 1) || (exp >= ndigits + 1))
|
||||
|
||||
static char *
|
||||
_gcvt(long double value, int ndigit, char *s, int flags)
|
||||
{
|
||||
int sign, dp;
|
||||
register char *s1, *s2;
|
||||
register int i;
|
||||
register int nndigit = ndigit;
|
||||
|
||||
s1 = _ecvt(value, ndigit, &dp, &sign);
|
||||
s2 = s;
|
||||
if (sign) *s2++ = '-';
|
||||
else if (flags & FL_SIGN)
|
||||
*s2++ = '+';
|
||||
else if (flags & FL_SPACE)
|
||||
*s2++ = ' ';
|
||||
|
||||
if (!(flags & FL_ALT))
|
||||
for (i = nndigit - 1; i > 0 && s1[i] == '0'; i--)
|
||||
nndigit--;
|
||||
|
||||
if (USE_EXP(dp,ndigit)) {
|
||||
/* Use E format */
|
||||
dp--;
|
||||
*s2++ = *s1++;
|
||||
if ((nndigit > 1) || (flags & FL_ALT)) *s2++ = '.';
|
||||
while (--nndigit > 0) *s2++ = *s1++;
|
||||
*s2++ = 'e';
|
||||
if (dp < 0) {
|
||||
*s2++ = '-';
|
||||
dp = -dp;
|
||||
}
|
||||
else *s2++ = '+';
|
||||
s2 += NDIGINEXP(dp);
|
||||
*s2 = 0;
|
||||
for (i = NDIGINEXP(dp); i > 0; i--) {
|
||||
*--s2 = dp % 10 + '0';
|
||||
dp /= 10;
|
||||
}
|
||||
return s;
|
||||
}
|
||||
/* Use f format */
|
||||
if (dp <= 0) {
|
||||
if (*s1 != '0') {
|
||||
/* otherwise the whole number is 0 */
|
||||
*s2++ = '0';
|
||||
*s2++ = '.';
|
||||
}
|
||||
while (dp < 0) {
|
||||
dp++;
|
||||
*s2++ = '0';
|
||||
}
|
||||
}
|
||||
for (i = 1; i <= nndigit; i++) {
|
||||
*s2++ = *s1++;
|
||||
if (i == dp) *s2++ = '.';
|
||||
}
|
||||
if (i <= dp) {
|
||||
while (i++ <= dp) *s2++ = '0';
|
||||
*s2++ = '.';
|
||||
}
|
||||
if ((s2[-1]=='.') && !(flags & FL_ALT)) s2--;
|
||||
*s2 = '\0';
|
||||
return s;
|
||||
}
|
||||
|
||||
char *
|
||||
_f_print(va_list *ap, int flags, char *s, char c, int precision)
|
||||
{
|
||||
register char *old_s = s;
|
||||
long double ld_val;
|
||||
|
||||
if (flags & FL_LONGDOUBLE) ld_val = va_arg(*ap, long double);
|
||||
else ld_val = (long double) va_arg(*ap, double);
|
||||
|
||||
switch(c) {
|
||||
case 'f':
|
||||
s = _pfloat(ld_val, s, precision, flags);
|
||||
break;
|
||||
case 'e':
|
||||
case 'E':
|
||||
s = _pscien(ld_val, s, precision , flags);
|
||||
break;
|
||||
case 'g':
|
||||
case 'G':
|
||||
s = _gcvt(ld_val, precision, s, flags);
|
||||
s += strlen(s);
|
||||
break;
|
||||
}
|
||||
if ( c == 'E' || c == 'G') {
|
||||
while (*old_s && *old_s != 'e') old_s++;
|
||||
if (*old_s == 'e') *old_s = 'E';
|
||||
}
|
||||
return s;
|
||||
}
|
||||
#endif /* NOFLOAT */
|
||||
|
|
|
@ -14,6 +14,21 @@ int _write(int d, const char *buf, int nbytes);
|
|||
int _isatty(int d);
|
||||
extern void (*_clean)(void);
|
||||
|
||||
static int
|
||||
do_write(int d, char *buf, int nbytes)
|
||||
{
|
||||
int c;
|
||||
|
||||
/* POSIX actually allows write() to return a positive value less
|
||||
than nbytes, so loop ...
|
||||
*/
|
||||
while ((c = _write(d, buf, nbytes)) > 0 && c < nbytes) {
|
||||
nbytes -= c;
|
||||
buf += c;
|
||||
}
|
||||
return c > 0;
|
||||
}
|
||||
|
||||
int
|
||||
__flushbuf(int c, FILE * stream)
|
||||
{
|
||||
|
@ -75,8 +90,8 @@ __flushbuf(int c, FILE * stream)
|
|||
return EOF;
|
||||
}
|
||||
}
|
||||
if (_write(fileno(stream), (char *)stream->_buf,
|
||||
-stream->_count) != -stream->_count) {
|
||||
if (! do_write(fileno(stream), (char *)stream->_buf,
|
||||
-stream->_count)) {
|
||||
stream->_flags |= _IOERR;
|
||||
return EOF;
|
||||
} else {
|
||||
|
@ -97,8 +112,7 @@ __flushbuf(int c, FILE * stream)
|
|||
return EOF;
|
||||
}
|
||||
}
|
||||
if (_write(fileno(stream), (char *)stream->_buf, count)
|
||||
!= count) {
|
||||
if (! do_write(fileno(stream), (char *)stream->_buf, count)) {
|
||||
*(stream->_buf) = c;
|
||||
stream->_flags |= _IOERR;
|
||||
return EOF;
|
||||
|
|
|
@ -12,17 +12,15 @@
|
|||
int _doprnt(const char *format, va_list ap, FILE *stream);
|
||||
int _doscan(FILE * stream, const char *format, va_list ap);
|
||||
char *_i_compute(unsigned long val, int base, char *s, int nrdigits);
|
||||
char *_f_print(va_list *ap, int flags, char *s, char c, int precision);
|
||||
void __cleanup(void);
|
||||
|
||||
FILE *popen(const char *command, const char *type);
|
||||
FILE *fdopen(int fd, const char *mode);
|
||||
|
||||
#ifndef NOFLOAT
|
||||
char *_pfloat(long double r, register char *s, int n, int flags);
|
||||
char *_pscien(long double r, register char *s, int n, int flags);
|
||||
char *_ecvt(long double value, int ndigit, int *decpt, int *sign);
|
||||
char *_fcvt(long double value, int ndigit, int *decpt, int *sign);
|
||||
char *_gcvt(long double value, int ndigit, char *s, int flags);
|
||||
#endif /* NOFLOAT */
|
||||
|
||||
#define FL_LJUST 0x0001 /* left-justify field */
|
||||
|
|
Loading…
Reference in a new issue