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