asprintf and snprintf support
This commit is contained in:
parent
c181849b95
commit
8b442f3f4c
60 changed files with 396 additions and 345 deletions
71
kern/misc.c
71
kern/misc.c
|
@ -25,6 +25,9 @@
|
|||
#include <grub/env.h>
|
||||
#include <grub/i18n.h>
|
||||
|
||||
static int
|
||||
grub_vsnprintf_real (char *str, grub_size_t n, const char *fmt, va_list args);
|
||||
|
||||
static int
|
||||
grub_iswordseparator (int c)
|
||||
{
|
||||
|
@ -202,7 +205,7 @@ grub_vprintf (const char *fmt, va_list args)
|
|||
{
|
||||
int ret;
|
||||
|
||||
ret = grub_vsprintf (0, fmt, args);
|
||||
ret = grub_vsnprintf_real (0, 0, fmt, args);
|
||||
grub_refresh ();
|
||||
return ret;
|
||||
}
|
||||
|
@ -626,11 +629,11 @@ grub_lltoa (char *str, int c, unsigned long long n)
|
|||
return p;
|
||||
}
|
||||
|
||||
int
|
||||
grub_vsprintf (char *str, const char *fmt, va_list args)
|
||||
static int
|
||||
grub_vsnprintf_real (char *str, grub_size_t n, const char *fmt, va_list args)
|
||||
{
|
||||
char c;
|
||||
int count = 0;
|
||||
grub_size_t count = 0;
|
||||
auto void write_char (unsigned char ch);
|
||||
auto void write_str (const char *s);
|
||||
auto void write_fill (const char ch, int n);
|
||||
|
@ -638,7 +641,10 @@ grub_vsprintf (char *str, const char *fmt, va_list args)
|
|||
void write_char (unsigned char ch)
|
||||
{
|
||||
if (str)
|
||||
*str++ = ch;
|
||||
{
|
||||
if (count < n)
|
||||
*str++ = ch;
|
||||
}
|
||||
else
|
||||
grub_putchar (ch);
|
||||
|
||||
|
@ -867,13 +873,64 @@ grub_vsprintf (char *str, const char *fmt, va_list args)
|
|||
}
|
||||
|
||||
int
|
||||
grub_sprintf (char *str, const char *fmt, ...)
|
||||
grub_vsnprintf (char *str, grub_size_t n, const char *fmt, va_list ap)
|
||||
{
|
||||
grub_size_t ret;
|
||||
|
||||
if (!n)
|
||||
return 0;
|
||||
|
||||
n--;
|
||||
|
||||
ret = grub_vsnprintf_real (str, n, fmt, ap);
|
||||
|
||||
return ret < n ? ret : n;
|
||||
}
|
||||
|
||||
int
|
||||
grub_snprintf (char *str, grub_size_t n, const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
int ret;
|
||||
|
||||
va_start (ap, fmt);
|
||||
ret = grub_vsprintf (str, fmt, ap);
|
||||
ret = grub_vsnprintf (str, n, fmt, ap);
|
||||
va_end (ap);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
#define PREALLOC_SIZE 255
|
||||
|
||||
char *
|
||||
grub_avsprintf (const char *fmt, va_list ap)
|
||||
{
|
||||
grub_size_t s, as = PREALLOC_SIZE;
|
||||
char *ret;
|
||||
|
||||
while (1)
|
||||
{
|
||||
ret = grub_malloc (as + 1);
|
||||
if (!ret)
|
||||
return NULL;
|
||||
|
||||
s = grub_vsnprintf (ret, as, fmt, ap);
|
||||
if (s <= as)
|
||||
return ret;
|
||||
|
||||
grub_free (ret);
|
||||
as = s;
|
||||
}
|
||||
}
|
||||
|
||||
char *
|
||||
grub_asprintf (const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
char *ret;
|
||||
|
||||
va_start (ap, fmt);
|
||||
ret = grub_avsprintf (fmt, ap);
|
||||
va_end (ap);
|
||||
|
||||
return ret;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue