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>
38 * Calculate the length of a fixed-size string.
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.
45 size_t strnlen(const char *str, size_t maxlen)
49 /* NULL and empty strings have length 0. */
53 /* Loop until we find a NUL character, or maxlen is reached. */
54 while ((*str++ != '\0') && (len < maxlen))
61 * Calculate the length of a string.
63 * @param str The input string.
64 * @return The length of the string, not including the final NUL character.
66 size_t strlen(const char *str)
70 /* NULL and empty strings have length 0. */
74 /* Loop until we find a NUL character. */
75 while (*str++ != '\0')
82 * Compare two strings.
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.
90 int strcasecmp(const char *s1, const char *s2)
95 res = tolower(s1[i]) - tolower(s2[i]);
96 if (res || (s1[i] == '\0'))
104 * Compare two strings with fixed length.
106 * @param s1 The first string.
107 * @param s2 The second string.
108 * @param maxlen Return at most maxlen characters as length of the string.
109 * @return A non-zero value if s1 and s2 differ, or zero if s1 equals s2.
111 int strncasecmp(const char *s1, const char *s2, size_t maxlen)
116 for (i = 0; i < maxlen; i++) {
117 res = tolower(s1[i]) - tolower(s2[i]);
118 if (res || (s1[i] == '\0'))
126 * Compare two strings.
128 * @param s1 The first string.
129 * @param s2 The second string.
130 * @return Returns a value less than zero, if s1 is shorter than s2. Returns
131 * zero, if s1 equals s2. Returns a value greater than zero, if
132 * s1 is longer than s2.
134 int strcmp(const char *s1, const char *s2)
138 for (i = 0; 1; i++) {
140 if (res || (s1[i] == '\0'))
148 * Compare two strings with fixed length.
150 * @param s1 The first string.
151 * @param s2 The second string.
152 * @param maxlen Return at most maxlen characters as length of the string.
153 * @return A non-zero value if s1 and s2 differ, or zero if s1 equals s2.
155 int strncmp(const char *s1, const char *s2, size_t maxlen)
160 for (i = 0; i < maxlen; i++) {
162 if (res || (s1[i] == '\0'))
170 * Copy a string with a maximum length.
172 * @param d The destination memory.
173 * @param s The source string.
174 * @param n Copy at most n characters as length of the string.
175 * @return A pointer to the destination memory.
177 char *strncpy(char *d, const char *s, size_t n)
179 /* Use +1 to get the NUL terminator. */
180 int max = n > strlen(s) + 1 ? strlen(s) + 1 : n;
183 for (i = 0; i < max; i++)
192 * @param d The destination memory.
193 * @param s The source string.
194 * @return A pointer to the destination memory.
196 char *strcpy(char *d, const char *s)
198 return strncpy(d, s, strlen(s) + 1);
202 * Concatenates two strings
204 * @param d The destination string.
205 * @param s The source string.
206 * @return A pointer to the destination string.
208 char *strcat(char *d, const char *s)
210 char *p = d + strlen(d);
214 for (i = 0; i < sl; i++)
222 * Concatenates two strings with a maximum length.
224 * @param d The destination string.
225 * @param s The source string.
226 * @param n Not more than n characters from s will be appended to d.
227 * @return A pointer to the destination string.
229 char *strncat(char *d, const char *s, size_t n)
231 char *p = d + strlen(d);
233 int max = n > sl ? sl : n;
234 // int max = n > strlen(s) ? strlen(s) : n;
237 for (i = 0; i < max; i++)
245 * Concatenates two strings with a maximum length.
247 * @param d The destination string.
248 * @param s The source string.
249 * @param n Not more than n characters from s will be appended to d.
250 * @return A pointer to the destination string.
252 size_t strlcat(char *d, const char *s, size_t n)
258 int max = n > (sl + dl) ? sl : (n - dl - 1);
261 for (i = 0; i < max; i++)
269 * Find a character in a string.
271 * @param s The string.
272 * @param c The character.
273 * @return A pointer to the first occurence of the character in the
274 * string, or NULL if the character was not encountered within the string.
276 char *strchr(const char *s, int c)
280 for (; *p != 0; p++) {
289 * Find a character in a string.
291 * @param s The string.
292 * @param c The character.
293 * @return A pointer to the last occurence of the character in the
294 * string, or NULL if the character was not encountered within the string.
297 char *strrchr(const char *s, int c)
299 char *p = (char *)s + strlen(s);
301 for (; p >= s; p--) {
310 * Duplicate a string.
312 * @param s The string to duplicate.
313 * @return A pointer to the copy of the original string.
315 char *strdup(const char *s)
318 char *p = malloc(n + 1);
328 * Find a substring within a string.
330 * @param h The haystack string.
331 * @param n The needle string (substring).
332 * @return A pointer to the first occurence of the substring in
333 * the string, or NULL if the substring was not encountered within the string.
335 char *strstr(const char *h, const char *n)
341 for (i = 0; i <= hn - nn; i++)
342 if (!memcmp(&h[i], n, nn))
343 return (char *)&h[i];
351 * @param stringp reference of the string to separate.
352 * @param delim string containing all delimiters.
353 * @return Token string.
355 char *strsep(char **stringp, const char *delim)
359 if (!stringp || !*stringp || !**stringp)
362 token = walk = *stringp;
364 /* Walk, search for delimiters */
365 while(*walk && !strchr(delim, *walk))
379 /* Check that a character is in the valid range for the
383 static int _valid(char ch, int base)
385 char end = (base > 9) ? '9' : '0' + (base - 1);
387 /* all bases will be some subset of the 0-9 range */
389 if (ch >= '0' && ch <= end)
392 /* Bases > 11 will also have to match in the a-z range */
395 if (tolower(ch) >= 'a' &&
396 tolower(ch) <= 'a' + (base - 11))
403 /* Return the "value" of the character in the given base */
405 static int _offset(char ch, int base)
407 if (ch >= '0' && ch <= '9')
410 return tolower(ch) - 'a';
414 * Convert the initial portion of a string into a signed int
415 * @param ptr A pointer to the string to convert
416 * @param endptr A pointer to the unconverted part of the string
417 * @param base The base of the number to convert, or 0 for auto
418 * @return A signed integer representation of the string
421 long int strtol(const char *ptr, char **endptr, int base)
427 *endptr = (char *) ptr;
429 /* Purge whitespace */
431 for( ; *ptr && isspace(*ptr); ptr++);
441 /* Determine the base */
444 if (ptr[0] == '0' && (ptr[1] == 'x' || ptr[1] == 'X'))
446 else if (ptr[0] == '0') {
454 /* Base 16 allows the 0x on front - so skip over it */
457 if (ptr[0] == '0' && (ptr[1] == 'x' || ptr[1] == 'X'))
461 /* If the first character isn't valid, then don't
464 if (!*ptr || !_valid(*ptr, base))
467 for( ; *ptr && _valid(*ptr, base); ptr++)
468 ret = (ret * base) + _offset(*ptr, base);
471 *endptr = (char *) ptr;
473 return ret * negative;
477 * Convert the initial portion of a string into an unsigned int
478 * @param ptr A pointer to the string to convert
479 * @param endptr A pointer to the unconverted part of the string
480 * @param base The base of the number to convert, or 0 for auto
481 * @return An unsigned integer representation of the string
484 unsigned long int strtoul(const char *ptr, char **endptr, int base)
489 *endptr = (char *) ptr;
491 /* Purge whitespace */
493 for( ; *ptr && isspace(*ptr); ptr++);
498 /* Determine the base */
501 if (ptr[0] == '0' && (ptr[1] == 'x' || ptr[1] == 'X'))
503 else if (ptr[0] == '0') {
511 /* Base 16 allows the 0x on front - so skip over it */
514 if (ptr[0] == '0' && (ptr[1] == 'x' || ptr[1] == 'X'))
518 /* If the first character isn't valid, then don't
521 if (!*ptr || !_valid(*ptr, base))
524 for( ; *ptr && _valid(*ptr, base); ptr++)
525 ret = (ret * base) + _offset(*ptr, base);
528 *endptr = (char *) ptr;
534 * Determine the number of leading characters in s that match characters in a
535 * @param s A pointer to the string to analyse
536 * @param a A pointer to an array of characters that match the prefix
537 * @return The number of matching characters
540 size_t strspn(const char *s, const char *a)
544 for (i = 0; s[i] != 0; i++) {
546 for (j = 0; j < al; j++) {
559 * Determine the number of leading characters in s that do not match characters in a
560 * @param s A pointer to the string to analyse
561 * @param a A pointer to an array of characters that do not match the prefix
562 * @return The number of not matching characters
565 size_t strcspn(const char *s, const char *a)
569 for (i = 0; s[i] != 0; i++) {
571 for (j = 0; j < al; j++) {
584 * Extract first token in string str that is delimited by a character in tokens.
585 * Destroys str and eliminates the token delimiter.
586 * @param str A pointer to the string to tokenize.
587 * @param delim A pointer to an array of characters that delimit the token
588 * @param ptr A pointer to a string pointer to keep state of the tokenizer
589 * @return Pointer to token
592 char* strtok_r(char *str, const char *delim, char **ptr)
594 /* start new tokenizing job or continue existing one? */
598 /* skip over prefix delimiters */
599 char *start = str + strspn(str, delim);
601 /* find first delimiter character */
602 char *end = start + strcspn(start, delim);
609 static char **strtok_global;
612 * Extract first token in string str that is delimited by a character in tokens.
613 * Destroys str, eliminates the token delimiter and uses global state.
614 * @param str A pointer to the string to tokenize.
615 * @param delim A pointer to an array of characters that delimit the token
616 * @return Pointer to token
619 char* strtok(char *str, const char *delim)
621 return strtok_r(str, delim, strtok_global);
625 * Print error message and error number
626 * @param s Error message to print
628 void perror(const char *s)
630 printf("%s: %d\n", s?s:"(none)", errno);