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);
191
#define PREALLOC_SIZE 255
194
grub_vprintf (const char *fmt, va_list args)
197
static char buf[PREALLOC_SIZE + 1];
202
s = grub_vsnprintf_real (buf, PREALLOC_SIZE, fmt, args);
203
if (s > PREALLOC_SIZE)
205
curbuf = grub_malloc (s + 1);
208
grub_errno = GRUB_ERR_NONE;
209
buf[PREALLOC_SIZE - 3] = '.';
210
buf[PREALLOC_SIZE - 2] = '.';
211
buf[PREALLOC_SIZE - 1] = '.';
212
buf[PREALLOC_SIZE] = 0;
215
s = grub_vsnprintf_real (curbuf, s, fmt, ap2);
227
grub_memcmp (const void *s1, const void *s2, grub_size_t n)
235
return (int) *t1 - (int) *t2;
244
int memcmp (const void *s1, const void *s2, grub_size_t n)
245
__attribute__ ((alias ("grub_memcmp")));
247
int memcmp (const void *s1, const void *s2, grub_size_t n)
249
return grub_memcmp (s1, s2, n);
254
grub_strcmp (const char *s1, const char *s2)
265
return (int) *s1 - (int) *s2;
269
grub_strncmp (const char *s1, const char *s2, grub_size_t n)
274
while (*s1 && *s2 && --n)
283
return (int) *s1 - (int) *s2;
287
grub_strchr (const char *s, int c)
300
grub_strrchr (const char *s, int c)
314
/* Copied from gnulib.
315
Written by Bruno Haible <bruno@clisp.org>, 2005. */
317
grub_strstr (const char *haystack, const char *needle)
319
/* Be careful not to look at the entire extent of haystack or needle
320
until needed. This is useful because of these two cases:
321
- haystack may be very long, and a match of needle found early,
322
- needle may be very long, and not even a short initial segment of
323
needle may be found in haystack. */
326
/* Speed up the following searches of needle by caching its first
332
if (*haystack == '\0')
336
/* The first character matches. */
338
const char *rhaystack = haystack + 1;
339
const char *rneedle = needle;
341
for (;; rhaystack++, rneedle++)
343
if (*rneedle == '\0')
345
return (char *) haystack;
346
if (*rhaystack == '\0')
349
if (*rhaystack != *rneedle)
350
/* Nothing in this round. */
357
return (char *) haystack;
361
grub_strword (const char *haystack, const char *needle)
363
const char *n_pos = needle;
365
while (grub_iswordseparator (*haystack))
370
/* Crawl both the needle and the haystack word we're on. */
371
while(*haystack && !grub_iswordseparator (*haystack)
372
&& *haystack == *n_pos)
378
/* If we reached the end of both words at the same time, the word
379
is found. If not, eat everything in the haystack that isn't the
380
next word (or the end of string) and "reset" the needle. */
381
if ( (!*haystack || grub_iswordseparator (*haystack))
382
&& (!*n_pos || grub_iswordseparator (*n_pos)))
387
while (*haystack && !grub_iswordseparator (*haystack))
389
while (grub_iswordseparator (*haystack))
400
return (c == '\n' || c == '\r' || c == ' ' || c == '\t');
406
return (c >= ' ' && c <= '~');
411
grub_strtoul (const char *str, char **end, int base)
413
unsigned long long num;
415
num = grub_strtoull (str, end, base);
418
grub_error (GRUB_ERR_OUT_OF_RANGE, "overflow is detected");
422
return (unsigned long) num;
426
grub_strtoull (const char *str, char **end, int base)
428
unsigned long long num = 0;
431
/* Skip white spaces. */
432
while (*str && grub_isspace (*str))
435
/* Guess the base, if not specified. The prefix `0x' means 16, and
436
the prefix `0' means 8. */
441
if (base == 0 || base == 16)
447
else if (base == 0 && str[1] >= '0' && str[1] <= '7')
458
digit = grub_tolower (*str) - '0';
461
digit += '0' - 'a' + 10;
462
if (digit >= (unsigned long) base)
468
/* NUM * BASE + DIGIT > ~0ULL */
469
if (num > grub_divmod64 (~0ULL - digit, base, 0))
471
grub_error (GRUB_ERR_OUT_OF_RANGE, "overflow is detected");
475
num = num * base + digit;
481
grub_error (GRUB_ERR_BAD_NUMBER, "unrecognized number");
492
grub_strdup (const char *s)
497
len = grub_strlen (s) + 1;
498
p = (char *) grub_malloc (len);
502
return grub_memcpy (p, s, len);
506
grub_strndup (const char *s, grub_size_t n)
511
len = grub_strlen (s);
514
p = (char *) grub_malloc (len + 1);
518
grub_memcpy (p, s, len);
524
grub_memset (void *s, int c, grub_size_t len)
527
grub_uint8_t pattern8 = c;
529
if (len >= 3 * sizeof (unsigned long))
531
unsigned long patternl = 0;
534
for (i = 0; i < sizeof (unsigned long); i++)
535
patternl |= ((unsigned long) pattern8) << (8 * i);
537
while (len > 0 && (((grub_addr_t) p) & (sizeof (unsigned long) - 1)))
539
*(grub_uint8_t *) p = pattern8;
540
p = (grub_uint8_t *) p + 1;
543
while (len >= sizeof (unsigned long))
545
*(unsigned long *) p = patternl;
546
p = (unsigned long *) p + 1;
547
len -= sizeof (unsigned long);
553
*(grub_uint8_t *) p = pattern8;
554
p = (grub_uint8_t *) p + 1;
561
void *memset (void *s, int c, grub_size_t n)
562
__attribute__ ((alias ("grub_memset")));
564
void *memset (void *s, int c, grub_size_t n)
566
return grub_memset (s, c, n);
571
grub_strlen (const char *s)
582
grub_reverse (char *str)
584
char *p = str + grub_strlen (str) - 1;
598
/* Divide N by D, return the quotient, and store the remainder in *R. */
600
grub_divmod64 (grub_uint64_t n, grub_uint32_t d, grub_uint32_t *r)
602
/* This algorithm is typically implemented by hardware. The idea
603
is to get the highest bit in N, 64 times, by keeping
604
upper(N * 2^i) = upper((Q * 10 + M) * 2^i), where upper
605
represents the high 64 bits in 128-bits space. */
607
unsigned long long q = 0;
610
/* Skip the slow computation if 32-bit arithmetic is possible. */
614
*r = ((grub_uint32_t) n) % d;
616
return ((grub_uint32_t) n) / d;
623
if (n & (1ULL << 63))
642
/* Convert a long long value to a string. This function avoids 64-bit
643
modular arithmetic or divisions. */
645
grub_lltoa (char *str, int c, unsigned long long n)
647
unsigned base = (c == 'x') ? 16 : 10;
650
if ((long long) n < 0 && c == 'd')
652
n = (unsigned long long) (-((long long) n));
661
unsigned d = (unsigned) (n & 0xf);
662
*p++ = (d > 9) ? d + 'a' - 10 : d + '0';
671
n = grub_divmod64 (n, 10, &m);
683
grub_vsnprintf_real (char *str, grub_size_t max_len, const char *fmt, va_list args)
686
grub_size_t count = 0;
687
auto void write_char (unsigned char ch);
688
auto void write_str (const char *s);
689
auto void write_fill (const char ch, int n);
691
void write_char (unsigned char ch)
699
void write_str (const char *s)
705
void write_fill (const char ch, int n)
708
for (i = 0; i < n; i++)
712
while ((c = *fmt++) != 0)
720
unsigned int format1 = 0;
721
unsigned int format2 = ~ 0U;
729
if (*fmt && *fmt =='-')
736
/* Read formatting parameters. */
737
while (*p && grub_isdigit (*p))
743
grub_strncpy (s, fmt, p - fmt);
747
format1 = grub_strtoul (s, 0, 10);
755
while (*p && grub_isdigit (*p))
760
char fstr[p - fmt + 1];
761
grub_strncpy (fstr, fmt, p - fmt);
763
format2 = grub_strtoul (fstr, 0, 10);
785
longlongfmt |= (sizeof (void *) == sizeof (long long));
796
ll = va_arg (args, long long);
797
grub_lltoa (tmp, c, ll);
799
else if (longfmt && unsig)
801
unsigned long l = va_arg (args, unsigned long);
802
grub_lltoa (tmp, c, l);
806
long l = va_arg (args, long);
807
grub_lltoa (tmp, c, l);
811
unsigned u = va_arg (args, unsigned);
812
grub_lltoa (tmp, c, u);
816
n = va_arg (args, int);
817
grub_lltoa (tmp, c, n);
819
if (! rightfill && grub_strlen (tmp) < format1)
820
write_fill (zerofill, format1 - grub_strlen (tmp));
822
if (rightfill && grub_strlen (tmp) < format1)
823
write_fill (zerofill, format1 - grub_strlen (tmp));
827
n = va_arg (args, int);
828
write_char (n & 0xff);
833
grub_uint32_t code = va_arg (args, grub_uint32_t);
842
else if (code <= 0x7ff)
847
else if (code <= 0xffff)
852
else if (code <= 0x1fffff)
857
else if (code <= 0x3ffffff)
862
else if (code <= 0x7fffffff)
874
write_char (mask | (code >> shift));
876
for (shift -= 6; shift >= 0; shift -= 6)
877
write_char (0x80 | (0x3f & (code >> shift)));
882
p = va_arg (args, char *);
886
while (len < format2 && p[len])
889
if (!rightfill && len < format1)
890
write_fill (zerofill, format1 - len);
893
for (i = 0; i < len; i++)
896
if (rightfill && len < format1)
897
write_fill (zerofill, format1 - len);
900
write_str ("(null)");
917
grub_vsnprintf (char *str, grub_size_t n, const char *fmt, va_list ap)
926
ret = grub_vsnprintf_real (str, n, fmt, ap);
928
return ret < n ? ret : n;
932
grub_snprintf (char *str, grub_size_t n, const char *fmt, ...)
938
ret = grub_vsnprintf (str, n, fmt, ap);
945
grub_xvasprintf (const char *fmt, va_list ap)
947
grub_size_t s, as = PREALLOC_SIZE;
954
ret = grub_malloc (as + 1);
958
s = grub_vsnprintf_real (ret, as, fmt, ap2);
968
grub_xasprintf (const char *fmt, ...)
974
ret = grub_xvasprintf (fmt, ap);
980
/* Abort GRUB. This function does not return. */
984
grub_printf ("\nAborted.");
987
if (grub_term_inputs)
990
grub_printf (" Press any key to exit.");
997
#if ! defined (APPLE_CC) && !defined (GRUB_UTIL)
998
/* GCC emits references to abort(). */
999
void abort (void) __attribute__ ((alias ("grub_abort")));
1002
#if NEED_ENABLE_EXECUTE_STACK && !defined(GRUB_UTIL) && !defined(GRUB_MACHINE_EMU)
1003
/* Some gcc versions generate a call to this function
1004
in trampolines for nested functions. */
1005
void __enable_execute_stack (void *addr __attribute__ ((unused)))
1010
#if NEED_REGISTER_FRAME_INFO && !defined(GRUB_UTIL)
1011
void __register_frame_info (void)
1015
void __deregister_frame_info (void)