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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-dev/] [or1k-gcc/] [libquadmath/] [printf/] [printf_fp.c] - Blame information for rev 834

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

Line No. Rev Author Line
1 740 jeremybenn
/* Floating point output for `printf'.
2
   Copyright (C) 1995-2003, 2006-2008, 2011 Free Software Foundation, Inc.
3
 
4
   This file is part of the GNU C Library.
5
   Written by Ulrich Drepper <drepper@gnu.ai.mit.edu>, 1995.
6
 
7
   The GNU C Library is free software; you can redistribute it and/or
8
   modify it under the terms of the GNU Lesser General Public
9
   License as published by the Free Software Foundation; either
10
   version 2.1 of the License, or (at your option) any later version.
11
 
12
   The GNU C Library is distributed in the hope that it will be useful,
13
   but WITHOUT ANY WARRANTY; without even the implied warranty of
14
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15
   Lesser General Public License for more details.
16
 
17
   You should have received a copy of the GNU Lesser General Public
18
   License along with the GNU C Library; if not, write to the Free
19
   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
20
   02111-1307 USA.  */
21
 
22
#include <config.h>
23
#include <float.h>
24
#include <math.h>
25
#include <string.h>
26
#include <unistd.h>
27
#include <stdlib.h>
28
#define NDEBUG
29
#include <assert.h>
30
#ifdef HAVE_ERRNO_H
31
#include <errno.h>
32
#endif
33
#include <stdio.h>
34
#include <stdarg.h>
35
#include "quadmath-printf.h"
36
#include "fpioconst.h"
37
 
38
#ifdef USE_I18N_NUMBER_H
39
#include "_i18n_number.h"
40
#endif
41
 
42
 
43
/* Macros for doing the actual output.  */
44
 
45
#define outchar(ch)                                                           \
46
  do                                                                          \
47
    {                                                                         \
48
      register const int outc = (ch);                                         \
49
      if (PUTC (outc, fp) == EOF)                                             \
50
        {                                                                     \
51
          if (buffer_malloced)                                                \
52
            free (wbuffer);                                                   \
53
          return -1;                                                          \
54
        }                                                                     \
55
      ++done;                                                                 \
56
    } while (0)
57
 
58
#define PRINT(ptr, wptr, len)                                                 \
59
  do                                                                          \
60
    {                                                                         \
61
      register size_t outlen = (len);                                         \
62
      if (len > 20)                                                           \
63
        {                                                                     \
64
          if (PUT (fp, wide ? (const char *) wptr : ptr, outlen) != outlen)   \
65
            {                                                                 \
66
              if (buffer_malloced)                                            \
67
                free (wbuffer);                                               \
68
              return -1;                                                      \
69
            }                                                                 \
70
          ptr += outlen;                                                      \
71
          done += outlen;                                                     \
72
        }                                                                     \
73
      else                                                                    \
74
        {                                                                     \
75
          if (wide)                                                           \
76
            while (outlen-- > 0)                                       \
77
              outchar (*wptr++);                                              \
78
          else                                                                \
79
            while (outlen-- > 0)                                       \
80
              outchar (*ptr++);                                               \
81
        }                                                                     \
82
    } while (0)
83
 
84
#define PADN(ch, len)                                                         \
85
  do                                                                          \
86
    {                                                                         \
87
      if (PAD (fp, ch, len) != len)                                           \
88
        {                                                                     \
89
          if (buffer_malloced)                                                \
90
            free (wbuffer);                                                   \
91
          return -1;                                                          \
92
        }                                                                     \
93
      done += len;                                                            \
94
    }                                                                         \
95
  while (0)
96
 
97
 
98
/* We use the GNU MP library to handle large numbers.
99
 
100
   An MP variable occupies a varying number of entries in its array.  We keep
101
   track of this number for efficiency reasons.  Otherwise we would always
102
   have to process the whole array.  */
103
#define MPN_VAR(name) mp_limb_t *name; mp_size_t name##size
104
 
