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_iswordseparator (int c
)
30 return (grub_isspace (c
) || c
== ',' || c
== ';' || c
== '|' || c
== '&');
34 grub_memmove (void *dest
, const void *src
, grub_size_t n
)
36 char *d
= (char *) dest
;
37 const char *s
= (const char *) src
;
55 void *memmove (void *dest
, const void *src
, grub_size_t n
)
56 __attribute__ ((alias ("grub_memmove")));
57 /* GCC emits references to memcpy() for struct copies etc. */
58 void *memcpy (void *dest
, const void *src
, grub_size_t n
)
59 __attribute__ ((alias ("grub_memmove")));
61 void *memcpy (void *dest
, const void *src
, grub_size_t n
)
63 return grub_memmove (dest
, src
, n
);
65 void *memmove (void *dest
, const void *src
, grub_size_t n
)
67 return grub_memmove (dest
, src
, n
);
72 grub_strcpy (char *dest
, const char *src
)
76 while ((*p
++ = *src
++) != '\0')
83 grub_strncpy (char *dest
, const char *src
, int c
)
87 while ((*p
++ = *src
++) != '\0' && --c
)
94 grub_stpcpy (char *dest
, const char *src
)
101 while (*s
++ != '\0');
107 grub_printf (const char *fmt
, ...)
113 ret
= grub_vprintf (fmt
, ap
);
119 #if defined (APPLE_CC) && ! defined (GRUB_UTIL)
121 grub_err_printf (const char *fmt
, ...)
127 ret
= grub_vprintf (fmt
, ap
);
134 #if ! defined (APPLE_CC) && ! defined (GRUB_UTIL)
135 int grub_err_printf (const char *fmt
, ...)
136 __attribute__ ((alias("grub_printf")));
140 grub_real_dprintf (const char *file
, const int line
, const char *condition
,
141 const char *fmt
, ...)
144 const char *debug
= grub_env_get ("debug");
149 if (grub_strword (debug
, "all") || grub_strword (debug
, condition
))
151 grub_printf ("%s:%d: ", file
, line
);
152 va_start (args
, fmt
);
153 grub_vprintf (fmt
, args
);
159 grub_vprintf (const char *fmt
, va_list args
)
163 ret
= grub_vsprintf (0, fmt
, args
);
169 grub_memcmp (const void *s1
, const void *s2
, grub_size_t n
)
177 return (int) *t1
- (int) *t2
;
186 int memcmp (const void *s1
, const void *s2
, grub_size_t n
)
187 __attribute__ ((alias ("grub_memcmp")));
191 grub_strcmp (const char *s1
, const char *s2
)
202 return (int) *s1
- (int) *s2
;
206 grub_strncmp (const char *s1
, const char *s2
, grub_size_t n
)
211 while (*s1
&& *s2
&& --n
)
220 return (int) *s1
- (int) *s2
;
224 grub_strchr (const char *s
, int c
)
237 grub_strrchr (const char *s
, int c
)
251 /* Copied from gnulib.
252 Written by Bruno Haible <bruno@clisp.org>, 2005. */
254 grub_strstr (const char *haystack
, const char *needle
)
256 /* Be careful not to look at the entire extent of haystack or needle
257 until needed. This is useful because of these two cases:
258 - haystack may be very long, and a match of needle found early,
259 - needle may be very long, and not even a short initial segment of
260 needle may be found in haystack. */
263 /* Speed up the following searches of needle by caching its first
269 if (*haystack
== '\0')
273 /* The first character matches. */
275 const char *rhaystack
= haystack
+ 1;
276 const char *rneedle
= needle
;
278 for (;; rhaystack
++, rneedle
++)
280 if (*rneedle
== '\0')
282 return (char *) haystack
;
283 if (*rhaystack
== '\0')
286 if (*rhaystack
!= *rneedle
)
287 /* Nothing in this round. */
294 return (char *) haystack
;
298 grub_strword (const char *haystack
, const char *needle
)
300 const char *n_pos
= needle
;
302 while (grub_iswordseparator (*haystack
))
307 /* Crawl both the needle and the haystack word we're on. */
308 while(*haystack
&& !grub_iswordseparator (*haystack
)
309 && *haystack
== *n_pos
)
315 /* If we reached the end of both words at the same time, the word
316 is found. If not, eat everything in the haystack that isn't the
317 next word (or the end of string) and "reset" the needle. */
318 if ( (!*haystack
|| grub_iswordseparator (*haystack
))
319 && (!*n_pos
|| grub_iswordseparator (*n_pos
)))
324 while (*haystack
&& !grub_iswordseparator (*haystack
))
326 while (grub_iswordseparator (*haystack
))
337 return (c
== '\n' || c
== '\r' || c
== ' ' || c
== '\t');
343 return (c
>= ' ' && c
<= '~');
348 grub_strtoul (const char *str
, char **end
, int base
)
350 unsigned long long num
;
352 num
= grub_strtoull (str
, end
, base
);
355 grub_error (GRUB_ERR_OUT_OF_RANGE
, "overflow is detected");
359 return (unsigned long) num
;
363 grub_strtoull (const char *str
, char **end
, int base
)
365 unsigned long long num
= 0;
368 /* Skip white spaces. */
369 while (*str
&& grub_isspace (*str
))
372 /* Guess the base, if not specified. The prefix `0x' means 16, and
373 the prefix `0' means 8. */
378 if (base
== 0 || base
== 16)
384 else if (base
== 0 && str
[1] >= '0' && str
[1] <= '7')
395 digit
= grub_tolower (*str
) - '0';
398 digit
+= '0' - 'a' + 10;
399 if (digit
>= (unsigned long) base
)
405 /* NUM * BASE + DIGIT > ~0ULL */
406 if (num
> grub_divmod64 (~0ULL - digit
, base
, 0))
408 grub_error (GRUB_ERR_OUT_OF_RANGE
, "overflow is detected");
412 num
= num
* base
+ digit
;
418 grub_error (GRUB_ERR_BAD_NUMBER
, "unrecognized number");
429 grub_strdup (const char *s
)
434 len
= grub_strlen (s
) + 1;
435 p
= (char *) grub_malloc (len
);
439 return grub_memcpy (p
, s
, len
);
443 grub_strndup (const char *s
, grub_size_t n
)
448 len
= grub_strlen (s
);
451 p
= (char *) grub_malloc (len
+ 1);
455 grub_memcpy (p
, s
, len
);
461 grub_memset (void *s
, int c
, grub_size_t n
)
463 unsigned char *p
= (unsigned char *) s
;
466 *p
++ = (unsigned char) c
;
471 void *memset (void *s
, int c
, grub_size_t n
)
472 __attribute__ ((alias ("grub_memset")));
476 grub_strlen (const char *s
)
487 grub_reverse (char *str
)
489 char *p
= str
+ grub_strlen (str
) - 1;
503 /* Divide N by D, return the quotient, and store the remainder in *R. */
505 grub_divmod64 (grub_uint64_t n
, grub_uint32_t d
, grub_uint32_t
*r
)
507 /* This algorithm is typically implemented by hardware. The idea
508 is to get the highest bit in N, 64 times, by keeping
509 upper(N * 2^i) = upper((Q * 10 + M) * 2^i), where upper
510 represents the high 64 bits in 128-bits space. */
512 unsigned long long q
= 0;
515 /* Skip the slow computation if 32-bit arithmetic is possible. */
519 *r
= ((grub_uint32_t
) n
) % d
;
521 return ((grub_uint32_t
) n
) / d
;
528 if (n
& (1ULL << 63))
547 /* Convert a long long value to a string. This function avoids 64-bit
548 modular arithmetic or divisions. */
550 grub_lltoa (char *str
, int c
, unsigned long long n
)
552 unsigned base
= (c
== 'x') ? 16 : 10;
555 if ((long long) n
< 0 && c
== 'd')
557 n
= (unsigned long long) (-((long long) n
));
566 unsigned d
= (unsigned) (n
& 0xf);
567 *p
++ = (d
> 9) ? d
+ 'a' - 10 : d
+ '0';
576 n
= grub_divmod64 (n
, 10, &m
);
588 grub_vsprintf (char *str
, const char *fmt
, va_list args
)
592 auto void write_char (unsigned char ch
);
593 auto void write_str (const char *s
);
594 auto void write_fill (const char ch
, int n
);
596 void write_char (unsigned char ch
)
606 void write_str (const char *s
)
612 void write_fill (const char ch
, int n
)
615 for (i
= 0; i
< n
; i
++)
619 while ((c
= *fmt
++) != 0)
627 unsigned int format1
= 0;
628 unsigned int format2
= ~ 0U;
636 if (*fmt
&& *fmt
=='-')
643 /* Read formatting parameters. */
644 while (*p
&& grub_isdigit (*p
))
650 grub_strncpy (s
, fmt
, p
- fmt
);
654 format1
= grub_strtoul (s
, 0, 10);
662 while (*p
&& grub_isdigit (*p
))
667 char fstr
[p
- fmt
+ 1];
668 grub_strncpy (fstr
, fmt
, p
- fmt
);
670 format2
= grub_strtoul (fstr
, 0, 10);
692 longlongfmt
|= (sizeof (void *) == sizeof (long long));
703 ll
= va_arg (args
, long long);
704 grub_lltoa (tmp
, c
, ll
);
706 else if (longfmt
&& unsig
)
708 unsigned long l
= va_arg (args
, unsigned long);
709 grub_lltoa (tmp
, c
, l
);
713 long l
= va_arg (args
, long);
714 grub_lltoa (tmp
, c
, l
);
718 unsigned u
= va_arg (args
, unsigned);
719 grub_lltoa (tmp
, c
, u
);
723 n
= va_arg (args
, int);
724 grub_lltoa (tmp
, c
, n
);
726 if (! rightfill
&& grub_strlen (tmp
) < format1
)
727 write_fill (zerofill
, format1
- grub_strlen (tmp
));
729 if (rightfill
&& grub_strlen (tmp
) < format1
)
730 write_fill (zerofill
, format1
- grub_strlen (tmp
));
734 n
= va_arg (args
, int);
735 write_char (n
& 0xff);
740 grub_uint32_t code
= va_arg (args
, grub_uint32_t
);
749 else if (code
<= 0x7ff)
754 else if (code
<= 0xffff)
759 else if (code
<= 0x1fffff)
764 else if (code
<= 0x3ffffff)
769 else if (code
<= 0x7fffffff)
781 write_char (mask
| (code
>> shift
));
783 for (shift
-= 6; shift
>= 0; shift
-= 6)
784 write_char (0x80 | (0x3f & (code
>> shift
)));
789 p
= va_arg (args
, char *);
793 while (len
< format2
&& p
[len
])
796 if (!rightfill
&& len
< format1
)
797 write_fill (zerofill
, format1
- len
);
800 for (i
= 0; i
< len
; i
++)
803 if (rightfill
&& len
< format1
)
804 write_fill (zerofill
, format1
- len
);
807 write_str ("(null)");
828 grub_sprintf (char *str
, const char *fmt
, ...)
834 ret
= grub_vsprintf (str
, fmt
, ap
);
840 /* Convert UTF-16 to UTF-8. */
842 grub_utf16_to_utf8 (grub_uint8_t
*dest
, grub_uint16_t
*src
,
845 grub_uint32_t code_high
= 0;
849 grub_uint32_t code
= *src
++;
853 if (code
>= 0xDC00 && code
<= 0xDFFF)
855 /* Surrogate pair. */
856 code
= ((code_high
- 0xD800) << 12) + (code
- 0xDC00) + 0x10000;
858 *dest
++ = (code
>> 18) | 0xF0;
859 *dest
++ = ((code
>> 12) & 0x3F) | 0x80;
860 *dest
++ = ((code
>> 6) & 0x3F) | 0x80;
861 *dest
++ = (code
& 0x3F) | 0x80;
875 else if (code
<= 0x07FF)
877 *dest
++ = (code
>> 6) | 0xC0;
878 *dest
++ = (code
& 0x3F) | 0x80;
880 else if (code
>= 0xD800 && code
<= 0xDBFF)
885 else if (code
>= 0xDC00 && code
<= 0xDFFF)
892 *dest
++ = (code
>> 12) | 0xE0;
893 *dest
++ = ((code
>> 6) & 0x3F) | 0x80;
894 *dest
++ = (code
& 0x3F) | 0x80;
902 /* Convert a (possibly null-terminated) UTF-8 string of at most SRCSIZE
903 bytes (if SRCSIZE is -1, it is ignored) in length to a UCS-4 string.
904 Return the number of characters converted. DEST must be able to hold
905 at least DESTSIZE characters. If an invalid sequence is found, return -1.
906 If SRCEND is not NULL, then *SRCEND is set to the next byte after the
907 last byte used in SRC. */
909 grub_utf8_to_ucs4 (grub_uint32_t
*dest
, grub_size_t destsize
,
910 const grub_uint8_t
*src
, grub_size_t srcsize
,
911 const grub_uint8_t
**srcend
)
913 grub_uint32_t
*p
= dest
;
915 grub_uint32_t code
= 0;
920 while (srcsize
&& destsize
)
922 grub_uint32_t c
= *src
++;
923 if (srcsize
!= (grub_size_t
)-1)
927 if ((c
& 0xc0) != 0x80)
944 if ((c
& 0x80) == 0x00)
946 else if ((c
& 0xe0) == 0xc0)
951 else if ((c
& 0xf0) == 0xe0)
956 else if ((c
& 0xf8) == 0xf0)
961 else if ((c
& 0xfc) == 0xf8)
966 else if ((c
& 0xfe) == 0xfc)
987 /* Abort GRUB. This function does not return. */
991 if (grub_term_get_current_output ())
993 grub_printf ("\nAborted.");
995 if (grub_term_get_current_input ())
997 grub_printf (" Press any key to exit.");
1006 /* GCC emits references to abort(). */
1007 void abort (void) __attribute__ ((alias ("grub_abort")));
1010 #ifdef NEED_ENABLE_EXECUTE_STACK
1011 /* Some gcc versions generate a call to this function
1012 in trampolines for nested functions. */
1013 void __enable_execute_stack (void *addr
__attribute__ ((unused
)))