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