From: ceriel Date: Mon, 10 Jun 1991 17:07:18 +0000 (+0000) Subject: Fixed flushbuf() so that it works with POSIX conformant Unix versions X-Git-Tag: release-5-5~1109 X-Git-Url: https://git.ndcode.org/public/gitweb.cgi?a=commitdiff_plain;h=9e9e7db6b461d803d9572d0c02432b575c4fa96b;p=ack.git Fixed flushbuf() so that it works with POSIX conformant Unix versions --- diff --git a/lang/cem/libcc.ansi/stdio/.distr b/lang/cem/libcc.ansi/stdio/.distr index 1a23b5577..06483bcac 100644 --- a/lang/cem/libcc.ansi/stdio/.distr +++ b/lang/cem/libcc.ansi/stdio/.distr @@ -27,7 +27,6 @@ fseek.c fsetpos.c ftell.c fwrite.c -gcvt.c getc.c getchar.c gets.c diff --git a/lang/cem/libcc.ansi/stdio/LIST b/lang/cem/libcc.ansi/stdio/LIST index 9f208f35a..a7ecf217d 100644 --- a/lang/cem/libcc.ansi/stdio/LIST +++ b/lang/cem/libcc.ansi/stdio/LIST @@ -44,7 +44,6 @@ ferror.c fileno.c fltpr.c ecvt.c -gcvt.c fillbuf.c fclose.c flushbuf.c diff --git a/lang/cem/libcc.ansi/stdio/doprnt.c b/lang/cem/libcc.ansi/stdio/doprnt.c index b3cf0731e..783f04406 100644 --- a/lang/cem/libcc.ansi/stdio/doprnt.c +++ b/lang/cem/libcc.ansi/stdio/doprnt.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': diff --git a/lang/cem/libcc.ansi/stdio/fltpr.c b/lang/cem/libcc.ansi/stdio/fltpr.c index 6472cd7d1..49fe75389 100644 --- a/lang/cem/libcc.ansi/stdio/fltpr.c +++ b/lang/cem/libcc.ansi/stdio/fltpr.c @@ -1,12 +1,14 @@ /* - * floatpr.c - print floating point numbers + * fltpr.c - print floating point numbers */ /* $Header$ */ #ifndef NOFLOAT +#include +#include #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 */ diff --git a/lang/cem/libcc.ansi/stdio/flushbuf.c b/lang/cem/libcc.ansi/stdio/flushbuf.c index f7d453b37..d8bdc21cf 100644 --- a/lang/cem/libcc.ansi/stdio/flushbuf.c +++ b/lang/cem/libcc.ansi/stdio/flushbuf.c @@ -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; diff --git a/lang/cem/libcc.ansi/stdio/loc_incl.h b/lang/cem/libcc.ansi/stdio/loc_incl.h index bbabe33af..e3eeb1bee 100644 --- a/lang/cem/libcc.ansi/stdio/loc_incl.h +++ b/lang/cem/libcc.ansi/stdio/loc_incl.h @@ -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 */