|
|
1.1 ! root 1: /* ! 2: Copyright (C) 1993 Free Software Foundation ! 3: ! 4: This file is part of the GNU IO Library. This library is free ! 5: software; you can redistribute it and/or modify it under the ! 6: terms of the GNU General Public License as published by the ! 7: Free Software Foundation; either version 2, or (at your option) ! 8: any later version. ! 9: ! 10: This library is distributed in the hope that it will be useful, ! 11: but WITHOUT ANY WARRANTY; without even the implied warranty of ! 12: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ! 13: GNU General Public License for more details. ! 14: ! 15: You should have received a copy of the GNU General Public License ! 16: along with GNU CC; see the file COPYING. If not, write to ! 17: the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. ! 18: ! 19: As a special exception, if you link this library with files ! 20: compiled with a GNU compiler to produce an executable, this does not cause ! 21: the resulting executable to be covered by the GNU General Public License. ! 22: This exception does not however invalidate any other reasons why ! 23: the executable file might be covered by the GNU General Public License. */ ! 24: ! 25: #include "libioP.h" ! 26: ! 27: /* Format floating-point number and print them. ! 28: Return number of chars printed, or EOF on error. ! 29: ! 30: sign_mode == '+' : print "-" or "+" ! 31: sign_mode == ' ' : print "-" or " " ! 32: sign_mode == '\0' : print "-' or "" ! 33: */ ! 34: ! 35: int _IO_outfloat(value, sb, type, width, precision, flags, ! 36: sign_mode, fill) ! 37: double value; ! 38: _IO_FILE *sb; ! 39: int type; ! 40: int width; ! 41: int precision; ! 42: int flags; ! 43: int sign_mode; ! 44: int fill; ! 45: { ! 46: int count = 0; ! 47: #define PUT(x) do {if (_IO_putc(x, sb) < 0) goto error; count++;} while (0) ! 48: #define PUTN(p, n) \ ! 49: do {int _n=n; count+=_n; if (_IO_sputn(sb, p,_n) != _n) goto error;} while(0) ! 50: #define PADN(fill, n) \ ! 51: do {int _n = n; count+=_n; if (_IO_padn(sb, fill, _n) != _n) goto error;} while (0) ! 52: int pad_kind = flags & (_IO_LEFT|_IO_RIGHT|_IO_INTERNAL); ! 53: int skip_zeroes = 0; ! 54: int show_dot = (flags & _IO_SHOWPOINT) != 0; ! 55: int decpt; ! 56: int sign; ! 57: int mode; ! 58: int exponent_size; ! 59: int print_sign; ! 60: int trailing_zeroes, useful_digits; ! 61: int padding, unpadded_width; ! 62: char *p; ! 63: char *exponent_start; ! 64: register int i; ! 65: #define EBUF_SIZE 12 ! 66: #define EBUF_END &ebuf[EBUF_SIZE] ! 67: char ebuf[EBUF_SIZE]; ! 68: char *end; ! 69: int exp = 0; ! 70: switch (type) ! 71: { ! 72: case 'f': ! 73: mode = 3; ! 74: break; ! 75: case 'e': ! 76: case 'E': ! 77: exp = type; ! 78: mode = 2; ! 79: if (precision != 999) ! 80: precision++; /* Add one to include digit before decimal point. */ ! 81: break; ! 82: case 'g': ! 83: case 'G': ! 84: exp = type == 'g' ? 'e' : 'E'; ! 85: if (precision == 0) precision = 1; ! 86: if (!(flags & _IO_SHOWPOINT)) ! 87: skip_zeroes = 1; ! 88: type = 'g'; ! 89: mode = 2; ! 90: break; ! 91: } ! 92: /* Do the actual convension */ ! 93: if (precision == 999 && mode != 3) ! 94: mode = 0; ! 95: p = _IO_dtoa(value, mode, precision, &decpt, &sign, &end); ! 96: useful_digits = end-p; ! 97: exponent_start = EBUF_END; ! 98: if (mode == 0) ! 99: precision = useful_digits; ! 100: /* Check if we need to emit an exponent. */ ! 101: if (mode != 3 && decpt != 9999) ! 102: { ! 103: i = decpt - 1; ! 104: if ((type != 'g' && type != 'F') || i < -4 || i >= precision) ! 105: { ! 106: /* Print the exponent into ebuf. ! 107: We write ebuf in reverse order (right-to-left). */ ! 108: char sign; ! 109: if (i >= 0) ! 110: sign = '+'; ! 111: else ! 112: sign = '-', i = -i; ! 113: /* Note: ANSI requires at least 2 exponent digits. */ ! 114: do { ! 115: *--exponent_start = (i % 10) + '0'; ! 116: i /= 10; ! 117: } while (i >= 10); ! 118: *--exponent_start = i + '0'; ! 119: *--exponent_start = sign; ! 120: *--exponent_start = exp; ! 121: } ! 122: } ! 123: exponent_size = EBUF_END - exponent_start; ! 124: if (mode == 1) ! 125: precision = 1; ! 126: /* If we print an exponent, always show just one digit before point. */ ! 127: if (exponent_size) ! 128: decpt = 1; ! 129: if (decpt == 9999) ! 130: { /* Infinity or NaN */ ! 131: decpt = useful_digits; ! 132: precision = 0; ! 133: show_dot = 0; ! 134: } ! 135: ! 136: /* dtoa truncates trailing zeroes. Set the variable trailing_zeroes to ! 137: the number of 0's we have to add (after the decimal point). */ ! 138: if (skip_zeroes) ! 139: trailing_zeroes = 0; ! 140: else if (type == 'f') ! 141: trailing_zeroes = useful_digits <= decpt ? precision ! 142: : precision-(useful_digits-decpt); ! 143: else if (exponent_size) /* 'e' 'E' or 'g' format using exponential notation*/ ! 144: trailing_zeroes = precision - useful_digits; ! 145: else /* 'g' format not using exponential notation. */ ! 146: trailing_zeroes = useful_digits <= decpt ? precision - decpt ! 147: : precision-useful_digits; ! 148: if (trailing_zeroes < 0) trailing_zeroes = 0; ! 149: ! 150: if (trailing_zeroes != 0 || useful_digits > decpt) ! 151: show_dot = 1; ! 152: if (sign_mode == 0) ! 153: print_sign = sign ? '-' : 0; ! 154: else if (sign_mode == '+') ! 155: print_sign = sign ? '-' : '+'; ! 156: else /* if (sign_mode == ' ') */ ! 157: print_sign = sign ? '-' : ' '; ! 158: ! 159: /* Calculate the width (before padding). */ ! 160: unpadded_width = ! 161: (print_sign != 0) + trailing_zeroes + exponent_size + show_dot ! 162: + useful_digits ! 163: + (decpt > useful_digits ? decpt - useful_digits ! 164: : decpt > 0 ? 0 : 1 - decpt); ! 165: ! 166: padding = width > unpadded_width ? width - unpadded_width : 0; ! 167: if (padding > 0 && pad_kind != _IO_LEFT && pad_kind != _IO_INTERNAL) ! 168: PADN(fill, padding); /* Default (right) adjust */ ! 169: if (print_sign) ! 170: PUT(print_sign); ! 171: if (pad_kind == _IO_INTERNAL && padding > 0) ! 172: PADN(fill, padding); ! 173: if (decpt > 0) ! 174: { ! 175: if (useful_digits >= decpt) ! 176: PUTN(p, decpt); ! 177: else ! 178: { ! 179: PUTN(p, useful_digits); ! 180: PADN('0', decpt-useful_digits); ! 181: } ! 182: if (show_dot) ! 183: { ! 184: PUT('.'); ! 185: /* Print digits after the decimal point. */ ! 186: if (useful_digits > decpt) ! 187: PUTN(p + decpt, useful_digits-decpt); ! 188: } ! 189: } ! 190: else ! 191: { ! 192: PUT('0'); ! 193: if (show_dot) ! 194: { ! 195: PUT('.'); ! 196: PADN('0', -decpt); ! 197: /* Print digits after the decimal point. */ ! 198: PUTN(p, useful_digits); ! 199: } ! 200: } ! 201: PADN('0', trailing_zeroes); ! 202: if (exponent_size) ! 203: PUTN(exponent_start, exponent_size); ! 204: if (pad_kind == _IO_LEFT && padding > 0) /* Left adjustment*/ ! 205: PADN(fill, padding); ! 206: return count; ! 207: error: ! 208: return EOF; ! 209: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.