2006-04-21 Yoshinori K. Okuji <okuji@enbug.org>
* kern/misc.c (grub_lltoa): New function. (grub_vsprintf): Added support for the long long suffix, i.e. "ll".
This commit is contained in:
parent
ff04ec24e9
commit
970d3b8ab0
2 changed files with 81 additions and 6 deletions
|
@ -1,3 +1,9 @@
|
|||
2006-04-21 Yoshinori K. Okuji <okuji@enbug.org>
|
||||
|
||||
* kern/misc.c (grub_lltoa): New function.
|
||||
(grub_vsprintf): Added support for the long long suffix,
|
||||
i.e. "ll".
|
||||
|
||||
2006-04-20 Hollis Blanchard <hollis@penguinppc.org>
|
||||
|
||||
* Makefile.in (LDFLAGS): Add variable.
|
||||
|
|
81
kern/misc.c
81
kern/misc.c
|
@ -499,6 +499,58 @@ grub_itoa (char *str, int c, unsigned n)
|
|||
return p;
|
||||
}
|
||||
|
||||
/* Convert a long long value to a string. This function avoids 64-bit
|
||||
modular arithmetic or divisions. */
|
||||
static char *
|
||||
grub_lltoa (char *str, int c, unsigned long long n)
|
||||
{
|
||||
unsigned base = (c == 'x') ? 16 : 10;
|
||||
char *p;
|
||||
|
||||
if ((long long) n < 0 && c == 'd')
|
||||
{
|
||||
n = (unsigned long long) (-((long long) n));
|
||||
*str++ = '-';
|
||||
}
|
||||
|
||||
p = str;
|
||||
|
||||
if (base == 16)
|
||||
do
|
||||
{
|
||||
unsigned d = (unsigned) (n & 0xf);
|
||||
*p++ = (d > 9) ? d + 'a' - 10 : d + '0';
|
||||
}
|
||||
while (n >>= 4);
|
||||
else
|
||||
/* BASE == 10 */
|
||||
do
|
||||
{
|
||||
unsigned high, low;
|
||||
unsigned high_mod, low_mod;
|
||||
unsigned d;
|
||||
|
||||
high = (unsigned) (n >> 32);
|
||||
low = (unsigned) (n & 0xffffffff);
|
||||
high_mod = high % 10;
|
||||
low_mod = low % 10;
|
||||
/* 6 = (1 << 32) % 10 */
|
||||
d = (high_mod * 6 + low_mod) % 10;
|
||||
*p++ = d + '0';
|
||||
|
||||
/* (HIGH_MOD << 31) / 5 = (HIGH_MOD << 32) / 10 */
|
||||
n = (((unsigned long long) (high / 10) << 32)
|
||||
+ ((high_mod << 31) / 5)
|
||||
+ low_mod / 10);
|
||||
}
|
||||
while (n);
|
||||
|
||||
*p = 0;
|
||||
|
||||
grub_reverse (str);
|
||||
return p;
|
||||
}
|
||||
|
||||
static char *
|
||||
grub_ftoa (char *str, double f, int round)
|
||||
{
|
||||
|
@ -555,7 +607,7 @@ grub_vsprintf (char *str, const char *fmt, va_list args)
|
|||
write_char (c);
|
||||
else
|
||||
{
|
||||
char tmp[16];
|
||||
char tmp[32];
|
||||
char *p;
|
||||
unsigned int format1 = 0;
|
||||
unsigned int format2 = 3;
|
||||
|
@ -563,6 +615,7 @@ grub_vsprintf (char *str, const char *fmt, va_list args)
|
|||
int rightfill = 0;
|
||||
int n;
|
||||
int longfmt = 0;
|
||||
int longlongfmt = 0;
|
||||
|
||||
if (*fmt && *fmt =='-')
|
||||
{
|
||||
|
@ -606,6 +659,11 @@ grub_vsprintf (char *str, const char *fmt, va_list args)
|
|||
{
|
||||
longfmt = 1;
|
||||
c = *fmt++;
|
||||
if (c == 'l')
|
||||
{
|
||||
longlongfmt = 1;
|
||||
c = *fmt++;
|
||||
}
|
||||
}
|
||||
|
||||
switch (c)
|
||||
|
@ -613,16 +671,27 @@ grub_vsprintf (char *str, const char *fmt, va_list args)
|
|||
case 'p':
|
||||
write_str ("0x");
|
||||
c = 'x';
|
||||
longlongfmt = (sizeof (void *) == sizeof (long long));
|
||||
/* fall through */
|
||||
case 'x':
|
||||
case 'u':
|
||||
case 'd':
|
||||
if (longfmt)
|
||||
n = va_arg (args, long);
|
||||
if (longlongfmt)
|
||||
{
|
||||
long long ll;
|
||||
|
||||
ll = va_arg (args, long long);
|
||||
grub_lltoa (tmp, c, ll);
|
||||
}
|
||||
else
|
||||
n = va_arg (args, int);
|
||||
grub_itoa (tmp, c, n);
|
||||
if (!rightfill && grub_strlen (tmp) < format1)
|
||||
{
|
||||
if (longfmt)
|
||||
n = va_arg (args, long);
|
||||
else
|
||||
n = va_arg (args, int);
|
||||
grub_itoa (tmp, c, n);
|
||||
}
|
||||
if (! rightfill && grub_strlen (tmp) < format1)
|
||||
write_fill (zerofill, format1 - grub_strlen (tmp));
|
||||
write_str (tmp);
|
||||
if (rightfill && grub_strlen (tmp) < format1)
|
||||
|
|
Loading…
Reference in a new issue