OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-old/] [newlib-1.17.0/] [newlib/] [libc/] [machine/] [powerpc/] [vfprintf.c] - Blame information for rev 862

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 148 jeremybenn
/*
2
FUNCTION
3
<<vprintf>>, <<vfprintf>>, <<vsprintf>>---format argument list
4
 
5
INDEX
6
        vprintf
7
INDEX
8
        vfprintf
9
INDEX
10
        vsprintf
11
INDEX
12
        vsnprintf
13
 
14
ANSI_SYNOPSIS
15
        #include <stdio.h>
16
        #include <stdarg.h>
17
        int vprintf(const char *<[fmt]>, va_list <[list]>);
18
        int vfprintf(FILE *<[fp]>, const char *<[fmt]>, va_list <[list]>);
19
        int vsprintf(char *<[str]>, const char *<[fmt]>, va_list <[list]>);
20
        int vsnprintf(char *<[str]>, size_t <[size]>, const char *<[fmt]>, va_list <[list]>);
21
 
22
        int _vprintf_r(void *<[reent]>, const char *<[fmt]>,
23
                        va_list <[list]>);
24
        int _vfprintf_r(void *<[reent]>, FILE *<[fp]>, const char *<[fmt]>,
25
                        va_list <[list]>);
26
        int _vsprintf_r(void *<[reent]>, char *<[str]>, const char *<[fmt]>,
27
                        va_list <[list]>);
28
        int _vsnprintf_r(void *<[reent]>, char *<[str]>, size_t <[size]>, const char *<[fmt]>,
29
                        va_list <[list]>);
30
 
31
TRAD_SYNOPSIS
32
        #include <stdio.h>
33
        #include <varargs.h>
34
        int vprintf( <[fmt]>, <[list]>)
35
        char *<[fmt]>;
36
        va_list <[list]>;
37
 
38
        int vfprintf(<[fp]>, <[fmt]>, <[list]>)
39
        FILE *<[fp]>;
40
        char *<[fmt]>;
41
        va_list <[list]>;
42
 
43
        int vsprintf(<[str]>, <[fmt]>, <[list]>)
44
        char *<[str]>;
45
        char *<[fmt]>;
46
        va_list <[list]>;
47
 
48
        int vsnprintf(<[str]>, <[size]>, <[fmt]>, <[list]>)
49
        char *<[str]>;
50
        size_t <[size]>;
51
        char *<[fmt]>;
52
        va_list <[list]>;
53
 
54
        int _vprintf_r(<[reent]>, <[fmt]>, <[list]>)
55
        char *<[reent]>;
56
        char *<[fmt]>;
57
        va_list <[list]>;
58
 
59
        int _vfprintf_r(<[reent]>, <[fp]>, <[fmt]>, <[list]>)
60
        char *<[reent]>;
61
        FILE *<[fp]>;
62
        char *<[fmt]>;
63
        va_list <[list]>;
64
 
65
        int _vsprintf_r(<[reent]>, <[str]>, <[fmt]>, <[list]>)
66
        char *<[reent]>;
67
        char *<[str]>;
68
        char *<[fmt]>;
69
        va_list <[list]>;
70
 
71
        int _vsnprintf_r(<[reent]>, <[str]>, <[size]>, <[fmt]>, <[list]>)
72
        char *<[reent]>;
73
        char *<[str]>;
74
        size_t <[size]>;
75
        char *<[fmt]>;
76
        va_list <[list]>;
77
 
78
DESCRIPTION
79
<<vprintf>>, <<vfprintf>>, <<vsprintf>> and <<vsnprintf>> are (respectively)
80
variants of <<printf>>, <<fprintf>>, <<sprintf>> and <<snprintf>>.  They differ
81
only in allowing their caller to pass the variable argument list as a
82
<<va_list>> object (initialized by <<va_start>>) rather than directly
83
accepting a variable number of arguments.
84
 
85
RETURNS
86
The return values are consistent with the corresponding functions:
87
<<vsprintf>> returns the number of bytes in the output string,
88
save that the concluding <<NULL>> is not counted.
89
<<vprintf>> and <<vfprintf>> return the number of characters transmitted.
90
If an error occurs, <<vprintf>> and <<vfprintf>> return <<EOF>>. No
91
error returns occur for <<vsprintf>>.
92
 
93
PORTABILITY
94
ANSI C requires all three functions.
95
 
96
Supporting OS subroutines required: <<close>>, <<fstat>>, <<isatty>>,
97
<<lseek>>, <<read>>, <<sbrk>>, <<write>>.
98
*/
99
 
100
/*-
101
 * Copyright (c) 1990 The Regents of the University of California.
102
 * All rights reserved.
103
 *
104
 * This code is derived from software contributed to Berkeley by
105
 * Chris Torek.
106
 *
107
 * Redistribution and use in source and binary forms, with or without
108
 * modification, are permitted provided that the following conditions
109
 * are met:
110
 * 1. Redistributions of source code must retain the above copyright
111
 *    notice, this list of conditions and the following disclaimer.
112
 * 2. Redistributions in binary form must reproduce the above copyright
113
 *    notice, this list of conditions and the following disclaimer in the
114
 *    documentation and/or other materials provided with the distribution.
115
 * 3. All advertising materials mentioning features or use of this software
116
 *    must display the following acknowledgement:
117
 *      This product includes software developed by the University of
118
 *      California, Berkeley and its contributors.
119
 * 4. Neither the name of the University nor the names of its contributors
120
 *    may be used to endorse or promote products derived from this software
121
 *    without specific prior written permission.
122
 *
123
 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
124
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
125
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
126
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
127
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
128
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
129
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
130
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
131
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
132
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
133
 * SUCH DAMAGE.
134
 */
135
 
136
#if defined(LIBC_SCCS) && !defined(lint)
137
/*static char *sccsid = "from: @(#)vfprintf.c   5.50 (Berkeley) 12/16/92";*/
138
static char *rcsid = "$Id: vfprintf.c 148 2010-06-30 19:21:22Z jeremybennett $";
139
#endif /* LIBC_SCCS and not lint */
140
 
141
/*
142
 * Actual printf innards.
143
 *
144
 * This code is large and complicated...
145
 */
146
 
147
#ifdef INTEGER_ONLY
148
#define VFPRINTF vfiprintf
149
#define _VFPRINTF_R _vfiprintf_r
150
#else
151
#define VFPRINTF vfprintf
152
#define _VFPRINTF_R _vfprintf_r
153
#ifndef NO_FLOATING_POINT
154
#define FLOATING_POINT
155
#endif
156
#endif
157
 
158
#include <_ansi.h>
159
#include <limits.h>
160
#include <stdio.h>
161
#include <stdlib.h>
162
#include <string.h>
163
#include <reent.h>
164
#include <wchar.h>
165
#include <string.h>
166
#ifdef __ALTIVEC__
167
#include <altivec.h>
168
#endif
169
 
