(root)/
gmp-6.3.0/
printf/
doprnti.c
       1  /* __gmp_doprnt_integer -- integer style formatted output.
       2  
       3     THE FUNCTIONS IN THIS FILE ARE FOR INTERNAL USE ONLY.  THEY'RE ALMOST
       4     CERTAIN TO BE SUBJECT TO INCOMPATIBLE CHANGES OR DISAPPEAR COMPLETELY IN
       5     FUTURE GNU MP RELEASES.
       6  
       7  Copyright 2001 Free Software Foundation, Inc.
       8  
       9  This file is part of the GNU MP Library.
      10  
      11  The GNU MP Library is free software; you can redistribute it and/or modify
      12  it under the terms of either:
      13  
      14    * the GNU Lesser General Public License as published by the Free
      15      Software Foundation; either version 3 of the License, or (at your
      16      option) any later version.
      17  
      18  or
      19  
      20    * the GNU General Public License as published by the Free Software
      21      Foundation; either version 2 of the License, or (at your option) any
      22      later version.
      23  
      24  or both in parallel, as here.
      25  
      26  The GNU MP Library is distributed in the hope that it will be useful, but
      27  WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
      28  or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
      29  for more details.
      30  
      31  You should have received copies of the GNU General Public License and the
      32  GNU Lesser General Public License along with the GNU MP Library.  If not,
      33  see https://www.gnu.org/licenses/.  */
      34  
      35  #include <stdarg.h>    /* for va_list and hence doprnt_funs_t */
      36  #include <string.h>
      37  #include <stdio.h>
      38  #include <stdlib.h>
      39  
      40  #include "gmp-impl.h"
      41  
      42  
      43  int
      44  __gmp_doprnt_integer (const struct doprnt_funs_t *funs,
      45  		      void *data,
      46  		      const struct doprnt_params_t *p,
      47  		      const char *s)
      48  {
      49    int         retval = 0;
      50    int         slen, justlen, showbaselen, sign, signlen, slashlen, zeros;
      51    int         justify, den_showbaselen;
      52    const char  *slash, *showbase;
      53  
      54    /* '+' or ' ' if wanted, and don't already have '-' */
      55    sign = p->sign;
      56    if (s[0] == '-')
      57      {
      58        sign = s[0];
      59        s++;
      60      }
      61    signlen = (sign != '\0');
      62  
      63    /* if the precision was explicitly 0, print nothing for a 0 value */
      64    if (*s == '0' && p->prec == 0)
      65      s++;
      66  
      67    slen = strlen (s);
      68    slash = strchr (s, '/');
      69  
      70    showbase = NULL;
      71    showbaselen = 0;
      72  
      73    if (p->showbase != DOPRNT_SHOWBASE_NO)
      74      {
      75        switch (p->base) {
      76        case 16:  showbase = "0x"; showbaselen = 2; break;
      77        case -16: showbase = "0X"; showbaselen = 2; break;
      78        case 8:   showbase = "0";  showbaselen = 1; break;
      79        }
      80      }
      81  
      82    den_showbaselen = showbaselen;
      83    if (slash == NULL
      84        || (p->showbase == DOPRNT_SHOWBASE_NONZERO && slash[1] == '0'))
      85      den_showbaselen = 0;
      86  
      87    if (p->showbase == DOPRNT_SHOWBASE_NONZERO && s[0] == '0')
      88      showbaselen = 0;
      89  
      90    /* the influence of p->prec on mpq is currently undefined */
      91    zeros = MAX (0, p->prec - slen);
      92  
      93    /* space left over after actual output length */
      94    justlen = p->width
      95      - (strlen(s) + signlen + showbaselen + den_showbaselen + zeros);
      96  
      97    justify = p->justify;
      98    if (justlen <= 0) /* no justifying if exceed width */
      99      justify = DOPRNT_JUSTIFY_NONE;
     100  
     101    if (justify == DOPRNT_JUSTIFY_RIGHT)             /* pad right */
     102      DOPRNT_REPS (p->fill, justlen);
     103  
     104    DOPRNT_REPS_MAYBE (sign, signlen);               /* sign */
     105  
     106    DOPRNT_MEMORY_MAYBE (showbase, showbaselen);     /* base */
     107  
     108    DOPRNT_REPS_MAYBE ('0', zeros);                  /* zeros */
     109  
     110    if (justify == DOPRNT_JUSTIFY_INTERNAL)          /* pad internal */
     111      DOPRNT_REPS (p->fill, justlen);
     112  
     113    /* if there's a showbase on the denominator, then print the numerator
     114       separately so it can be inserted */
     115    if (den_showbaselen != 0)
     116      {
     117        ASSERT (slash != NULL);
     118        slashlen = slash+1 - s;
     119        DOPRNT_MEMORY (s, slashlen);                 /* numerator and slash */
     120        slen -= slashlen;
     121        s += slashlen;
     122        DOPRNT_MEMORY (showbase, den_showbaselen);
     123      }
     124  
     125    DOPRNT_MEMORY (s, slen);                         /* number, or denominator */
     126  
     127    if (justify == DOPRNT_JUSTIFY_LEFT)              /* pad left */
     128      DOPRNT_REPS (p->fill, justlen);
     129  
     130   done:
     131    return retval;
     132  
     133   error:
     134    retval = -1;
     135    goto done;
     136  }