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 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>
28 grub_memmove (void *dest
, const void *src
, grub_size_t n
)
30 char *d
= (char *) dest
;
31 const char *s
= (const char *) src
;
49 void *memmove (void *dest
, const void *src
, grub_size_t n
)
50 __attribute__ ((alias ("grub_memmove")));
51 /* GCC emits references to memcpy() for struct copies etc. */
52 void *memcpy (void *dest
, const void *src
, grub_size_t n
)
53 __attribute__ ((alias ("grub_memmove")));
55 void *memcpy (void *dest
, const void *src
, grub_size_t n
)
57 return grub_memmove (dest
, src
, n
);
59 void *memmove (void *dest
, const void *src
, grub_size_t n
)
61 return grub_memmove (dest
, src
, n
);
66 grub_strcpy (char *dest
, const char *src
)
70 while ((*p
++ = *src
++) != '\0')
77 grub_strncpy (char *dest
, const char *src
, int c
)
81 while ((*p
++ = *src
++) != '\0' && --c
)
88 grub_stpcpy (char *dest
, const char *src
)
101 grub_strcat (char *dest
, const char *src
)
108 while ((*p
= *src
) != '\0')
118 grub_strncat (char *dest
, const char *src
, int c
)
125 while ((*p
= *src
) != '\0' && c
--)
137 grub_printf (const char *fmt
, ...)
143 ret
= grub_vprintf (fmt
, ap
);
149 #if defined (APPLE_CC) && ! defined (GRUB_UTIL)
151 grub_err_printf (const char *fmt
, ...)
157 ret
= grub_vprintf (fmt
, ap
);
164 #if ! defined (APPLE_CC) && ! defined (GRUB_UTIL)
165 int grub_err_printf (const char *fmt
, ...)
166 __attribute__ ((alias("grub_printf")));
170 grub_real_dprintf (const char *file
, const int line
, const char *condition
,
171 const char *fmt
, ...)
174 const char *debug
= grub_env_get ("debug");
179 if (grub_strword (debug
, "all") || grub_strword (debug
, condition
))
181 grub_printf ("%s:%d: ", file
, line
);
182 va_start (args
, fmt
);
183 grub_vprintf (fmt
, args
);
189 grub_vprintf (const char *fmt
, va_list args
)
193 ret
= grub_vsprintf (0, fmt
, args
);
199 grub_memcmp (const void *s1
, const void *s2
, grub_size_t n
)
207 return (int) *t1
- (int) *t2
;
216 int memcmp (const void *s1
, const void *s2
, grub_size_t n
)
217 __attribute__ ((alias ("grub_memcmp")));
221 grub_strcmp (const char *s1
, const char *s2
)
232 return (int) *s1
- (int) *s2
;
236 grub_strncmp (const char *s1
, const char *s2
, grub_size_t n
)
241 while (*s1
&& *s2
&& --n
)
250 return (int) *s1
- (int) *s2
;
254 grub_strcasecmp (const char *s1
, const char *s2
)
258 if (grub_tolower (*s1
) != grub_tolower (*s2
))
265 return (int) grub_tolower (*s1
) - (int) grub_tolower (*s2
);
269 grub_strncasecmp (const char *s1
, const char *s2
, grub_size_t n
)
274 while (*s1
&& *s2
&& --n
)
276 if (grub_tolower (*s1
) != grub_tolower (*s2
))
283 return (int) grub_tolower (*s1
) - (int) grub_tolower (*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
))
398 grub_iswordseparator (int c
)
400 return (grub_isspace (c
) || c
== ',' || c
== ';' || c
== '|' || c
== '&');
406 return (c
== '\n' || c
== '\r' || c
== ' ' || c
== '\t');
412 return (c
>= 0x00 && c
<= 0x1F) || c
== 0x7F;
418 return (c
>= ' ' && c
<= '~');
424 return (c
>= 'a' && c
<= 'z') || (c
>= 'A' && c
<= 'Z');
430 return grub_isalpha (c
) || grub_isdigit (c
);
436 return (c
>= '0' && c
<= '9');
442 return (c
>= '!' && c
<= '~');
448 if (c
>= 'A' && c
<= 'Z')
449 return c
- 'A' + 'a';
455 grub_strtol (const char *str
, char **end
, int base
)
459 while (*str
&& grub_isspace (*str
))
468 unsigned long long magnitude
;
469 magnitude
= grub_strtoull (str
, end
, base
);
472 if (magnitude
> -((long long) GRUB_LONG_MIN
))
474 grub_error (GRUB_ERR_OUT_OF_RANGE
, "negative overflow");
475 return GRUB_LONG_MIN
;
477 return -((long long) magnitude
);
481 if (magnitude
> GRUB_LONG_MAX
)
483 grub_error (GRUB_ERR_OUT_OF_RANGE
, "positive overflow");
484 return GRUB_LONG_MAX
;
486 return (long) magnitude
;
491 grub_strtoul (const char *str
, char **end
, int base
)
493 unsigned long long num
;
495 num
= grub_strtoull (str
, end
, base
);
498 grub_error (GRUB_ERR_OUT_OF_RANGE
, "overflow is detected");
502 return (unsigned long) num
;
506 grub_strtoull (const char *str
, char **end
, int base
)
508 unsigned long long num
= 0;
511 /* Skip white spaces. */
512 while (*str
&& grub_isspace (*str
))
515 /* Guess the base, if not specified. The prefix `0x' means 16, and
516 the prefix `0' means 8. */
521 if (base
== 0 || base
== 16)
527 else if (base
== 0 && str
[1] >= '0' && str
[1] <= '7')
538 digit
= grub_tolower (*str
) - '0';
541 digit
+= '0' - 'a' + 10;
542 if (digit
>= (unsigned long) base
)
548 /* NUM * BASE + DIGIT > ~0ULL */
549 if (num
> grub_divmod64 (~0ULL - digit
, base
, 0))
551 grub_error (GRUB_ERR_OUT_OF_RANGE
, "overflow is detected");
555 num
= num
* base
+ digit
;
561 grub_error (GRUB_ERR_BAD_NUMBER
, "unrecognized number");
572 grub_strdup (const char *s
)
577 len
= grub_strlen (s
) + 1;
578 p
= (char *) grub_malloc (len
);
582 return grub_memcpy (p
, s
, len
);
586 grub_strndup (const char *s
, grub_size_t n
)
591 len
= grub_strlen (s
);
594 p
= (char *) grub_malloc (len
+ 1);
598 grub_memcpy (p
, s
, len
);
604 grub_memset (void *s
, int c
, grub_size_t n
)
606 unsigned char *p
= (unsigned char *) s
;
609 *p
++ = (unsigned char) c
;
614 void *memset (void *s
, int c
, grub_size_t n
)
615 __attribute__ ((alias ("grub_memset")));
619 grub_strlen (const char *s
)
630 grub_reverse (char *str
)
632 char *p
= str
+ grub_strlen (str
) - 1;
646 /* Divide N by D, return the quotient, and store the remainder in *R. */
648 grub_divmod64 (grub_uint64_t n
, grub_uint32_t d
, grub_uint32_t
*r
)
650 /* This algorithm is typically implemented by hardware. The idea
651 is to get the highest bit in N, 64 times, by keeping
652 upper(N * 2^i) = upper((Q * 10 + M) * 2^i), where upper
653 represents the high 64 bits in 128-bits space. */
655 unsigned long long q
= 0;
658 /* Skip the slow computation if 32-bit arithmetic is possible. */
662 *r
= ((grub_uint32_t
) n
) % d
;
664 return ((grub_uint32_t
) n
) / d
;
671 if (n
& (1ULL << 63))
690 /* Convert a long long value to a string. This function avoids 64-bit
691 modular arithmetic or divisions. */
693 grub_lltoa (char *str
, int c
, unsigned long long n
)
695 unsigned base
= (c
== 'x') ? 16 : 10;
698 if ((long long) n
< 0 && c
== 'd')
700 n
= (unsigned long long) (-((long long) n
));
709 unsigned d
= (unsigned) (n
& 0xf);
710 *p
++ = (d
> 9) ? d
+ 'a' - 10 : d
+ '0';
719 n
= grub_divmod64 (n
, 10, &m
);
731 grub_vsprintf (char *str
, const char *fmt
, va_list args
)
735 auto void write_char (unsigned char ch
);
736 auto void write_str (const char *s
);
737 auto void write_fill (const char ch
, int n
);
739 void write_char (unsigned char ch
)
749 void write_str (const char *s
)
755 void write_fill (const char ch
, int n
)
758 for (i
= 0; i
< n
; i
++)
762 while ((c
= *fmt
++) != 0)
770 unsigned int format1
= 0;
771 unsigned int format2
= ~ 0U;
779 if (*fmt
&& *fmt
=='-')
786 /* Read formatting parameters. */
787 while (*p
&& grub_isdigit (*p
))
793 grub_strncpy (s
, fmt
, p
- fmt
);
797 format1
= grub_strtoul (s
, 0, 10);
805 while (*p
&& grub_isdigit (*p
))
810 char fstr
[p
- fmt
+ 1];
811 grub_strncpy (fstr
, fmt
, p
- fmt
);
813 format2
= grub_strtoul (fstr
, 0, 10);
835 longlongfmt
|= (sizeof (void *) == sizeof (long long));
846 ll
= va_arg (args
, long long);
847 grub_lltoa (tmp
, c
, ll
);
849 else if (longfmt
&& unsig
)
851 unsigned long l
= va_arg (args
, unsigned long);
852 grub_lltoa (tmp
, c
, l
);
856 long l
= va_arg (args
, long);
857 grub_lltoa (tmp
, c
, l
);
861 unsigned u
= va_arg (args
, unsigned);
862 grub_lltoa (tmp
, c
, u
);
866 n
= va_arg (args
, int);
867 grub_lltoa (tmp
, c
, n
);
869 if (! rightfill
&& grub_strlen (tmp
) < format1
)
870 write_fill (zerofill
, format1
- grub_strlen (tmp
));
872 if (rightfill
&& grub_strlen (tmp
) < format1
)
873 write_fill (zerofill
, format1
- grub_strlen (tmp
));
877 n
= va_arg (args
, int);
878 write_char (n
& 0xff);
883 grub_uint32_t code
= va_arg (args
, grub_uint32_t
);
892 else if (code
<= 0x7ff)
897 else if (code
<= 0xffff)
902 else if (code
<= 0x1fffff)
907 else if (code
<= 0x3ffffff)
912 else if (code
<= 0x7fffffff)
924 write_char (mask
| (code
>> shift
));
926 for (shift
-= 6; shift
>= 0; shift
-= 6)
927 write_char (0x80 | (0x3f & (code
>> shift
)));
932 p
= va_arg (args
, char *);
936 while (len
< format2
&& p
[len
])
939 if (!rightfill
&& len
< format1
)
940 write_fill (zerofill
, format1
- len
);
943 for (i
= 0; i
< len
; i
++)
946 if (rightfill
&& len
< format1
)
947 write_fill (zerofill
, format1
- len
);
950 write_str ("(null)");
971 grub_sprintf (char *str
, const char *fmt
, ...)
977 ret
= grub_vsprintf (str
, fmt
, ap
);
983 /* Convert UTF-16 to UTF-8. */
985 grub_utf16_to_utf8 (grub_uint8_t
*dest
, grub_uint16_t
*src
,
988 grub_uint32_t code_high
= 0;
992 grub_uint32_t code
= *src
++;
996 if (code
>= 0xDC00 && code
<= 0xDFFF)
998 /* Surrogate pair. */
999 code
= ((code_high
- 0xD800) << 12) + (code
- 0xDC00) + 0x10000;
1001 *dest
++ = (code
>> 18) | 0xF0;
1002 *dest
++ = ((code
>> 12) & 0x3F) | 0x80;
1003 *dest
++ = ((code
>> 6) & 0x3F) | 0x80;
1004 *dest
++ = (code
& 0x3F) | 0x80;
1018 else if (code
<= 0x07FF)
1020 *dest
++ = (code
>> 6) | 0xC0;
1021 *dest
++ = (code
& 0x3F) | 0x80;
1023 else if (code
>= 0xD800 && code
<= 0xDBFF)
1028 else if (code
>= 0xDC00 && code
<= 0xDFFF)
1035 *dest
++ = (code
>> 12) | 0xE0;
1036 *dest
++ = ((code
>> 6) & 0x3F) | 0x80;
1037 *dest
++ = (code
& 0x3F) | 0x80;
1045 /* Convert a (possibly null-terminated) UTF-8 string of at most SRCSIZE
1046 bytes (if SRCSIZE is -1, it is ignored) in length to a UCS-4 string.
1047 Return the number of characters converted. DEST must be able to hold
1048 at least DESTSIZE characters. If an invalid sequence is found, return -1.
1049 If SRCEND is not NULL, then *SRCEND is set to the next byte after the
1050 last byte used in SRC. */
1052 grub_utf8_to_ucs4 (grub_uint32_t
*dest
, grub_size_t destsize
,
1053 const grub_uint8_t
*src
, grub_size_t srcsize
,
1054 const grub_uint8_t
**srcend
)
1056 grub_uint32_t
*p
= dest
;
1058 grub_uint32_t code
= 0;
1063 while (srcsize
&& destsize
)
1065 grub_uint32_t c
= *src
++;
1066 if (srcsize
!= (grub_size_t
)-1)
1070 if ((c
& 0xc0) != 0x80)
1087 if ((c
& 0x80) == 0x00)
1089 else if ((c
& 0xe0) == 0xc0)
1094 else if ((c
& 0xf0) == 0xe0)
1099 else if ((c
& 0xf8) == 0xf0)
1104 else if ((c
& 0xfc) == 0xf8)
1109 else if ((c
& 0xfe) == 0xfc)
1130 /* Abort GRUB. This function does not return. */
1134 if (grub_term_get_current_output ())
1136 grub_printf ("\nAborted.");
1138 if (grub_term_get_current_input ())
1140 grub_printf (" Press any key to exit.");
1149 /* GCC emits references to abort(). */
1150 void abort (void) __attribute__ ((alias ("grub_abort")));
1153 #ifdef NEED_ENABLE_EXECUTE_STACK
1154 /* Some gcc versions generate a call to this function
1155 in trampolines for nested functions. */
1156 void __enable_execute_stack (void *addr
__attribute__ ((unused
)))