170
#ifdef _HAVE_STDC
171
#include <stdarg.h>
172
#else
173
#include <varargs.h>
174
#endif
175
 
176
#include "local.h"
177
#include "fvwrite.h"
178
#include "vfieeefp.h"
179
 
180
/* Currently a test is made to see if long double processing is warranted.
181
   This could be changed in the future should the _ldtoa_r code be
182
   preferred over _dtoa_r.  */
183
#define _NO_LONGDBL
184
#if defined _WANT_IO_LONG_DOUBLE && (LDBL_MANT_DIG > DBL_MANT_DIG)
185
#undef _NO_LONGDBL
186
#endif
187
 
188
#define _NO_LONGLONG
189
#if defined _WANT_IO_LONG_LONG && defined __GNUC__
190
# undef _NO_LONGLONG
191
#endif
192
 
193
#ifdef __ALTIVEC__
194
typedef union
195
{
196
  vector int v;
197
  float f[4];
198
  int   i[16 / sizeof(int)];
199
  long  l[4];
200
  short s[8];
201
  signed char c[16];
202
} vec_16_byte_union;
203
#endif /* __ALTIVEC__ */
204
 
205
/*
206
 * Flush out all the vectors defined by the given uio,
207
 * then reset it so that it can be reused.
208
 */
209
static int
210
__sprint_r(rptr, fp, uio)
211
        struct _reent *rptr;
212
        FILE *fp;
213
        register struct __suio *uio;
214
{
215
        register int err;
216
 
217
        if (uio->uio_resid == 0) {
218
                uio->uio_iovcnt = 0;
219
                return (0);
220
        }
221
        err = __sfvwrite_r(rptr, fp, uio);
222
        uio->uio_resid = 0;
223
        uio->uio_iovcnt = 0;
224
        return (err);
225
}
226
 
227
/*
228
 * Helper function for `fprintf to unbuffered unix file': creates a
229
 * temporary buffer.  We only work on write-only files; this avoids
230
 * worries about ungetc buffers and so forth.
231
 */
232
static int
233
__sbprintf_r(rptr, fp, fmt, ap)
234
        struct _reent *rptr;
235
        register FILE *fp;
236
        const char *fmt;
237
        va_list ap;
238
{
239
        int ret;
240
        FILE fake;
241
        unsigned char buf[BUFSIZ];
242
 
243
        /* copy the important variables */
244
        fake._flags = fp->_flags & ~__SNBF;
245
        fake._file = fp->_file;
246
        fake._cookie = fp->_cookie;
247
        fake._write = fp->_write;
248
 
249
        /* set up the buffer */
250
        fake._bf._base = fake._p = buf;
251
        fake._bf._size = fake._w = sizeof(buf);
252
        fake._lbfsize = 0;       /* not actually used, but Just In Case */
253
 
254
        /* do the work, then copy any error status */
255
        ret = _VFPRINTF_R(rptr, &fake, fmt, ap);
256
        if (ret >= 0 && _fflush_r(rptr, &fake))
257
                ret = EOF;
258
        if (fake._flags & __SERR)
259
                fp->_flags |= __SERR;
260
        return (ret);
261
}
262
 
263
 
264
#ifdef FLOATING_POINT
265
#include <locale.h>
266
#include <math.h>
267
#include "floatio.h"
268
 
269
#define BUF             (MAXEXP+MAXFRACT+1)     /* + decimal point */
270
#define DEFPREC         6
271
 
272
#ifdef _NO_LONGDBL
273
static char *cvt _PARAMS((struct _reent *, double, int, int, char *, int *, int, int *));
274
#else
275
static char *cvt _PARAMS((struct _reent *, _LONG_DOUBLE, int, int, char *, int *, int, int *));
276
extern int  _ldcheck _PARAMS((_LONG_DOUBLE *));
277
#endif
278
 
279
static int exponent _PARAMS((char *, int, int));
280
 
281
#ifdef __SPE__
282
static char *cvt_ufix64 _PARAMS((struct _reent *, unsigned long long, int,  int *, int *));
283
#endif /* __SPE__ */
284
 
285
#else /* no FLOATING_POINT */
286
 
287
#define BUF             40
288
 
289
#endif /* FLOATING_POINT */
290
 
291
 
292
/*
293
 * Macros for converting digits to letters and vice versa
294
 */
295
#define to_digit(c)     ((c) - '0')
296
#define is_digit(c)     ((unsigned)to_digit(c) <= 9)
297
#define to_char(n)      ((n) + '0')
298
 
299
/*
300
 * Flags used during conversion.
301
 */
302
#define ALT             0x001           /* alternate form */
303
#define HEXPREFIX       0x002           /* add 0x or 0X prefix */
304
#define LADJUST         0x004           /* left adjustment */
305
#define LONGDBL         0x008           /* long double */
306
#define LONGINT         0x010           /* long integer */
307
#ifndef _NO_LONGLONG
308
#define QUADINT         0x020           /* quad integer */
309
#else /* ifdef _NO_LONGLONG, make QUADINT equivalent to LONGINT, so
310
         that %lld behaves the same as %ld, not as %d, as expected if:
311
         sizeof (long long) = sizeof long > sizeof int  */
312
#define QUADINT         LONGINT
313
#endif
314
#define SHORTINT        0x040           /* short integer */
315
#define ZEROPAD         0x080           /* zero (as opposed to blank) pad */
316
#define FPT             0x100           /* Floating point number */
317
#define VECTOR          0x200           /* vector */
318
#define FIXEDPOINT      0x400           /* fixed-point */
319
 
320
int
321
_DEFUN (VFPRINTF, (fp, fmt0, ap),
322
        FILE * fp _AND
323
        _CONST char *fmt0 _AND
324
        va_list ap)
325
{
326
  CHECK_INIT (_REENT, fp);
327
  return _VFPRINTF_R (_REENT, fp, fmt0, ap);
328
}
329
 
330
int
331
_DEFUN (_VFPRINTF_R, (data, fp, fmt0, ap),
332
        struct _reent *data _AND
333
        FILE * fp _AND
334
        _CONST char *fmt0 _AND
335
        va_list ap)
