1
/* misc.c - definitions of misc functions */
3
* GRUB -- GRand Unified Bootloader
4
* Copyright (C) 1999,2000,2001,2002,2003,2004,2005,2006,2007,2008,2009,2010 Free Software Foundation, Inc.
6
* GRUB is free software: you can redistribute it and/or modify
7
* it under the terms of the GNU General Public License as published by
8
* the Free Software Foundation, either version 3 of the License, or
9
* (at your option) any later version.
11
* GRUB is distributed in the hope that it will be useful,
12
* but WITHOUT ANY WARRANTY; without even the implied warranty of
13
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
* GNU General Public License for more details.
16
* You should have received a copy of the GNU General Public License
17
* along with GRUB. If not, see <http://www.gnu.org/licenses/>.
20
#include <grub/misc.h>
24
#include <grub/term.h>
26
#include <grub/i18n.h>
29
grub_vsnprintf_real (char *str, grub_size_t n, const char *fmt, va_list args);
32
grub_iswordseparator (int c)
34
return (grub_isspace (c) || c == ',' || c == ';' || c == '|' || c == '&');
37
/* grub_gettext_dummy is not translating anything. */
39
grub_gettext_dummy (const char *s)
44
const char* (*grub_gettext) (const char *s) = grub_gettext_dummy;
47
grub_memmove (void *dest, const void *src, grub_size_t n)
49
char *d = (char *) dest;
50
const char *s = (const char *) src;
68
void *memmove (void *dest, const void *src, grub_size_t n)
69
__attribute__ ((alias ("grub_memmove")));
70
/* GCC emits references to memcpy() for struct copies etc. */
71
void *memcpy (void *dest, const void *src, grub_size_t n)
72
__attribute__ ((alias ("grub_memmove")));
74
void *memcpy (void *dest, const void *src, grub_size_t n)
76
return grub_memmove (dest, src, n);
78
void *memmove (void *dest, const void *src, grub_size_t n)
80
return grub_memmove (dest, src, n);
85
grub_strcpy (char *dest, const char *src)
89
while ((*p++ = *src++) != '\0')
96
grub_strncpy (char *dest, const char *src, int c)
100
while ((*p++ = *src++) != '\0' && --c)
107
grub_stpcpy (char *dest, const char *src)
114
while (*s++ != '\0');
120
grub_printf (const char *fmt, ...)
126
ret = grub_vprintf (fmt, ap);
133
grub_printf_ (const char *fmt, ...)
139
ret = grub_vprintf (_(fmt), ap);
146
grub_puts_ (const char *s)
148
return grub_puts (_(s));
151
#if defined (APPLE_CC) && ! defined (GRUB_UTIL)
153
grub_err_printf (const char *fmt, ...)
159
ret = grub_vprintf (fmt, ap);
166
#if ! defined (APPLE_CC) && ! defined (GRUB_UTIL)
167
int grub_err_printf (const char *fmt, ...)
168
__attribute__ ((alias("grub_printf")));
172
grub_real_dprintf (const char *file, const int line, const char *condition,
173
const char *fmt, ...)
176
const char *debug = grub_env_get ("debug");
181
if (grub_strword (debug, "all") || grub_strword (debug, condition))
183
grub_printf ("%s:%d: ", file, line);
184
va_start (args, fmt);
185
grub_vprintf (fmt, args);
190
#define PREALLOC_SIZE 255
193
grub_vprintf (const char *fmt, va_list args)
196
static char buf[PREALLOC_SIZE + 1];
199
s = grub_vsnprintf_real (buf, PREALLOC_SIZE, fmt, args);
200
if (s > PREALLOC_SIZE)
202
curbuf = grub_malloc (s + 1);
205
grub_errno = GRUB_ERR_NONE;
206
buf[PREALLOC_SIZE - 3] = '.';
207
buf[PREALLOC_SIZE - 2] = '.';
208
buf[PREALLOC_SIZE - 1] = '.';
209
buf[PREALLOC_SIZE] = 0;
212
s = grub_vsnprintf_real (curbuf, s, fmt, args);
224
grub_memcmp (const void *s1, const void *s2, grub_size_t n)
232
return (int) *t1 - (int) *t2;
241
int memcmp (const void *s1, const void *s2, grub_size_t n)
242
__attribute__ ((alias ("grub_memcmp")));
244
int memcmp (const void *s1, const void *s2, grub_size_t n)
246
return grub_memcmp (s1, s2, n);
251
grub_strcmp (const char *s1, const char *s2)
262
return (int) *s1 - (int) *s2;
266
grub_strncmp (const char *s1, const char *s2, grub_size_t n)
271
while (*s1 && *s2 && --n)
280
return (int) *s1 - (int) *s2;
284
grub_strchr (const char *s, int c)
297
grub_strrchr (const char *s, int c)
311
/* Copied from gnulib.
312
Written by Bruno Haible <bruno@clisp.org>, 2005. */
314
grub_strstr (const char *haystack, const char *needle)
316
/* Be careful not to look at the entire extent of haystack or needle
317
until needed. This is useful because of these two cases:
318
- haystack may be very long, and a match of needle found early,
319
- needle may be very long, and not even a short initial segment of
320
needle may be found in haystack. */
323
/* Speed up the following searches of needle by caching its first
329
if (*haystack == '\0')
333
/* The first character matches. */
335
const char *rhaystack = haystack + 1;
336
const char *rneedle = needle;
338
for (;; rhaystack++, rneedle++)
340
if (*rneedle == '\0')
342
return (char *) haystack;
343
if (*rhaystack == '\0')
346
if (*rhaystack != *rneedle)
347
/* Nothing in this round. */
354
return (char *) haystack;
358
grub_strword (const char *haystack, const char *needle)
360
const char *n_pos = needle;
362
while (grub_iswordseparator (*haystack))
367
/* Crawl both the needle and the haystack word we're on. */
368
while(*haystack && !grub_iswordseparator (*haystack)
369
&& *haystack == *n_pos)
375
/* If we reached the end of both words at the same time, the word
376
is found. If not, eat everything in the haystack that isn't the
377
next word (or the end of string) and "reset" the needle. */
378
if ( (!*haystack || grub_iswordseparator (*haystack))
379
&& (!*n_pos || grub_iswordseparator (*n_pos)))
384
while (*haystack && !grub_iswordseparator (*haystack))
386
while (grub_iswordseparator (*haystack))
397
return (c == '\n' || c == '\r' || c == ' ' || c == '\t');
403
return (c >= ' ' && c <= '~');
408
grub_strtoul (const char *str, char **end, int base)
410
unsigned long long num;
412
num = grub_strtoull (str, end, base);
415
grub_error (GRUB_ERR_OUT_OF_RANGE, "overflow is detected");
419
return (unsigned long) num;
423
grub_strtoull (const char *str, char **end, int base)
425
unsigned long long num = 0;
428
/* Skip white spaces. */
429
while (*str && grub_isspace (*str))
432
/* Guess the base, if not specified. The prefix `0x' means 16, and
433
the prefix `0' means 8. */
438
if (base == 0 || base == 16)
444
else if (base == 0 && str[1] >= '0' && str[1] <= '7')
455
digit = grub_tolower (*str) - '0';
458
digit += '0' - 'a' + 10;
459
if (digit >= (unsigned long) base)
465
/* NUM * BASE + DIGIT > ~0ULL */
466
if (num > grub_divmod64 (~0ULL - digit, base, 0))
468
grub_error (GRUB_ERR_OUT_OF_RANGE, "overflow is detected");
472
num = num * base + digit;
478
grub_error (GRUB_ERR_BAD_NUMBER, "unrecognized number");
489
grub_strdup (const char *s)
494
len = grub_strlen (s) + 1;
495
p = (char *) grub_malloc (len);
499
return grub_memcpy (p, s, len);
503
grub_strndup (const char *s, grub_size_t n)
508
len = grub_strlen (s);
511
p = (char *) grub_malloc (len + 1);
515
grub_memcpy (p, s, len);
521
grub_memset (void *s, int c, grub_size_t len)
524
grub_uint8_t pattern8 = c;
526
if (len >= 3 * sizeof (unsigned long))
528
unsigned long patternl = 0;
531
for (i = 0; i < sizeof (unsigned long); i++)
532
patternl |= ((unsigned long) pattern8) << (8 * i);
534
while (len > 0 && (((grub_addr_t) p) & (sizeof (unsigned long) - 1)))
536
*(grub_uint8_t *) p = pattern8;
537
p = (grub_uint8_t *) p + 1;
540
while (len >= sizeof (unsigned long))
542
*(unsigned long *) p = patternl;
543
p = (unsigned long *) p + 1;
544
len -= sizeof (unsigned long);
550
*(grub_uint8_t *) p = pattern8;
551
p = (grub_uint8_t *) p + 1;
558
void *memset (void *s, int c, grub_size_t n)
559
__attribute__ ((alias ("grub_memset")));
561
void *memset (void *s, int c, grub_size_t n)
563
return grub_memset (s, c, n);
568
grub_strlen (const char *s)
579
grub_reverse (char *str)
581
char *p = str + grub_strlen (str) - 1;
595
/* Divide N by D, return the quotient, and store the remainder in *R. */
597
grub_divmod64 (grub_uint64_t n, grub_uint32_t d, grub_uint32_t *r)
599
/* This algorithm is typically implemented by hardware. The idea
600
is to get the highest bit in N, 64 times, by keeping
601
upper(N * 2^i) = upper((Q * 10 + M) * 2^i), where upper
602
represents the high 64 bits in 128-bits space. */
604
unsigned long long q = 0;
607
/* Skip the slow computation if 32-bit arithmetic is possible. */
611
*r = ((grub_uint32_t) n) % d;
613
return ((grub_uint32_t) n) / d;
620
if (n & (1ULL << 63))
639
/* Convert a long long value to a string. This function avoids 64-bit
640
modular arithmetic or divisions. */
642
grub_lltoa (char *str, int c, unsigned long long n)
644
unsigned base = (c == 'x') ? 16 : 10;
647
if ((long long) n < 0 && c == 'd')
649
n = (unsigned long long) (-((long long) n));
658
unsigned d = (unsigned) (n & 0xf);
659
*p++ = (d > 9) ? d + 'a' - 10 : d + '0';
668
n = grub_divmod64 (n, 10, &m);
680
grub_vsnprintf_real (char *str, grub_size_t max_len, const char *fmt, va_list args)
683
grub_size_t count = 0;
684
auto void write_char (unsigned char ch);
685
auto void write_str (const char *s);
686
auto void write_fill (const char ch, int n);
688
void write_char (unsigned char ch)
696
void write_str (const char *s)
702
void write_fill (const char ch, int n)
705
for (i = 0; i < n; i++)
709
while ((c = *fmt++) != 0)
717
unsigned int format1 = 0;
718
unsigned int format2 = ~ 0U;
726
if (*fmt && *fmt =='-')
733
/* Read formatting parameters. */
734
while (*p && grub_isdigit (*p))
740
grub_strncpy (s, fmt, p - fmt);
744
format1 = grub_strtoul (s, 0, 10);
752
while (*p && grub_isdigit (*p))
757
char fstr[p - fmt + 1];
758
grub_strncpy (fstr, fmt, p - fmt);
760
format2 = grub_strtoul (fstr, 0, 10);
782
longlongfmt |= (sizeof (void *) == sizeof (long long));
793
ll = va_arg (args, long long);
794
grub_lltoa (tmp, c, ll);
796
else if (longfmt && unsig)
798
unsigned long l = va_arg (args, unsigned long);
799
grub_lltoa (tmp, c, l);
803
long l = va_arg (args, long);
804
grub_lltoa (tmp, c, l);
808
unsigned u = va_arg (args, unsigned);
809
grub_lltoa (tmp, c, u);
813
n = va_arg (args, int);
814
grub_lltoa (tmp, c, n);
816
if (! rightfill && grub_strlen (tmp) < format1)
817
write_fill (zerofill, format1 - grub_strlen (tmp));
819
if (rightfill && grub_strlen (tmp) < format1)
820
write_fill (zerofill, format1 - grub_strlen (tmp));
824
n = va_arg (args, int);
825
write_char (n & 0xff);
830
grub_uint32_t code = va_arg (args, grub_uint32_t);
839
else if (code <= 0x7ff)
844
else if (code <= 0xffff)
849
else if (code <= 0x1fffff)
854
else if (code <= 0x3ffffff)
859
else if (code <= 0x7fffffff)
871
write_char (mask | (code >> shift));
873
for (shift -= 6; shift >= 0; shift -= 6)
874
write_char (0x80 | (0x3f & (code >> shift)));
879
p = va_arg (args, char *);
883
while (len < format2 && p[len])
886
if (!rightfill && len < format1)
887
write_fill (zerofill, format1 - len);
890
for (i = 0; i < len; i++)
893
if (rightfill && len < format1)
894
write_fill (zerofill, format1 - len);
897
write_str ("(null)");
914
grub_vsnprintf (char *str, grub_size_t n, const char *fmt, va_list ap)
923
ret = grub_vsnprintf_real (str, n, fmt, ap);
925
return ret < n ? ret : n;
929
grub_snprintf (char *str, grub_size_t n, const char *fmt, ...)
935
ret = grub_vsnprintf (str, n, fmt, ap);
942
grub_xvasprintf (const char *fmt, va_list ap)
944
grub_size_t s, as = PREALLOC_SIZE;
949
ret = grub_malloc (as + 1);
953
s = grub_vsnprintf_real (ret, as, fmt, ap);
963
grub_xasprintf (const char *fmt, ...)
969
ret = grub_xvasprintf (fmt, ap);
975
/* Abort GRUB. This function does not return. */
979
grub_printf ("\nAborted.");
982
if (grub_term_inputs)
985
grub_printf (" Press any key to exit.");
993
/* GCC emits references to abort(). */
994
void abort (void) __attribute__ ((alias ("grub_abort")));
997
#if defined(NEED_ENABLE_EXECUTE_STACK) && !defined(GRUB_UTIL) && !defined(GRUB_MACHINE_EMU)
998
/* Some gcc versions generate a call to this function
999
in trampolines for nested functions. */
1000
void __enable_execute_stack (void *addr __attribute__ ((unused)))
1005
#if defined (NEED_REGISTER_FRAME_INFO) && !defined(GRUB_UTIL)
1006
void __register_frame_info (void)
1010
void __deregister_frame_info (void)