]> git.proxmox.com Git - grub2.git/blame - kern/misc.c
2003-11-12 Marco Gerards <metgerards@student.han.nl>
[grub2.git] / kern / misc.c
CommitLineData
6a161fa9 1/* misc.c - definitions of misc functions */
2/*
3 * PUPA -- Preliminary Universal Programming Architecture for GRUB
4 * Copyright (C) 1999,2000,2001,2002 Free Software Foundation, Inc.
5 * Copyright (C) 2002 Yoshinori K. Okuji <okuji@enbug.org>
a35eed7c 6 * Copyright (C) 2003 Marco Gerards <metgerards@student.han.nl>
6a161fa9 7 *
8 * PUPA is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with PUPA; if not, write to the Free Software
20 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 */
22
23#include <pupa/misc.h>
24#include <pupa/err.h>
25#include <pupa/mm.h>
26#include <stdarg.h>
27#include <pupa/term.h>
28
29void *
a5ffe966 30pupa_memmove (void *dest, const void *src, pupa_size_t n)
6a161fa9 31{
32 char *d = (char *) dest;
a5ffe966 33 const char *s = (const char *) src;
34
35 if (d < s)
36 while (n--)
37 *d++ = *s++;
38 else
39 {
40 d += n;
41 s += n;
42
43 while (n--)
44 *--d = *--s;
45 }
6a161fa9 46
47 return dest;
48}
49
a5ffe966 50char *
51pupa_strcpy (char *dest, const char *src)
52{
53 char *p = dest;
54
55 while ((*p++ = *src++) != '\0')
56 ;
57
58 return dest;
59}
60
a35eed7c 61char *
62pupa_strncpy (char *dest, const char *src, int c)
63{
64 char *p = dest;
65 int pos = 0;
66
67 while ((*p++ = *src++) != '\0' && c > pos)
68 pos++;
69
70 return dest;
71}
72
a5ffe966 73char *
74pupa_strcat (char *dest, const char *src)
75{
76 char *p = dest;
77
78 while (*p)
79 p++;
80
81 while ((*p++ = *src++) != '\0')
82 ;
83
84 return dest;
85}
a5ffe966 86
6a161fa9 87int
88pupa_printf (const char *fmt, ...)
89{
90 va_list ap;
91 int ret;
92
93 va_start (ap, fmt);
94 ret = pupa_vprintf (fmt, ap);
95 va_end (ap);
96
97 return ret;
98}
99
100int
101pupa_vprintf (const char *fmt, va_list args)
102{
103 return pupa_vsprintf (0, fmt, args);
104}
105
106int
107pupa_memcmp (const void *s1, const void *s2, pupa_size_t n)
108{
109 const char *t1 = s1;
110 const char *t2 = s2;
111
112 while (n--)
113 {
114 if (*t1 != *t2)
115 return (int) *t1 - (int) *t2;
116
117 t1++;
118 t2++;
119 }
120
121 return 0;
122}
123
124int
125pupa_strcmp (const char *s1, const char *s2)
126{
127 while (*s1 && *s2)
128 {
129 if (*s1 != *s2)
130 return (int) *s1 - (int) *s2;
131
132 s1++;
133 s2++;
134 }
135
136 return (int) *s1 - (int) *s2;
137}
138
a35eed7c 139int
140pupa_strncmp (const char *s1, const char *s2, int c)
141{
142 int p = 1;
143
144 while (*s1 && *s2 && p < c)
145 {
146 if (*s1 != *s2)
147 return (int) *s1 - (int) *s2;
148
149 s1++;
150 s2++;
151 p++;
152 }
153
154 return (int) *s1 - (int) *s2;
155}
156
6a161fa9 157char *
158pupa_strchr (const char *s, int c)
159{
160 while (*s)
161 {
162 if (*s == c)
163 return (char *) s;
164 s++;
165 }
166
167 return 0;
168}
169
170char *
171pupa_strrchr (const char *s, int c)
172{
173 char *p = 0;
174
175 while (*s)
176 {
177 if (*s == c)
178 p = (char *) s;
179 s++;
180 }
181
182 return p;
183}
184
185int
186pupa_isspace (int c)
187{
188 return (c == '\n' || c == '\r' || c == ' ' || c == '\t');
189}
190
191int
192pupa_isprint (int c)
193{
194 return (c >= ' ' && c <= '~');
195}
196
197int
198pupa_isalpha (int c)
199{
200 return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z');
201}
202
203int
204pupa_tolower (int c)
205{
206 if (c >= 'A' && c <= 'Z')
207 return c - 'A' + 'a';
208
209 return c;
210}
211
212unsigned long
213pupa_strtoul (const char *str, char **end, int base)
214{
215 unsigned long num = 0;
216 int found = 0;
217
218 /* Skip white spaces. */
219 while (*str && pupa_isspace (*str))
220 str++;
221
222 /* Guess the base, if not specified. The prefix `0x' means 16, and
223 the prefix `0' means 8. */
224 if (str[0] == '0')
225 {
226 if (str[1] == 'x')
227 {
228 if (base == 0 || base == 16)
229 {
230 base = 16;
231 str += 2;
232 }
233 }
234 else if (str[1] >= '0' && str[1] <= '7')
235 base = 8;
236 }
237
238 if (base == 0)
239 base = 10;
240
241 while (*str)
242 {
243 unsigned long digit;
244
245 digit = pupa_tolower (*str) - '0';
246 if (digit > 9)
247 {
248 digit += '0' - 'a' + 10;
249 if (digit >= (unsigned long) base)
250 break;
251 }
252
253 found = 1;
254
255 if (num > (~0UL - digit) / base)
256 {
257 pupa_error (PUPA_ERR_OUT_OF_RANGE, "overflow is detected");
258 return 0;
259 }
260
261 num += num * base + digit;
262 str++;
263 }
264
265 if (! found)
266 {
267 pupa_error (PUPA_ERR_BAD_NUMBER, "unrecognized number");
268 return 0;
269 }
270
271 if (end)
272 *end = (char *) str;
273
274 return num;
275}
276
277char *
278pupa_strdup (const char *s)
279{
280 pupa_size_t len;
281 char *p;
282
283 len = pupa_strlen (s) + 1;
284 p = (char *) pupa_malloc (len);
285 if (! p)
286 return 0;
287
288 return pupa_memcpy (p, s, len);
289}
290
291void *
292pupa_memset (void *s, int c, pupa_size_t n)
293{
294 unsigned char *p = (unsigned char *) s;
295
296 while (n--)
297 *p++ = (unsigned char) c;
298
299 return s;
300}
301
302pupa_size_t
303pupa_strlen (const char *s)
304{
a5ffe966 305 const char *p = s;
6a161fa9 306
307 while (*p)
308 p++;
309
310 return p - s;
311}
312
313static inline void
314pupa_reverse (char *str)
315{
316 char *p = str + pupa_strlen (str) - 1;
317
318 while (str < p)
319 {
320 char tmp;
321
322 tmp = *str;
323 *str = *p;
324 *p = tmp;
325 str++;
326 p--;
327 }
328}
329
a5ffe966 330static char *
6a161fa9 331pupa_itoa (char *str, int c, unsigned n)
332{
333 unsigned base = (c == 'x') ? 16 : 10;
334 char *p;
335
336 if ((int) n < 0 && c == 'd')
337 {
338 n = (unsigned) (-((int) n));
339 *str++ = '-';
340 }
341
342 p = str;
343 do
344 {
345 unsigned d = n % base;
346 *p++ = (d > 9) ? d + 'a' - 10 : d + '0';
347 }
348 while (n /= base);
349 *p = 0;
350
351 pupa_reverse (str);
352 return p;
353}
354
355int
356pupa_vsprintf (char *str, const char *fmt, va_list args)
357{
358 char c;
359 int count = 0;
18d9c7cd 360 auto void write_char (unsigned char ch);
6a161fa9 361 auto void write_str (const char *s);
362
18d9c7cd 363 void write_char (unsigned char ch)
6a161fa9 364 {
365 if (str)
a5ffe966 366 *str++ = ch;
6a161fa9 367 else
a5ffe966 368 pupa_putchar (ch);
6a161fa9 369
370 count++;
371 }
372
373 void write_str (const char *s)
374 {
375 while (*s)
376 write_char (*s++);
377 }
378
379 while ((c = *fmt++) != 0)
380 {
381 if (c != '%')
382 write_char (c);
383 else
384 {
385 char tmp[16];
386 char *p;
387 int n;
388
389 c = *fmt++;
390
391 switch (c)
392 {
393 case 'p':
394 write_str ("0x");
395 c = 'x';
396 /* fall through */
397 case 'x':
398 case 'u':
399 case 'd':
400 n = va_arg (args, int);
401 pupa_itoa (tmp, c, n);
402 write_str (tmp);
403 break;
404
405 case 'c':
406 n = va_arg (args, int);
18d9c7cd 407 write_char (n & 0xff);
408 break;
409
410 case 'C':
411 {
412 pupa_uint32_t code = va_arg (args, pupa_uint32_t);
413 int shift;
414 unsigned mask;
415
416 if (code <= 0x7f)
417 {
418 shift = 0;
419 mask = 0;
420 }
421 else if (code <= 0x7ff)
422 {
423 shift = 6;
424 mask = 0xc0;
425 }
426 else if (code <= 0xffff)
427 {
428 shift = 12;
429 mask = 0xe0;
430 }
431 else if (code <= 0x1fffff)
432 {
433 shift = 18;
434 mask = 0xf0;
435 }
436 else if (code <= 0x3ffffff)
437 {
438 shift = 24;
439 mask = 0xf8;
440 }
441 else if (code <= 0x7fffffff)
442 {
443 shift = 30;
444 mask = 0xfc;
445 }
446 else
447 {
448 code = '?';
449 shift = 0;
450 mask = 0;
451 }
452
453 write_char (mask | (code >> shift));
454
455 for (shift -= 6; shift >= 0; shift -= 6)
456 write_char (0x80 | (0x3f & (code >> shift)));
457 }
6a161fa9 458 break;
459
460 case 's':
461 p = va_arg (args, char *);
462 if (p)
463 write_str (p);
464 else
465 write_str ("(null)");
466 break;
467
468 default:
469 write_char (c);
470 break;
471 }
472 }
473 }
474
475 if (str)
476 *str = '\0';
477
478 return count;
479}
480
481int
482pupa_sprintf (char *str, const char *fmt, ...)
483{
484 va_list ap;
485 int ret;
486
487 va_start (ap, fmt);
488 ret = pupa_vsprintf (str, fmt, ap);
489 va_end (ap);
490
491 return ret;
492}