ignore grub-dumpbios
[grub2/phcoder.git] / kern / misc.c
blob5a1253594c14ca15440877a04cda6514773e00c5
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;
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")));
53 char *
54 grub_strcpy (char *dest, const char *src)
56 char *p = dest;
58 while ((*p++ = *src++) != '\0')
61 return dest;
64 char *
65 grub_strncpy (char *dest, const char *src, int c)
67 char *p = dest;
69 while ((*p++ = *src++) != '\0' && --c)
72 return dest;
75 char *
76 grub_stpcpy (char *dest, const char *src)
78 char *d = dest;
79 const char *s = src;
82 *d++ = *s;
83 while (*s++ != '\0');
85 return d - 1;
88 char *
89 grub_strcat (char *dest, const char *src)
91 char *p = dest;
93 while (*p)
94 p++;
96 while ((*p = *src) != '\0')
98 p++;
99 src++;
102 return dest;
105 char *
106 grub_strncat (char *dest, const char *src, int c)
108 char *p = dest;
110 while (*p)
111 p++;
113 while ((*p = *src) != '\0' && c--)
115 p++;
116 src++;
119 *p = '\0';
121 return dest;
125 grub_printf (const char *fmt, ...)
127 va_list ap;
128 int ret;
130 va_start (ap, fmt);
131 ret = grub_vprintf (fmt, ap);
132 va_end (ap);
134 return ret;
137 #ifndef GRUB_UTIL
138 int grub_err_printf (const char *fmt, ...)
139 __attribute__ ((alias("grub_printf")));
140 #endif
142 void
143 grub_real_dprintf (const char *file, const int line, const char *condition,
144 const char *fmt, ...)
146 va_list args;
147 const char *debug = grub_env_get ("debug");
149 if (! debug)
150 return;
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);
157 va_end (args);
162 grub_vprintf (const char *fmt, va_list args)
164 int ret;
166 ret = grub_vsprintf (0, fmt, args);
167 grub_refresh ();
168 return ret;
172 grub_memcmp (const void *s1, const void *s2, grub_size_t n)
174 const char *t1 = s1;
175 const char *t2 = s2;
177 while (n--)
179 if (*t1 != *t2)
180 return (int) *t1 - (int) *t2;
182 t1++;
183 t2++;
186 return 0;
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)
194 while (*s1 && *s2)
196 if (*s1 != *s2)
197 break;
199 s1++;
200 s2++;
203 return (int) *s1 - (int) *s2;
207 grub_strncmp (const char *s1, const char *s2, grub_size_t n)
209 if (n == 0)
210 return 0;
212 while (*s1 && *s2 && --n)
214 if (*s1 != *s2)
215 break;
217 s1++;
218 s2++;
221 return (int) *s1 - (int) *s2;
225 grub_strcasecmp (const char *s1, const char *s2)
227 while (*s1 && *s2)
229 if (grub_tolower (*s1) != grub_tolower (*s2))
230 break;
232 s1++;
233 s2++;
236 return (int) grub_tolower (*s1) - (int) grub_tolower (*s2);
240 grub_strncasecmp (const char *s1, const char *s2, grub_size_t n)
242 if (n == 0)
243 return 0;
245 while (*s1 && *s2 && --n)
247 if (grub_tolower (*s1) != grub_tolower (*s2))
248 break;
250 s1++;
251 s2++;
254 return (int) grub_tolower (*s1) - (int) grub_tolower (*s2);
257 char *
258 grub_strchr (const char *s, int c)
260 while (*s)
262 if (*s == c)
263 return (char *) s;
264 s++;
267 return 0;
270 char *
271 grub_strrchr (const char *s, int c)
273 char *p = 0;
275 while (*s)
277 if (*s == c)
278 p = (char *) s;
279 s++;
282 return p;
285 /* Copied from gnulib.
286 Written by Bruno Haible <bruno@clisp.org>, 2005. */
287 char *
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. */
295 if (*needle != '\0')
297 /* Speed up the following searches of needle by caching its first
298 character. */
299 char b = *needle++;
301 for (;; haystack++)
303 if (*haystack == '\0')
304 /* No match. */
305 return NULL;
306 if (*haystack == b)
307 /* The first character matches. */
309 const char *rhaystack = haystack + 1;
310 const char *rneedle = needle;
312 for (;; rhaystack++, rneedle++)
314 if (*rneedle == '\0')
315 /* Found a match. */
316 return (char *) haystack;
317 if (*rhaystack == '\0')
318 /* No match. */
319 return NULL;
320 if (*rhaystack != *rneedle)
321 /* Nothing in this round. */
322 break;
327 else
328 return (char *) haystack;
332 grub_strword (const char *haystack, const char *needle)
334 const char *n_pos = needle;
336 while (grub_iswordseparator (*haystack))
337 haystack++;
339 while (*haystack)
341 /* Crawl both the needle and the haystack word we're on. */
342 while(*haystack && !grub_iswordseparator (*haystack)
343 && *haystack == *n_pos)
345 haystack++;
346 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)))
354 return 1;
355 else
357 n_pos = needle;
358 while (*haystack && !grub_iswordseparator (*haystack))
359 haystack++;
360 while (grub_iswordseparator (*haystack))
361 haystack++;
365 return 0;
369 grub_iswordseparator (int c)
371 return (grub_isspace (c) || c == ',' || c == ';' || c == '|' || c == '&');
375 grub_isspace (int c)
377 return (c == '\n' || c == '\r' || c == ' ' || c == '\t');
381 grub_isprint (int c)
383 return (c >= ' ' && c <= '~');
387 grub_isalpha (int c)
389 return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z');
393 grub_isdigit (int c)
395 return (c >= '0' && c <= '9');
399 grub_isgraph (int c)
401 return (c >= '!' && c <= '~');
405 grub_tolower (int c)
407 if (c >= 'A' && c <= 'Z')
408 return c - 'A' + 'a';
410 return c;
414 unsigned long
415 grub_strtoul (const char *str, char **end, int base)
417 unsigned long long num;
419 num = grub_strtoull (str, end, base);
420 if (num > ~0UL)
422 grub_error (GRUB_ERR_OUT_OF_RANGE, "overflow is detected");
423 return ~0UL;
426 return (unsigned long) num;
429 unsigned long long
430 grub_strtoull (const char *str, char **end, int base)
432 unsigned long long num = 0;
433 int found = 0;
435 /* Skip white spaces. */
436 while (*str && grub_isspace (*str))
437 str++;
439 /* Guess the base, if not specified. The prefix `0x' means 16, and
440 the prefix `0' means 8. */
441 if (str[0] == '0')
443 if (str[1] == 'x')
445 if (base == 0 || base == 16)
447 base = 16;
448 str += 2;
451 else if (base == 0 && str[1] >= '0' && str[1] <= '7')
452 base = 8;
455 if (base == 0)
456 base = 10;
458 while (*str)
460 unsigned long digit;
462 digit = grub_tolower (*str) - '0';
463 if (digit > 9)
465 digit += '0' - 'a' + 10;
466 if (digit >= (unsigned long) base)
467 break;
470 found = 1;
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");
476 return ~0ULL;
479 num = num * base + digit;
480 str++;
483 if (! found)
485 grub_error (GRUB_ERR_BAD_NUMBER, "unrecognized number");
486 return 0;
489 if (end)
490 *end = (char *) str;
492 return num;
495 char *
496 grub_strdup (const char *s)
498 grub_size_t len;
499 char *p;
501 len = grub_strlen (s) + 1;
502 p = (char *) grub_malloc (len);
503 if (! p)
504 return 0;
506 return grub_memcpy (p, s, len);
509 char *
510 grub_strndup (const char *s, grub_size_t n)
512 grub_size_t len;
513 char *p;
515 len = grub_strlen (s);
516 if (len > n)
517 len = n;
518 p = (char *) grub_malloc (len + 1);
519 if (! p)
520 return 0;
522 grub_memcpy (p, s, len);
523 p[len] = '\0';
524 return p;
527 void *
528 grub_memset (void *s, int c, grub_size_t n)
530 unsigned char *p = (unsigned char *) s;
532 while (n--)
533 *p++ = (unsigned char) c;
535 return s;
537 void *memset (void *s, int c, grub_size_t n)
538 __attribute__ ((alias ("grub_memset")));
540 grub_size_t
541 grub_strlen (const char *s)
543 const char *p = s;
545 while (*p)
546 p++;
548 return p - s;
551 static inline void
552 grub_reverse (char *str)
554 char *p = str + grub_strlen (str) - 1;
556 while (str < p)
558 char tmp;
560 tmp = *str;
561 *str = *p;
562 *p = tmp;
563 str++;
564 p--;
568 static char *
569 grub_itoa (char *str, int c, unsigned n)
571 unsigned base = (c == 'x') ? 16 : 10;
572 char *p;
574 if ((int) n < 0 && c == 'd')
576 n = (unsigned) (-((int) n));
577 *str++ = '-';
580 p = str;
583 unsigned d = n % base;
584 *p++ = (d > 9) ? d + 'a' - 10 : d + '0';
586 while (n /= base);
587 *p = 0;
589 grub_reverse (str);
590 return p;
593 static char *
594 grub_ltoa (char *str, int c, unsigned long n)
596 unsigned long base = (c == 'x') ? 16 : 10;
597 char *p;
599 if ((long) n < 0 && c == 'd')
601 n = (unsigned long) (-((long) n));
602 *str++ = '-';
605 p = str;
608 unsigned long d = n % base;
609 *p++ = (d > 9) ? d + 'a' - 10 : d + '0';
611 while (n /= base);
612 *p = 0;
614 grub_reverse (str);
615 return p;
618 /* Divide N by D, return the quotient, and store the remainder in *R. */
619 grub_uint64_t
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. */
626 unsigned bits = 64;
627 unsigned long long q = 0;
628 unsigned m = 0;
630 /* Skip the slow computation if 32-bit arithmetic is possible. */
631 if (n < 0xffffffff)
633 if (r)
634 *r = ((grub_uint32_t) n) % d;
636 return ((grub_uint32_t) n) / d;
639 while (bits--)
641 m <<= 1;
643 if (n & (1ULL << 63))
644 m |= 1;
646 q <<= 1;
647 n <<= 1;
649 if (m >= d)
651 q |= 1;
652 m -= d;
656 if (r)
657 *r = m;
659 return q;
662 /* Convert a long long value to a string. This function avoids 64-bit
663 modular arithmetic or divisions. */
664 static char *
665 grub_lltoa (char *str, int c, unsigned long long n)
667 unsigned base = (c == 'x') ? 16 : 10;
668 char *p;
670 if ((long long) n < 0 && c == 'd')
672 n = (unsigned long long) (-((long long) n));
673 *str++ = '-';
676 p = str;
678 if (base == 16)
681 unsigned d = (unsigned) (n & 0xf);
682 *p++ = (d > 9) ? d + 'a' - 10 : d + '0';
684 while (n >>= 4);
685 else
686 /* BASE == 10 */
689 unsigned m;
691 n = grub_divmod64 (n, 10, &m);
692 *p++ = m + '0';
694 while (n);
696 *p = 0;
698 grub_reverse (str);
699 return p;
703 grub_vsprintf (char *str, const char *fmt, va_list args)
705 char c;
706 int count = 0;
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)
713 if (str)
714 *str++ = ch;
715 else
716 grub_putchar (ch);
718 count++;
721 void write_str (const char *s)
723 while (*s)
724 write_char (*s++);
727 void write_fill (const char ch, int n)
729 int i;
730 for (i = 0; i < n; i++)
731 write_char (ch);
734 while ((c = *fmt++) != 0)
736 if (c != '%')
737 write_char (c);
738 else
740 char tmp[32];
741 char *p;
742 unsigned int format1 = 0;
743 unsigned int format2 = ~ 0U;
744 char zerofill = ' ';
745 int rightfill = 0;
746 int n;
747 int longfmt = 0;
748 int longlongfmt = 0;
750 if (*fmt && *fmt =='-')
752 rightfill = 1;
753 fmt++;
756 p = (char *) fmt;
757 /* Read formatting parameters. */
758 while (*p && grub_isdigit (*p))
759 p++;
761 if (p > fmt)
763 char s[p - fmt + 1];
764 grub_strncpy (s, fmt, p - fmt);
765 s[p - fmt] = 0;
766 if (s[0] == '0')
767 zerofill = '0';
768 format1 = grub_strtoul (s, 0, 10);
769 fmt = p;
772 if (*p && *p == '.')
774 p++;
775 fmt++;
776 while (*p && grub_isdigit (*p))
777 p++;
779 if (p > fmt)
781 char fstr[p - fmt + 1];
782 grub_strncpy (fstr, fmt, p - fmt);
783 fstr[p - fmt] = 0;
784 format2 = grub_strtoul (fstr, 0, 10);
785 fmt = p;
789 c = *fmt++;
790 if (c == 'l')
792 longfmt = 1;
793 c = *fmt++;
794 if (c == 'l')
796 longlongfmt = 1;
797 c = *fmt++;
801 switch (c)
803 case 'p':
804 write_str ("0x");
805 c = 'x';
806 longlongfmt |= (sizeof (void *) == sizeof (long long));
807 /* fall through */
808 case 'x':
809 case 'u':
810 case 'd':
811 if (longlongfmt)
813 long long ll;
815 ll = va_arg (args, long long);
816 grub_lltoa (tmp, c, ll);
818 else if (longfmt)
820 long l = va_arg (args, long);
821 grub_ltoa (tmp, c, l);
823 else
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));
830 write_str (tmp);
831 if (rightfill && grub_strlen (tmp) < format1)
832 write_fill (zerofill, format1 - grub_strlen (tmp));
833 break;
835 case 'c':
836 n = va_arg (args, int);
837 write_char (n & 0xff);
838 break;
840 case 'C':
842 grub_uint32_t code = va_arg (args, grub_uint32_t);
843 int shift;
844 unsigned mask;
846 if (code <= 0x7f)
848 shift = 0;
849 mask = 0;
851 else if (code <= 0x7ff)
853 shift = 6;
854 mask = 0xc0;
856 else if (code <= 0xffff)
858 shift = 12;
859 mask = 0xe0;
861 else if (code <= 0x1fffff)
863 shift = 18;
864 mask = 0xf0;
866 else if (code <= 0x3ffffff)
868 shift = 24;
869 mask = 0xf8;
871 else if (code <= 0x7fffffff)
873 shift = 30;
874 mask = 0xfc;
876 else
878 code = '?';
879 shift = 0;
880 mask = 0;
883 write_char (mask | (code >> shift));
885 for (shift -= 6; shift >= 0; shift -= 6)
886 write_char (0x80 | (0x3f & (code >> shift)));
888 break;
890 case 's':
891 p = va_arg (args, char *);
892 if (p)
894 grub_size_t len = 0;
895 while (len < format2 && p[len])
896 len++;
898 if (!rightfill && len < format1)
899 write_fill (zerofill, format1 - len);
901 grub_size_t i;
902 for (i = 0; i < len; i++)
903 write_char (*p++);
905 if (rightfill && len < format1)
906 write_fill (zerofill, format1 - len);
908 else
909 write_str ("(null)");
911 break;
913 default:
914 write_char (c);
915 break;
920 if (str)
921 *str = '\0';
923 if (count && !str)
924 grub_refresh ();
926 return count;
930 grub_sprintf (char *str, const char *fmt, ...)
932 va_list ap;
933 int ret;
935 va_start (ap, fmt);
936 ret = grub_vsprintf (str, fmt, ap);
937 va_end (ap);
939 return ret;
942 /* Convert UTF-16 to UTF-8. */
943 grub_uint8_t *
944 grub_utf16_to_utf8 (grub_uint8_t *dest, grub_uint16_t *src,
945 grub_size_t size)
947 grub_uint32_t code_high = 0;
949 while (size--)
951 grub_uint32_t code = *src++;
953 if (code_high)
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;
965 else
967 /* Error... */
968 *dest++ = '?';
971 code_high = 0;
973 else
975 if (code <= 0x007F)
976 *dest++ = code;
977 else if (code <= 0x07FF)
979 *dest++ = (code >> 6) | 0xC0;
980 *dest++ = (code & 0x3F) | 0x80;
982 else if (code >= 0xD800 && code <= 0xDBFF)
984 code_high = code;
985 continue;
987 else if (code >= 0xDC00 && code <= 0xDFFF)
989 /* Error... */
990 *dest++ = '?';
992 else
994 *dest++ = (code >> 12) | 0xE0;
995 *dest++ = ((code >> 6) & 0x3F) | 0x80;
996 *dest++ = (code & 0x3F) | 0x80;
1001 return dest;
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. */
1010 grub_ssize_t
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;
1016 int count = 0;
1017 grub_uint32_t code = 0;
1019 if (srcend)
1020 *srcend = src;
1022 while (srcsize && destsize)
1024 grub_uint32_t c = *src++;
1025 if (srcsize != (grub_size_t)-1)
1026 srcsize--;
1027 if (count)
1029 if ((c & 0xc0) != 0x80)
1031 /* invalid */
1032 return -1;
1034 else
1036 code <<= 6;
1037 code |= (c & 0x3f);
1038 count--;
1041 else
1043 if (c == 0)
1044 break;
1046 if ((c & 0x80) == 0x00)
1047 code = c;
1048 else if ((c & 0xe0) == 0xc0)
1050 count = 1;
1051 code = c & 0x1f;
1053 else if ((c & 0xf0) == 0xe0)
1055 count = 2;
1056 code = c & 0x0f;
1058 else if ((c & 0xf8) == 0xf0)
1060 count = 3;
1061 code = c & 0x07;
1063 else if ((c & 0xfc) == 0xf8)
1065 count = 4;
1066 code = c & 0x03;
1068 else if ((c & 0xfe) == 0xfc)
1070 count = 5;
1071 code = c & 0x01;
1073 else
1074 return -1;
1077 if (count == 0)
1079 *p++ = code;
1080 destsize--;
1084 if (srcend)
1085 *srcend = src;
1086 return p - dest;
1089 /* Abort GRUB. This function does not return. */
1090 void
1091 grub_abort (void)
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.");
1100 grub_getkey ();
1104 grub_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)))
1115 #endif