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 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
)
197 return (int) *s1
- (int) *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
)
215 return (int) *s1
- (int) *s2
;
221 return (int) *s1
- (int) *s2
;
225 grub_strncasecmp (const char *s1
, const char *s2
, int c
)
229 while (grub_tolower (*s1
) && grub_tolower (*s2
) && p
< c
)
231 if (grub_tolower (*s1
) != grub_tolower (*s2
))
232 return (int) grub_tolower (*s1
) - (int) grub_tolower (*s2
);
239 return (int) *s1
- (int) *s2
;
243 grub_strchr (const char *s
, int c
)
256 grub_strrchr (const char *s
, int c
)
270 /* Copied from gnulib.
271 Written by Bruno Haible <bruno@clisp.org>, 2005. */
273 grub_strstr (const char *haystack
, const char *needle
)
275 /* Be careful not to look at the entire extent of haystack or needle
276 until needed. This is useful because of these two cases:
277 - haystack may be very long, and a match of needle found early,
278 - needle may be very long, and not even a short initial segment of
279 needle may be found in haystack. */
282 /* Speed up the following searches of needle by caching its first
288 if (*haystack
== '\0')
292 /* The first character matches. */
294 const char *rhaystack
= haystack
+ 1;
295 const char *rneedle
= needle
;
297 for (;; rhaystack
++, rneedle
++)
299 if (*rneedle
== '\0')
301 return (char *) haystack
;
302 if (*rhaystack
== '\0')
305 if (*rhaystack
!= *rneedle
)
306 /* Nothing in this round. */
313 return (char *) haystack
;
317 grub_strword (const char *haystack
, const char *needle
)
319 const char *n_pos
= needle
;
321 while (grub_iswordseparator (*haystack
))
326 /* Crawl both the needle and the haystack word we're on. */
327 while(*haystack
&& !grub_iswordseparator (*haystack
)
328 && *haystack
== *n_pos
)
334 /* If we reached the end of both words at the same time, the word
335 is found. If not, eat everything in the haystack that isn't the
336 next word (or the end of string) and "reset" the needle. */
337 if ( (!*haystack
|| grub_iswordseparator (*haystack
))
338 && (!*n_pos
|| grub_iswordseparator (*n_pos
)))
343 while (*haystack
&& !grub_iswordseparator (*haystack
))
345 while (grub_iswordseparator (*haystack
))
354 grub_iswordseparator (int c
)
356 return (grub_isspace (c
) || c
== ',' || c
== ';' || c
== '|' || c
== '&');
362 return (c
== '\n' || c
== '\r' || c
== ' ' || c
== '\t');
368 return (c
>= ' ' && c
<= '~');
374 return (c
>= 'a' && c
<= 'z') || (c
>= 'A' && c
<= 'Z');
380 return (c
>= '0' && c
<= '9');
386 return (c
>= '!' && c
<= '~');
392 if (c
>= 'A' && c
<= 'Z')
393 return c
- 'A' + 'a';
400 grub_strtoul (const char *str
, char **end
, int base
)
402 unsigned long long num
;
404 num
= grub_strtoull (str
, end
, base
);
407 grub_error (GRUB_ERR_OUT_OF_RANGE
, "overflow is detected");
411 return (unsigned long) num
;
415 grub_strtoull (const char *str
, char **end
, int base
)
417 unsigned long long num
= 0;
420 /* Skip white spaces. */
421 while (*str
&& grub_isspace (*str
))
424 /* Guess the base, if not specified. The prefix `0x' means 16, and
425 the prefix `0' means 8. */
426 if (base
== 0 && str
[0] == '0')
430 if (base
== 0 || base
== 16)
436 else if (str
[1] >= '0' && str
[1] <= '7')
447 digit
= grub_tolower (*str
) - '0';
450 digit
+= '0' - 'a' + 10;
451 if (digit
>= (unsigned long) base
)
457 /* NUM * BASE + DIGIT > ~0ULL */
458 if (num
> grub_divmod64 (~0ULL - digit
, base
, 0))
460 grub_error (GRUB_ERR_OUT_OF_RANGE
, "overflow is detected");
464 num
= num
* base
+ digit
;
470 grub_error (GRUB_ERR_BAD_NUMBER
, "unrecognized number");
481 grub_strdup (const char *s
)
486 len
= grub_strlen (s
) + 1;
487 p
= (char *) grub_malloc (len
);
491 return grub_memcpy (p
, s
, len
);
495 grub_strndup (const char *s
, grub_size_t n
)
500 len
= grub_strlen (s
);
503 p
= (char *) grub_malloc (len
+ 1);
507 grub_memcpy (p
, s
, len
);
513 grub_memset (void *s
, int c
, grub_size_t n
)
515 unsigned char *p
= (unsigned char *) s
;
518 *p
++ = (unsigned char) c
;
522 void *memset (void *s
, int c
, grub_size_t n
)
523 __attribute__ ((alias ("grub_memset")));
526 grub_strlen (const char *s
)
537 grub_reverse (char *str
)
539 char *p
= str
+ grub_strlen (str
) - 1;
554 grub_itoa (char *str
, int c
, unsigned n
)
556 unsigned base
= (c
== 'x') ? 16 : 10;
559 if ((int) n
< 0 && c
== 'd')
561 n
= (unsigned) (-((int) n
));
568 unsigned d
= n
% base
;
569 *p
++ = (d
> 9) ? d
+ 'a' - 10 : d
+ '0';
578 /* Divide N by D, return the quotient, and store the remainder in *R. */
580 grub_divmod64 (grub_uint64_t n
, grub_uint32_t d
, grub_uint32_t
*r
)
582 /* This algorithm is typically implemented by hardware. The idea
583 is to get the highest bit in N, 64 times, by keeping
584 upper(N * 2^i) = upper((Q * 10 + M) * 2^i), where upper
585 represents the high 64 bits in 128-bits space. */
587 unsigned long long q
= 0;
590 /* Skip the slow computation if 32-bit arithmetic is possible. */
594 *r
= ((grub_uint32_t
) n
) % d
;
596 return ((grub_uint32_t
) n
) / d
;
603 if (n
& (1ULL << 63))
622 /* Convert a long long value to a string. This function avoids 64-bit
623 modular arithmetic or divisions. */
625 grub_lltoa (char *str
, int c
, unsigned long long n
)
627 unsigned base
= (c
== 'x') ? 16 : 10;
630 if ((long long) n
< 0 && c
== 'd')
632 n
= (unsigned long long) (-((long long) n
));
641 unsigned d
= (unsigned) (n
& 0xf);
642 *p
++ = (d
> 9) ? d
+ 'a' - 10 : d
+ '0';
651 n
= grub_divmod64 (n
, 10, &m
);
663 grub_vsprintf (char *str
, const char *fmt
, va_list args
)
667 auto void write_char (unsigned char ch
);
668 auto void write_str (const char *s
);
669 auto void write_fill (const char ch
, int n
);
671 void write_char (unsigned char ch
)
681 void write_str (const char *s
)
687 void write_fill (const char ch
, int n
)
690 for (i
= 0; i
< n
; i
++)
694 while ((c
= *fmt
++) != 0)
702 unsigned int format1
= 0;
703 unsigned int format2
= 3;
710 if (*fmt
&& *fmt
=='-')
717 /* Read formatting parameters. */
718 while (*p
&& grub_isdigit (*p
))
724 grub_strncpy (s
, fmt
, p
- fmt
);
728 format1
= grub_strtoul (s
, 0, 10);
734 while (*p
&& grub_isdigit (*p
))
740 grub_strncpy (fstr
, fmt
, p
- fmt
);
741 format2
= grub_strtoul (fstr
, 0, 10);
764 longlongfmt
|= (sizeof (void *) == sizeof (long long));
773 ll
= va_arg (args
, long long);
774 grub_lltoa (tmp
, c
, ll
);
779 n
= va_arg (args
, long);
781 n
= va_arg (args
, int);
782 grub_itoa (tmp
, c
, n
);
784 if (! rightfill
&& grub_strlen (tmp
) < format1
)
785 write_fill (zerofill
, format1
- grub_strlen (tmp
));
787 if (rightfill
&& grub_strlen (tmp
) < format1
)
788 write_fill (zerofill
, format1
- grub_strlen (tmp
));
792 n
= va_arg (args
, int);
793 write_char (n
& 0xff);
798 grub_uint32_t code
= va_arg (args
, grub_uint32_t
);
807 else if (code
<= 0x7ff)
812 else if (code
<= 0xffff)
817 else if (code
<= 0x1fffff)
822 else if (code
<= 0x3ffffff)
827 else if (code
<= 0x7fffffff)
839 write_char (mask
| (code
>> shift
));
841 for (shift
-= 6; shift
>= 0; shift
-= 6)
842 write_char (0x80 | (0x3f & (code
>> shift
)));
847 p
= va_arg (args
, char *);
850 if (!rightfill
&& grub_strlen (p
) < format1
)
851 write_fill (zerofill
, format1
- grub_strlen (p
));
855 if (rightfill
&& grub_strlen (p
) < format1
)
856 write_fill (zerofill
, format1
- grub_strlen (p
));
859 write_str ("(null)");
880 grub_sprintf (char *str
, const char *fmt
, ...)
886 ret
= grub_vsprintf (str
, fmt
, ap
);
892 /* Convert UTF-16 to UTF-8. */
894 grub_utf16_to_utf8 (grub_uint8_t
*dest
, grub_uint16_t
*src
,
897 grub_uint32_t code_high
= 0;
901 grub_uint32_t code
= *src
++;
905 if (code
>= 0xDC00 && code
<= 0xDFFF)
907 /* Surrogate pair. */
908 code
= ((code_high
- 0xD800) << 12) + (code
- 0xDC00) + 0x10000;
910 *dest
++ = (code
>> 18) | 0xF0;
911 *dest
++ = ((code
>> 12) & 0x3F) | 0x80;
912 *dest
++ = ((code
>> 6) & 0x3F) | 0x80;
913 *dest
++ = (code
& 0x3F) | 0x80;
927 else if (code
<= 0x07FF)
929 *dest
++ = (code
>> 6) | 0xC0;
930 *dest
++ = (code
& 0x3F) | 0x80;
932 else if (code
>= 0xD800 && code
<= 0xDBFF)
937 else if (code
>= 0xDC00 && code
<= 0xDFFF)
944 *dest
++ = (code
>> 12) | 0xE0;
945 *dest
++ = ((code
>> 6) & 0x3F) | 0x80;
946 *dest
++ = (code
& 0x3F) | 0x80;
954 /* Convert an UTF-8 string to an UCS-4 string. Return the number of
955 characters converted. DEST must be able to hold at least SIZE
956 characters (when the input is unknown). If an invalid sequence is found,
959 grub_utf8_to_ucs4 (grub_uint32_t
*dest
, const grub_uint8_t
*src
,
962 grub_uint32_t
*p
= dest
;
964 grub_uint32_t code
= 0;
968 grub_uint32_t c
= *src
++;
972 if ((c
& 0xc0) != 0x80)
986 if ((c
& 0x80) == 0x00)
988 else if ((c
& 0xe0) == 0xc0)
993 else if ((c
& 0xf0) == 0xe0)
998 else if ((c
& 0xf8) == 0xf0)
1003 else if ((c
& 0xfc) == 0xf8)
1008 else if ((c
& 0xfe) == 0xfc)
1025 /* Abort GRUB. This function does not return. */
1029 if (grub_term_get_current ())
1031 grub_printf ("\nAborted. Press any key to exit.");
1037 /* GCC emits references to abort(). */
1038 void abort (void) __attribute__ ((alias ("grub_abort")));
1040 #ifdef NEED_ENABLE_EXECUTE_STACK
1041 /* Some gcc versions generate a call to this function
1042 in trampolines for nested functions. */
1043 __enable_execute_stack (void *addr
__attribute__ ((unused
)))