336
{
337
        register char *fmt;     /* format string */
338
        register int ch;        /* character from fmt */
339
        register int n, m;      /* handy integers (short term usage) */
340
        register char *cp;      /* handy char pointer (short term usage) */
341
        register struct __siov *iovp;/* for PRINT macro */
342
        register int flags;     /* flags as above */
343
        int ret;                /* return value accumulator */
344
        int width;              /* width from format (%8d), or 0 */
345
        int prec;               /* precision from format (%.3d), or -1 */
346
        char sign;              /* sign prefix (' ', '+', '-', or \0) */
347
        char old_sign;          /* saved value of sign when looping for vectors */
348
        int old_ch;             /* saved value of ch when looping for vectors */
349
        char *format_anchor;    /* start of format to process */
350
        wchar_t wc;
351
#ifdef FLOATING_POINT
352
        char *decimal_point = localeconv()->decimal_point;
353
        char softsign;          /* temporary negative sign for floats */
354
#ifdef _NO_LONGDBL
355
        union { int i; double d; } _double_ = {0};
356
        #define _fpvalue (_double_.d)
357
#else
358
        union { int i; _LONG_DOUBLE ld; } _long_double_ = {0};
359
        #define _fpvalue (_long_double_.ld)
360
        int tmp;
361
#endif
362
        int expt;               /* integer value of exponent */
363
        int expsize = 0; /* character count for expstr */
364
        int ndig;               /* actual number of digits returned by cvt */
365
        char expstr[7];         /* buffer for exponent string */
366
#endif
367
 
368
#ifndef _NO_LONGLONG
369
#define quad_t    long long
370
#define u_quad_t  unsigned long long
371
#else
372
#define quad_t    long
373
#define u_quad_t  u_long
374
#endif
375
 
376
        u_quad_t _uquad;        /* integer arguments %[diouxX] */
377
        enum { OCT, DEC, HEX } base;/* base for [diouxX] conversion */
378
        int dprec;              /* a copy of prec if [diouxX], 0 otherwise */
379
        int realsz;             /* field size expanded by dprec */
380
        int size;               /* size of converted field or string */
381
        char *xdigs = NULL;     /* digits for [xX] conversion */
382
#define NIOV 8
383
        struct __suio uio;      /* output information: summary */
384
        struct __siov iov[NIOV];/* ... and individual io vectors */
385
        char buf[BUF];          /* space for %c, %[diouxX], %[eEfgG] */
386
        char ox[2];             /* space for 0x hex-prefix */
387
#ifdef __ALTIVEC__
388
        char vec_sep;           /* vector separator char */
389
        int vec_print_count;    /* number of vector chunks remaining */
390
        vec_16_byte_union vec_tmp;
391
#endif /* __ALTIVEC__ */ 
392
        mbstate_t state;          /* mbtowc calls from library must not change state */
393
 
394
        /*
395
         * Choose PADSIZE to trade efficiency vs. size.  If larger printf
396
         * fields occur frequently, increase PADSIZE and make the initialisers
397
         * below longer.
398
         */
399
#define PADSIZE 16              /* pad chunk size */
400
        static _CONST char blanks[PADSIZE] =
401
         {' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' '};
402
        static _CONST char zeroes[PADSIZE] =
403
         {'0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0'};
404
 
405
        /*
406
         * BEWARE, these `goto error' on error, and PAD uses `n'.
407
         */
408
#define PRINT(ptr, len) { \
409
        iovp->iov_base = (ptr); \
410
        iovp->iov_len = (len); \
411
        uio.uio_resid += (len); \
412
        iovp++; \
413
        if (++uio.uio_iovcnt >= NIOV) { \
414
                if (__sprint_r(data, fp, &uio)) \
415
                        goto error; \
416
                iovp = iov; \
417
        } \
418
}
419
#define PAD(howmany, with) { \
420
        if ((n = (howmany)) > 0) { \
421
                while (n > PADSIZE) { \
422
                        PRINT(with, PADSIZE); \
423
                        n -= PADSIZE; \
424
                } \
425
                PRINT(with, n); \
426
        } \
427
}
428
#define FLUSH() { \
429
        if (uio.uio_resid && __sprint_r(data, fp, &uio)) \
430
                goto error; \
431
        uio.uio_iovcnt = 0; \
432
        iovp = iov; \
433
}
434
 
435
#ifdef __ALTIVEC__
436
#define GET_SHORT(ap) \
437
        (flags&VECTOR ? \
438
            (vec_print_count < 8 ? (short)vec_tmp.s[8 - vec_print_count] : \
439
                (vec_tmp.v = va_arg(ap, vector int), (short)vec_tmp.s[0])) : \
440
            (short)va_arg(ap, int))
441
#define GET_USHORT(ap) \
442
        (flags&VECTOR ? \
443
            (vec_print_count < 8 ? (u_short)vec_tmp.s[8 - vec_print_count] : \
444
                (vec_tmp.v = va_arg(ap, vector int), (u_short)vec_tmp.s[0])) : \
445
            (u_short)va_arg(ap, int))
446
 
447
#define GET_LONG(ap) \
448
        (flags&VECTOR ? \
449
            (vec_print_count < 4 ? (long)vec_tmp.l[4 - vec_print_count] : \
450
                (vec_tmp.v = va_arg(ap, vector int), vec_tmp.l[0])) : \
451
            va_arg(ap, long int))
452
#define GET_ULONG(ap) \
453
        (flags&VECTOR ? \
454
            (vec_print_count < 4 ? (u_long)vec_tmp.l[4 - vec_print_count] : \
455
                (vec_tmp.v = va_arg(ap, vector int), (u_long)vec_tmp.l[0])) : \
456
            (u_long)va_arg(ap, unsigned long int))
457
 
458
#define GET_INT(ap) \
459
        (flags&VECTOR ? \
460
            (vec_print_count < 16 ? \
461
                vec_tmp.c[16 - vec_print_count] : \
462
                (vec_tmp.v = va_arg(ap, vector int), (int)vec_tmp.c[0])) : \
463
            va_arg(ap, int))
464
#define GET_UINT(ap) \
465
        (flags&VECTOR ? \
466
            (vec_print_count < 16 ? \
467
                (u_int)((unsigned char)vec_tmp.c[16 - vec_print_count]) : \
468
                (vec_tmp.v = va_arg(ap, vector int), (u_int)((unsigned char)vec_tmp.c[0]))) : \
469
            (u_int)va_arg(ap, unsigned int))
470
#else /* !__ALTIVEC__ */
471
#define GET_SHORT(ap) ((short)va_arg(ap, int))
472
#define GET_USHORT(ap) ((u_short)va_arg(ap, int))
473
#define GET_LONG(ap) (va_arg(ap, long int))
474
#define GET_ULONG(ap) ((u_long)va_arg(ap, unsigned long int))
475
#define GET_INT(ap) ((int)va_arg(ap, int))
476
#define GET_UINT(ap) ((u_int)va_arg(ap, unsigned int))
477
#endif /* !__ALTIVEC__ */
478
 
479
#ifndef _NO_LONGLONG
480
#define SARG() \
481
        (flags&QUADINT ? va_arg(ap, quad_t) : \
482
            flags&LONGINT ? GET_LONG(ap) : \
483
            flags&SHORTINT ? (long)GET_SHORT(ap) : \
484
            (long)GET_INT(ap))
485
#define UARG() \
486
        (flags&QUADINT ? va_arg(ap, u_quad_t) : \
487
            flags&LONGINT ? GET_ULONG(ap) : \
488
            flags&SHORTINT ? (u_long)GET_USHORT(ap) : \
489
            (u_long)GET_UINT(ap))
