Merge branch 'dmigen' into phcoder
[grub2/phcoder.git] / kern / misc.c
blob3fa84e91ded245bb81cb993b299d0b7b535a5044
1 /* misc.c - definitions of misc functions */
2 /*
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>
21 #include <grub/err.h>
22 #include <grub/mm.h>
23 #include <stdarg.h>
24 #include <grub/term.h>
25 #include <grub/env.h>
27 void *
28 grub_memmove (void *dest, const void *src, grub_size_t n)
30 char *d = (char *) dest;
31 const char *s = (const char *) src;
33 if (d < s)
34 while (n--)
35 *d++ = *s++;
36 else
38 d += n;
39 s += n;
41 while (n--)
42 *--d = *--s;
45 return dest;
48 #ifndef APPLE_CC
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")));
54 #else
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);
63 #endif
65 char *
66 grub_strcpy (char *dest, const char *src)
68 char *p = dest;
70 while ((*p++ = *src++) != '\0')
73 return dest;
76 char *
77 grub_strncpy (char *dest, const char *src, int c)
79 char *p = dest;
81 while ((*p++ = *src++) != '\0' && --c)
84 return dest;
87 char *
88 grub_stpcpy (char *dest, const char *src)
90 char *d = dest;
91 const char *s = src;
94 *d++ = *s;
95 while (*s++ != '\0');
97 return d - 1;
100 char *
101 grub_strcat (char *dest, const char *src)
103 char *p = dest;
105 while (*p)
106 p++;
108 while ((*p = *src) != '\0')
110 p++;
111 src++;
114 return dest;
117 char *
118 grub_strncat (char *dest, const char *src, int c)
120 char *p = dest;
122 while (*p)
123 p++;
125 while ((*p = *src) != '\0' && c--)
127 p++;
128 src++;
131 *p = '\0';
133 return dest;
137 grub_printf (const char *fmt, ...)
139 va_list ap;
140 int ret;
142 va_start (ap, fmt);
143 ret = grub_vprintf (fmt, ap);
144 va_end (ap);
146 return ret;
149 #if defined (APPLE_CC) && ! defined (GRUB_UTIL)
151 grub_err_printf (const char *fmt, ...)
153 va_list ap;
154 int ret;
156 va_start (ap, fmt);
157 ret = grub_vprintf (fmt, ap);
158 va_end (ap);
160 return ret;
162 #endif
164 #if ! defined (APPLE_CC) && ! defined (GRUB_UTIL)
165 int grub_err_printf (const char *fmt, ...)
166 __attribute__ ((alias("grub_printf")));
167 #endif
169 void
170 grub_real_dprintf (const char *file, const int line, const char *condition,
171 const char *fmt, ...)
173 va_list args;
174 const char *debug = grub_env_get ("debug");
176 if (! debug)
177 return;
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);
184 va_end (args);
189 grub_vprintf (const char *fmt, va_list args)
191 int ret;
193 ret = grub_vsprintf (0, fmt, args);
194 grub_refresh ();
195 return ret;
199 grub_memcmp (const void *s1, const void *s2, grub_size_t n)
201 const char *t1 = s1;
202 const char *t2 = s2;
204 while (n--)
206 if (*t1 != *t2)
207 return (int) *t1 - (int) *t2;
209 t1++;
210 t2++;
213 return 0;
215 #ifndef APPLE_CC
216 int memcmp (const void *s1, const void *s2, grub_size_t n)
217 __attribute__ ((alias ("grub_memcmp")));
218 #endif
221 grub_strcmp (const char *s1, const char *s2)
223 while (*s1 && *s2)
225 if (*s1 != *s2)
226 break;
228 s1++;
229 s2++;
232 return (int) *s1 - (int) *s2;
236 grub_strncmp (const char *s1, const char *s2, grub_size_t n)
238 if (n == 0)
239 return 0;
241 while (*s1 && *s2 && --n)
243 if (*s1 != *s2)
244 break;
246 s1++;
247 s2++;
250 return (int) *s1 - (int) *s2;
254 grub_strcasecmp (const char *s1, const char *s2)
256 while (*s1 && *s2)
258 if (grub_tolower (*s1) != grub_tolower (*s2))
259 break;
261 s1++;
262 s2++;
265 return (int) grub_tolower (*s1) - (int) grub_tolower (*s2);
269 grub_strncasecmp (const char *s1, const char *s2, grub_size_t n)
271 if (n == 0)
272 return 0;
274 while (*s1 && *s2 && --n)
276 if (grub_tolower (*s1) != grub_tolower (*s2))
277 break;
279 s1++;
280 s2++;
283 return (int) grub_tolower (*s1) - (int) grub_tolower (*s2);
286 char *
287 grub_strchr (const char *s, int c)
289 while (*s)
291 if (*s == c)
292 return (char *) s;
293 s++;
296 return 0;
299 char *
300 grub_strrchr (const char *s, int c)
302 char *p = 0;
304 while (*s)
306 if (*s == c)
307 p = (char *) s;
308 s++;
311 return p;
314 /* Copied from gnulib.
315 Written by Bruno Haible <bruno@clisp.org>, 2005. */
316 char *
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. */
324 if (*needle != '\0')
326 /* Speed up the following searches of needle by caching its first
327 character. */
328 char b = *needle++;
330 for (;; haystack++)
332 if (*haystack == '\0')
333 /* No match. */
334 return NULL;
335 if (*haystack == b)
336 /* The first character matches. */
338 const char *rhaystack = haystack + 1;
339 const char *rneedle = needle;
341 for (;; rhaystack++, rneedle++)
343 if (*rneedle == '\0')
344 /* Found a match. */
345 return (char *) haystack;
346 if (*rhaystack == '\0')
347 /* No match. */
348 return NULL;
349 if (*rhaystack != *rneedle)
350 /* Nothing in this round. */
351 break;
356 else
357 return (char *) haystack;
361 grub_strword (const char *haystack, const char *needle)
363 const char *n_pos = needle;
365 while (grub_iswordseparator (*haystack))
366 haystack++;
368 while (*haystack)
370 /* Crawl both the needle and the haystack word we're on. */
371 while(*haystack && !grub_iswordseparator (*haystack)
372 && *haystack == *n_pos)
374 haystack++;
375 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)))
383 return 1;
384 else
386 n_pos = needle;
387 while (*haystack && !grub_iswordseparator (*haystack))
388 haystack++;
389 while (grub_iswordseparator (*haystack))
390 haystack++;
394 return 0;
398 grub_iswordseparator (int c)
400 return (grub_isspace (c) || c == ',' || c == ';' || c == '|' || c == '&');
404 grub_isspace (int c)
406 return (c == '\n' || c == '\r' || c == ' ' || c == '\t');
410 grub_iscntrl (int c)
412 return (c >= 0x00 && c <= 0x1F) || c == 0x7F;
416 grub_isprint (int c)
418 return (c >= ' ' && c <= '~');
422 grub_isalpha (int c)
424 return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z');
428 grub_isalnum (int c)
430 return grub_isalpha (c) || grub_isdigit (c);
434 grub_isdigit (int c)
436 return (c >= '0' && c <= '9');
440 grub_isgraph (int c)
442 return (c >= '!' && c <= '~');
446 grub_tolower (int c)
448 if (c >= 'A' && c <= 'Z')
449 return c - 'A' + 'a';
451 return c;
454 long
455 grub_strtol (const char *str, char **end, int base)
457 int negative = 0;
459 while (*str && grub_isspace (*str))
460 str++;
462 if (*str == '-')
464 negative = 1;
465 str++;
468 unsigned long long magnitude;
469 magnitude = grub_strtoull (str, end, base);
470 if (negative)
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);
479 else
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;
490 unsigned long
491 grub_strtoul (const char *str, char **end, int base)
493 unsigned long long num;
495 num = grub_strtoull (str, end, base);
496 if (num > ~0UL)
498 grub_error (GRUB_ERR_OUT_OF_RANGE, "overflow is detected");
499 return ~0UL;
502 return (unsigned long) num;
505 unsigned long long
506 grub_strtoull (const char *str, char **end, int base)
508 unsigned long long num = 0;
509 int found = 0;
511 /* Skip white spaces. */
512 while (*str && grub_isspace (*str))
513 str++;
515 /* Guess the base, if not specified. The prefix `0x' means 16, and
516 the prefix `0' means 8. */
517 if (str[0] == '0')
519 if (str[1] == 'x')
521 if (base == 0 || base == 16)
523 base = 16;
524 str += 2;
527 else if (base == 0 && str[1] >= '0' && str[1] <= '7')
528 base = 8;
531 if (base == 0)
532 base = 10;
534 while (*str)
536 unsigned long digit;
538 digit = grub_tolower (*str) - '0';
539 if (digit > 9)
541 digit += '0' - 'a' + 10;
542 if (digit >= (unsigned long) base)
543 break;
546 found = 1;
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");
552 return ~0ULL;
555 num = num * base + digit;
556 str++;
559 if (! found)
561 grub_error (GRUB_ERR_BAD_NUMBER, "unrecognized number");
562 return 0;
565 if (end)
566 *end = (char *) str;
568 return num;
571 char *
572 grub_strdup (const char *s)
574 grub_size_t len;
575 char *p;
577 len = grub_strlen (s) + 1;
578 p = (char *) grub_malloc (len);
579 if (! p)
580 return 0;
582 return grub_memcpy (p, s, len);
585 char *
586 grub_strndup (const char *s, grub_size_t n)
588 grub_size_t len;
589 char *p;
591 len = grub_strlen (s);
592 if (len > n)
593 len = n;
594 p = (char *) grub_malloc (len + 1);
595 if (! p)
596 return 0;
598 grub_memcpy (p, s, len);
599 p[len] = '\0';
600 return p;
603 void *
604 grub_memset (void *s, int c, grub_size_t n)
606 unsigned char *p = (unsigned char *) s;
608 while (n--)
609 *p++ = (unsigned char) c;
611 return s;
613 #ifndef APPLE_CC
614 void *memset (void *s, int c, grub_size_t n)
615 __attribute__ ((alias ("grub_memset")));
616 #endif
618 grub_size_t
619 grub_strlen (const char *s)
621 const char *p = s;
623 while (*p)
624 p++;
626 return p - s;
629 static inline void
630 grub_reverse (char *str)
632 char *p = str + grub_strlen (str) - 1;
634 while (str < p)
636 char tmp;
638 tmp = *str;
639 *str = *p;
640 *p = tmp;
641 str++;
642 p--;
646 /* Divide N by D, return the quotient, and store the remainder in *R. */
647 grub_uint64_t
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. */
654 unsigned bits = 64;
655 unsigned long long q = 0;
656 unsigned m = 0;
658 /* Skip the slow computation if 32-bit arithmetic is possible. */
659 if (n < 0xffffffff)
661 if (r)
662 *r = ((grub_uint32_t) n) % d;
664 return ((grub_uint32_t) n) / d;
667 while (bits--)
669 m <<= 1;
671 if (n & (1ULL << 63))
672 m |= 1;
674 q <<= 1;
675 n <<= 1;
677 if (m >= d)
679 q |= 1;
680 m -= d;
684 if (r)
685 *r = m;
687 return q;
690 /* Convert a long long value to a string. This function avoids 64-bit
691 modular arithmetic or divisions. */
692 static char *
693 grub_lltoa (char *str, int c, unsigned long long n)
695 unsigned base = (c == 'x') ? 16 : 10;
696 char *p;
698 if ((long long) n < 0 && c == 'd')
700 n = (unsigned long long) (-((long long) n));
701 *str++ = '-';
704 p = str;
706 if (base == 16)
709 unsigned d = (unsigned) (n & 0xf);
710 *p++ = (d > 9) ? d + 'a' - 10 : d + '0';
712 while (n >>= 4);
713 else
714 /* BASE == 10 */
717 unsigned m;
719 n = grub_divmod64 (n, 10, &m);
720 *p++ = m + '0';
722 while (n);
724 *p = 0;
726 grub_reverse (str);
727 return p;
731 grub_vsprintf (char *str, const char *fmt, va_list args)
733 char c;
734 int count = 0;
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)
741 if (str)
742 *str++ = ch;
743 else
744 grub_putchar (ch);
746 count++;
749 void write_str (const char *s)
751 while (*s)
752 write_char (*s++);
755 void write_fill (const char ch, int n)
757 int i;
758 for (i = 0; i < n; i++)
759 write_char (ch);
762 while ((c = *fmt++) != 0)
764 if (c != '%')
765 write_char (c);
766 else
768 char tmp[32];
769 char *p;
770 unsigned int format1 = 0;
771 unsigned int format2 = ~ 0U;
772 char zerofill = ' ';
773 int rightfill = 0;
774 int n;
775 int longfmt = 0;
776 int longlongfmt = 0;
777 int unsig = 0;
779 if (*fmt && *fmt =='-')
781 rightfill = 1;
782 fmt++;
785 p = (char *) fmt;
786 /* Read formatting parameters. */
787 while (*p && grub_isdigit (*p))
788 p++;
790 if (p > fmt)
792 char s[p - fmt + 1];
793 grub_strncpy (s, fmt, p - fmt);
794 s[p - fmt] = 0;
795 if (s[0] == '0')
796 zerofill = '0';
797 format1 = grub_strtoul (s, 0, 10);
798 fmt = p;
801 if (*p && *p == '.')
803 p++;
804 fmt++;
805 while (*p && grub_isdigit (*p))
806 p++;
808 if (p > fmt)
810 char fstr[p - fmt + 1];
811 grub_strncpy (fstr, fmt, p - fmt);
812 fstr[p - fmt] = 0;
813 format2 = grub_strtoul (fstr, 0, 10);
814 fmt = p;
818 c = *fmt++;
819 if (c == 'l')
821 longfmt = 1;
822 c = *fmt++;
823 if (c == 'l')
825 longlongfmt = 1;
826 c = *fmt++;
830 switch (c)
832 case 'p':
833 write_str ("0x");
834 c = 'x';
835 longlongfmt |= (sizeof (void *) == sizeof (long long));
836 /* Fall through. */
837 case 'x':
838 case 'u':
839 unsig = 1;
840 /* Fall through. */
841 case 'd':
842 if (longlongfmt)
844 long long ll;
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);
854 else if (longfmt)
856 long l = va_arg (args, long);
857 grub_lltoa (tmp, c, l);
859 else if (unsig)
861 unsigned u = va_arg (args, unsigned);
862 grub_lltoa (tmp, c, u);
864 else
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));
871 write_str (tmp);
872 if (rightfill && grub_strlen (tmp) < format1)
873 write_fill (zerofill, format1 - grub_strlen (tmp));
874 break;
876 case 'c':
877 n = va_arg (args, int);
878 write_char (n & 0xff);
879 break;
881 case 'C':
883 grub_uint32_t code = va_arg (args, grub_uint32_t);
884 int shift;
885 unsigned mask;
887 if (code <= 0x7f)
889 shift = 0;
890 mask = 0;
892 else if (code <= 0x7ff)
894 shift = 6;
895 mask = 0xc0;
897 else if (code <= 0xffff)
899 shift = 12;
900 mask = 0xe0;
902 else if (code <= 0x1fffff)
904 shift = 18;
905 mask = 0xf0;
907 else if (code <= 0x3ffffff)
909 shift = 24;
910 mask = 0xf8;
912 else if (code <= 0x7fffffff)
914 shift = 30;
915 mask = 0xfc;
917 else
919 code = '?';
920 shift = 0;
921 mask = 0;
924 write_char (mask | (code >> shift));
926 for (shift -= 6; shift >= 0; shift -= 6)
927 write_char (0x80 | (0x3f & (code >> shift)));
929 break;
931 case 's':
932 p = va_arg (args, char *);
933 if (p)
935 grub_size_t len = 0;
936 while (len < format2 && p[len])
937 len++;
939 if (!rightfill && len < format1)
940 write_fill (zerofill, format1 - len);
942 grub_size_t i;
943 for (i = 0; i < len; i++)
944 write_char (*p++);
946 if (rightfill && len < format1)
947 write_fill (zerofill, format1 - len);
949 else
950 write_str ("(null)");
952 break;
954 default:
955 write_char (c);
956 break;
961 if (str)
962 *str = '\0';
964 if (count && !str)
965 grub_refresh ();
967 return count;
971 grub_sprintf (char *str, const char *fmt, ...)
973 va_list ap;
974 int ret;
976 va_start (ap, fmt);
977 ret = grub_vsprintf (str, fmt, ap);
978 va_end (ap);
980 return ret;
983 /* Convert UTF-16 to UTF-8. */
984 grub_uint8_t *
985 grub_utf16_to_utf8 (grub_uint8_t *dest, grub_uint16_t *src,
986 grub_size_t size)
988 grub_uint32_t code_high = 0;
990 while (size--)
992 grub_uint32_t code = *src++;
994 if (code_high)
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;
1006 else
1008 /* Error... */
1009 *dest++ = '?';
1012 code_high = 0;
1014 else
1016 if (code <= 0x007F)
1017 *dest++ = code;
1018 else if (code <= 0x07FF)
1020 *dest++ = (code >> 6) | 0xC0;
1021 *dest++ = (code & 0x3F) | 0x80;
1023 else if (code >= 0xD800 && code <= 0xDBFF)
1025 code_high = code;
1026 continue;
1028 else if (code >= 0xDC00 && code <= 0xDFFF)
1030 /* Error... */
1031 *dest++ = '?';
1033 else
1035 *dest++ = (code >> 12) | 0xE0;
1036 *dest++ = ((code >> 6) & 0x3F) | 0x80;
1037 *dest++ = (code & 0x3F) | 0x80;
1042 return dest;
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. */
1051 grub_ssize_t
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;
1057 int count = 0;
1058 grub_uint32_t code = 0;
1060 if (srcend)
1061 *srcend = src;
1063 while (srcsize && destsize)
1065 grub_uint32_t c = *src++;
1066 if (srcsize != (grub_size_t)-1)
1067 srcsize--;
1068 if (count)
1070 if ((c & 0xc0) != 0x80)
1072 /* invalid */
1073 return -1;
1075 else
1077 code <<= 6;
1078 code |= (c & 0x3f);
1079 count--;
1082 else
1084 if (c == 0)
1085 break;
1087 if ((c & 0x80) == 0x00)
1088 code = c;
1089 else if ((c & 0xe0) == 0xc0)
1091 count = 1;
1092 code = c & 0x1f;
1094 else if ((c & 0xf0) == 0xe0)
1096 count = 2;
1097 code = c & 0x0f;
1099 else if ((c & 0xf8) == 0xf0)
1101 count = 3;
1102 code = c & 0x07;
1104 else if ((c & 0xfc) == 0xf8)
1106 count = 4;
1107 code = c & 0x03;
1109 else if ((c & 0xfe) == 0xfc)
1111 count = 5;
1112 code = c & 0x01;
1114 else
1115 return -1;
1118 if (count == 0)
1120 *p++ = code;
1121 destsize--;
1125 if (srcend)
1126 *srcend = src;
1127 return p - dest;
1130 /* Abort GRUB. This function does not return. */
1131 void
1132 grub_abort (void)
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.");
1141 grub_getkey ();
1145 grub_exit ();
1148 #ifndef APPLE_CC
1149 /* GCC emits references to abort(). */
1150 void abort (void) __attribute__ ((alias ("grub_abort")));
1151 #endif
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)))
1159 #endif