Attached patch moves functions out of the huge libpayload.h into headers
[coreboot.git] / payloads / libpayload / libc / string.c
1 /*
2  * This file is part of the libpayload project.
3  *
4  * Copyright (C) 2007 Uwe Hermann <uwe@hermann-uwe.de>
5  * Copyright (C) 2008 Advanced Micro Devices, Inc.
6  * Copyright (C) 2010 coresystems GmbH
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions
10  * are met:
11  * 1. Redistributions of source code must retain the above copyright
12  *    notice, this list of conditions and the following disclaimer.
13  * 2. Redistributions in binary form must reproduce the above copyright
14  *    notice, this list of conditions and the following disclaimer in the
15  *    documentation and/or other materials provided with the distribution.
16  * 3. The name of the author may not be used to endorse or promote products
17  *    derived from this software without specific prior written permission.
18  *
19  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
20  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
23  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29  * SUCH DAMAGE.
30  */
31
32 #include <libpayload.h>
33 #include <string.h>
34 #include <ctype.h>
35 #include <errno.h>
36
37 /**
38  * Calculate the length of a fixed-size string.
39  *
40  * @param str The input string.
41  * @param maxlen Return at most maxlen characters as length of the string.
42  * @return The length of the string, not including the final NUL character.
43  *         The maximum length returned is maxlen.
44  */
45 size_t strnlen(const char *str, size_t maxlen)
46 {
47         size_t len = 0;
48
49         /* NULL and empty strings have length 0. */
50         if (!str)
51                 return 0;
52
53         /* Loop until we find a NUL character, or maxlen is reached. */
54         while ((*str++ != '\0') && (len < maxlen))
55                 len++;
56
57         return len;
58 }
59
60 /**
61  * Calculate the length of a string.
62  *
63  * @param str The input string.
64  * @return The length of the string, not including the final NUL character.
65  */
66 size_t strlen(const char *str)
67 {
68         size_t len = 0;
69
70         /* NULL and empty strings have length 0. */
71         if (!str)
72                 return 0;
73
74         /* Loop until we find a NUL character. */
75         while (*str++ != '\0')
76                 len++;
77
78         return len;
79 }
80
81 /**
82  * Compare two strings.
83  *
84  * @param s1 The first string.
85  * @param s2 The second string.
86  * @return Returns a value less than zero, if s1 is shorter than s2. Returns
87  *         zero, if s1 equals s2. Returns a value greater than zero, if
88  *         s1 is longer than s2.
89  */
90 int strcasecmp(const char *s1, const char *s2)
91 {
92         int i;
93
94         for (i = 0; 1; i++) {
95                 if (tolower(s1[i]) != tolower(s2[i]))
96                         return s1[i] - s2[i];
97         }
98
99         return 0;
100 }
101
102 /**
103  * Compare two strings with fixed length.
104  *
105  * @param s1 The first string.
106  * @param s2 The second string.
107  * @param maxlen Return at most maxlen characters as length of the string.
108  * @return A non-zero value if s1 and s2 differ, or zero if s1 equals s2.
109  */
110 int strncasecmp(const char *s1, const char *s2, size_t maxlen)
111 {
112         int i;
113
114         for (i = 0; i < maxlen; i++) {
115                 if (tolower(s1[i]) != tolower(s2[i]))
116                         return s1[i] - s2[i];
117         }
118
119         return 0;
120 }
121
122 /**
123  * Compare two strings.
124  *
125  * @param s1 The first string.
126  * @param s2 The second string.
127  * @return Returns a value less than zero, if s1 is shorter than s2. Returns
128  *         zero, if s1 equals s2. Returns a value greater than zero, if
129  *         s1 is longer than s2.
130  */
131 int strcmp(const char *s1, const char *s2)
132 {
133         int i;
134
135         for (i = 0; 1; i++) {
136                 if (s1[i] != s2[i])
137                         return s1[i] - s2[i];
138         }
139
140         return 0;
141 }
142
143 /**
144  * Compare two strings with fixed length.
145  *
146  * @param s1 The first string.
147  * @param s2 The second string.
148  * @param maxlen Return at most maxlen characters as length of the string.
149  * @return A non-zero value if s1 and s2 differ, or zero if s1 equals s2.
150  */
151 int strncmp(const char *s1, const char *s2, size_t maxlen)
152 {
153         int i;
154
155         for (i = 0; i < maxlen; i++) {
156                 if (s1[i] != s2[i])
157                         return s1[i] - s2[i];
158         }
159
160         return 0;
161 }
162
163 /**
164  * Copy a string with a maximum length.
165  *
166  * @param d The destination memory.
167  * @param s The source string.
168  * @param n Copy at most n characters as length of the string.
169  * @return A pointer to the destination memory.
170  */
171 char *strncpy(char *d, const char *s, size_t n)
172 {
173         /* Use +1 to get the NUL terminator. */
174         int max = n > strlen(s) + 1 ? strlen(s) + 1 : n;
175         int i;
176
177         for (i = 0; i < max; i++)
178                 d[i] = (char)s[i];
179
180         return d;
181 }
182
183 /**
184  * Copy a string.
185  *
186  * @param d The destination memory.
187  * @param s The source string.
188  * @return A pointer to the destination memory.
189  */
190 char *strcpy(char *d, const char *s)
191 {
192         return strncpy(d, s, strlen(s) + 1);
193 }
194
195 /**
196  * Concatenates two strings
197  *
198  * @param d The destination string.
199  * @param s The source string.
200  * @return A pointer to the destination string.
201  */
202 char *strcat(char *d, const char *s)
203 {
204         char *p = d + strlen(d);
205         int sl = strlen(s);
206         int i;
207
208         for (i = 0; i < sl; i++)
209                 p[i] = s[i];
210
211         p[i] = '\0';
212         return d;
213 }
214
215 /**
216  * Concatenates two strings with a maximum length.
217  *
218  * @param d The destination string.
219  * @param s The source string.
220  * @param n Not more than n characters from s will be appended to d.
221  * @return A pointer to the destination string.
222  */
223 char *strncat(char *d, const char *s, size_t n)
224 {
225         char *p = d + strlen(d);
226         int sl = strlen(s);
227         int max = n > sl ? sl : n;
228         // int max = n > strlen(s) ? strlen(s) : n;
229         int i;
230
231         for (i = 0; i < max; i++)
232                 p[i] = s[i];
233
234         p[i] = '\0';
235         return d;
236 }
237
238 /**
239  * Concatenates two strings with a maximum length.
240  *
241  * @param d The destination string.
242  * @param s The source string.
243  * @param n Not more than n characters from s will be appended to d.
244  * @return A pointer to the destination string.
245  */
246 size_t strlcat(char *d, const char *s, size_t n)
247 {
248         int sl = strlen(s);
249         int dl = strlen(d);
250
251         char *p = d + dl;
252         int max = n > (sl + dl) ? sl : (n - dl - 1);
253         int i;
254
255         for (i = 0; i < max; i++)
256                 p[i] = s[i];
257
258         p[i] = '\0';
259         return max;
260 }
261
262 /**
263  * Find a character in a string.
264  *
265  * @param s The string.
266  * @param c The character.
267  * @return A pointer to the first occurence of the character in the
268  * string, or NULL if the character was not encountered within the string.
269  */
270 char *strchr(const char *s, int c)
271 {
272         char *p = (char *)s;
273
274         for (; *p != 0; p++) {
275                 if (*p == c)
276                         return p;
277         }
278
279         return NULL;
280 }
281
282 /**
283  * Find a character in a string.
284  *
285  * @param s The string.
286  * @param c The character.
287  * @return A pointer to the last occurence of the character in the
288  * string, or NULL if the character was not encountered within the string.
289  */
290
291 char *strrchr(const char *s, int c)
292 {
293         char *p = (char *)s + strlen(s);
294
295         for (; p >= s; p--) {
296                 if (*p == c)
297                         return p;
298         }
299
300         return NULL;
301 }
302
303 /**
304  * Duplicate a string.
305  *
306  * @param s The string to duplicate.
307  * @return A pointer to the copy of the original string.
308  */
309 char *strdup(const char *s)
310 {
311         int n = strlen(s);
312         char *p = malloc(n + 1);
313
314         if (p != NULL) {
315                 strncpy(p, s, n);
316                 p[n] = 0;
317         }
318         return p;
319 }
320
321 /**
322  * Find a substring within a string.
323  *
324  * @param h The haystack string.
325  * @param n The needle string (substring).
326  * @return A pointer to the first occurence of the substring in
327  * the string, or NULL if the substring was not encountered within the string.
328  */
329 char *strstr(const char *h, const char *n)
330 {
331         int hn = strlen(h);
332         int nn = strlen(n);
333         int i;
334
335         for (i = 0; i <= hn - nn; i++)
336                 if (!memcmp(&h[i], n, nn))
337                         return (char *)&h[i];
338
339         return NULL;
340 }
341
342 /**
343  * Separate strings.
344  *
345  * @param stringp reference of the string to separate.
346  * @param delim string containing all delimiters.
347  * @return Token string.
348  */
349 char *strsep(char **stringp, const char *delim)
350 {
351         char *walk, *token;
352
353         if (!stringp || !*stringp || !**stringp)
354                 return NULL;
355
356         token = walk = *stringp;
357
358         /* Walk, search for delimiters */
359         while(*walk && !strchr(delim, *walk))
360                 walk++;
361
362         if (*walk) {
363                 /* NUL terminate */
364                 *walk = '\0';
365                 walk++;
366         }
367
368         *stringp = walk;
369
370         return token;
371 }
372
373 /* Check that a character is in the valid range for the
374    given base
375 */
376
377 static int _valid(char ch, int base)
378 {
379         char end = (base > 9) ? '9' : '0' + (base - 1);
380
381         /* all bases will be some subset of the 0-9 range */
382
383         if (ch >= '0' && ch <= end)
384                 return 1;
385
386         /* Bases > 11 will also have to match in the a-z range */
387
388         if (base > 11) {
389                 if (tolower(ch) >= 'a' &&
390                     tolower(ch) <= 'a' + (base - 11))
391                         return 1;
392         }
393
394         return 0;
395 }
396
397 /* Return the "value" of the character in the given base */
398
399 static int _offset(char ch, int base)
400 {
401         if (ch >= '0' && ch <= '9')
402                 return ch - '0';
403         else
404                 return tolower(ch) - 'a';
405 }
406
407 /**
408  * Convert the initial portion of a string into a signed int
409  * @param ptr A pointer to the string to convert
410  * @param endptr A pointer to the unconverted part of the string
411  * @param base The base of the number to convert, or 0 for auto
412  * @return A signed integer representation of the string
413  */
414
415 long int strtol(const char *ptr, char **endptr, int base)
416 {
417         int ret = 0;
418         int negative = 1;
419
420         if (endptr != NULL)
421                 *endptr = (char *) ptr;
422
423         /* Purge whitespace */
424
425         for( ; *ptr && isspace(*ptr); ptr++);
426
427         if (ptr[0] == '-') {
428                 negative = -1;
429                 ptr++;
430         }
431
432         if (!*ptr)
433                 return 0;
434
435         /* Determine the base */
436
437         if (base == 0) {
438                 if (ptr[0] == '0' && (ptr[1] == 'x' || ptr[1] == 'X'))
439                         base = 16;
440                 else if (ptr[0] == '0') {
441                         base = 8;
442                         ptr++;
443                 }
444                 else
445                         base = 10;
446         }
447
448         /* Base 16 allows the 0x on front - so skip over it */
449
450         if (base == 16) {
451                 if (ptr[0] == '0' && (ptr[1] == 'x' || ptr[1] == 'X'))
452                         ptr += 2;
453         }
454
455         /* If the first character isn't valid, then don't
456          * bother */
457
458         if (!*ptr || !_valid(*ptr, base))
459                 return 0;
460
461         for( ; *ptr && _valid(*ptr, base); ptr++)
462                 ret = (ret * base) + _offset(*ptr, base);
463
464         if (endptr != NULL)
465                 *endptr = (char *) ptr;
466
467         return ret * negative;
468 }
469
470 /**
471  * Convert the initial portion of a string into an unsigned int
472  * @param ptr A pointer to the string to convert
473  * @param endptr A pointer to the unconverted part of the string
474  * @param base The base of the number to convert, or 0 for auto
475  * @return An unsigned integer representation of the string
476  */
477
478 unsigned long int strtoul(const char *ptr, char **endptr, int base)
479 {
480         int ret = 0;
481
482         if (endptr != NULL)
483                 *endptr = (char *) ptr;
484
485         /* Purge whitespace */
486
487         for( ; *ptr && isspace(*ptr); ptr++);
488
489         if (!*ptr)
490                 return 0;
491
492         /* Determine the base */
493
494         if (base == 0) {
495                 if (ptr[0] == '0' && (ptr[1] == 'x' || ptr[1] == 'X'))
496                         base = 16;
497                 else if (ptr[0] == '0') {
498                         base = 8;
499                         ptr++;
500                 }
501                 else
502                         base = 10;
503         }
504
505         /* Base 16 allows the 0x on front - so skip over it */
506
507         if (base == 16) {
508                 if (ptr[0] == '0' && (ptr[1] == 'x' || ptr[1] == 'X'))
509                         ptr += 2;
510         }
511
512         /* If the first character isn't valid, then don't
513          * bother */
514
515         if (!*ptr || !_valid(*ptr, base))
516                 return 0;
517
518         for( ; *ptr && _valid(*ptr, base); ptr++)
519                 ret = (ret * base) + _offset(*ptr, base);
520
521         if (endptr != NULL)
522                 *endptr = (char *) ptr;
523
524         return ret;
525 }
526
527 /**
528  * Determine the number of leading characters in s that match characters in a
529  * @param s A pointer to the string to analyse
530  * @param a A pointer to an array of characters that match the prefix
531  * @return The number of matching characters
532  */
533
534 size_t strspn(const char *s, const char *a)
535 {
536         int i, j;
537         int al = strlen(a);
538         for (i = 0; s[i] != 0; i++) {
539                 int found = 0;
540                 for (j = 0; j < al; j++) {
541                         if (s[i] == a[j]) {
542                                 found = 1;
543                                 break;
544                         }
545                 }
546                 if (!found)
547                         break;
548         }
549         return i;
550 }
551
552 /**
553  * Determine the number of leading characters in s that do not match characters in a
554  * @param s A pointer to the string to analyse
555  * @param a A pointer to an array of characters that do not match the prefix
556  * @return The number of not matching characters
557  */
558
559 size_t strcspn(const char *s, const char *a)
560 {
561         int i, j;
562         int al = strlen(a);
563         for (i = 0; s[i] != 0; i++) {
564                 int found = 0;
565                 for (j = 0; j < al; j++) {
566                         if (s[i] == a[j]) {
567                                 found = 1;
568                                 break;
569                         }
570                 }
571                 if (found)
572                         break;
573         }
574         return i;
575 }
576
577 /**
578  * Extract first token in string str that is delimited by a character in tokens.
579  * Destroys str and eliminates the token delimiter.
580  * @param str A pointer to the string to tokenize.
581  * @param delim A pointer to an array of characters that delimit the token
582  * @param ptr A pointer to a string pointer to keep state of the tokenizer
583  * @return Pointer to token
584  */
585
586 char* strtok_r(char *str, const char *delim, char **ptr)
587 {
588         /* start new tokenizing job or continue existing one? */
589         if (str == NULL)
590                 str = *ptr;
591
592         /* skip over prefix delimiters */
593         char *start = str + strspn(str, delim);
594
595         /* find first delimiter character */
596         char *end = start + strcspn(start, delim);
597         end[0] = '\0';
598
599         *ptr = end+1;
600         return start;
601 }
602
603 static char **strtok_global;
604
605 /**
606  * Extract first token in string str that is delimited by a character in tokens.
607  * Destroys str, eliminates the token delimiter and uses global state.
608  * @param str A pointer to the string to tokenize.
609  * @param delim A pointer to an array of characters that delimit the token
610  * @return Pointer to token
611  */
612
613 char* strtok(char *str, const char *delim)
614 {
615         return strtok_r(str, delim, strtok_global);
616 }
617
618 /**
619  * Print error message and error number
620  * @param s Error message to print
621  */
622 void perror(const char *s)
623 {
624         printf("%s: %d\n", s?s:"(none)", errno);
625 }