490
#ifdef __SPE__
491
#define SFPARG() \
492
        (flags&LONGINT ? va_arg(ap, quad_t) : \
493
            flags&SHORTINT ? (long)GET_SHORT(ap) : \
494
            (long)va_arg(ap, int))
495
#define UFPARG() \
496
        (flags&LONGINT ? va_arg(ap, u_quad_t) : \
497
            flags&SHORTINT ? (u_long)GET_USHORT(ap) : \
498
            (u_long)va_arg(ap, u_int))
499
#endif /* __SPE__ */
500
#else
501
#define SARG() \
502
        (flags&LONGINT ? GET_LONG(ap) : \
503
            flags&SHORTINT ? (long)GET_SHORT(ap) : \
504
            (long)GET_INT(ap))
505
#define UARG() \
506
        (flags&LONGINT ? GET_ULONG(ap) : \
507
            flags&SHORTINT ? (u_long)GET_USHORT(ap) : \
508
            (u_long)GET_UINT(ap))
509
#ifdef __SPE__
510
#define SFPARG() \
511
        (flags&LONGINT ? (va_arg(ap, long) << 32) : \
512
            flags&SHORTINT ? (long)GET_SHORT(ap) : \
513
            (long)va_arg(ap, int))
514
#define UFPARG() \
515
        (flags&LONGINT ? (va_arg(ap, u_long) <<32) : \
516
            flags&SHORTINT ? (u_long)GET_USHORT(ap) : \
517
            (u_long)va_arg(ap, u_int))
518
#endif /* __SPE__ */
519
#endif
520
 
521
        memset (&state, '\0', sizeof (state));
522
 
523
        /* sorry, fprintf(read_only_file, "") returns EOF, not 0 */
524
        if (cantwrite (data, fp)) {
525
                _funlockfile (fp);
526
                return (EOF);
527
        }
528
 
529
        /* optimise fprintf(stderr) (and other unbuffered Unix files) */
530
        if ((fp->_flags & (__SNBF|__SWR|__SRW)) == (__SNBF|__SWR) &&
531
            fp->_file >= 0)
532
                return (__sbprintf_r(data, fp, fmt0, ap));
533
 
534
        fmt = (char *)fmt0;
535
        uio.uio_iov = iovp = iov;
536
        uio.uio_resid = 0;
537
        uio.uio_iovcnt = 0;
538
        ret = 0;
539
 
540
        /*
541
         * Scan the format for conversions (`%' character).
542
         */
543
 
