fsetpos.c
ftell.c
fwrite.c
-gcvt.c
getc.c
getchar.c
gets.c
fileno.c
fltpr.c
ecvt.c
-gcvt.c
fillbuf.c
fclose.c
flushbuf.c
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)
{
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':
/*
- * 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;
return s;
}
-char *
+static char *
_pscien(long double r, register char *s, int n, int flags)
{
int sign, dp;
*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 */
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)
{
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 {
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;
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 */