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
;
47 void *memmove (void *dest
, const void *src
, grub_size_t n
)
48 __attribute__ ((alias ("grub_memmove")));
49 /* GCC emits references to memcpy() for struct copies etc. */
50 void *memcpy (void *dest
, const void *src
, grub_size_t n
)
51 __attribute__ ((alias ("grub_memmove")));
54 grub_strcpy (char *dest
, const char *src
)
58 while ((*p
++ = *src
++) != '\0')
65 grub_strncpy (char *dest
, const char *src
, int c
)
69 while ((*p
++ = *src
++) != '\0' && --c
)
76 grub_stpcpy (char *dest
, const char *src
)
89 grub_strcat (char *dest
, const char *src
)
96 while ((*p
= *src
) != '\0')
106 grub_strncat (char *dest
, const char *src
, int c
)
113 while ((*p
= *src
) != '\0' && c
--)
125 grub_printf (const char *fmt
, ...)
131 ret
= grub_vprintf (fmt
, ap
);
138 int grub_err_printf (const char *fmt
, ...)
139 __attribute__ ((alias("grub_printf")));
143 grub_real_dprintf (const char *file
, const int line
, const char *condition
,
144 const char *fmt
, ...)
147 const char *debug
= grub_env_get ("debug");
152 if (grub_strword (debug
, "all") || grub_strword (debug
, condition
))
154 grub_printf ("%s:%d: ", file
, line
);
155 va_start (args
, fmt
);
156 grub_vprintf (fmt
, args
);
162 grub_vprintf (const char *fmt
, va_list args
)
166 ret
= grub_vsprintf (0, fmt
, args
);
172 grub_memcmp (const void *s1
, const void *s2
, grub_size_t n
)
180 return (int) *t1
- (int) *t2
;
188 int memcmp (const void *s1
, const void *s2
, grub_size_t n
)
189 __attribute__ ((alias ("grub_memcmp")));
192 grub_strcmp (const char *s1
, const char *s2
)
203 return (int) *s1
- (int) *s2
;
207 grub_strncmp (const char *s1
, const char *s2
, grub_size_t n
)
212 while (*s1
&& *s2
&& --n
)
221 return (int) *s1
- (int) *s2
;
225 grub_strcasecmp (const char *s1
, const char *s2
)
229 if (grub_tolower (*s1
) != grub_tolower (*s2
))
236 return (int) grub_tolower (*s1
) - (int) grub_tolower (*s2
);
240 grub_strncasecmp (const char *s1
, const char *s2
, grub_size_t n
)
245 while (*s1
&& *s2
&& --n
)
247 if (grub_tolower (*s1
) != grub_tolower (*s2
))
254 return (int) grub_tolower (*s1
) - (int) grub_tolower (*s2
);
258 grub_strchr (const char *s
, int c
)
271 grub_strrchr (const char *s
, int c
)
285 /* Copied from gnulib.
286 Written by Bruno Haible <bruno@clisp.org>, 2005. */
288 grub_strstr (const char *haystack
, const char *needle
)
290 /* Be careful not to look at the entire extent of haystack or needle
291 until needed. This is useful because of these two cases:
292 - haystack may be very long, and a match of needle found early,
293 - needle may be very long, and not even a short initial segment of
294 needle may be found in haystack. */
297 /* Speed up the following searches of needle by caching its first
303 if (*haystack
== '\0')
307 /* The first character matches. */
309 const char *rhaystack
= haystack
+ 1;
310 const char *rneedle
= needle
;
312 for (;; rhaystack
++, rneedle
++)
314 if (*rneedle
== '\0')
316 return (char *) haystack
;
317 if (*rhaystack
== '\0')
320 if (*rhaystack
!= *rneedle
)
321 /* Nothing in this round. */
328 return (char *) haystack
;
332 grub_strword (const char *haystack
, const char *needle
)
334 const char *n_pos
= needle
;
336 while (grub_iswordseparator (*haystack
))
341 /* Crawl both the needle and the haystack word we're on. */
342 while(*haystack
&& !grub_iswordseparator (*haystack
)
343 && *haystack
== *n_pos
)
349 /* If we reached the end of both words at the same time, the word
350 is found. If not, eat everything in the haystack that isn't the
351 next word (or the end of string) and "reset" the needle. */
352 if ( (!*haystack
|| grub_iswordseparator (*haystack
))
353 && (!*n_pos
|| grub_iswordseparator (*n_pos
)))
358 while (*haystack
&& !grub_iswordseparator (*haystack
))
360 while (grub_iswordseparator (*haystack
))
369 grub_iswordseparator (int c
)
371 return (grub_isspace (c
) || c
== ',' || c
== ';' || c
== '|' || c
== '&');
377 return (c
== '\n' || c
== '\r' || c
== ' ' || c
== '\t');
383 return (c
>= ' ' && c
<= '~');
389 return (c
>= 'a' && c
<= 'z') || (c
>= 'A' && c
<= 'Z');
395 return (c
>= '0' && c
<= '9');
401 return (c
>= '!' && c
<= '~');
407 if (c
>= 'A' && c
<= 'Z')
408 return c
- 'A' + 'a';
415 grub_strtoul (const char *str
, char **end
, int base
)
417 unsigned long long num
;
419 num
= grub_strtoull (str
, end
, base
);
422 grub_error (GRUB_ERR_OUT_OF_RANGE
, "overflow is detected");
426 return (unsigned long) num
;
430 grub_strtoull (const char *str
, char **end
, int base
)
432 unsigned long long num
= 0;
435 /* Skip white spaces. */
436 while (*str
&& grub_isspace (*str
))
439 /* Guess the base, if not specified. The prefix `0x' means 16, and
440 the prefix `0' means 8. */
445 if (base
== 0 || base
== 16)
451 else if (base
== 0 && str
[1] >= '0' && str
[1] <= '7')
462 digit
= grub_tolower (*str
) - '0';
465 digit
+= '0' - 'a' + 10;
466 if (digit
>= (unsigned long) base
)
472 /* NUM * BASE + DIGIT > ~0ULL */
473 if (num
> grub_divmod64 (~0ULL - digit
, base
, 0))
475 grub_error (GRUB_ERR_OUT_OF_RANGE
, "overflow is detected");
479 num
= num
* base
+ digit
;
485 grub_error (GRUB_ERR_BAD_NUMBER
, "unrecognized number");
496 grub_strdup (const char *s
)
501 len
= grub_strlen (s
) + 1;
502 p
= (char *) grub_malloc (len
);
506 return grub_memcpy (p
, s
, len
);
510 grub_strndup (const char *s
, grub_size_t n
)
515 len
= grub_strlen (s
);
518 p
= (char *) grub_malloc (len
+ 1);
522 grub_memcpy (p
, s
, len
);
528 grub_memset (void *s
, int c
, grub_size_t n
)
530 unsigned char *p
= (unsigned char *) s
;
533 *p
++ = (unsigned char) c
;
537 void *memset (void *s
, int c
, grub_size_t n
)
538 __attribute__ ((alias ("grub_memset")));
541 grub_strlen (const char *s
)
552 grub_reverse (char *str
)
554 char *p
= str
+ grub_strlen (str
) - 1;
569 grub_itoa (char *str
, int c
, unsigned n
)
571 unsigned base
= (c
== 'x') ? 16 : 10;
574 if ((int) n
< 0 && c
== 'd')
576 n
= (unsigned) (-((int) n
));
583 unsigned d
= n
% base
;
584 *p
++ = (d
> 9) ? d
+ 'a' - 10 : d
+ '0';
594 grub_ltoa (char *str
, int c
, unsigned long n
)
596 unsigned long base
= (c
== 'x') ? 16 : 10;
599 if ((long) n
< 0 && c
== 'd')
601 n
= (unsigned long) (-((long) n
));
608 unsigned long d
= n
% base
;
609 *p
++ = (d
> 9) ? d
+ 'a' - 10 : d
+ '0';
618 /* Divide N by D, return the quotient, and store the remainder in *R. */
620 grub_divmod64 (grub_uint64_t n
, grub_uint32_t d
, grub_uint32_t
*r
)
622 /* This algorithm is typically implemented by hardware. The idea
623 is to get the highest bit in N, 64 times, by keeping
624 upper(N * 2^i) = upper((Q * 10 + M) * 2^i), where upper
625 represents the high 64 bits in 128-bits space. */
627 unsigned long long q
= 0;
630 /* Skip the slow computation if 32-bit arithmetic is possible. */
634 *r
= ((grub_uint32_t
) n
) % d
;
636 return ((grub_uint32_t
) n
) / d
;
643 if (n
& (1ULL << 63))
662 /* Convert a long long value to a string. This function avoids 64-bit
663 modular arithmetic or divisions. */
665 grub_lltoa (char *str
, int c
, unsigned long long n
)
667 unsigned base
= (c
== 'x') ? 16 : 10;
670 if ((long long) n
< 0 && c
== 'd')
672 n
= (unsigned long long) (-((long long) n
));
681 unsigned d
= (unsigned) (n
& 0xf);
682 *p
++ = (d
> 9) ? d
+ 'a' - 10 : d
+ '0';
691 n
= grub_divmod64 (n
, 10, &m
);
703 grub_vsprintf (char *str
, const char *fmt
, va_list args
)
707 auto void write_char (unsigned char ch
);
708 auto void write_str (const char *s
);
709 auto void write_fill (const char ch
, int n
);
711 void write_char (unsigned char ch
)
721 void write_str (const char *s
)
727 void write_fill (const char ch
, int n
)
730 for (i
= 0; i
< n
; i
++)
734 while ((c
= *fmt
++) != 0)
742 unsigned int format1
= 0;
743 unsigned int format2
= ~ 0U;
750 if (*fmt
&& *fmt
=='-')
757 /* Read formatting parameters. */
758 while (*p
&& grub_isdigit (*p
))
764 grub_strncpy (s
, fmt
, p
- fmt
);
768 format1
= grub_strtoul (s
, 0, 10);
776 while (*p
&& grub_isdigit (*p
))
781 char fstr
[p
- fmt
+ 1];
782 grub_strncpy (fstr
, fmt
, p
- fmt
);
784 format2
= grub_strtoul (fstr
, 0, 10);
806 longlongfmt
|= (sizeof (void *) == sizeof (long long));
815 ll
= va_arg (args
, long long);
816 grub_lltoa (tmp
, c
, ll
);
820 long l
= va_arg (args
, long);
821 grub_ltoa (tmp
, c
, l
);
825 n
= va_arg (args
, int);
826 grub_itoa (tmp
, c
, n
);
828 if (! rightfill
&& grub_strlen (tmp
) < format1
)
829 write_fill (zerofill
, format1
- grub_strlen (tmp
));
831 if (rightfill
&& grub_strlen (tmp
) < format1
)
832 write_fill (zerofill
, format1
- grub_strlen (tmp
));
836 n
= va_arg (args
, int);
837 write_char (n
& 0xff);
842 grub_uint32_t code
= va_arg (args
, grub_uint32_t
);
851 else if (code
<= 0x7ff)
856 else if (code
<= 0xffff)
861 else if (code
<= 0x1fffff)
866 else if (code
<= 0x3ffffff)
871 else if (code
<= 0x7fffffff)
883 write_char (mask
| (code
>> shift
));
885 for (shift
-= 6; shift
>= 0; shift
-= 6)
886 write_char (0x80 | (0x3f & (code
>> shift
)));
891 p
= va_arg (args
, char *);
895 while (len
< format2
&& p
[len
])
898 if (!rightfill
&& len
< format1
)
899 write_fill (zerofill
, format1
- len
);
902 for (i
= 0; i
< len
; i
++)
905 if (rightfill
&& len
< format1
)
906 write_fill (zerofill
, format1
- len
);
909 write_str ("(null)");
930 grub_sprintf (char *str
, const char *fmt
, ...)
936 ret
= grub_vsprintf (str
, fmt
, ap
);
942 /* Convert UTF-16 to UTF-8. */
944 grub_utf16_to_utf8 (grub_uint8_t
*dest
, grub_uint16_t
*src
,
947 grub_uint32_t code_high
= 0;
951 grub_uint32_t code
= *src
++;
955 if (code
>= 0xDC00 && code
<= 0xDFFF)
957 /* Surrogate pair. */
958 code
= ((code_high
- 0xD800) << 12) + (code
- 0xDC00) + 0x10000;
960 *dest
++ = (code
>> 18) | 0xF0;
961 *dest
++ = ((code
>> 12) & 0x3F) | 0x80;
962 *dest
++ = ((code
>> 6) & 0x3F) | 0x80;
963 *dest
++ = (code
& 0x3F) | 0x80;
977 else if (code
<= 0x07FF)
979 *dest
++ = (code
>> 6) | 0xC0;
980 *dest
++ = (code
& 0x3F) | 0x80;
982 else if (code
>= 0xD800 && code
<= 0xDBFF)
987 else if (code
>= 0xDC00 && code
<= 0xDFFF)
994 *dest
++ = (code
>> 12) | 0xE0;
995 *dest
++ = ((code
>> 6) & 0x3F) | 0x80;
996 *dest
++ = (code
& 0x3F) | 0x80;
1004 /* Convert a (possibly null-terminated) UTF-8 string of at most SRCSIZE
1005 bytes (if SRCSIZE is -1, it is ignored) in length to a UCS-4 string.
1006 Return the number of characters converted. DEST must be able to hold
1007 at least DESTSIZE characters. If an invalid sequence is found, return -1.
1008 If SRCEND is not NULL, then *SRCEND is set to the next byte after the
1009 last byte used in SRC. */
1011 grub_utf8_to_ucs4 (grub_uint32_t
*dest
, grub_size_t destsize
,
1012 const grub_uint8_t
*src
, grub_size_t srcsize
,
1013 const grub_uint8_t
**srcend
)
1015 grub_uint32_t
*p
= dest
;
1017 grub_uint32_t code
= 0;
1022 while (srcsize
&& destsize
)
1024 grub_uint32_t c
= *src
++;
1025 if (srcsize
!= (grub_size_t
)-1)
1029 if ((c
& 0xc0) != 0x80)
1046 if ((c
& 0x80) == 0x00)
1048 else if ((c
& 0xe0) == 0xc0)
1053 else if ((c
& 0xf0) == 0xe0)
1058 else if ((c
& 0xf8) == 0xf0)
1063 else if ((c
& 0xfc) == 0xf8)
1068 else if ((c
& 0xfe) == 0xfc)
1089 /* Abort GRUB. This function does not return. */
1093 if (grub_term_get_current_output ())
1095 grub_printf ("\nAborted.");
1097 if (grub_term_get_current_input ())
1099 grub_printf (" Press any key to exit.");
1106 /* GCC emits references to abort(). */
1107 void abort (void) __attribute__ ((alias ("grub_abort")));
1109 #ifdef NEED_ENABLE_EXECUTE_STACK
1110 /* Some gcc versions generate a call to this function
1111 in trampolines for nested functions. */
1112 __enable_execute_stack (void *addr
__attribute__ ((unused
)))