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