105
#define MPN_ASSIGN(dst,src)                                                   \
106
  memcpy (dst, src, (dst##size = src##size) * sizeof (mp_limb_t))
107
#define MPN_GE(u,v) \
108
  (u##size > v##size || (u##size == v##size && mpn_cmp (u, v, u##size) >= 0))
109
 
110
extern mp_size_t mpn_extract_flt128 (mp_ptr res_ptr, mp_size_t size,
111
                                     int *expt, int *is_neg,
112
                                     __float128 value) attribute_hidden;
113
static unsigned int guess_grouping (unsigned int intdig_max,
114
                                    const char *grouping);
115
 
116
 
117
static wchar_t *group_number (wchar_t *buf, wchar_t *bufend,
118
                              unsigned int intdig_no, const char *grouping,
119
                              wchar_t thousands_sep, int ngroups);
120
 
121
 
122
int
123
__quadmath_printf_fp (struct __quadmath_printf_file *fp,
124
                      const struct printf_info *info,
125
                      const void *const *args)
126
{
127
  /* The floating-point value to output.  */
128
  __float128 fpnum;
129
 
130
  /* Locale-dependent representation of decimal point.  */
131
  const char *decimal;
132
  wchar_t decimalwc;
133
 
134
  /* Locale-dependent thousands separator and grouping specification.  */
135
  const char *thousands_sep = NULL;
136
  wchar_t thousands_sepwc = L_('\0');
137
  const char *grouping;
138
 
139
  /* "NaN" or "Inf" for the special cases.  */
140
  const char *special = NULL;
141
  const wchar_t *wspecial = NULL;
142
 
143
  /* We need just a few limbs for the input before shifting to the right
144
     position.  */
145
  mp_limb_t fp_input[(FLT128_MANT_DIG + BITS_PER_MP_LIMB - 1) / BITS_PER_MP_LIMB];
146
  /* We need to shift the contents of fp_input by this amount of bits.  */
147
  int to_shift = 0;
148
 
149
  /* The fraction of the floting-point value in question  */
150
  MPN_VAR(frac);
151
  /* and the exponent.  */
152
  int exponent;
153
  /* Sign of the exponent.  */
154
  int expsign = 0;
155
  /* Sign of float number.  */
156
  int is_neg = 0;
157
 
158
  /* Scaling factor.  */
159
  MPN_VAR(scale);
160
 
161
  /* Temporary bignum value.  */
162
  MPN_VAR(tmp);
163
 
164
  /* Digit which is result of last hack_digit() call.  */
165
  wchar_t digit;
166
 
167
  /* The type of output format that will be used: 'e'/'E' or 'f'.  */
168
  int type;
169
 
170
  /* Counter for number of written characters.  */
171
  int done = 0;
172
 
173
  /* General helper (carry limb).  */
174
  mp_limb_t cy;
175
 
176
  /* Nonzero if this is output on a wide character stream.  */
177
  int wide = info->wide;
178
 
179
  /* Buffer in which we produce the output.  */
180
  wchar_t *wbuffer = NULL;
181
  /* Flag whether wbuffer is malloc'ed or not.  */
182
  int buffer_malloced = 0;
183
 
184
  auto wchar_t hack_digit (void);
185
 
186
  wchar_t hack_digit (void)
187
    {
188
      mp_limb_t hi;
189
 
190
      if (expsign != 0 && type == 'f' && exponent-- > 0)
191
        hi = 0;
192
      else if (scalesize == 0)
193
        {
194
          hi = frac[fracsize - 1];
195
          frac[fracsize - 1] = mpn_mul_1 (frac, frac, fracsize - 1, 10);
196
        }
197
      else
198
        {
199
          if (fracsize < scalesize)
200
            hi = 0;
201
          else
202
            {
203
              hi = mpn_divmod (tmp, frac, fracsize, scale, scalesize);
204
              tmp[fracsize - scalesize] = hi;
205
              hi = tmp[0];
206
 
207
              fracsize = scalesize;
208
              while (fracsize != 0 && frac[fracsize - 1] == 0)
209
                --fracsize;
210
              if (fracsize == 0)
211
                {
212
                  /* We're not prepared for an mpn variable with zero
213
                     limbs.  */
214
                  fracsize = 1;
215
                  return L_('0') + hi;
216
                }
217
            }
218
 
219
          mp_limb_t _cy = mpn_mul_1 (frac, frac, fracsize, 10);
220
          if (_cy != 0)
221
            frac[fracsize++] = _cy;
222
        }
223
 
224
      return L_('0') + hi;
225
    }
226
 
227
  /* Figure out the decimal point character.  */
228
#ifdef USE_NL_LANGINFO
229
  if (info->extra == 0)
230
    decimal = nl_langinfo (DECIMAL_POINT);
231
  else
232
    {
233
      decimal = nl_langinfo (MON_DECIMAL_POINT);
234
      if (*decimal == '\0')
235
        decimal = nl_langinfo (DECIMAL_POINT);
236
    }
237
  /* The decimal point character must never be zero.  */
238
  assert (*decimal != '\0');
239
#elif defined USE_LOCALECONV
240
  const struct lconv *lc = localeconv ();
241
  if (info->extra == 0)
242
    decimal = lc->decimal_point;
243
  else
244
    {
245
      decimal = lc->mon_decimal_point;
246
      if (decimal == NULL || *decimal == '\0')
247
        decimal = lc->decimal_point;
248
    }
249
  if (decimal == NULL || *decimal == '\0')
250
    decimal = ".";
251
#else
252
  decimal = ".";
253
#endif
254
#ifdef USE_NL_LANGINFO_WC
255
  if (info->extra == 0)
256
    decimalwc = nl_langinfo_wc (_NL_NUMERIC_DECIMAL_POINT_WC);
257
  else
258
    {
259
      decimalwc = nl_langinfo_wc (_NL_MONETARY_DECIMAL_POINT_WC);
260
      if (decimalwc == L_('\0'))
261
        decimalwc = nl_langinfo_wc (_NL_NUMERIC_DECIMAL_POINT_WC);
262
    }
263
  /* The decimal point character must never be zero.  */
264
  assert (decimalwc != L_('\0'));
265
#else
266
  decimalwc = L_('.');
267
#endif
268
 
269
#if defined USE_NL_LANGINFO && defined USE_NL_LANGINFO_WC
270
  if (info->group)
271
    {
272
      if (info->extra == 0)
273
        grouping = nl_langinfo (GROUPING);
274
      else
275
        grouping = nl_langinfo (MON_GROUPING);
276
 
277
      if (*grouping <= 0 || *grouping == CHAR_MAX)
278
        grouping = NULL;
279
      else
280
        {
281
          /* Figure out the thousands separator character.  */
282
          if (wide)
283
            {
284
              if (info->extra == 0)
285
                thousands_sepwc = nl_langinfo_wc (_NL_NUMERIC_THOUSANDS_SEP_WC);
286
              else
287
                thousands_sepwc = nl_langinfo_wc (_NL_MONETARY_THOUSANDS_SEP_WC);
288
 
289
              if (thousands_sepwc == L_('\0'))
290
                grouping = NULL;
291
            }
292
          else
293
            {
294
              if (info->extra == 0)
295
                thousands_sep = nl_langinfo (THOUSANDS_SEP);
296
              else
297
                thousands_sep = nl_langinfo (MON_THOUSANDS_SEP);
298
              if (*thousands_sep == '\0')
299
                grouping = NULL;
300
            }
301
        }
302
    }
303
  else
304
#elif defined USE_NL_LANGINFO
305
  if (info->group && !wide)
306
    {
307
      if (info->extra == 0)
308
        grouping = nl_langinfo (GROUPING);
309
      else
310
        grouping = nl_langinfo (MON_GROUPING);
311
 
312
      if (*grouping <= 0 || *grouping == CHAR_MAX)
313
        grouping = NULL;
314
      else
315
        {
316
          /* Figure out the thousands separator character.  */
317
          if (info->extra == 0)
318
            thousands_sep = nl_langinfo (THOUSANDS_SEP);
319
          else
320
            thousands_sep = nl_langinfo (MON_THOUSANDS_SEP);
321
 
322
          if (*thousands_sep == '\0')
323
            grouping = NULL;
324
        }
325
    }
326
  else
327
#elif defined USE_LOCALECONV
328
  if (info->group && !wide)
329
    {
330
      if (info->extra == 0)
331
        grouping = lc->grouping;
332
      else
333
        grouping = lc->mon_grouping;
334
 
335
      if (grouping == NULL || *grouping <= 0 || *grouping == CHAR_MAX)
336
        grouping = NULL;
337
      else
338
        {
339
          /* Figure out the thousands separator character.  */
340
          if (info->extra == 0)
341
            thousands_sep = lc->thousands_sep;
342
          else
343
            thousands_sep = lc->mon_thousands_sep;
344
 
345
          if (thousands_sep == NULL || *thousands_sep == '\0')
346
            grouping = NULL;
347
        }
348
    }
349
  else
350
#endif
351
    grouping = NULL;
352
  if (grouping != NULL && !wide)
353
    /* If we are printing multibyte characters and there is a
354
       multibyte representation for the thousands separator,
355
       we must ensure the wide character thousands separator
356
       is available, even if it is fake.  */
357
    thousands_sepwc = (wchar_t) 0xfffffffe;
358
 
359
  /* Fetch the argument value.  */
360
    {
361
      fpnum = **(const __float128 **) args[0];
362
 
363
      /* Check for special values: not a number or infinity.  */
364
      if (isnanq (fpnum))
365
        {
366
          ieee854_float128 u = { .value = fpnum };
367
          is_neg = u.ieee.negative != 0;
368
          if (isupper (info->spec))
369
            {
370
              special = "NAN";
371
              wspecial = L_("NAN");
372
            }
373
            else
374
              {
375
                special = "nan";
376
                wspecial = L_("nan");
377
              }
378
        }
379
      else if (isinfq (fpnum))
380
        {
381
          is_neg = fpnum < 0;
382
          if (isupper (info->spec))
383
            {
384
              special = "INF";
385
              wspecial = L_("INF");
386
            }
387
          else
388
            {
389
              special = "inf";
390
              wspecial = L_("inf");
391
            }
392
        }
393
      else
394
        {
395
          fracsize = mpn_extract_flt128 (fp_input,
396
                                         (sizeof (fp_input) /
397
                                          sizeof (fp_input[0])),
398
                                         &exponent, &is_neg, fpnum);
399
          to_shift = 1 + fracsize * BITS_PER_MP_LIMB - FLT128_MANT_DIG;
400
        }
401
    }
402
 
403
  if (special)
404
    {
405
      int width = info->width;
406
 
407
      if (is_neg || info->showsign || info->space)
408
        --width;
409
      width -= 3;
410
 
411
      if (!info->left && width > 0)
412
        PADN (' ', width);
413
 
414
      if (is_neg)
415
        outchar ('-');
416
      else if (info->showsign)
417
        outchar ('+');
418
      else if (info->space)
419
        outchar (' ');
420
 
421
      PRINT (special, wspecial, 3);
422
 
423
      if (info->left && width > 0)
424
        PADN (' ', width);
425
 
426
      return done;
427
    }
428
 
429
 
430
  /* We need three multiprecision variables.  Now that we have the exponent
431
     of the number we can allocate the needed memory.  It would be more
432
     efficient to use variables of the fixed maximum size but because this
433
     would be really big it could lead to memory problems.  */
434
  {
435
    mp_size_t bignum_size = ((ABS (exponent) + BITS_PER_MP_LIMB - 1)
436
                             / BITS_PER_MP_LIMB
437
                             + (FLT128_MANT_DIG / BITS_PER_MP_LIMB > 2 ? 8 : 4))
438
                            * sizeof (mp_limb_t);
439
    frac = (mp_limb_t *) alloca (bignum_size);
440
    tmp = (mp_limb_t *) alloca (bignum_size);
441
    scale = (mp_limb_t *) alloca (bignum_size);
442
  }
443
 
444
  /* We now have to distinguish between numbers with positive and negative
445
     exponents because the method used for the one is not applicable/efficient
446
     for the other.  */
447
  scalesize = 0;
448
  if (exponent > 2)
449
    {
450
      /* |FP| >= 8.0.  */
451
      int scaleexpo = 0;
452
      int explog = FLT128_MAX_10_EXP_LOG;
453
      int exp10 = 0;
454
      const struct mp_power *powers = &_fpioconst_pow10[explog + 1];
455
      int cnt_h, cnt_l, i;
456
 
457
      if ((exponent + to_shift) % BITS_PER_MP_LIMB == 0)
458
        {
459
          MPN_COPY_DECR (frac + (exponent + to_shift) / BITS_PER_MP_LIMB,
460
                         fp_input, fracsize);
461
          fracsize += (exponent + to_shift) / BITS_PER_MP_LIMB;
462
        }
463
      else
464
        {
465
          cy = mpn_lshift (frac + (exponent + to_shift) / BITS_PER_MP_LIMB,
466
                           fp_input, fracsize,
467
                           (exponent + to_shift) % BITS_PER_MP_LIMB);
468
          fracsize += (exponent + to_shift) / BITS_PER_MP_LIMB;
469
          if (cy)
470
            frac[fracsize++] = cy;
471
        }
472
      MPN_ZERO (frac, (exponent + to_shift) / BITS_PER_MP_LIMB);
473
 
474
      assert (powers > &_fpioconst_pow10[0]);
475
      do
476
        {
477
          --powers;
478
 
479
          /* The number of the product of two binary numbers with n and m
480
             bits respectively has m+n or m+n-1 bits.   */
481
          if (exponent >= scaleexpo + powers->p_expo - 1)
482
            {
483
              if (scalesize == 0)
484
                {
485
                  if (FLT128_MANT_DIG > _FPIO_CONST_OFFSET * BITS_PER_MP_LIMB)
486
                    {
487
#define _FPIO_CONST_SHIFT \
488
  (((FLT128_MANT_DIG + BITS_PER_MP_LIMB - 1) / BITS_PER_MP_LIMB) \
489
   - _FPIO_CONST_OFFSET)
490
                      /* 64bit const offset is not enough for
491
                         IEEE quad long double.  */
492
                      tmpsize = powers->arraysize + _FPIO_CONST_SHIFT;
493
                      memcpy (tmp + _FPIO_CONST_SHIFT,
494
                              &__tens[powers->arrayoff],
495
                              tmpsize * sizeof (mp_limb_t));
496
                      MPN_ZERO (tmp, _FPIO_CONST_SHIFT);
497
                      /* Adjust exponent, as scaleexpo will be this much
498
                         bigger too.  */
499
                      exponent += _FPIO_CONST_SHIFT * BITS_PER_MP_LIMB;
500
                    }
501
                  else
502
                    {
503
                      tmpsize = powers->arraysize;
504
                      memcpy (tmp, &__tens[powers->arrayoff],
505
                              tmpsize * sizeof (mp_limb_t));
506
                    }
507
                }
508
              else
509
                {
510
                  cy = mpn_mul (tmp, scale, scalesize,
511
                                &__tens[powers->arrayoff
512
                                        + _FPIO_CONST_OFFSET],
513
                                powers->arraysize - _FPIO_CONST_OFFSET);
514
                  tmpsize = scalesize + powers->arraysize - _FPIO_CONST_OFFSET;
515
                  if (cy == 0)
516
                    --tmpsize;
517
                }
518
 
519
              if (MPN_GE (frac, tmp))
520
                {
521
                  int cnt;
522
                  MPN_ASSIGN (scale, tmp);
523
                  count_leading_zeros (cnt, scale[scalesize - 1]);
524
                  scaleexpo = (scalesize - 2) * BITS_PER_MP_LIMB - cnt - 1;
525
                  exp10 |= 1 << explog;
526
                }
527
            }
528
          --explog;
529
        }
530
      while (powers > &_fpioconst_pow10[0]);
531
      exponent = exp10;
532
 
533
      /* Optimize number representations.  We want to represent the numbers
534
         with the lowest number of bytes possible without losing any
535
         bytes. Also the highest bit in the scaling factor has to be set
536
         (this is a requirement of the MPN division routines).  */
537
      if (scalesize > 0)
538
        {
539
          /* Determine minimum number of zero bits at the end of
540
             both numbers.  */
541
          for (i = 0; scale[i] == 0 && frac[i] == 0; i++)
542
            ;
543
 
544
          /* Determine number of bits the scaling factor is misplaced.  */
545
          count_leading_zeros (cnt_h, scale[scalesize - 1]);
546
 
547
          if (cnt_h == 0)
548
            {
549
              /* The highest bit of the scaling factor is already set.  So
550
                 we only have to remove the trailing empty limbs.  */
551
              if (i > 0)
552
                {
553
                  MPN_COPY_INCR (scale, scale + i, scalesize - i);
554
                  scalesize -= i;
555
                  MPN_COPY_INCR (frac, frac + i, fracsize - i);
556
                  fracsize -= i;
557
                }
558
            }
559
          else
560
            {
561
              if (scale[i] != 0)
562
                {
563
                  count_trailing_zeros (cnt_l, scale[i]);
564
                  if (frac[i] != 0)
565
                    {
566
                      int cnt_l2;
567
                      count_trailing_zeros (cnt_l2, frac[i]);
568
                      if (cnt_l2 < cnt_l)
569
                        cnt_l = cnt_l2;
570
                    }
571
                }
572
              else
573
                count_trailing_zeros (cnt_l, frac[i]);
574
 
575
              /* Now shift the numbers to their optimal position.  */
576
              if (i == 0 && BITS_PER_MP_LIMB - cnt_h > cnt_l)
577
                {
578
                  /* We cannot save any memory.  So just roll both numbers
579
                     so that the scaling factor has its highest bit set.  */
580
 
581
                  (void) mpn_lshift (scale, scale, scalesize, cnt_h);
582
                  cy = mpn_lshift (frac, frac, fracsize, cnt_h);
583
                  if (cy != 0)
584
                    frac[fracsize++] = cy;
585
                }
586
              else if (BITS_PER_MP_LIMB - cnt_h <= cnt_l)
587
                {
588
                  /* We can save memory by removing the trailing zero limbs
589
                     and by packing the non-zero limbs which gain another
590
                     free one. */
591
 
592
                  (void) mpn_rshift (scale, scale + i, scalesize - i,
593
                                     BITS_PER_MP_LIMB - cnt_h);
594
                  scalesize -= i + 1;
595
                  (void) mpn_rshift (frac, frac + i, fracsize - i,
596
                                     BITS_PER_MP_LIMB - cnt_h);
597
                  fracsize -= frac[fracsize - i - 1] == 0 ? i + 1 : i;
598
                }
599
              else
600
                {
601
                  /* We can only save the memory of the limbs which are zero.
602
                     The non-zero parts occupy the same number of limbs.  */
603
 
604
                  (void) mpn_rshift (scale, scale + (i - 1),
605
                                     scalesize - (i - 1),
606
                                     BITS_PER_MP_LIMB - cnt_h);
607
                  scalesize -= i;
608
                  (void) mpn_rshift (frac, frac + (i - 1),
609
                                     fracsize - (i - 1),
610
                                     BITS_PER_MP_LIMB - cnt_h);
611
                  fracsize -= frac[fracsize - (i - 1) - 1] == 0 ? i : i - 1;
612
                }
613
            }
614
        }
615
    }
616
  else if (exponent < 0)
617
    {
618
      /* |FP| < 1.0.  */
619
      int exp10 = 0;
620
      int explog = FLT128_MAX_10_EXP_LOG;
621
      const struct mp_power *powers = &_fpioconst_pow10[explog + 1];
622
 
623
      /* Now shift the input value to its right place.  */
624
      cy = mpn_lshift (frac, fp_input, fracsize, to_shift);
625
      frac[fracsize++] = cy;
626
      assert (cy == 1 || (frac[fracsize - 2] == 0 && frac[0] == 0));
627
 
628
      expsign = 1;
629
      exponent = -exponent;
630
 
631
      assert (powers != &_fpioconst_pow10[0]);
632
      do
633
        {
634
          --powers;
635
 
636
          if (exponent >= powers->m_expo)
637
            {
638
              int i, incr, cnt_h, cnt_l;
639
              mp_limb_t topval[2];
640
 
641
              /* The mpn_mul function expects the first argument to be
642
                 bigger than the second.  */
643
              if (fracsize < powers->arraysize - _FPIO_CONST_OFFSET)
644
                cy = mpn_mul (tmp, &__tens[powers->arrayoff
645
                                           + _FPIO_CONST_OFFSET],
646
                              powers->arraysize - _FPIO_CONST_OFFSET,
647
                              frac, fracsize);
648
              else
649
                cy = mpn_mul (tmp, frac, fracsize,
650
                              &__tens[powers->arrayoff + _FPIO_CONST_OFFSET],
651
                              powers->arraysize - _FPIO_CONST_OFFSET);
652
              tmpsize = fracsize + powers->arraysize - _FPIO_CONST_OFFSET;
653
              if (cy == 0)
654
                --tmpsize;
655
 
656
              count_leading_zeros (cnt_h, tmp[tmpsize - 1]);
657
              incr = (tmpsize - fracsize) * BITS_PER_MP_LIMB
658
                     + BITS_PER_MP_LIMB - 1 - cnt_h;
659
 
660
              assert (incr <= powers->p_expo);
661
 
662
              /* If we increased the exponent by exactly 3 we have to test
663
                 for overflow.  This is done by comparing with 10 shifted
664
                 to the right position.  */
665
              if (incr == exponent + 3)
666
                {
667
                  if (cnt_h <= BITS_PER_MP_LIMB - 4)
668
                    {
669
                      topval[0] = 0;
670
                      topval[1]
671
                        = ((mp_limb_t) 10) << (BITS_PER_MP_LIMB - 4 - cnt_h);
672
                    }
673
                  else
674
                    {
675
                      topval[0] = ((mp_limb_t) 10) << (BITS_PER_MP_LIMB - 4);
676
                      topval[1] = 0;
677
                      (void) mpn_lshift (topval, topval, 2,
678
                                         BITS_PER_MP_LIMB - cnt_h);
679
                    }
680
                }
681
 
682
              /* We have to be careful when multiplying the last factor.
683
                 If the result is greater than 1.0 be have to test it
684
                 against 10.0.  If it is greater or equal to 10.0 the
685
                 multiplication was not valid.  This is because we cannot
686
                 determine the number of bits in the result in advance.  */
687
              if (incr < exponent + 3
688
                  || (incr == exponent + 3 &&
689
                      (tmp[tmpsize - 1] < topval[1]
690
                       || (tmp[tmpsize - 1] == topval[1]
691
                           && tmp[tmpsize - 2] < topval[0]))))
692
                {
693
                  /* The factor is right.  Adapt binary and decimal
694
                     exponents.  */
695
                  exponent -= incr;
696
                  exp10 |= 1 << explog;
697
 
698
                  /* If this factor yields a number greater or equal to
699
                     1.0, we must not shift the non-fractional digits down. */
700
                  if (exponent < 0)
701
                    cnt_h += -exponent;
702
 
703
                  /* Now we optimize the number representation.  */
704
                  for (i = 0; tmp[i] == 0; ++i);
705
                  if (cnt_h == BITS_PER_MP_LIMB - 1)
706
                    {
707
                      MPN_COPY (frac, tmp + i, tmpsize - i);
708
                      fracsize = tmpsize - i;
709
                    }
710
                  else
711
                    {
712
                      count_trailing_zeros (cnt_l, tmp[i]);
713
 
714
                      /* Now shift the numbers to their optimal position.  */
715
                      if (i == 0 && BITS_PER_MP_LIMB - 1 - cnt_h > cnt_l)
716
                        {
717
                          /* We cannot save any memory.  Just roll the
718
                             number so that the leading digit is in a
719
                             separate limb.  */
720
 
721
                          cy = mpn_lshift (frac, tmp, tmpsize, cnt_h + 1);
722
                          fracsize = tmpsize + 1;
723
                          frac[fracsize - 1] = cy;
724
                        }
725
                      else if (BITS_PER_MP_LIMB - 1 - cnt_h <= cnt_l)
726
                        {
727
                          (void) mpn_rshift (frac, tmp + i, tmpsize - i,
728
                                             BITS_PER_MP_LIMB - 1 - cnt_h);
729
                          fracsize = tmpsize - i;
730
                        }
731
                      else
732
                        {
733
                          /* We can only save the memory of the limbs which
734
                             are zero.  The non-zero parts occupy the same
735
                             number of limbs.  */
736
 
737
                          (void) mpn_rshift (frac, tmp + (i - 1),
738
                                             tmpsize - (i - 1),
739
                                             BITS_PER_MP_LIMB - 1 - cnt_h);
740
                          fracsize = tmpsize - (i - 1);
741
                        }
742
                    }
743
                }
744
            }
745
          --explog;
746
        }
747
      while (powers != &_fpioconst_pow10[1] && exponent > 0);
748
      /* All factors but 10^-1 are tested now.  */
749
      if (exponent > 0)
750
        {
751
          int cnt_l;
752
 
753
          cy = mpn_mul_1 (tmp, frac, fracsize, 10);
754
          tmpsize = fracsize;
755
          assert (cy == 0 || tmp[tmpsize - 1] < 20);
756
 
757
          count_trailing_zeros (cnt_l, tmp[0]);
758
          if (cnt_l < MIN (4, exponent))
759
            {
760
              cy = mpn_lshift (frac, tmp, tmpsize,
761
                               BITS_PER_MP_LIMB - MIN (4, exponent));
762
              if (cy != 0)
763
                frac[tmpsize++] = cy;
764
            }
765
          else
766
            (void) mpn_rshift (frac, tmp, tmpsize, MIN (4, exponent));
767
          fracsize = tmpsize;
768
          exp10 |= 1;
769
          assert (frac[fracsize - 1] < 10);
770
        }
771
      exponent = exp10;
772
    }
773
  else
774
    {
775
      /* This is a special case.  We don't need a factor because the
776
         numbers are in the range of 1.0 <= |fp| < 8.0.  We simply
777
         shift it to the right place and divide it by 1.0 to get the
778
         leading digit.  (Of course this division is not really made.)  */
779
      assert (0 <= exponent && exponent < 3 &&
780
              exponent + to_shift < BITS_PER_MP_LIMB);
781
 
782
      /* Now shift the input value to its right place.  */
783
      cy = mpn_lshift (frac, fp_input, fracsize, (exponent + to_shift));
784
      frac[fracsize++] = cy;
785
      exponent = 0;
786
    }
787
 
788
  {
789
    int width = info->width;
790
    wchar_t *wstartp, *wcp;
791
    size_t chars_needed;
792
    int expscale;
793
    int intdig_max, intdig_no = 0;
794
    int fracdig_min;
795
    int fracdig_max;
796
    int dig_max;
797
    int significant;
798
    int ngroups = 0;
799
    char spec = tolower (info->spec);
800
 
801
    if (spec == 'e')
802
      {
803
        type = info->spec;
804
        intdig_max = 1;
805
        fracdig_min = fracdig_max = info->prec < 0 ? 6 : info->prec;
806
        chars_needed = 1 + 1 + (size_t) fracdig_max + 1 + 1 + 4;
807
        /*             d   .     ddd         e   +-  ddd  */
808
        dig_max = __INT_MAX__;          /* Unlimited.  */
809
        significant = 1;                /* Does not matter here.  */
810
      }
811
    else if (spec == 'f')
812
      {
813
        type = 'f';
814
        fracdig_min = fracdig_max = info->prec < 0 ? 6 : info->prec;
815
        dig_max = __INT_MAX__;          /* Unlimited.  */
816
        significant = 1;                /* Does not matter here.  */
817
        if (expsign == 0)
818
          {
819
            intdig_max = exponent + 1;
820
            /* This can be really big!  */  /* XXX Maybe malloc if too big? */
821
            chars_needed = (size_t) exponent + 1 + 1 + (size_t) fracdig_max;
822
          }
823
        else
824
          {
825
            intdig_max = 1;
826
            chars_needed = 1 + 1 + (size_t) fracdig_max;
827
          }
828
      }
829
    else
830
      {
831
        dig_max = info->prec < 0 ? 6 : (info->prec == 0 ? 1 : info->prec);
832
        if ((expsign == 0 && exponent >= dig_max)
833
            || (expsign != 0 && exponent > 4))
834
          {
835
            if ('g' - 'G' == 'e' - 'E')
836
              type = 'E' + (info->spec - 'G');
837
            else
838
              type = isupper (info->spec) ? 'E' : 'e';
839
            fracdig_max = dig_max - 1;
840
            intdig_max = 1;
841
            chars_needed = 1 + 1 + (size_t) fracdig_max + 1 + 1 + 4;
842
          }
843
        else
844
          {
845
            type = 'f';
846
            intdig_max = expsign == 0 ? exponent + 1 : 0;
847
            fracdig_max = dig_max - intdig_max;
848
            /* We need space for the significant digits and perhaps
849
               for leading zeros when < 1.0.  The number of leading
850
               zeros can be as many as would be required for
851
               exponential notation with a negative two-digit
852
               exponent, which is 4.  */
853
            chars_needed = (size_t) dig_max + 1 + 4;
854
          }
855
        fracdig_min = info->alt ? fracdig_max : 0;
856
        significant = 0;         /* We count significant digits.  */
857
      }
858
 
859
    if (grouping)
860
      {
861
        /* Guess the number of groups we will make, and thus how
862
           many spaces we need for separator characters.  */
863
        ngroups = guess_grouping (intdig_max, grouping);
864
        /* Allocate one more character in case rounding increases the
865
           number of groups.  */
866
        chars_needed += ngroups + 1;
867
      }
868
 
869
    /* Allocate buffer for output.  We need two more because while rounding
870
       it is possible that we need two more characters in front of all the
871
       other output.  If the amount of memory we have to allocate is too
872
       large use `malloc' instead of `alloca'.  */
873
    if (__builtin_expect (chars_needed >= (size_t) -1 / sizeof (wchar_t) - 2
874
                          || chars_needed < fracdig_max, 0))
875
      {
876
        /* Some overflow occurred.  */
877
#if defined HAVE_ERRNO_H && defined ERANGE
878
        errno = ERANGE;
879
#endif
880
        return -1;
881
      }
882
    size_t wbuffer_to_alloc = (2 + chars_needed) * sizeof (wchar_t);
883
    buffer_malloced = wbuffer_to_alloc >= 4096;
884
    if (__builtin_expect (buffer_malloced, 0))
885
      {
886
        wbuffer = (wchar_t *) malloc (wbuffer_to_alloc);
887
        if (wbuffer == NULL)
888
          /* Signal an error to the caller.  */
889
          return -1;
890
      }
891
    else
892
      wbuffer = (wchar_t *) alloca (wbuffer_to_alloc);
893
    wcp = wstartp = wbuffer + 2;        /* Let room for rounding.  */
894
 
895
    /* Do the real work: put digits in allocated buffer.  */
896
    if (expsign == 0 || type != 'f')
897
      {
898
        assert (expsign == 0 || intdig_max == 1);
899
        while (intdig_no < intdig_max)
900
          {
901
            ++intdig_no;
902
            *wcp++ = hack_digit ();
903
          }
904
        significant = 1;
905
        if (info->alt
906
            || fracdig_min > 0
907
            || (fracdig_max > 0 && (fracsize > 1 || frac[0] != 0)))
908
          *wcp++ = decimalwc;
909
      }
910
    else
911
      {
912
        /* |fp| < 1.0 and the selected type is 'f', so put "0."
913
           in the buffer.  */
914
        *wcp++ = L_('0');
915
        --exponent;
916
        *wcp++ = decimalwc;
917
      }
918
 
919
    /* Generate the needed number of fractional digits.  */
920
    int fracdig_no = 0;
921
    int added_zeros = 0;
922
    while (fracdig_no < fracdig_min + added_zeros
923
           || (fracdig_no < fracdig_max && (fracsize > 1 || frac[0] != 0)))
924
      {
925
        ++fracdig_no;
926
        *wcp = hack_digit ();
927
        if (*wcp++ != L_('0'))
928
          significant = 1;
929
        else if (significant == 0)
930
          {
931
            ++fracdig_max;
932
            if (fracdig_min > 0)
933
              ++added_zeros;
934
          }
935
      }
936
 
937
    /* Do rounding.  */
938
    digit = hack_digit ();
939
    if (digit > L_('4'))
940
      {
941
        wchar_t *wtp = wcp;
942
 
943
        if (digit == L_('5')
944
            && ((*(wcp - 1) != decimalwc && (*(wcp - 1) & 1) == 0)
945
                || ((*(wcp - 1) == decimalwc && (*(wcp - 2) & 1) == 0))))
946
          {
947
            /* This is the critical case.        */
948
            if (fracsize == 1 && frac[0] == 0)
949
              /* Rest of the number is zero -> round to even.
950
                 (IEEE 754-1985 4.1 says this is the default rounding.)  */
951
              goto do_expo;
952
            else if (scalesize == 0)
953
              {
954
                /* Here we have to see whether all limbs are zero since no
955
                   normalization happened.  */
956
                size_t lcnt = fracsize;
957
                while (lcnt >= 1 && frac[lcnt - 1] == 0)
958
                  --lcnt;
959
                if (lcnt == 0)
960
                  /* Rest of the number is zero -> round to even.
961
                     (IEEE 754-1985 4.1 says this is the default rounding.)  */
962
                  goto do_expo;
963
              }
964
          }
965
 
966
        if (fracdig_no > 0)
967
          {
968
            /* Process fractional digits.  Terminate if not rounded or
969
               radix character is reached.  */
970
            int removed = 0;
971
            while (*--wtp != decimalwc && *wtp == L_('9'))
972
              {
973
                *wtp = L_('0');
974
                ++removed;
975
              }
976
            if (removed == fracdig_min && added_zeros > 0)
977
              --added_zeros;
978
            if (*wtp != decimalwc)
979
              /* Round up.  */
980
              (*wtp)++;
981
            else if (__builtin_expect (spec == 'g' && type == 'f' && info->alt
982
                                       && wtp == wstartp + 1
983
                                       && wstartp[0] == L_('0'),
984
                                       0))
985
              /* This is a special case: the rounded number is 1.0,
986
                 the format is 'g' or 'G', and the alternative format
987
                 is selected.  This means the result must be "1.".  */
988
              --added_zeros;
989
          }
990
 
991
        if (fracdig_no == 0 || *wtp == decimalwc)
992
          {
993
            /* Round the integer digits.  */
994
            if (*(wtp - 1) == decimalwc)
995
              --wtp;
996
 
997
            while (--wtp >= wstartp && *wtp == L_('9'))
998
              *wtp = L_('0');
999
 
1000
            if (wtp >= wstartp)
1001
              /* Round up.  */
1002
              (*wtp)++;
1003
            else
1004
              /* It is more critical.  All digits were 9's.  */
1005
              {
1006
                if (type != 'f')
1007
                  {
1008
                    *wstartp = '1';
1009
                    exponent += expsign == 0 ? 1 : -1;
1010
 
1011
                    /* The above exponent adjustment could lead to 1.0e-00,
1012
                       e.g. for 0.999999999.  Make sure exponent 0 always
1013
                       uses + sign.  */
1014
                    if (exponent == 0)
1015
                      expsign = 0;
1016
                  }
1017
                else if (intdig_no == dig_max)
1018
                  {
1019
                    /* This is the case where for type %g the number fits
1020
                       really in the range for %f output but after rounding
1021
                       the number of digits is too big.  */
1022
                    *--wstartp = decimalwc;
1023
                    *--wstartp = L_('1');
1024
 
1025
                    if (info->alt || fracdig_no > 0)
1026
                      {
1027
                        /* Overwrite the old radix character.  */
1028
                        wstartp[intdig_no + 2] = L_('0');
1029
                        ++fracdig_no;
1030
                      }
1031
 
1032
                    fracdig_no += intdig_no;
1033
                    intdig_no = 1;
1034
                    fracdig_max = intdig_max - intdig_no;
1035
                    ++exponent;
1036
                    /* Now we must print the exponent.  */
1037
                    type = isupper (info->spec) ? 'E' : 'e';
1038
                  }
1039
                else
1040
                  {
1041
                    /* We can simply add another another digit before the
1042
                       radix.  */
1043
                    *--wstartp = L_('1');
1044
                    ++intdig_no;
1045
                  }
1046
 
1047
                /* While rounding the number of digits can change.
1048
                   If the number now exceeds the limits remove some
1049
                   fractional digits.  */
1050
                if (intdig_no + fracdig_no > dig_max)
1051
                  {
1052
                    wcp -= intdig_no + fracdig_no - dig_max;
1053
                    fracdig_no -= intdig_no + fracdig_no - dig_max;
1054
                  }
1055
              }
1056
          }
1057
      }
1058
 
1059
  do_expo:
1060
    /* Now remove unnecessary '0' at the end of the string.  */
1061
    while (fracdig_no > fracdig_min + added_zeros && *(wcp - 1) == L_('0'))
1062
      {
1063
        --wcp;
1064
        --fracdig_no;
1065
      }
1066
    /* If we eliminate all fractional digits we perhaps also can remove
1067
       the radix character.  */
1068
    if (fracdig_no == 0 && !info->alt && *(wcp - 1) == decimalwc)
1069
      --wcp;
1070
 
1071
    if (grouping)
1072
      {
1073
        /* Rounding might have changed the number of groups.  We allocated
1074
           enough memory but we need here the correct number of groups.  */
1075
        if (intdig_no != intdig_max)
1076
          ngroups = guess_grouping (intdig_no, grouping);
1077
 
1078
        /* Add in separator characters, overwriting the same buffer.  */
1079
        wcp = group_number (wstartp, wcp, intdig_no, grouping, thousands_sepwc,
1080
                            ngroups);
1081
      }
1082
 
1083
    /* Write the exponent if it is needed.  */
1084
    if (type != 'f')
1085
      {
1086
        if (__builtin_expect (expsign != 0 && exponent == 4 && spec == 'g', 0))
1087
          {
1088
            /* This is another special case.  The exponent of the number is
1089
               really smaller than -4, which requires the 'e'/'E' format.
1090
               But after rounding the number has an exponent of -4.  */
1091
            assert (wcp >= wstartp + 1);
1092
            assert (wstartp[0] == L_('1'));
1093
            memcpy (wstartp, L_("0.0001"), 6 * sizeof (wchar_t));
1094
            wstartp[1] = decimalwc;
1095
            if (wcp >= wstartp + 2)
1096
              {
1097
                size_t cnt;
1098
                for (cnt = 0; cnt < wcp - (wstartp + 2); cnt++)
1099
                  wstartp[6 + cnt] = L_('0');
1100
                wcp += 4;
1101
              }
1102
            else
1103
              wcp += 5;
1104
          }
1105
        else
1106
          {
1107
            *wcp++ = (wchar_t) type;
1108
            *wcp++ = expsign ? L_('-') : L_('+');
1109
 
1110
            /* Find the magnitude of the exponent.      */
1111
            expscale = 10;
1112
            while (expscale <= exponent)
1113
              expscale *= 10;
1114
 
1115
            if (exponent < 10)
1116
              /* Exponent always has at least two digits.  */
1117
              *wcp++ = L_('0');
1118
            else
1119
              do
1120
                {
1121
                  expscale /= 10;
1122
                  *wcp++ = L_('0') + (exponent / expscale);
1123
                  exponent %= expscale;
1124
                }
1125
              while (expscale > 10);
1126
            *wcp++ = L_('0') + exponent;
1127
          }
1128
      }
1129
 
1130
    /* Compute number of characters which must be filled with the padding
1131
       character.  */
1132
    if (is_neg || info->showsign || info->space)
1133
      --width;
1134
    width -= wcp - wstartp;
1135
 
1136
    if (!info->left && info->pad != '0' && width > 0)
1137
      PADN (info->pad, width);
1138
 
1139
    if (is_neg)
1140
      outchar ('-');
1141
    else if (info->showsign)
1142
      outchar ('+');
1143
    else if (info->space)
1144
      outchar (' ');
1145
 
1146
    if (!info->left && info->pad == '0' && width > 0)
1147
      PADN ('0', width);
1148
 
1149
    {
1150
      char *buffer = NULL;
1151
      char *buffer_end __attribute__((__unused__)) = NULL;
1152
      char *cp = NULL;
1153
      char *tmpptr;
1154
 
1155
      if (! wide)
1156
        {
1157
          /* Create the single byte string.  */
1158
          size_t decimal_len;
1159
          size_t thousands_sep_len;
1160
          wchar_t *copywc;
1161
#ifdef USE_I18N_NUMBER_H
1162
          size_t factor = (info->i18n
1163
                           ? nl_langinfo_wc (_NL_CTYPE_MB_CUR_MAX)
1164
                           : 1);
1165
#else
1166
          size_t factor = 1;
1167
#endif
1168
 
1169
          decimal_len = strlen (decimal);
1170
 
1171
          if (thousands_sep == NULL)
1172
            thousands_sep_len = 0;
1173
          else
1174
            thousands_sep_len = strlen (thousands_sep);
1175
 
1176
          size_t nbuffer = (2 + chars_needed * factor + decimal_len
1177
                            + ngroups * thousands_sep_len);
1178
          if (__builtin_expect (buffer_malloced, 0))
1179
            {
1180
              buffer = (char *) malloc (nbuffer);
1181
              if (buffer == NULL)
1182
                {
1183
                  /* Signal an error to the caller.  */
1184
                  free (wbuffer);
1185
                  return -1;
1186
                }
1187
            }
1188
          else
1189
            buffer = (char *) alloca (nbuffer);
1190
          buffer_end = buffer + nbuffer;
1191
 
1192
          /* Now copy the wide character string.  Since the character
1193
             (except for the decimal point and thousands separator) must
1194
             be coming from the ASCII range we can esily convert the
1195
             string without mapping tables.  */
1196
          for (cp = buffer, copywc = wstartp; copywc < wcp; ++copywc)
1197
            if (*copywc == decimalwc)
1198
              memcpy (cp, decimal, decimal_len), cp += decimal_len;
1199
            else if (*copywc == thousands_sepwc)
1200
              memcpy (cp, thousands_sep, thousands_sep_len), cp += thousands_sep_len;
1201
            else
1202
              *cp++ = (char) *copywc;
1203
        }
1204
 
1205
      tmpptr = buffer;
1206
#if USE_I18N_NUMBER_H
1207
      if (__builtin_expect (info->i18n, 0))
1208
        {
1209
          tmpptr = _i18n_number_rewrite (tmpptr, cp, buffer_end);
1210
          cp = buffer_end;
1211
          assert ((uintptr_t) buffer <= (uintptr_t) tmpptr);
1212
          assert ((uintptr_t) tmpptr < (uintptr_t) buffer_end);
1213
        }
1214
#endif
1215
 
1216
      PRINT (tmpptr, wstartp, wide ? wcp - wstartp : cp - tmpptr);
1217
 
1218
      /* Free the memory if necessary.  */
1219
      if (__builtin_expect (buffer_malloced, 0))
1220
        {
1221
          free (buffer);
1222
          free (wbuffer);
1223
        }
1224
    }
1225
 
1226
    if (info->left && width > 0)
1227
      PADN (info->pad, width);
1228
  }
1229
  return done;
1230
}
1231
 
1232
/* Return the number of extra grouping characters that will be inserted
1233
   into a number with INTDIG_MAX integer digits.  */
1234
 
1235
static unsigned int
1236
guess_grouping (unsigned int intdig_max, const char *grouping)
1237
{
1238
  unsigned int groups;
1239
 
1240
  /* We treat all negative values like CHAR_MAX.  */
1241
 
1242
  if (*grouping == CHAR_MAX || *grouping <= 0)
1243
    /* No grouping should be done.  */
1244
    return 0;
1245
 
1246
  groups = 0;
1247
  while (intdig_max > (unsigned int) *grouping)
1248
    {
1249
      ++groups;
1250
      intdig_max -= *grouping++;
1251
 
1252
      if (*grouping == 0)
1253
        {
1254
          /* Same grouping repeats.  */
1255
          groups += (intdig_max - 1) / grouping[-1];
1256
          break;
1257
        }
1258
      else if (*grouping == CHAR_MAX || *grouping <= 0)
1259
        /* No more grouping should be done.  */
1260
        break;
1261
    }
1262
 
1263
  return groups;
1264
}
1265
 
1266
/* Group the INTDIG_NO integer digits of the number in [BUF,BUFEND).
1267
   There is guaranteed enough space past BUFEND to extend it.
1268
   Return the new end of buffer.  */
1269
 
1270
static wchar_t *
1271
group_number (wchar_t *buf, wchar_t *bufend, unsigned int intdig_no,
1272
              const char *grouping, wchar_t thousands_sep, int ngroups)
1273
{
1274
  wchar_t *p;
1275
 
1276
  if (ngroups == 0)
1277
    return bufend;
1278
 
1279
  /* Move the fractional part down.  */
1280
  memmove (buf + intdig_no + ngroups, buf + intdig_no,
1281
           (bufend - (buf + intdig_no)) * sizeof (wchar_t));
1282
 
1283
  p = buf + intdig_no + ngroups - 1;
1284
  do
1285
    {
1286
      unsigned int len = *grouping++;
1287
      do
1288
        *p-- = buf[--intdig_no];
1289
      while (--len > 0);
1290
      *p-- = thousands_sep;
1291
 
1292
      if (*grouping == 0)
1293
        /* Same grouping repeats.  */
1294
        --grouping;
1295
      else if (*grouping == CHAR_MAX || *grouping <= 0)
1296
        /* No more grouping should be done.  */
1297
        break;
1298
    } while (intdig_no > (unsigned int) *grouping);
1299
 
1300
  /* Copy the remaining ungrouped digits.  */
1301
  do
1302
    *p-- = buf[--intdig_no];
1303
  while (p > buf);
1304
 
1305
  return bufend + ngroups;
1306
}

powered by: WebSVN 2.1.0

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