2009-11-21 Samuel Thibault <samuel.thibault@ens-lyon.org>
[grub2.git] / kern / misc.c
blobcacfbc7532416d6e6048b75ad80ac061c128c2ba
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 static int
28 grub_iswordseparator (int c)
30 return (grub_isspace (c) || c == ',' || c == ';' || c == '|' || c == '&');
33 void *
34 grub_memmove (void *dest, const void *src, grub_size_t n)
36 char *d = (char *) dest;
37 const char *s = (const char *) src;
39 if (d < s)
40 while (n--)
41 *d++ = *s++;
42 else
44 d += n;
45 s += n;
47 while (n--)
48 *--d = *--s;
51 return dest;
54 #ifndef APPLE_CC
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")));
60 #else
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);
69 #endif
71 char *
72 grub_strcpy (char *dest, const char *src)
74 char *p = dest;
76 while ((*p++ = *src++) != '\0')
79 return dest;
82 char *
83 grub_strncpy (char *dest, const char *src, int c)
85 char *p = dest;
87 while ((*p++ = *src++) != '\0' && --c)
90 return dest;
93 char *
94 grub_stpcpy (char *dest, const char *src)
96 char *d = dest;
97 const char *s = src;
100 *d++ = *s;
101 while (*s++ != '\0');
103 return d - 1;
107 grub_printf (const char *fmt, ...)
109 va_list ap;
110 int ret;
112 va_start (ap, fmt);
113 ret = grub_vprintf (fmt, ap);
114 va_end (ap);
116 return ret;
119 #if defined (APPLE_CC) && ! defined (GRUB_UTIL)
121 grub_err_printf (const char *fmt, ...)
123 va_list ap;
124 int ret;
126 va_start (ap, fmt);
127 ret = grub_vprintf (fmt, ap);
128 va_end (ap);
130 return ret;
132 #endif
134 #if ! defined (APPLE_CC) && ! defined (GRUB_UTIL)
135 int grub_err_printf (const char *fmt, ...)
136 __attribute__ ((alias("grub_printf")));
137 #endif
139 void
140 grub_real_dprintf (const char *file, const int line, const char *condition,
141 const char *fmt, ...)
143 va_list args;
144 const char *debug = grub_env_get ("debug");
146 if (! debug)
147 return;
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);
154 va_end (args);
159 grub_vprintf (const char *fmt, va_list args)
161 int ret;
163 ret = grub_vsprintf (0, fmt, args);
164 grub_refresh ();
165 return ret;
169 grub_memcmp (const void *s1, const void *s2, grub_size_t n)
171 const char *t1 = s1;
172 const char *t2 = s2;
174 while (n--)
176 if (*t1 != *t2)
177 return (int) *t1 - (int) *t2;
179 t1++;
180 t2++;
183 return 0;
185 #ifndef APPLE_CC
186 int memcmp (const void *s1, const void *s2, grub_size_t n)
187 __attribute__ ((alias ("grub_memcmp")));
188 #endif
191 grub_strcmp (const char *s1, const char *s2)
193 while (*s1 && *s2)
195 if (*s1 != *s2)
196 break;
198 s1++;
199 s2++;
202 return (int) *s1 - (int) *s2;
206 grub_strncmp (const char *s1, const char *s2, grub_size_t n)
208 if (n == 0)
209 return 0;
211 while (*s1 && *s2 && --n)
213 if (*s1 != *s2)
214 break;
216 s1++;
217 s2++;
220 return (int) *s1 - (int) *s2;
223 char *
224 grub_strchr (const char *s, int c)
228 if (*s == c)
229 return (char *) s;
231 while (*s++);
233 return 0;
236 char *
237 grub_strrchr (const char *s, int c)
239 char *p = NULL;
243 if (*s == c)
244 p = (char *) s;
246 while (*s++);
248 return p;
251 /* Copied from gnulib.
252 Written by Bruno Haible <bruno@clisp.org>, 2005. */
253 char *
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. */
261 if (*needle != '\0')
263 /* Speed up the following searches of needle by caching its first
264 character. */
265 char b = *needle++;
267 for (;; haystack++)
269 if (*haystack == '\0')
270 /* No match. */
271 return NULL;
272 if (*haystack == b)
273 /* The first character matches. */
275 const char *rhaystack = haystack + 1;
276 const char *rneedle = needle;
278 for (;; rhaystack++, rneedle++)
280 if (*rneedle == '\0')
281 /* Found a match. */
282 return (char *) haystack;
283 if (*rhaystack == '\0')
284 /* No match. */
285 return NULL;
286 if (*rhaystack != *rneedle)
287 /* Nothing in this round. */
288 break;
293 else
294 return (char *) haystack;
298 grub_strword (const char *haystack, const char *needle)
300 const char *n_pos = needle;
302 while (grub_iswordseparator (*haystack))
303 haystack++;
305 while (*haystack)
307 /* Crawl both the needle and the haystack word we're on. */
308 while(*haystack && !grub_iswordseparator (*haystack)
309 && *haystack == *n_pos)
311 haystack++;
312 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)))
320 return 1;
321 else
323 n_pos = needle;
324 while (*haystack && !grub_iswordseparator (*haystack))
325 haystack++;
326 while (grub_iswordseparator (*haystack))
327 haystack++;
331 return 0;
335 grub_isspace (int c)
337 return (c == '\n' || c == '\r' || c == ' ' || c == '\t');
341 grub_isprint (int c)
343 return (c >= ' ' && c <= '~');
347 unsigned long
348 grub_strtoul (const char *str, char **end, int base)
350 unsigned long long num;
352 num = grub_strtoull (str, end, base);
353 if (num > ~0UL)
355 grub_error (GRUB_ERR_OUT_OF_RANGE, "overflow is detected");
356 return ~0UL;
359 return (unsigned long) num;
362 unsigned long long
363 grub_strtoull (const char *str, char **end, int base)
365 unsigned long long num = 0;
366 int found = 0;
368 /* Skip white spaces. */
369 while (*str && grub_isspace (*str))
370 str++;
372 /* Guess the base, if not specified. The prefix `0x' means 16, and
373 the prefix `0' means 8. */
374 if (str[0] == '0')
376 if (str[1] == 'x')
378 if (base == 0 || base == 16)
380 base = 16;
381 str += 2;
384 else if (base == 0 && str[1] >= '0' && str[1] <= '7')
385 base = 8;
388 if (base == 0)
389 base = 10;
391 while (*str)
393 unsigned long digit;
395 digit = grub_tolower (*str) - '0';
396 if (digit > 9)
398 digit += '0' - 'a' + 10;
399 if (digit >= (unsigned long) base)
400 break;
403 found = 1;
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");
409 return ~0ULL;
412 num = num * base + digit;
413 str++;
416 if (! found)
418 grub_error (GRUB_ERR_BAD_NUMBER, "unrecognized number");
419 return 0;
422 if (end)
423 *end = (char *) str;
425 return num;
428 char *
429 grub_strdup (const char *s)
431 grub_size_t len;
432 char *p;
434 len = grub_strlen (s) + 1;
435 p = (char *) grub_malloc (len);
436 if (! p)
437 return 0;
439 return grub_memcpy (p, s, len);
442 char *
443 grub_strndup (const char *s, grub_size_t n)
445 grub_size_t len;
446 char *p;
448 len = grub_strlen (s);
449 if (len > n)
450 len = n;
451 p = (char *) grub_malloc (len + 1);
452 if (! p)
453 return 0;
455 grub_memcpy (p, s, len);
456 p[len] = '\0';
457 return p;
460 void *
461 grub_memset (void *s, int c, grub_size_t n)
463 unsigned char *p = (unsigned char *) s;
465 while (n--)
466 *p++ = (unsigned char) c;
468 return s;
470 #ifndef APPLE_CC
471 void *memset (void *s, int c, grub_size_t n)
472 __attribute__ ((alias ("grub_memset")));
473 #endif
475 grub_size_t
476 grub_strlen (const char *s)
478 const char *p = s;
480 while (*p)
481 p++;
483 return p - s;
486 static inline void
487 grub_reverse (char *str)
489 char *p = str + grub_strlen (str) - 1;
491 while (str < p)
493 char tmp;
495 tmp = *str;
496 *str = *p;
497 *p = tmp;
498 str++;
499 p--;
503 /* Divide N by D, return the quotient, and store the remainder in *R. */
504 grub_uint64_t
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. */
511 unsigned bits = 64;
512 unsigned long long q = 0;
513 unsigned m = 0;
515 /* Skip the slow computation if 32-bit arithmetic is possible. */
516 if (n < 0xffffffff)
518 if (r)
519 *r = ((grub_uint32_t) n) % d;
521 return ((grub_uint32_t) n) / d;
524 while (bits--)
526 m <<= 1;
528 if (n & (1ULL << 63))
529 m |= 1;
531 q <<= 1;
532 n <<= 1;
534 if (m >= d)
536 q |= 1;
537 m -= d;
541 if (r)
542 *r = m;
544 return q;
547 /* Convert a long long value to a string. This function avoids 64-bit
548 modular arithmetic or divisions. */
549 static char *
550 grub_lltoa (char *str, int c, unsigned long long n)
552 unsigned base = (c == 'x') ? 16 : 10;
553 char *p;
555 if ((long long) n < 0 && c == 'd')
557 n = (unsigned long long) (-((long long) n));
558 *str++ = '-';
561 p = str;
563 if (base == 16)
566 unsigned d = (unsigned) (n & 0xf);
567 *p++ = (d > 9) ? d + 'a' - 10 : d + '0';
569 while (n >>= 4);
570 else
571 /* BASE == 10 */
574 unsigned m;
576 n = grub_divmod64 (n, 10, &m);
577 *p++ = m + '0';
579 while (n);
581 *p = 0;
583 grub_reverse (str);
584 return p;
588 grub_vsprintf (char *str, const char *fmt, va_list args)
590 char c;
591 int count = 0;
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)
598 if (str)
599 *str++ = ch;
600 else
601 grub_putchar (ch);
603 count++;
606 void write_str (const char *s)
608 while (*s)
609 write_char (*s++);
612 void write_fill (const char ch, int n)
614 int i;
615 for (i = 0; i < n; i++)
616 write_char (ch);
619 while ((c = *fmt++) != 0)
621 if (c != '%')
622 write_char (c);
623 else
625 char tmp[32];
626 char *p;
627 unsigned int format1 = 0;
628 unsigned int format2 = ~ 0U;
629 char zerofill = ' ';
630 int rightfill = 0;
631 int n;
632 int longfmt = 0;
633 int longlongfmt = 0;
634 int unsig = 0;
636 if (*fmt && *fmt =='-')
638 rightfill = 1;
639 fmt++;
642 p = (char *) fmt;
643 /* Read formatting parameters. */
644 while (*p && grub_isdigit (*p))
645 p++;
647 if (p > fmt)
649 char s[p - fmt + 1];
650 grub_strncpy (s, fmt, p - fmt);
651 s[p - fmt] = 0;
652 if (s[0] == '0')
653 zerofill = '0';
654 format1 = grub_strtoul (s, 0, 10);
655 fmt = p;
658 if (*p && *p == '.')
660 p++;
661 fmt++;
662 while (*p && grub_isdigit (*p))
663 p++;
665 if (p > fmt)
667 char fstr[p - fmt + 1];
668 grub_strncpy (fstr, fmt, p - fmt);
669 fstr[p - fmt] = 0;
670 format2 = grub_strtoul (fstr, 0, 10);
671 fmt = p;
675 c = *fmt++;
676 if (c == 'l')
678 longfmt = 1;
679 c = *fmt++;
680 if (c == 'l')
682 longlongfmt = 1;
683 c = *fmt++;
687 switch (c)
689 case 'p':
690 write_str ("0x");
691 c = 'x';
692 longlongfmt |= (sizeof (void *) == sizeof (long long));
693 /* Fall through. */
694 case 'x':
695 case 'u':
696 unsig = 1;
697 /* Fall through. */
698 case 'd':
699 if (longlongfmt)
701 long long ll;
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);
711 else if (longfmt)
713 long l = va_arg (args, long);
714 grub_lltoa (tmp, c, l);
716 else if (unsig)
718 unsigned u = va_arg (args, unsigned);
719 grub_lltoa (tmp, c, u);
721 else
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));
728 write_str (tmp);
729 if (rightfill && grub_strlen (tmp) < format1)
730 write_fill (zerofill, format1 - grub_strlen (tmp));
731 break;
733 case 'c':
734 n = va_arg (args, int);
735 write_char (n & 0xff);
736 break;
738 case 'C':
740 grub_uint32_t code = va_arg (args, grub_uint32_t);
741 int shift;
742 unsigned mask;
744 if (code <= 0x7f)
746 shift = 0;
747 mask = 0;
749 else if (code <= 0x7ff)
751 shift = 6;
752 mask = 0xc0;
754 else if (code <= 0xffff)
756 shift = 12;
757 mask = 0xe0;
759 else if (code <= 0x1fffff)
761 shift = 18;
762 mask = 0xf0;
764 else if (code <= 0x3ffffff)
766 shift = 24;
767 mask = 0xf8;
769 else if (code <= 0x7fffffff)
771 shift = 30;
772 mask = 0xfc;
774 else
776 code = '?';
777 shift = 0;
778 mask = 0;
781 write_char (mask | (code >> shift));
783 for (shift -= 6; shift >= 0; shift -= 6)
784 write_char (0x80 | (0x3f & (code >> shift)));
786 break;
788 case 's':
789 p = va_arg (args, char *);
790 if (p)
792 grub_size_t len = 0;
793 while (len < format2 && p[len])
794 len++;
796 if (!rightfill && len < format1)
797 write_fill (zerofill, format1 - len);
799 grub_size_t i;
800 for (i = 0; i < len; i++)
801 write_char (*p++);
803 if (rightfill && len < format1)
804 write_fill (zerofill, format1 - len);
806 else
807 write_str ("(null)");
809 break;
811 default:
812 write_char (c);
813 break;
818 if (str)
819 *str = '\0';
821 if (count && !str)
822 grub_refresh ();
824 return count;
828 grub_sprintf (char *str, const char *fmt, ...)
830 va_list ap;
831 int ret;
833 va_start (ap, fmt);
834 ret = grub_vsprintf (str, fmt, ap);
835 va_end (ap);
837 return ret;
840 /* Convert UTF-16 to UTF-8. */
841 grub_uint8_t *
842 grub_utf16_to_utf8 (grub_uint8_t *dest, grub_uint16_t *src,
843 grub_size_t size)
845 grub_uint32_t code_high = 0;
847 while (size--)
849 grub_uint32_t code = *src++;
851 if (code_high)
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;
863 else
865 /* Error... */
866 *dest++ = '?';
869 code_high = 0;
871 else
873 if (code <= 0x007F)
874 *dest++ = code;
875 else if (code <= 0x07FF)
877 *dest++ = (code >> 6) | 0xC0;
878 *dest++ = (code & 0x3F) | 0x80;
880 else if (code >= 0xD800 && code <= 0xDBFF)
882 code_high = code;
883 continue;
885 else if (code >= 0xDC00 && code <= 0xDFFF)
887 /* Error... */
888 *dest++ = '?';
890 else
892 *dest++ = (code >> 12) | 0xE0;
893 *dest++ = ((code >> 6) & 0x3F) | 0x80;
894 *dest++ = (code & 0x3F) | 0x80;
899 return dest;
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. */
908 grub_ssize_t
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;
914 int count = 0;
915 grub_uint32_t code = 0;
917 if (srcend)
918 *srcend = src;
920 while (srcsize && destsize)
922 grub_uint32_t c = *src++;
923 if (srcsize != (grub_size_t)-1)
924 srcsize--;
925 if (count)
927 if ((c & 0xc0) != 0x80)
929 /* invalid */
930 return -1;
932 else
934 code <<= 6;
935 code |= (c & 0x3f);
936 count--;
939 else
941 if (c == 0)
942 break;
944 if ((c & 0x80) == 0x00)
945 code = c;
946 else if ((c & 0xe0) == 0xc0)
948 count = 1;
949 code = c & 0x1f;
951 else if ((c & 0xf0) == 0xe0)
953 count = 2;
954 code = c & 0x0f;
956 else if ((c & 0xf8) == 0xf0)
958 count = 3;
959 code = c & 0x07;
961 else if ((c & 0xfc) == 0xf8)
963 count = 4;
964 code = c & 0x03;
966 else if ((c & 0xfe) == 0xfc)
968 count = 5;
969 code = c & 0x01;
971 else
972 return -1;
975 if (count == 0)
977 *p++ = code;
978 destsize--;
982 if (srcend)
983 *srcend = src;
984 return p - dest;
987 /* Abort GRUB. This function does not return. */
988 void
989 grub_abort (void)
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.");
998 grub_getkey ();
1002 grub_exit ();
1005 #ifndef APPLE_CC
1006 /* GCC emits references to abort(). */
1007 void abort (void) __attribute__ ((alias ("grub_abort")));
1008 #endif
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)))
1016 #endif