2 * This file is part of the libpayload project.
4 * Copyright (C) 2007 Uwe Hermann <uwe@hermann-uwe.de>
5 * Copyright (C) 2008 Advanced Micro Devices, Inc.
6 * Copyright (C) 2010 coresystems GmbH
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
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.
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
32 #include <libpayload.h>
39 * Calculate the length of a fixed-size string.
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.
46 size_t strnlen(const char *str, size_t maxlen)
50 /* NULL and empty strings have length 0. */
54 /* Loop until we find a NUL character, or maxlen is reached. */
55 while ((*str++ != '\0') && (len < maxlen))
62 * Calculate the length of a string.
64 * @param str The input string.
65 * @return The length of the string, not including the final NUL character.
67 size_t strlen(const char *str)
71 /* NULL and empty strings have length 0. */
75 /* Loop until we find a NUL character. */
76 while (*str++ != '\0')
83 * Compare two strings.
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.
91 int strcasecmp(const char *s1, const char *s2)
96 res = tolower(s1[i]) - tolower(s2[i]);
97 if (res || (s1[i] == '\0'))
105 * Compare two strings with fixed length.
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.
112 int strncasecmp(const char *s1, const char *s2, size_t maxlen)
117 for (i = 0; i < maxlen; i++) {
118 res = tolower(s1[i]) - tolower(s2[i]);
119 if (res || (s1[i] == '\0'))
127 * Compare two strings.
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.
135 int strcmp(const char *s1, const char *s2)
139 for (i = 0; 1; i++) {
141 if (res || (s1[i] == '\0'))
149 * Compare two strings with fixed length.
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.
156 int strncmp(const char *s1, const char *s2, size_t maxlen)
161 for (i = 0; i < maxlen; i++) {
163 if (res || (s1[i] == '\0'))
171 * Copy a string with a maximum length.
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.
178 char *strncpy(char *d, const char *s, size_t n)
180 /* Use +1 to get the NUL terminator. */
181 int max = n > strlen(s) + 1 ? strlen(s) + 1 : n;
184 for (i = 0; i < max; i++)
193 * @param d The destination memory.
194 * @param s The source string.
195 * @return A pointer to the destination memory.
197 char *strcpy(char *d, const char *s)
199 return strncpy(d, s, strlen(s) + 1);
203 * Concatenates two strings
205 * @param d The destination string.
206 * @param s The source string.
207 * @return A pointer to the destination string.
209 char *strcat(char *d, const char *s)
211 char *p = d + strlen(d);
215 for (i = 0; i < sl; i++)
223 * Concatenates two strings with a maximum length.
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.
230 char *strncat(char *d, const char *s, size_t n)
232 char *p = d + strlen(d);
234 int max = n > sl ? sl : n;
235 // int max = n > strlen(s) ? strlen(s) : n;
238 for (i = 0; i < max; i++)
246 * Concatenates two strings with a maximum length.
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.
253 size_t strlcat(char *d, const char *s, size_t n)
259 int max = n > (sl + dl) ? sl : (n - dl - 1);
262 for (i = 0; i < max; i++)
270 * Find a character in a string.
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.
277 char *strchr(const char *s, int c)
281 for (; *p != 0; p++) {
290 * Find a character in a string.
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.
298 char *strrchr(const char *s, int c)
300 char *p = (char *)s + strlen(s);
302 for (; p >= s; p--) {
311 * Duplicate a string.
313 * @param s The string to duplicate.
314 * @return A pointer to the copy of the original string.
316 char *strdup(const char *s)
319 char *p = malloc(n + 1);
329 * Find a substring within a string.
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.
336 char *strstr(const char *h, const char *n)
342 for (i = 0; i <= hn - nn; i++)
343 if (!memcmp(&h[i], n, nn))
344 return (char *)&h[i];
352 * @param stringp reference of the string to separate.
353 * @param delim string containing all delimiters.
354 * @return Token string.
356 char *strsep(char **stringp, const char *delim)
360 if (!stringp || !*stringp || !**stringp)
363 token = walk = *stringp;
365 /* Walk, search for delimiters */
366 while(*walk && !strchr(delim, *walk))
380 /* Check that a character is in the valid range for the
384 static int _valid(char ch, int base)
386 char end = (base > 9) ? '9' : '0' + (base - 1);
388 /* all bases will be some subset of the 0-9 range */
390 if (ch >= '0' && ch <= end)
393 /* Bases > 11 will also have to match in the a-z range */
396 if (tolower(ch) >= 'a' &&
397 tolower(ch) <= 'a' + (base - 11))
404 /* Return the "value" of the character in the given base */
406 static int _offset(char ch, int base)
408 if (ch >= '0' && ch <= '9')
411 return 10 + tolower(ch) - 'a';
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
422 long int strtol(const char *ptr, char **endptr, int base)
428 *endptr = (char *) ptr;
430 /* Purge whitespace */
432 for( ; *ptr && isspace(*ptr); ptr++);
442 /* Determine the base */
445 if (ptr[0] == '0' && (ptr[1] == 'x' || ptr[1] == 'X'))
447 else if (ptr[0] == '0') {
455 /* Base 16 allows the 0x on front - so skip over it */
458 if (ptr[0] == '0' && (ptr[1] == 'x' || ptr[1] == 'X'))
462 /* If the first character isn't valid, then don't
465 if (!*ptr || !_valid(*ptr, base))
468 for( ; *ptr && _valid(*ptr, base); ptr++)
469 ret = (ret * base) + _offset(*ptr, base);
472 *endptr = (char *) ptr;
474 return ret * negative;
477 long atol(const char *nptr)
479 return strtol(nptr, NULL, 10);
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
490 unsigned long long int strtoull(const char *ptr, char **endptr, int base)
492 unsigned long long int ret = 0;
495 *endptr = (char *) ptr;
497 /* Purge whitespace */
499 for( ; *ptr && isspace(*ptr); ptr++);
504 /* Determine the base */
507 if (ptr[0] == '0' && (ptr[1] == 'x' || ptr[1] == 'X'))
509 else if (ptr[0] == '0') {
517 /* Base 16 allows the 0x on front - so skip over it */
520 if (ptr[0] == '0' && (ptr[1] == 'x' || ptr[1] == 'X'))
524 /* If the first character isn't valid, then don't
527 if (!*ptr || !_valid(*ptr, base))
530 for( ; *ptr && _valid(*ptr, base); ptr++)
531 ret = (ret * base) + _offset(*ptr, base);
534 *endptr = (char *) ptr;
539 unsigned long int strtoul(const char *ptr, char **endptr, int base)
541 unsigned long long val = strtoull(ptr, endptr, base);
542 if (val > UINT32_MAX) return UINT32_MAX;
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
554 size_t strspn(const char *s, const char *a)
558 for (i = 0; s[i] != 0; i++) {
560 for (j = 0; j < al; j++) {
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
579 size_t strcspn(const char *s, const char *a)
583 for (i = 0; s[i] != 0; i++) {
585 for (j = 0; j < al; j++) {
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
606 char* strtok_r(char *str, const char *delim, char **ptr)
608 /* start new tokenizing job or continue existing one? */
612 /* skip over prefix delimiters */
613 char *start = str + strspn(str, delim);
615 /* find first delimiter character */
616 char *end = start + strcspn(start, delim);
623 static char **strtok_global;
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
633 char* strtok(char *str, const char *delim)
635 return strtok_r(str, delim, strtok_global);
639 * Print error message and error number
640 * @param s Error message to print
642 void perror(const char *s)
644 printf("%s: %d\n", s?s:"(none)", errno);