544
        for (;;) {
545
                cp = fmt;
546
                while ((n = _mbtowc_r(data, &wc, fmt, MB_CUR_MAX, &state)) > 0) {
547
                        fmt += n;
548
                        if (wc == '%') {
549
                                fmt--;
550
                                break;
551
                        }
552
                }
553
                if ((m = fmt - cp) != 0) {
554
                        PRINT(cp, m);
555
                        ret += m;
556
                }
557
                if (n <= 0)
558
                        goto done;
559
                fmt++;          /* skip over '%' */
560
 
561
                flags = 0;
562
                dprec = 0;
563
                width = 0;
564
                prec = -1;
565
                sign = '\0';
566
                old_sign = '\0';
567
#ifdef __ALTIVEC__
568
                vec_print_count = 0;
569
                vec_sep = ' ';
570
#endif /* __ALTIVEC__ */
571
 
572
                format_anchor = fmt;
573
rflag:          ch = *fmt++;
574
                old_ch = ch;
575
reswitch:       switch (ch) {
576
                case ' ':
577
                        /*
578
                         * ``If the space and + flags both appear, the space
579
                         * flag will be ignored.''
580
                         *      -- ANSI X3J11
581
                         */
582
                        if (!sign)
583
                                sign = ' ';
584
                        goto rflag;
585
                case '#':
586
                        flags |= ALT;
587
                        goto rflag;
588
                case '*':
589
                        /*
590
                         * ``A negative field width argument is taken as a
591
                         * - flag followed by a positive field width.''
592
                         *      -- ANSI X3J11
593
                         * They don't exclude field widths read from args.
594
                         */
595
                        if ((width = va_arg(ap, int)) >= 0)
596
                                goto rflag;
597
                        width = -width;
598
                        /* FALLTHROUGH */
599
                case '-':
600
                        flags |= LADJUST;
601
                        goto rflag;
602
                case '+':
603
                        sign = '+';
604
                        goto rflag;
605
#ifdef __ALTIVEC__
606
                case ',':
607
                case ';':
608
                case ':':
609
                case '_':
610
                        if (vec_sep != ' ')
611
                          {
612
                            fmt = format_anchor;
613
                            continue;
614
                          }
615
                        vec_sep = ch;
616
                        goto rflag;
617
#endif /* __ALTIVEC__ */
618
                case '.':
619
                        if ((ch = *fmt++) == '*') {
620
                                n = va_arg(ap, int);
621
                                prec = n < 0 ? -1 : n;
622
                                goto rflag;
623
                        }
624
                        n = 0;
625
                        while (is_digit(ch)) {
626
                                n = 10 * n + to_digit(ch);
627
                                ch = *fmt++;
628
                        }
629
                        prec = n < 0 ? -1 : n;
630
                        goto reswitch;
631
                case '0':
632
                        /*
633
                         * ``Note that 0 is taken as a flag, not as the
634
                         * beginning of a field width.''
635
                         *      -- ANSI X3J11
636
                         */
637
                        flags |= ZEROPAD;
638
                        goto rflag;
639
                case '1': case '2': case '3': case '4':
640
                case '5': case '6': case '7': case '8': case '9':
641
                        n = 0;
642
                        do {
643
                                n = 10 * n + to_digit(ch);
644
                                ch = *fmt++;
645
                        } while (is_digit(ch));
646
                        width = n;
647
                        goto reswitch;
648
#ifdef FLOATING_POINT
649
                case 'L':
650
#ifdef __ALTIVEC__
651
                        if (flags & VECTOR)
652
                          {
653
                            fmt = format_anchor;
654
                            continue;
655
                          }
656
#endif /* __ALTIVEC__ */
657
                        flags |= LONGDBL;
658
                        goto rflag;
659
#endif
660
                case 'h':
661
                        if (flags & LONGINT)
662
                          {
663
                            fmt = format_anchor;
664
                            continue;
665
                          }
666
                        flags |= SHORTINT;
667
#ifdef __ALTIVEC__
668
                        if (flags & VECTOR)
669
                          vec_print_count = 8;
670
#endif
671
                        goto rflag;
672
                case 'l':
673
                        if (flags & SHORTINT)
674
                          {
675
                            fmt = format_anchor;
676
                            continue;
677
                          }
678
                        if (*fmt == 'l') {
679
                                fmt++;
680
                                flags |= QUADINT;
681
                                flags &= ~VECTOR;
682
                        } else {
683
                                flags |= LONGINT;
684
#ifdef __ALTIVEC__
685
                                if (flags & VECTOR)
686
                                  vec_print_count = 4;
687
#endif
688
                        }
689
                        goto rflag;
690
#ifdef __ALTIVEC__
691
                case 'v':
692
                        if (flags & VECTOR)
693
                          {
694
                            fmt = format_anchor;
695
                            continue;
696
                          }
697
                        flags |= VECTOR;
698
                        vec_print_count = (flags & SHORTINT) ? 8 :
699
                          ((flags & LONGINT) ? 4 : 16);
700
                        goto rflag;
701
#endif
702
                case 'q':
703
#ifdef __ALTIVEC__
704
                        if (flags & VECTOR)
705
                          {
706
                            fmt = format_anchor;
707
                            continue;
708
                          }
709
#endif /* __ALTIVEC__ */
710
                        flags |= QUADINT;
711
                        goto rflag;
712
                case 'c':
713
#ifdef __ALTIVEC__
714
                        if (flags & VECTOR)
715
                          {
716
                            int k;
717
                            vec_16_byte_union tmp;
718
                            if (flags & (SHORTINT | LONGINT))
719
                              {
720
                                fmt = format_anchor;
721
                                continue;
722
                              }
723
                            tmp.v = va_arg(ap, vector int);
724
                            cp = buf;
725
                            for (k = 0; k < 15; ++k)
726
                              {
727
                                *cp++ = tmp.c[k];
728
                                if (vec_sep != ' ')
729
                                  *cp++ = vec_sep;
730
                              }
731
                            *cp++ = tmp.c[15];
732
                            size = cp - buf;
733
                            cp = buf;
734
                            vec_print_count = 0;
735
                          }
736
                        else
737
#endif /* __ALTIVEC__ */
738
                          {
739
                            *(cp = buf) = va_arg(ap, int);
740
                            size = 1;
741
                          }
742
                        sign = '\0';
743
                        break;
744
                case 'D':
745
                        flags |= LONGINT;
746
                        /*FALLTHROUGH*/
747
                case 'd':
748
                case 'i':
749
#ifdef __ALTIVEC__
750
                        if (!(flags & VECTOR) && vec_sep != ' ')
751
                          {
752
                            fmt = format_anchor;
753
                            continue;
754
                          }
755
#endif /* __ALTIVEC__ */
756
                        _uquad = SARG();
757
                        if ((quad_t)_uquad < 0)
758
                        {
759
                                _uquad = -(quad_t)_uquad;
760
                                old_sign = sign;
761
                                sign = '-';
762
                        }
763
                        base = DEC;
764
                        goto number;
765
#ifdef FLOATING_POINT
766
                case 'e':
767
                case 'E':
768
                case 'f':
769
                case 'g':
770
                case 'G':
771
                        if (prec == -1) {
772
                                prec = DEFPREC;
773
                        } else if ((ch == 'g' || ch == 'G') && prec == 0) {
774
                                prec = 1;
775
                        }
776
 
777
#ifdef _NO_LONGDBL
778
                        if (flags & LONGDBL) {
779
                                _fpvalue = (double) va_arg(ap, _LONG_DOUBLE);
780
#ifdef __ALTIVEC__
781
                        } else if (flags & VECTOR) {
782
                                if (vec_print_count >= 4)
783
                                  {
784
                                    vec_print_count = 4;
785
                                    vec_tmp.v = va_arg(ap, vector int);
786
                                  }
787
                                _fpvalue = (double)vec_tmp.f[4 - vec_print_count];
788
                        } else if (vec_sep != ' ') {
789
                                 fmt = format_anchor;
790
                                 continue;
791
 
792
#endif /* __ALTIVEC__ */
793
                        } else {
794
                                _fpvalue = va_arg(ap, double);
795
                        }
796
 
797
                        /* do this before tricky precision changes */
798
                        if (isinf(_fpvalue)) {
799
                                if (_fpvalue < 0)
800
                                  {
801
                                    old_sign = sign;
802
                                    sign = '-';
803
                                  }
804
 
805
                                cp = "Inf";
806
                                size = 3;
807
                                break;
808
                        }
809
                        if (isnan(_fpvalue)) {
810
                                cp = "NaN";
811
                                size = 3;
812
                                break;
813
                        }
814
 
815
#else /* !_NO_LONGDBL */
816
 
817
                        if (flags & LONGDBL) {
818
                                _fpvalue = va_arg(ap, _LONG_DOUBLE);
819
#ifdef __ALTIVEC__
820
                        } else if (flags & VECTOR) {
821
                                if (vec_print_count >= 4)
822
                                  {
823
                                    vec_print_count = 4;
824
                                    vec_tmp.v = va_arg(ap, vector int);
825
                                  }
826
                                _fpvalue = (_LONG_DOUBLE)k.f[4 - vec_print_count];
827
#endif /* __ALTIVEC__ */
828
                        } else {
829
                                _fpvalue = (_LONG_DOUBLE)va_arg(ap, double);
830
                        }
831
 
832
                        /* do this before tricky precision changes */
833
                        tmp = _ldcheck (&_fpvalue);
834
                        if (tmp == 2) {
835
                                if (_fpvalue < 0)
836
                                  {
837
                                    old_sign = sign;
838
                                    sign = '-';
839
                                  }
840
                                cp = "Inf";
841
                                size = 3;
842
                                break;
843
                        }
844
                        if (tmp == 1) {
845
                                cp = "NaN";
846
                                size = 3;
847
                                break;
848
                        }
849
#endif /* !_NO_LONGDBL */
850
 
851
                        flags |= FPT;
852
 
853
                        cp = cvt(data, _fpvalue, prec, flags, &softsign,
854
                                &expt, ch, &ndig);
855
 
856
                        if (ch == 'g' || ch == 'G') {
857
                                if (expt <= -4 || expt > prec)
858
                                  {
859
                                    old_ch = ch;
860
                                    ch = (ch == 'g') ? 'e' : 'E';
861
                                  }
862
                                else
863
                                        ch = 'g';
864
                        }
865
                        if (ch <= 'e') {        /* 'e' or 'E' fmt */
866
                                --expt;
867
                                expsize = exponent(expstr, expt, ch);
868
                                size = expsize + ndig;
869
                                if (ndig > 1 || flags & ALT)
870
                                        ++size;
871
                        } else if (ch == 'f') {         /* f fmt */
872
                                if (expt > 0) {
873
                                        size = expt;
874
                                        if (prec || flags & ALT)
875
                                                size += prec + 1;
876
                                } else  /* "0.X" */
877
                                        size = (prec || flags & ALT)
878
                                                  ? prec + 2
879
                                                  : 1;
880
                        } else if (expt >= ndig) {      /* fixed g fmt */
881
                                size = expt;
882
                                if (flags & ALT)
883
                                        ++size;
884
                        } else
885
                                size = ndig + (expt > 0 ?
886
                                        1 : 2 - expt);
887
 
888
                        if (softsign)
889
                          {
890
                            old_sign = sign;
891
                            sign = '-';
892
                          }
893
                        break;
894
#endif /* FLOATING_POINT */
895
#ifdef __SPE__
896
                case 'r':
897
                        flags |= FIXEDPOINT;
898
                        _uquad = SFPARG();
899
                        if ((quad_t)_uquad < 0)
900
                          {
901
                            sign = '-';
902
                            _uquad = -(quad_t)_uquad;
903
                          }
904
                        if (flags & SHORTINT)
905
                          _uquad <<= (sizeof(quad_t) - sizeof(short)) * 8 + 1;
906
                        else if (flags & LONGINT)
907
                          _uquad <<= 1;
908
                        else
909
                          _uquad <<= (sizeof(quad_t) - sizeof(long)) * 8 + 1;
910
 
911
                        if (_uquad == 0 && sign)
912
                          {
913
                            /* we have -1.0 which has to be handled special */
914
                            cp = "100000";
915
                            expt = 1;
916
                            ndig = 6;
917
                            break;
918
                          }
919
 
920
                        goto fixed_nosign;
921
                case 'R':
922
                        flags |= FIXEDPOINT;
923
                        _uquad = UFPARG();
924
                        if (flags & SHORTINT)
925
                          _uquad <<= (sizeof(quad_t) - sizeof(short)) * 8;
926
                        else if (!(flags & LONGINT))
927
                          _uquad <<= (sizeof(quad_t) - sizeof(long)) * 8;
928
 
929
fixed_nosign:
930
                        if (prec == -1)
931
                          prec = DEFPREC;
932
 
933
#ifndef _NO_LONGLONG
934
                        cp = cvt_ufix64 (data, _uquad, prec, &expt, &ndig);
935
#else
936
                        cp = cvs_ufix32 (data, _uquad, prec, &expt, &ndig);
937
#endif
938
 
939
                        /* act like %f of format "0.X" */
940
                        size = prec + 2;
941
 
942
                        break;
943
#endif /* __SPE__ */
944
                case 'n':
945
#ifdef __ALTIVEC__
946
                        if (flags & VECTOR)
947
                          {
948
                            fmt = format_anchor;
949
                            continue;
950
                          }
951
#endif /* __ALTIVEC__ */
952
#ifndef _NO_LONGLONG
953
                        if (flags & QUADINT)
954
                                *va_arg(ap, quad_t *) = ret;
955
                        else
956
#endif
957
                        if (flags & LONGINT)
958
                                *va_arg(ap, long *) = ret;
959
                        else if (flags & SHORTINT)
960
                                *va_arg(ap, short *) = ret;
961
                        else
962
                                *va_arg(ap, int *) = ret;
963
                        continue;       /* no output */
964
                case 'O':
965
                        flags |= LONGINT;
966
                        /*FALLTHROUGH*/
967
                case 'o':
968
#ifdef __ALTIVEC__
969
                        if (!(flags & VECTOR) && vec_sep != ' ')
970
                          {
971
                            fmt = format_anchor;
972
                            continue;
973
                          }
974
#endif /* __ALTIVEC__ */
975
                        _uquad = UARG();
976
                        base = OCT;
977
                        goto nosign;
978
                case 'p':
979
                        /*
980
                         * ``The argument shall be a pointer to void.  The
981
                         * value of the pointer is converted to a sequence
982
                         * of printable characters, in an implementation-
983
                         * defined manner.''
984
                         *      -- ANSI X3J11
985
                         */
986
                        /* NOSTRICT */
987
#ifdef __ALTIVEC__
988
                        if (flags & VECTOR)
989
                          _uquad = UARG();
990
                        else if (vec_sep != ' ')
991
                          {
992
                            fmt = format_anchor;
993
                            continue;
994
                          }
995
                        else
996
#endif /* __ALTIVEC__ */
997
                          _uquad = (u_long)(unsigned _POINTER_INT)va_arg(ap, void *);
998
                        base = HEX;
999
                        xdigs = "0123456789abcdef";
1000
                        flags |= HEXPREFIX;
1001
                        ch = 'x';
1002
                        goto nosign;
1003
                case 's':
1004
#ifdef __ALTIVEC__
1005
                        if (flags & VECTOR)
1006
                          {
1007
                            fmt = format_anchor;
1008
                            continue;
1009
                          }
1010
#endif /* __ALTIVEC__ */
1011
                        if ((cp = va_arg(ap, char *)) == NULL)
1012
                                cp = "(null)";
1013
                        if (prec >= 0) {
1014
                                /*
1015
                                 * can't use strlen; can only look for the
1016
                                 * NUL in the first `prec' characters, and
1017
                                 * strlen() will go further.
1018
                                 */
1019
                                char *p = memchr(cp, 0, prec);
1020
 
1021
                                if (p != NULL) {
1022
                                        size = p - cp;
1023
                                        if (size > prec)
1024
                                                size = prec;
1025
                                } else
1026
                                        size = prec;
1027
                        } else
1028
                                size = strlen(cp);
1029
                        sign = '\0';
1030
                        break;
1031
                case 'U':
1032
                        flags |= LONGINT;
1033
                        /*FALLTHROUGH*/
1034
                case 'u':
1035
#ifdef __ALTIVEC__
1036
                        if (!(flags & VECTOR) && vec_sep != ' ')
1037
                          {
1038
                            fmt = format_anchor;
1039
                            continue;
1040
                          }
1041
#endif /* __ALTIVEC__ */
1042
                        _uquad = UARG();
1043
                        base = DEC;
1044
                        goto nosign;
1045
                case 'X':
1046
                        xdigs = "0123456789ABCDEF";
1047
                        goto hex;
1048
                case 'x':
1049
                        xdigs = "0123456789abcdef";
1050
#ifdef __ALTIVEC__
1051
                        if (!(flags & VECTOR) && vec_sep != ' ')
1052
                          {
1053
                            fmt = format_anchor;
1054
                            continue;
1055
                          }
1056
#endif /* __ALTIVEC__ */
1057
hex:                    _uquad = UARG();
1058
                        base = HEX;
1059
                        /* leading 0x/X only if non-zero */
1060
                        if (flags & ALT && _uquad != 0)
1061
                                flags |= HEXPREFIX;
1062
 
1063
                        /* unsigned conversions */
1064
nosign:                 sign = '\0';
1065
                        /*
1066
                         * ``... diouXx conversions ... if a precision is
1067
                         * specified, the 0 flag will be ignored.''
1068
                         *      -- ANSI X3J11
1069
                         */
1070
number:                 if ((dprec = prec) >= 0)
1071
                                flags &= ~ZEROPAD;
1072
 
1073
                        /*
1074
                         * ``The result of converting a zero value with an
1075
                         * explicit precision of zero is no characters.''
1076
                         *      -- ANSI X3J11
1077
                         */
1078
                        cp = buf + BUF;
1079
                        if (_uquad != 0 || prec != 0) {
1080
                                /*
1081
                                 * Unsigned mod is hard, and unsigned mod
1082
                                 * by a constant is easier than that by
1083
                                 * a variable; hence this switch.
1084
                                 */
1085
                                switch (base) {
1086
                                case OCT:
1087
                                        do {
1088
                                                *--cp = to_char(_uquad & 7);
1089
                                                _uquad >>= 3;
1090
                                        } while (_uquad);
1091
                                        /* handle octal leading 0 */
1092
                                        if (flags & ALT && *cp != '0')
1093
                                                *--cp = '0';
1094
                                        break;
1095
 
1096
                                case DEC:
1097
                                        /* many numbers are 1 digit */
1098
                                        while (_uquad >= 10) {
1099
                                                *--cp = to_char(_uquad % 10);
1100
                                                _uquad /= 10;
1101
                                        }
1102
                                        *--cp = to_char(_uquad);
1103
                                        break;
1104
 
1105
                                case HEX:
1106
                                        do {
1107
                                                *--cp = xdigs[_uquad & 15];
1108
                                                _uquad >>= 4;
1109
                                        } while (_uquad);
1110
                                        break;
1111
 
1112
                                default:
1113
                                        cp = "bug in vfprintf: bad base";
1114
                                        size = strlen(cp);
1115
                                        goto skipsize;
1116
                                }
1117
                        }
1118
                       /*
1119
                        * ...result is to be converted to an 'alternate form'.
1120
                        * For o conversion, it increases the precision to force
1121
                        * the first digit of the result to be a zero."
1122
                        *     -- ANSI X3J11
1123
                        *
1124
                        * To demonstrate this case, compile and run:
1125
                        *    printf ("%#.0o",0);
1126
                        */
1127
                       else if (base == OCT && (flags & ALT))
1128
                         *--cp = '0';
1129
 
1130
                        size = buf + BUF - cp;
1131
                skipsize:
1132
                        break;
1133
                default:        /* "%?" prints ?, unless ? is NUL */
1134
                        flags &= ~VECTOR;
1135
                        if (ch == '\0')
1136
                                goto done;
1137
                        /* pretend it was %c with argument ch */
1138
                        cp = buf;
1139
                        *cp = ch;
1140
                        size = 1;
1141
                        sign = '\0';
1142
                        break;
1143
                }
1144
 
1145
                /*
1146
                 * All reasonable formats wind up here.  At this point, `cp'
1147
                 * points to a string which (if not flags&LADJUST) should be
1148
                 * padded out to `width' places.  If flags&ZEROPAD, it should
1149
                 * first be prefixed by any sign or other prefix; otherwise,
1150
                 * it should be blank padded before the prefix is emitted.
1151
                 * After any left-hand padding and prefixing, emit zeroes
1152
                 * required by a decimal [diouxX] precision, then print the
1153
                 * string proper, then emit zeroes required by any leftover
1154
                 * floating precision; finally, if LADJUST, pad with blanks.
1155
                 *
1156
                 * Compute actual size, so we know how much to pad.
1157
                 * size excludes decimal prec; realsz includes it.
1158
                 */
1159
                realsz = dprec > size ? dprec : size;
1160
                if (sign)
1161
                        realsz++;
1162
                else if (flags & HEXPREFIX)
1163
                        realsz+= 2;
1164
 
1165
                /* right-adjusting blank padding */
1166
                if ((flags & (LADJUST|ZEROPAD)) == 0)
1167
                        PAD(width - realsz, blanks);
1168
 
1169
                /* prefix */
1170
                if (sign) {
1171
                        PRINT(&sign, 1);
1172
                } else if (flags & HEXPREFIX) {
1173
                        ox[0] = '0';
1174
                        ox[1] = ch;
1175
                        PRINT(ox, 2);
1176
                }
1177
 
1178
                /* right-adjusting zero padding */
1179
                if ((flags & (LADJUST|ZEROPAD)) == ZEROPAD)
1180
                        PAD(width - realsz, zeroes);
1181
 
1182
                /* leading zeroes from decimal precision */
1183
                PAD(dprec - size, zeroes);
1184
 
1185
                /* the string or number proper */
1186
#ifdef FLOATING_POINT
1187
                if ((flags & FPT) == 0) {
1188
#ifdef __SPE__
1189
                        if (flags & FIXEDPOINT) {
1190
                                if (_uquad == 0 && !sign) {
1191
                                        /* kludge for __dtoa irregularity */
1192
                                        PRINT("0", 1);
1193
                                        if (expt < ndig || (flags & ALT) != 0) {
1194
                                                PRINT(decimal_point, 1);
1195
                                                PAD(ndig - 1, zeroes);
1196
                                        }
1197
                                } else if (expt <= 0) {
1198
                                        PRINT("0", 1);
1199
                                        if(expt || ndig) {
1200
                                                PRINT(decimal_point, 1);
1201
                                                PAD(-expt, zeroes);
1202
                                                PRINT(cp, ndig);
1203
                                        }
1204
                                } else if (expt >= ndig) {
1205
                                        PRINT(cp, ndig);
1206
                                        PAD(expt - ndig, zeroes);
1207
                                        if (flags & ALT)
1208
                                                PRINT(".", 1);
1209
                                } else {
1210
                                        PRINT(cp, expt);
1211
                                        cp += expt;
1212
                                        PRINT(".", 1);
1213
                                        PRINT(cp, ndig-expt);
1214
                                }
1215
                        } else
1216
#endif /* __SPE__ */
1217
                                PRINT(cp, size);
1218
                } else {        /* glue together f_p fragments */
1219
                        if (ch >= 'f') {        /* 'f' or 'g' */
1220
                                if (_fpvalue == 0) {
1221
                                        /* kludge for __dtoa irregularity */
1222
                                        PRINT("0", 1);
1223
                                        if (expt < ndig || (flags & ALT) != 0) {
1224
                                                PRINT(decimal_point, 1);
1225
                                                PAD(ndig - 1, zeroes);
1226
                                        }
1227
                                } else if (expt <= 0) {
1228
                                        PRINT("0", 1);
1229
                                        if(expt || ndig) {
1230
                                                PRINT(decimal_point, 1);
1231
                                                PAD(-expt, zeroes);
1232
                                                PRINT(cp, ndig);
1233
                                        }
1234
                                } else if (expt >= ndig) {
1235
                                        PRINT(cp, ndig);
1236
                                        PAD(expt - ndig, zeroes);
1237
                                        if (flags & ALT)
1238
                                                PRINT(".", 1);
1239
                                } else {
1240
                                        PRINT(cp, expt);
1241
                                        cp += expt;
1242
                                        PRINT(".", 1);
1243
                                        PRINT(cp, ndig-expt);
1244
                                }
1245
                        } else {        /* 'e' or 'E' */
1246
                                if (ndig > 1 || flags & ALT) {
1247
                                        ox[0] = *cp++;
1248
                                        ox[1] = '.';
1249
                                        PRINT(ox, 2);
1250
                                       if (_fpvalue) {
1251
                                                PRINT(cp, ndig-1);
1252
                                        } else  /* 0.[0..] */
1253
                                                /* __dtoa irregularity */
1254
                                                PAD(ndig - 1, zeroes);
1255
                                } else  /* XeYYY */
1256
                                        PRINT(cp, 1);
1257
                                PRINT(expstr, expsize);
1258
                        }
1259
                }
1260
#else
1261
                PRINT(cp, size);
1262
#endif
1263
                /* left-adjusting padding (always blank) */
1264
                if (flags & LADJUST)
1265
                        PAD(width - realsz, blanks);
1266
 
1267
                /* finally, adjust ret */
1268
                ret += width > realsz ? width : realsz;
1269
 
1270
#ifdef __ALTIVEC__              
1271
                if ((flags & VECTOR) && vec_print_count-- > 1)
1272
                  {
1273
                    /* add vector separator */
1274
                    if (ch != 'c' || vec_sep != ' ')
1275
                      {
1276
                        PRINT(&vec_sep, 1);
1277
                        ret += 1;
1278
                      }
1279
                    FLUSH();
1280
                    sign = old_sign;
1281
                    ch = old_ch;
1282
                    goto reswitch;
1283
                  }
1284
#endif /* __ALTIVEC__ */
1285
                FLUSH();        /* copy out the I/O vectors */
1286
        }
