1
/* misc.c - definitions of misc functions */
3
* GRUB -- GRand Unified Bootloader
4
* Copyright (C) 1999,2000,2001,2002,2003,2004,2005 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 2 of the License, or
9
* (at your option) any later version.
11
* This program 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, write to the Free Software
18
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21
#include <grub/misc.h>
25
#include <grub/term.h>
29
grub_memmove (void *dest, const void *src, grub_size_t n)
31
char *d = (char *) dest;
32
const char *s = (const char *) src;
48
void *memmove (void *dest, const void *src, grub_size_t n)
49
__attribute__ ((alias ("grub_memmove")));
50
/* GCC emits references to memcpy() for struct copies etc. */
51
void *memcpy (void *dest, const void *src, grub_size_t n)
52
__attribute__ ((alias ("grub_memmove")));
55
grub_strcpy (char *dest, const char *src)
59
while ((*p++ = *src++) != '\0')
66
grub_strncpy (char *dest, const char *src, int c)
70
while ((*p++ = *src++) != '\0' && --c)
77
grub_stpcpy (char *dest, const char *src)
90
grub_strcat (char *dest, const char *src)
97
while ((*p++ = *src++) != '\0')
104
grub_strncat (char *dest, const char *src, int c)
111
while ((*p++ = *src++) != '\0' && --c)
119
grub_printf (const char *fmt, ...)
125
ret = grub_vprintf (fmt, ap);
132
grub_real_dprintf(const char *file, const int line, const char *condition,
133
const char *fmt, ...)
136
const char *debug = grub_env_get ("debug");
139
if (grub_strword (debug, "all") || grub_strword (debug, condition))
141
grub_printf ("%s,%d : ", file, line);
142
va_start (args, fmt);
143
grub_vprintf (fmt, args);
149
grub_vprintf (const char *fmt, va_list args)
153
ret = grub_vsprintf (0, fmt, args);
159
grub_memcmp (const void *s1, const void *s2, grub_size_t n)
167
return (int) *t1 - (int) *t2;
175
void *memcmp (const void *s1, const void *s2, grub_size_t n)
176
__attribute__ ((alias ("grub_memcmp")));
179
grub_strcmp (const char *s1, const char *s2)
184
return (int) *s1 - (int) *s2;
190
return (int) *s1 - (int) *s2;
194
grub_strncmp (const char *s1, const char *s2, grub_size_t n)
199
while (*s1 && *s2 && --n)
202
return (int) *s1 - (int) *s2;
208
return (int) *s1 - (int) *s2;
212
grub_strncasecmp (const char *s1, const char *s2, int c)
216
while (grub_tolower (*s1) && grub_tolower (*s2) && p < c)
218
if (grub_tolower (*s1) != grub_tolower (*s2))
219
return (int) grub_tolower (*s1) - (int) grub_tolower (*s2);
226
return (int) *s1 - (int) *s2;
230
grub_strchr (const char *s, int c)
243
grub_strrchr (const char *s, int c)
258
grub_strword (const char *haystack, const char *needle)
260
const char *n_pos = needle;
262
while (grub_iswordseparator (*haystack))
267
/* Crawl both the needle and the haystack word we're on. */
268
while(*haystack && !grub_iswordseparator (*haystack)
269
&& *haystack == *n_pos)
275
/* If we reached the end of both words at the same time, the word
276
is found. If not, eat everything in the haystack that isn't the
277
next word (or the end of string) and "reset" the needle. */
278
if ( (!*haystack || grub_iswordseparator (*haystack))
279
&& (!*n_pos || grub_iswordseparator (*n_pos)))
284
while (*haystack && !grub_iswordseparator (*haystack))
286
while (grub_iswordseparator (*haystack))
295
grub_iswordseparator (int c)
297
return (grub_isspace (c) || c == ',' || c == ';' || c == '|' || c == '&');
303
return (c == '\n' || c == '\r' || c == ' ' || c == '\t');
309
return (c >= ' ' && c <= '~');
315
return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z');
321
return (c >= '0' && c <= '9');
327
return (c >= '!' && c <= '~');
333
if (c >= 'A' && c <= 'Z')
334
return c - 'A' + 'a';
340
grub_strtoul (const char *str, char **end, int base)
342
unsigned long num = 0;
345
/* Skip white spaces. */
346
while (*str && grub_isspace (*str))
349
/* Guess the base, if not specified. The prefix `0x' means 16, and
350
the prefix `0' means 8. */
355
if (base == 0 || base == 16)
361
else if (str[1] >= '0' && str[1] <= '7')
372
digit = grub_tolower (*str) - '0';
375
digit += '0' - 'a' + 10;
376
if (digit >= (unsigned long) base)
382
if (num > (~0UL - digit) / base)
384
grub_error (GRUB_ERR_OUT_OF_RANGE, "overflow is detected");
388
num = num * base + digit;
394
grub_error (GRUB_ERR_BAD_NUMBER, "unrecognized number");
405
grub_strdup (const char *s)
410
len = grub_strlen (s) + 1;
411
p = (char *) grub_malloc (len);
415
return grub_memcpy (p, s, len);
419
grub_strndup (const char *s, grub_size_t n)
424
len = grub_strlen (s);
427
p = (char *) grub_malloc (len + 1);
431
grub_memcpy (p, s, len);
437
grub_memset (void *s, int c, grub_size_t n)
439
unsigned char *p = (unsigned char *) s;
442
*p++ = (unsigned char) c;
446
void *memset (void *s, int c, grub_size_t n)
447
__attribute__ ((alias ("grub_memset")));
450
grub_strlen (const char *s)
461
grub_reverse (char *str)
463
char *p = str + grub_strlen (str) - 1;
478
grub_itoa (char *str, int c, unsigned n)
480
unsigned base = (c == 'x') ? 16 : 10;
483
if ((int) n < 0 && c == 'd')
485
n = (unsigned) (-((int) n));
492
unsigned d = n % base;
493
*p++ = (d > 9) ? d + 'a' - 10 : d + '0';
503
grub_ftoa (char *str, double f, int round)
507
unsigned int power = 1;
510
for (i = 0; i < round; i++)
514
fractp = (f - (float) intp) * power;
516
grub_sprintf (str, "%d.%d", intp, fractp);
521
grub_vsprintf (char *str, const char *fmt, va_list args)
525
auto void write_char (unsigned char ch);
526
auto void write_str (const char *s);
527
auto void write_fill (const char ch, int n);
529
void write_char (unsigned char ch)
539
void write_str (const char *s)
545
void write_fill (const char ch, int n)
548
for (i = 0; i < n; i++)
552
while ((c = *fmt++) != 0)
560
unsigned int format1 = 0;
561
unsigned int format2 = 3;
567
if (*fmt && *fmt =='-')
574
/* Read formatting parameters. */
575
while (*p && grub_isdigit (*p))
581
grub_strncpy (s, fmt, p - fmt);
585
format1 = grub_strtoul (s, 0, 10);
591
while (*p && grub_isdigit (*p))
597
grub_strncpy (fstr, fmt, p - fmt);
598
format2 = grub_strtoul (fstr, 0, 10);
621
n = va_arg (args, long);
623
n = va_arg (args, int);
624
grub_itoa (tmp, c, n);
625
if (!rightfill && grub_strlen (tmp) < format1)
626
write_fill (zerofill, format1 - grub_strlen (tmp));
628
if (rightfill && grub_strlen (tmp) < format1)
629
write_fill (zerofill, format1 - grub_strlen (tmp));
633
n = va_arg (args, int);
634
write_char (n & 0xff);
640
f = va_arg (args, double);
641
grub_ftoa (tmp, f, format2);
642
if (!rightfill && grub_strlen (tmp) < format1)
643
write_fill (zerofill, format1 - grub_strlen (tmp));
645
if (rightfill && grub_strlen (tmp) < format1)
646
write_fill (zerofill, format1 - grub_strlen (tmp));
652
grub_uint32_t code = va_arg (args, grub_uint32_t);
661
else if (code <= 0x7ff)
666
else if (code <= 0xffff)
671
else if (code <= 0x1fffff)
676
else if (code <= 0x3ffffff)
681
else if (code <= 0x7fffffff)
693
write_char (mask | (code >> shift));
695
for (shift -= 6; shift >= 0; shift -= 6)
696
write_char (0x80 | (0x3f & (code >> shift)));
701
p = va_arg (args, char *);
704
if (!rightfill && grub_strlen (p) < format1)
705
write_fill (zerofill, format1 - grub_strlen (p));
709
if (rightfill && grub_strlen (p) < format1)
710
write_fill (zerofill, format1 - grub_strlen (p));
713
write_str ("(null)");
734
grub_sprintf (char *str, const char *fmt, ...)
740
ret = grub_vsprintf (str, fmt, ap);
746
/* Convert UTF-16 to UTF-8. */
748
grub_utf16_to_utf8 (grub_uint8_t *dest, grub_uint16_t *src,
751
grub_uint32_t code_high = 0;
755
grub_uint32_t code = *src++;
759
if (code >= 0xDC00 && code <= 0xDFFF)
761
/* Surrogate pair. */
762
code = ((code_high - 0xD800) << 12) + (code - 0xDC00) + 0x10000;
764
*dest++ = (code >> 18) | 0xF0;
765
*dest++ = ((code >> 12) & 0x3F) | 0x80;
766
*dest++ = ((code >> 6) & 0x3F) | 0x80;
767
*dest++ = (code & 0x3F) | 0x80;
781
else if (code <= 0x07FF)
783
*dest++ = (code >> 6) | 0xC0;
784
*dest++ = (code & 0x3F) | 0x80;
786
else if (code >= 0xD800 && code <= 0xDBFF)
791
else if (code >= 0xDC00 && code <= 0xDFFF)
798
*dest++ = (code >> 16) | 0xE0;
799
*dest++ = ((code >> 12) & 0x3F) | 0x80;
800
*dest++ = (code & 0x3F) | 0x80;
808
/* Convert an UTF-8 string to an UCS-4 string. Return the number of
809
characters converted. DEST must be able to hold at least SIZE
810
characters (when the input is unknown). If an invalid sequence is found,
813
grub_utf8_to_ucs4 (grub_uint32_t *dest, const grub_uint8_t *src,
816
grub_uint32_t *p = dest;
818
grub_uint32_t code = 0;
822
grub_uint32_t c = *src++;
826
if ((c & 0xc0) != 0x80)
840
if ((c & 0x80) == 0x00)
842
else if ((c & 0xe0) == 0xc0)
847
else if ((c & 0xf0) == 0xe0)
852
else if ((c & 0xf8) == 0xf0)
857
else if ((c & 0xfc) == 0xf8)
862
else if ((c & 0xfe) == 0xfc)