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
>= ' ' && c
<= '~');
418 return (c
>= 'a' && c
<= 'z') || (c
>= 'A' && c
<= 'Z');
424 return (c
>= '0' && c
<= '9');
430 return (c
>= '!' && c
<= '~');
436 if (c
>= 'A' && c
<= 'Z')
437 return c
- 'A' + 'a';
444 grub_strtoul (const char *str
, char **end
, int base
)
446 unsigned long long num
;
448 num
= grub_strtoull (str
, end
, base
);
451 grub_error (GRUB_ERR_OUT_OF_RANGE
, "overflow is detected");
455 return (unsigned long) num
;
459 grub_strtoull (const char *str
, char **end
, int base
)
461 unsigned long long num
= 0;
464 /* Skip white spaces. */
465 while (*str
&& grub_isspace (*str
))
468 /* Guess the base, if not specified. The prefix `0x' means 16, and
469 the prefix `0' means 8. */
474 if (base
== 0 || base
== 16)
480 else if (base
== 0 && str
[1] >= '0' && str
[1] <= '7')
491 digit
= grub_tolower (*str
) - '0';
494 digit
+= '0' - 'a' + 10;
495 if (digit
>= (unsigned long) base
)
501 /* NUM * BASE + DIGIT > ~0ULL */
502 if (num
> grub_divmod64 (~0ULL - digit
, base
, 0))
504 grub_error (GRUB_ERR_OUT_OF_RANGE
, "overflow is detected");
508 num
= num
* base
+ digit
;
514 grub_error (GRUB_ERR_BAD_NUMBER
, "unrecognized number");
525 grub_strdup (const char *s
)
530 len
= grub_strlen (s
) + 1;
531 p
= (char *) grub_malloc (len
);
535 return grub_memcpy (p
, s
, len
);
539 grub_strndup (const char *s
, grub_size_t n
)
544 len
= grub_strlen (s
);
547 p
= (char *) grub_malloc (len
+ 1);
551 grub_memcpy (p
, s
, len
);
557 grub_memset (void *s
, int c
, grub_size_t n
)
559 unsigned char *p
= (unsigned char *) s
;
562 *p
++ = (unsigned char) c
;
567 void *memset (void *s
, int c
, grub_size_t n
)
568 __attribute__ ((alias ("grub_memset")));
572 grub_strlen (const char *s
)
583 grub_reverse (char *str
)
585 char *p
= str
+ grub_strlen (str
) - 1;
599 /* Divide N by D, return the quotient, and store the remainder in *R. */
601 grub_divmod64 (grub_uint64_t n
, grub_uint32_t d
, grub_uint32_t
*r
)
603 /* This algorithm is typically implemented by hardware. The idea
604 is to get the highest bit in N, 64 times, by keeping
605 upper(N * 2^i) = upper((Q * 10 + M) * 2^i), where upper
606 represents the high 64 bits in 128-bits space. */
608 unsigned long long q
= 0;
611 /* Skip the slow computation if 32-bit arithmetic is possible. */
615 *r
= ((grub_uint32_t
) n
) % d
;
617 return ((grub_uint32_t
) n
) / d
;
624 if (n
& (1ULL << 63))
643 /* Convert a long long value to a string. This function avoids 64-bit
644 modular arithmetic or divisions. */
646 grub_lltoa (char *str
, int c
, unsigned long long n
)
648 unsigned base
= (c
== 'x') ? 16 : 10;
651 if ((long long) n
< 0 && c
== 'd')
653 n
= (unsigned long long) (-((long long) n
));
662 unsigned d
= (unsigned) (n
& 0xf);
663 *p
++ = (d
> 9) ? d
+ 'a' - 10 : d
+ '0';
672 n
= grub_divmod64 (n
, 10, &m
);
684 grub_vsprintf (char *str
, const char *fmt
, va_list args
)
688 auto void write_char (unsigned char ch
);
689 auto void write_str (const char *s
);
690 auto void write_fill (const char ch
, int n
);
692 void write_char (unsigned char ch
)
702 void write_str (const char *s
)
708 void write_fill (const char ch
, int n
)
711 for (i
= 0; i
< n
; i
++)
715 while ((c
= *fmt
++) != 0)
723 unsigned int format1
= 0;
724 unsigned int format2
= ~ 0U;
732 if (*fmt
&& *fmt
=='-')
739 /* Read formatting parameters. */
740 while (*p
&& grub_isdigit (*p
))
746 grub_strncpy (s
, fmt
, p
- fmt
);
750 format1
= grub_strtoul (s
, 0, 10);
758 while (*p
&& grub_isdigit (*p
))
763 char fstr
[p
- fmt
+ 1];
764 grub_strncpy (fstr
, fmt
, p
- fmt
);
766 format2
= grub_strtoul (fstr
, 0, 10);
788 longlongfmt
|= (sizeof (void *) == sizeof (long long));
799 ll
= va_arg (args
, long long);
800 grub_lltoa (tmp
, c
, ll
);
802 else if (longfmt
&& unsig
)
804 unsigned long l
= va_arg (args
, unsigned long);
805 grub_lltoa (tmp
, c
, l
);
809 long l
= va_arg (args
, long);
810 grub_lltoa (tmp
, c
, l
);
814 unsigned u
= va_arg (args
, unsigned);
815 grub_lltoa (tmp
, c
, u
);
819 n
= va_arg (args
, int);
820 grub_lltoa (tmp
, c
, n
);
822 if (! rightfill
&& grub_strlen (tmp
) < format1
)
823 write_fill (zerofill
, format1
- grub_strlen (tmp
));
825 if (rightfill
&& grub_strlen (tmp
) < format1
)
826 write_fill (zerofill
, format1
- grub_strlen (tmp
));
830 n
= va_arg (args
, int);
831 write_char (n
& 0xff);
836 grub_uint32_t code
= va_arg (args
, grub_uint32_t
);
845 else if (code
<= 0x7ff)
850 else if (code
<= 0xffff)
855 else if (code
<= 0x1fffff)
860 else if (code
<= 0x3ffffff)
865 else if (code
<= 0x7fffffff)
877 write_char (mask
| (code
>> shift
));
879 for (shift
-= 6; shift
>= 0; shift
-= 6)
880 write_char (0x80 | (0x3f & (code
>> shift
)));
885 p
= va_arg (args
, char *);
889 while (len
< format2
&& p
[len
])
892 if (!rightfill
&& len
< format1
)
893 write_fill (zerofill
, format1
- len
);
896 for (i
= 0; i
< len
; i
++)
899 if (rightfill
&& len
< format1
)
900 write_fill (zerofill
, format1
- len
);
903 write_str ("(null)");
924 grub_sprintf (char *str
, const char *fmt
, ...)
930 ret
= grub_vsprintf (str
, fmt
, ap
);
936 /* Convert UTF-16 to UTF-8. */
938 grub_utf16_to_utf8 (grub_uint8_t
*dest
, grub_uint16_t
*src
,
941 grub_uint32_t code_high
= 0;
945 grub_uint32_t code
= *src
++;
949 if (code
>= 0xDC00 && code
<= 0xDFFF)
951 /* Surrogate pair. */
952 code
= ((code_high
- 0xD800) << 12) + (code
- 0xDC00) + 0x10000;
954 *dest
++ = (code
>> 18) | 0xF0;
955 *dest
++ = ((code
>> 12) & 0x3F) | 0x80;
956 *dest
++ = ((code
>> 6) & 0x3F) | 0x80;
957 *dest
++ = (code
& 0x3F) | 0x80;
971 else if (code
<= 0x07FF)
973 *dest
++ = (code
>> 6) | 0xC0;
974 *dest
++ = (code
& 0x3F) | 0x80;
976 else if (code
>= 0xD800 && code
<= 0xDBFF)
981 else if (code
>= 0xDC00 && code
<= 0xDFFF)
988 *dest
++ = (code
>> 12) | 0xE0;
989 *dest
++ = ((code
>> 6) & 0x3F) | 0x80;
990 *dest
++ = (code
& 0x3F) | 0x80;
998 /* Convert a (possibly null-terminated) UTF-8 string of at most SRCSIZE
999 bytes (if SRCSIZE is -1, it is ignored) in length to a UCS-4 string.
1000 Return the number of characters converted. DEST must be able to hold
1001 at least DESTSIZE characters. If an invalid sequence is found, return -1.
1002 If SRCEND is not NULL, then *SRCEND is set to the next byte after the
1003 last byte used in SRC. */
1005 grub_utf8_to_ucs4 (grub_uint32_t
*dest
, grub_size_t destsize
,
1006 const grub_uint8_t
*src
, grub_size_t srcsize
,
1007 const grub_uint8_t
**srcend
)
1009 grub_uint32_t
*p
= dest
;
1011 grub_uint32_t code
= 0;
1016 while (srcsize
&& destsize
)
1018 grub_uint32_t c
= *src
++;
1019 if (srcsize
!= (grub_size_t
)-1)
1023 if ((c
& 0xc0) != 0x80)
1040 if ((c
& 0x80) == 0x00)
1042 else if ((c
& 0xe0) == 0xc0)
1047 else if ((c
& 0xf0) == 0xe0)
1052 else if ((c
& 0xf8) == 0xf0)
1057 else if ((c
& 0xfc) == 0xf8)
1062 else if ((c
& 0xfe) == 0xfc)
1083 /* Abort GRUB. This function does not return. */
1087 if (grub_term_get_current_output ())
1089 grub_printf ("\nAborted.");
1091 if (grub_term_get_current_input ())
1093 grub_printf (" Press any key to exit.");
1102 /* GCC emits references to abort(). */
1103 void abort (void) __attribute__ ((alias ("grub_abort")));
1106 #ifdef NEED_ENABLE_EXECUTE_STACK
1107 /* Some gcc versions generate a call to this function
1108 in trampolines for nested functions. */
1109 __enable_execute_stack (void *addr
__attribute__ ((unused
)))