1287
done:
1288
        FLUSH();
1289
error:
1290
        return (__sferror(fp) ? EOF : ret);
1291
        /* NOTREACHED */
1292
}
1293
 
1294
#ifdef FLOATING_POINT
1295
 
1296
#ifdef _NO_LONGDBL
1297
extern char *_dtoa_r _PARAMS((struct _reent *, double, int,
1298
                              int, int *, int *, char **));
1299
#else
1300
extern char *_ldtoa_r _PARAMS((struct _reent *, _LONG_DOUBLE, int,
1301
                              int, int *, int *, char **));
1302
#undef word0
1303
#define word0(x) ldword0(x)
1304
#endif
1305
 
1306
static char *
1307
cvt(data, value, ndigits, flags, sign, decpt, ch, length)
1308
        struct _reent *data;
1309
#ifdef _NO_LONGDBL
1310
        double value;
1311
#else
1312
        _LONG_DOUBLE value;
1313
#endif
1314
        int ndigits, flags, *decpt, ch, *length;
1315
        char *sign;
1316
{
1317
        int mode, dsgn;
1318
        char *digits, *bp, *rve;
1319
#ifdef _NO_LONGDBL
1320
        union double_union tmp;
1321
#else
1322
        struct ldieee *ldptr;
1323
#endif
1324
 
1325
        if (ch == 'f') {
1326
                mode = 3;               /* ndigits after the decimal point */
1327
        } else {
1328
                /* To obtain ndigits after the decimal point for the 'e'
1329
                 * and 'E' formats, round to ndigits + 1 significant
1330
                 * figures.
1331
                 */
1332
                if (ch == 'e' || ch == 'E') {
1333
                        ndigits++;
1334
                }
1335
                mode = 2;               /* ndigits significant digits */
1336
        }
1337
 
1338
#ifdef _NO_LONGDBL
1339
        tmp.d = value;
1340
 
1341
        if (word0(tmp) & Sign_bit) { /* this will check for < 0 and -0.0 */
1342
                value = -value;
1343
                *sign = '-';
1344
        } else
1345
                *sign = '\000';
1346
 
1347
        digits = _dtoa_r(data, value, mode, ndigits, decpt, &dsgn, &rve);
1348
#else /* !_NO_LONGDBL */
1349
        ldptr = (struct ldieee *)&value;
1350
        if (ldptr->sign) { /* this will check for < 0 and -0.0 */
1351
                value = -value;
1352
                *sign = '-';
1353
        } else
1354
                *sign = '\000';
1355
 
1356
        digits = _ldtoa_r(data, value, mode, ndigits, decpt, &dsgn, &rve);
1357
#endif /* !_NO_LONGDBL */
1358
 
1359
        if ((ch != 'g' && ch != 'G') || flags & ALT) {  /* Print trailing zeros */
1360
                bp = digits + ndigits;
1361
                if (ch == 'f') {
1362
                        if (*digits == '0' && value)
1363
                                *decpt = -ndigits + 1;
1364
                        bp += *decpt;
1365
                }
1366
                if (value == 0)  /* kludge for __dtoa irregularity */
1367
                        rve = bp;
1368
                while (rve < bp)
1369
                        *rve++ = '0';
1370
        }
1371
        *length = rve - digits;
1372
        return (digits);
1373
}
1374
 
