|
Packit |
5c3484 |
/* __gmp_doprnt_integer -- integer style formatted output.
|
|
Packit |
5c3484 |
|
|
Packit |
5c3484 |
THE FUNCTIONS IN THIS FILE ARE FOR INTERNAL USE ONLY. THEY'RE ALMOST
|
|
Packit |
5c3484 |
CERTAIN TO BE SUBJECT TO INCOMPATIBLE CHANGES OR DISAPPEAR COMPLETELY IN
|
|
Packit |
5c3484 |
FUTURE GNU MP RELEASES.
|
|
Packit |
5c3484 |
|
|
Packit |
5c3484 |
Copyright 2001 Free Software Foundation, Inc.
|
|
Packit |
5c3484 |
|
|
Packit |
5c3484 |
This file is part of the GNU MP Library.
|
|
Packit |
5c3484 |
|
|
Packit |
5c3484 |
The GNU MP Library is free software; you can redistribute it and/or modify
|
|
Packit |
5c3484 |
it under the terms of either:
|
|
Packit |
5c3484 |
|
|
Packit |
5c3484 |
* the GNU Lesser General Public License as published by the Free
|
|
Packit |
5c3484 |
Software Foundation; either version 3 of the License, or (at your
|
|
Packit |
5c3484 |
option) any later version.
|
|
Packit |
5c3484 |
|
|
Packit |
5c3484 |
or
|
|
Packit |
5c3484 |
|
|
Packit |
5c3484 |
* the GNU General Public License as published by the Free Software
|
|
Packit |
5c3484 |
Foundation; either version 2 of the License, or (at your option) any
|
|
Packit |
5c3484 |
later version.
|
|
Packit |
5c3484 |
|
|
Packit |
5c3484 |
or both in parallel, as here.
|
|
Packit |
5c3484 |
|
|
Packit |
5c3484 |
The GNU MP Library is distributed in the hope that it will be useful, but
|
|
Packit |
5c3484 |
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
|
Packit |
5c3484 |
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
|
Packit |
5c3484 |
for more details.
|
|
Packit |
5c3484 |
|
|
Packit |
5c3484 |
You should have received copies of the GNU General Public License and the
|
|
Packit |
5c3484 |
GNU Lesser General Public License along with the GNU MP Library. If not,
|
|
Packit |
5c3484 |
see https://www.gnu.org/licenses/. */
|
|
Packit |
5c3484 |
|
|
Packit |
5c3484 |
#include <stdarg.h> /* for va_list and hence doprnt_funs_t */
|
|
Packit |
5c3484 |
#include <string.h>
|
|
Packit |
5c3484 |
#include <stdio.h>
|
|
Packit |
5c3484 |
#include <stdlib.h>
|
|
Packit |
5c3484 |
|
|
Packit |
5c3484 |
#include "gmp.h"
|
|
Packit |
5c3484 |
#include "gmp-impl.h"
|
|
Packit |
5c3484 |
|
|
Packit |
5c3484 |
|
|
Packit |
5c3484 |
int
|
|
Packit |
5c3484 |
__gmp_doprnt_integer (const struct doprnt_funs_t *funs,
|
|
Packit |
5c3484 |
void *data,
|
|
Packit |
5c3484 |
const struct doprnt_params_t *p,
|
|
Packit |
5c3484 |
const char *s)
|
|
Packit |
5c3484 |
{
|
|
Packit |
5c3484 |
int retval = 0;
|
|
Packit |
5c3484 |
int slen, justlen, showbaselen, sign, signlen, slashlen, zeros;
|
|
Packit |
5c3484 |
int justify, den_showbaselen;
|
|
Packit |
5c3484 |
const char *slash, *showbase;
|
|
Packit |
5c3484 |
|
|
Packit |
5c3484 |
/* '+' or ' ' if wanted, and don't already have '-' */
|
|
Packit |
5c3484 |
sign = p->sign;
|
|
Packit |
5c3484 |
if (s[0] == '-')
|
|
Packit |
5c3484 |
{
|
|
Packit |
5c3484 |
sign = s[0];
|
|
Packit |
5c3484 |
s++;
|
|
Packit |
5c3484 |
}
|
|
Packit |
5c3484 |
signlen = (sign != '\0');
|
|
Packit |
5c3484 |
|
|
Packit |
5c3484 |
/* if the precision was explicitly 0, print nothing for a 0 value */
|
|
Packit |
5c3484 |
if (*s == '0' && p->prec == 0)
|
|
Packit |
5c3484 |
s++;
|
|
Packit |
5c3484 |
|
|
Packit |
5c3484 |
slen = strlen (s);
|
|
Packit |
5c3484 |
slash = strchr (s, '/');
|
|
Packit |
5c3484 |
|
|
Packit |
5c3484 |
showbase = NULL;
|
|
Packit |
5c3484 |
showbaselen = 0;
|
|
Packit |
5c3484 |
|
|
Packit |
5c3484 |
if (p->showbase != DOPRNT_SHOWBASE_NO)
|
|
Packit |
5c3484 |
{
|
|
Packit |
5c3484 |
switch (p->base) {
|
|
Packit |
5c3484 |
case 16: showbase = "0x"; showbaselen = 2; break;
|
|
Packit |
5c3484 |
case -16: showbase = "0X"; showbaselen = 2; break;
|
|
Packit |
5c3484 |
case 8: showbase = "0"; showbaselen = 1; break;
|
|
Packit |
5c3484 |
}
|
|
Packit |
5c3484 |
}
|
|
Packit |
5c3484 |
|
|
Packit |
5c3484 |
den_showbaselen = showbaselen;
|
|
Packit |
5c3484 |
if (slash == NULL
|
|
Packit |
5c3484 |
|| (p->showbase == DOPRNT_SHOWBASE_NONZERO && slash[1] == '0'))
|
|
Packit |
5c3484 |
den_showbaselen = 0;
|
|
Packit |
5c3484 |
|
|
Packit |
5c3484 |
if (p->showbase == DOPRNT_SHOWBASE_NONZERO && s[0] == '0')
|
|
Packit |
5c3484 |
showbaselen = 0;
|
|
Packit |
5c3484 |
|
|
Packit |
5c3484 |
/* the influence of p->prec on mpq is currently undefined */
|
|
Packit |
5c3484 |
zeros = MAX (0, p->prec - slen);
|
|
Packit |
5c3484 |
|
|
Packit |
5c3484 |
/* space left over after actual output length */
|
|
Packit |
5c3484 |
justlen = p->width
|
|
Packit |
5c3484 |
- (strlen(s) + signlen + showbaselen + den_showbaselen + zeros);
|
|
Packit |
5c3484 |
|
|
Packit |
5c3484 |
justify = p->justify;
|
|
Packit |
5c3484 |
if (justlen <= 0) /* no justifying if exceed width */
|
|
Packit |
5c3484 |
justify = DOPRNT_JUSTIFY_NONE;
|
|
Packit |
5c3484 |
|
|
Packit |
5c3484 |
if (justify == DOPRNT_JUSTIFY_RIGHT) /* pad right */
|
|
Packit |
5c3484 |
DOPRNT_REPS (p->fill, justlen);
|
|
Packit |
5c3484 |
|
|
Packit |
5c3484 |
DOPRNT_REPS_MAYBE (sign, signlen); /* sign */
|
|
Packit |
5c3484 |
|
|
Packit |
5c3484 |
DOPRNT_MEMORY_MAYBE (showbase, showbaselen); /* base */
|
|
Packit |
5c3484 |
|
|
Packit |
5c3484 |
DOPRNT_REPS_MAYBE ('0', zeros); /* zeros */
|
|
Packit |
5c3484 |
|
|
Packit |
5c3484 |
if (justify == DOPRNT_JUSTIFY_INTERNAL) /* pad internal */
|
|
Packit |
5c3484 |
DOPRNT_REPS (p->fill, justlen);
|
|
Packit |
5c3484 |
|
|
Packit |
5c3484 |
/* if there's a showbase on the denominator, then print the numerator
|
|
Packit |
5c3484 |
separately so it can be inserted */
|
|
Packit |
5c3484 |
if (den_showbaselen != 0)
|
|
Packit |
5c3484 |
{
|
|
Packit |
5c3484 |
ASSERT (slash != NULL);
|
|
Packit |
5c3484 |
slashlen = slash+1 - s;
|
|
Packit |
5c3484 |
DOPRNT_MEMORY (s, slashlen); /* numerator and slash */
|
|
Packit |
5c3484 |
slen -= slashlen;
|
|
Packit |
5c3484 |
s += slashlen;
|
|
Packit |
5c3484 |
DOPRNT_MEMORY (showbase, den_showbaselen);
|
|
Packit |
5c3484 |
}
|
|
Packit |
5c3484 |
|
|
Packit |
5c3484 |
DOPRNT_MEMORY (s, slen); /* number, or denominator */
|
|
Packit |
5c3484 |
|
|
Packit |
5c3484 |
if (justify == DOPRNT_JUSTIFY_LEFT) /* pad left */
|
|
Packit |
5c3484 |
DOPRNT_REPS (p->fill, justlen);
|
|
Packit |
5c3484 |
|
|
Packit |
5c3484 |
done:
|
|
Packit |
5c3484 |
return retval;
|
|
Packit |
5c3484 |
|
|
Packit |
5c3484 |
error:
|
|
Packit |
5c3484 |
retval = -1;
|
|
Packit |
5c3484 |
goto done;
|
|
Packit |
5c3484 |
}
|