Fixed flushbuf() so that it works with POSIX conformant Unix versions
authorceriel <none@none>
Mon, 10 Jun 1991 17:07:18 +0000 (17:07 +0000)
committerceriel <none@none>
Mon, 10 Jun 1991 17:07:18 +0000 (17:07 +0000)
lang/cem/libcc.ansi/stdio/.distr
lang/cem/libcc.ansi/stdio/LIST
lang/cem/libcc.ansi/stdio/doprnt.c
lang/cem/libcc.ansi/stdio/fltpr.c
lang/cem/libcc.ansi/stdio/flushbuf.c
lang/cem/libcc.ansi/stdio/loc_incl.h

index 1a23b55..06483bc 100644 (file)
@@ -27,7 +27,6 @@ fseek.c
 fsetpos.c
 ftell.c
 fwrite.c
-gcvt.c
 getc.c
 getchar.c
 gets.c
index 9f208f3..a7ecf21 100644 (file)
@@ -44,7 +44,6 @@ ferror.c
 fileno.c
 fltpr.c
 ecvt.c
-gcvt.c
 fillbuf.c
 fclose.c
 flushbuf.c
index b3cf073..783f044 100644 (file)
@@ -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':
index 6472cd7..49fe753 100644 (file)
@@ -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 */
index f7d453b..d8bdc21 100644 (file)
@@ -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;
index bbabe33..e3eeb1b 100644 (file)
 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 */