1375
static int
1376
exponent(p0, exp, fmtch)
1377
        char *p0;
1378
        int exp, fmtch;
1379
{
1380
        register char *p, *t;
1381
        char expbuf[40];
1382
 
1383
        p = p0;
1384
        *p++ = fmtch;
1385
        if (exp < 0) {
1386
                exp = -exp;
1387
                *p++ = '-';
1388
        }
1389
        else
1390
                *p++ = '+';
1391
        t = expbuf + 40;
1392
        if (exp > 9) {
1393
                do {
1394
                        *--t = to_char(exp % 10);
1395
                } while ((exp /= 10) > 9);
1396
                *--t = to_char(exp);
1397
                for (; t < expbuf + 40; *p++ = *t++);
1398
        }
1399
        else {
1400
                *p++ = '0';
1401
                *p++ = to_char(exp);
1402
        }
1403
        return (p - p0);
1404
}
1405
#endif /* FLOATING_POINT */
1406
 
1407
#ifdef __SPE__
1408
extern char *_ufix64toa_r _PARAMS((struct _reent *, unsigned long long, int,
1409
                                   int, int *, int *, char **));
1410
static char *
1411
cvt_ufix64 (data, value, ndigits, decpt, length)
1412
        struct _reent *data;
1413
        unsigned long long value;
1414
        int ndigits, *decpt, *length;
1415
{
1416
        int dsgn;
1417
        char *digits, *bp, *rve;
1418
 
1419
        /* treat the same as %f format and use mode=3 */
1420
        digits = _ufix64toa_r (data, value, 3, ndigits, decpt, &dsgn, &rve);
1421
 
1422
        /* print trailing zeroes */
1423
        bp = digits + ndigits;
1424
        if (*digits == '0' && value)
1425
          *decpt = -ndigits + 1;
1426
        bp += *decpt;
1427
        if (value == 0)  /* kludge for __dtoa irregularity */
1428
          rve = bp;
1429
        while (rve < bp)
1430
          *rve++ = '0';
1431
        *length = rve - digits;
1432
        return (digits);
1433
}
1434
#endif /* __SPE__ */

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.