Fixed flushbuf() so that it works with POSIX conformant Unix versions
This commit is contained in:
parent
e6a017827e
commit
9e9e7db6b4
6 changed files with 124 additions and 45 deletions
|
@ -27,7 +27,6 @@ fseek.c
|
||||||
fsetpos.c
|
fsetpos.c
|
||||||
ftell.c
|
ftell.c
|
||||||
fwrite.c
|
fwrite.c
|
||||||
gcvt.c
|
|
||||||
getc.c
|
getc.c
|
||||||
getchar.c
|
getchar.c
|
||||||
gets.c
|
gets.c
|
||||||
|
|
|
@ -44,7 +44,6 @@ ferror.c
|
||||||
fileno.c
|
fileno.c
|
||||||
fltpr.c
|
fltpr.c
|
||||||
ecvt.c
|
ecvt.c
|
||||||
gcvt.c
|
|
||||||
fillbuf.c
|
fillbuf.c
|
||||||
fclose.c
|
fclose.c
|
||||||
flushbuf.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;
|
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
|
int
|
||||||
_doprnt(register const char *fmt, va_list ap, FILE *stream)
|
_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;
|
precision = sizeof(buf) - 1;
|
||||||
|
|
||||||
flags |= FL_SIGNEDCONV;
|
flags |= FL_SIGNEDCONV;
|
||||||
s = f_print(&ap, flags, s, c, precision);
|
s = _f_print(&ap, flags, s, c, precision);
|
||||||
break;
|
break;
|
||||||
#endif /* NOFLOAT */
|
#endif /* NOFLOAT */
|
||||||
case 'r':
|
case 'r':
|
||||||
|
|
|
@ -1,12 +1,14 @@
|
||||||
/*
|
/*
|
||||||
* floatpr.c - print floating point numbers
|
* fltpr.c - print floating point numbers
|
||||||
*/
|
*/
|
||||||
/* $Header$ */
|
/* $Header$ */
|
||||||
|
|
||||||
#ifndef NOFLOAT
|
#ifndef NOFLOAT
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdarg.h>
|
||||||
#include "loc_incl.h"
|
#include "loc_incl.h"
|
||||||
|
|
||||||
char *
|
static char *
|
||||||
_pfloat(long double r, register char *s, int n, int flags)
|
_pfloat(long double r, register char *s, int n, int flags)
|
||||||
{
|
{
|
||||||
register char *s1;
|
register char *s1;
|
||||||
|
@ -39,7 +41,7 @@ _pfloat(long double r, register char *s, int n, int flags)
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
char *
|
static char *
|
||||||
_pscien(long double r, register char *s, int n, int flags)
|
_pscien(long double r, register char *s, int n, int flags)
|
||||||
{
|
{
|
||||||
int sign, dp;
|
int sign, dp;
|
||||||
|
@ -74,4 +76,103 @@ _pscien(long double r, register char *s, int n, int flags)
|
||||||
*s++ = '0' + (dp%10);
|
*s++ = '0' + (dp%10);
|
||||||
return s;
|
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 */
|
#endif /* NOFLOAT */
|
||||||
|
|
|
@ -14,6 +14,21 @@ int _write(int d, const char *buf, int nbytes);
|
||||||
int _isatty(int d);
|
int _isatty(int d);
|
||||||
extern void (*_clean)(void);
|
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
|
int
|
||||||
__flushbuf(int c, FILE * stream)
|
__flushbuf(int c, FILE * stream)
|
||||||
{
|
{
|
||||||
|
@ -75,8 +90,8 @@ __flushbuf(int c, FILE * stream)
|
||||||
return EOF;
|
return EOF;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (_write(fileno(stream), (char *)stream->_buf,
|
if (! do_write(fileno(stream), (char *)stream->_buf,
|
||||||
-stream->_count) != -stream->_count) {
|
-stream->_count)) {
|
||||||
stream->_flags |= _IOERR;
|
stream->_flags |= _IOERR;
|
||||||
return EOF;
|
return EOF;
|
||||||
} else {
|
} else {
|
||||||
|
@ -97,8 +112,7 @@ __flushbuf(int c, FILE * stream)
|
||||||
return EOF;
|
return EOF;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (_write(fileno(stream), (char *)stream->_buf, count)
|
if (! do_write(fileno(stream), (char *)stream->_buf, count)) {
|
||||||
!= count) {
|
|
||||||
*(stream->_buf) = c;
|
*(stream->_buf) = c;
|
||||||
stream->_flags |= _IOERR;
|
stream->_flags |= _IOERR;
|
||||||
return EOF;
|
return EOF;
|
||||||
|
|
|
@ -12,17 +12,15 @@
|
||||||
int _doprnt(const char *format, va_list ap, FILE *stream);
|
int _doprnt(const char *format, va_list ap, FILE *stream);
|
||||||
int _doscan(FILE * stream, const char *format, va_list ap);
|
int _doscan(FILE * stream, const char *format, va_list ap);
|
||||||
char *_i_compute(unsigned long val, int base, char *s, int nrdigits);
|
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);
|
void __cleanup(void);
|
||||||
|
|
||||||
FILE *popen(const char *command, const char *type);
|
FILE *popen(const char *command, const char *type);
|
||||||
FILE *fdopen(int fd, const char *mode);
|
FILE *fdopen(int fd, const char *mode);
|
||||||
|
|
||||||
#ifndef NOFLOAT
|
#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 *_ecvt(long double value, int ndigit, int *decpt, int *sign);
|
||||||
char *_fcvt(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 */
|
#endif /* NOFLOAT */
|
||||||
|
|
||||||
#define FL_LJUST 0x0001 /* left-justify field */
|
#define FL_LJUST 0x0001 /* left-justify field */
|
||||||
|
|
Loading…
Reference in a new issue