35,11 → 35,13 |
|
#include <string.h> |
#include <stdlib.h> |
#include <assert.h> |
#include <limits.h> |
#include <ctype.h> |
#include <malloc.h> |
#include <errno.h> |
#include <align.h> |
#include <mem.h> |
#include <string.h> |
|
/** Byte mask consisting of lowest @n bits (out of 8) */ |
461,40 → 463,91 |
|
} |
|
/** Copy NULL-terminated string. |
/** Copy string. |
* |
* Copy source string @a src to destination buffer @a dst. |
* No more than @a size bytes are written. NULL-terminator is always |
* written after the last succesfully copied character (i.e. if the |
* destination buffer is has at least 1 byte, it will be always |
* NULL-terminated). |
* Copy source string @a src to destination buffer @a dest. |
* No more than @a size bytes are written. If the size of the output buffer |
* is at least one byte, the output string will always be well-formed, i.e. |
* null-terminated and containing only complete characters. |
* |
* @param dst Destination buffer. |
* @param count Size of the destination buffer (must be > 0). |
* @param src Source string. |
*/ |
void str_cpy(char *dest, size_t size, const char *src) |
{ |
wchar_t ch; |
size_t src_off; |
size_t dest_off; |
|
/* There must be space for a null terminator in the buffer. */ |
assert(size > 0); |
|
src_off = 0; |
dest_off = 0; |
|
while ((ch = str_decode(src, &src_off, STR_NO_LIMIT)) != 0) { |
if (chr_encode(ch, dest, &dest_off, size - 1) != EOK) |
break; |
} |
|
dest[dest_off] = '\0'; |
} |
|
/** Copy size-limited substring. |
* |
* Copy prefix of string @a src of max. size @a size to destination buffer |
* @a dest. No more than @a size bytes are written. The output string will |
* always be well-formed, i.e. null-terminated and containing only complete |
* characters. |
* |
* No more than @a n bytes are read from the input string, so it does not |
* have to be null-terminated. |
* |
* @param dst Destination buffer. |
* @param count Size of the destination buffer. |
* |
* @param count Size of the destination buffer (must be > 0). |
* @param src Source string. |
* @param n Maximum number of bytes to read from @a src. |
*/ |
void str_ncpy(char *dst, const char *src, size_t size) |
void str_ncpy(char *dest, size_t size, const char *src, size_t n) |
{ |
/* No space for the NULL-terminator in the buffer */ |
if (size == 0) |
return; |
|
wchar_t ch; |
size_t str_off = 0; |
size_t dst_off = 0; |
size_t src_off; |
size_t dest_off; |
|
/* There must be space for a null terminator in the buffer. */ |
assert(size > 0); |
|
while ((ch = str_decode(src, &str_off, STR_NO_LIMIT)) != 0) { |
if (chr_encode(ch, dst, &dst_off, size) != EOK) |
src_off = 0; |
dest_off = 0; |
|
while ((ch = str_decode(src, &src_off, n)) != 0) { |
if (chr_encode(ch, dest, &dest_off, size - 1) != EOK) |
break; |
} |
|
if (dst_off >= size) |
dst[size - 1] = 0; |
else |
dst[dst_off] = 0; |
|
dest[dest_off] = '\0'; |
} |
|
/** Append one string to another. |
* |
* Append source string @a src to string in destination buffer @a dest. |
* Size of the destination buffer is @a dest. If the size of the output buffer |
* is at least one byte, the output string will always be well-formed, i.e. |
* null-terminated and containing only complete characters. |
* |
* @param dst Destination buffer. |
* @param count Size of the destination buffer. |
* @param src Source string. |
*/ |
void str_append(char *dest, size_t size, const char *src) |
{ |
size_t dstr_size; |
|
dstr_size = str_size(dest); |
str_cpy(dest + dstr_size, size - dstr_size, src); |
} |
|
/** Copy NULL-terminated wide string to string |
* |
* Copy source wide string @a src to destination buffer @a dst. |
535,21 → 588,45 |
* @param ch Character to look for. |
* |
* @return Pointer to character in @a str or NULL if not found. |
* |
*/ |
const char *str_chr(const char *str, wchar_t ch) |
{ |
wchar_t acc; |
size_t off = 0; |
size_t last = 0; |
|
while ((acc = str_decode(str, &off, STR_NO_LIMIT)) != 0) { |
if (acc == ch) |
return (str + off); |
return (str + last); |
last = off; |
} |
|
return NULL; |
} |
|
/** Find last occurence of character in string. |
* |
* @param str String to search. |
* @param ch Character to look for. |
* |
* @return Pointer to character in @a str or NULL if not found. |
*/ |
const char *str_rchr(const char *str, wchar_t ch) |
{ |
wchar_t acc; |
size_t off = 0; |
size_t last = 0; |
char *res = NULL; |
|
while ((acc = str_decode(str, &off, STR_NO_LIMIT)) != 0) { |
if (acc == ch) |
res = (str + last); |
last = off; |
} |
|
return res; |
} |
|
/** Insert a wide character into a wide string. |
* |
* Insert a wide character into a wide string at position |
606,42 → 683,6 |
return true; |
} |
|
/** Count the number of characters in the string, not including terminating 0. |
* |
* @param str String. |
* @return Number of characters in string. |
*/ |
size_t strlen(const char *str) |
{ |
size_t counter = 0; |
|
while (str[counter] != 0) |
counter++; |
|
return counter; |
} |
|
int strcmp(const char *a, const char *b) |
{ |
int c = 0; |
|
while (a[c] && b[c] && (!(a[c] - b[c]))) |
c++; |
|
return (a[c] - b[c]); |
} |
|
int strncmp(const char *a, const char *b, size_t n) |
{ |
size_t c = 0; |
|
while (c < n && a[c] && b[c] && (!(a[c] - b[c]))) |
c++; |
|
return ( c < n ? a[c] - b[c] : 0); |
|
} |
|
int stricmp(const char *a, const char *b) |
{ |
int c = 0; |
652,44 → 693,6 |
return (tolower(a[c]) - tolower(b[c])); |
} |
|
/** Return pointer to the first occurence of character c in string. |
* |
* @param str Scanned string. |
* @param c Searched character (taken as one byte). |
* @return Pointer to the matched character or NULL if it is not |
* found in given string. |
*/ |
char *strchr(const char *str, int c) |
{ |
while (*str != '\0') { |
if (*str == (char) c) |
return (char *) str; |
str++; |
} |
|
return NULL; |
} |
|
/** Return pointer to the last occurence of character c in string. |
* |
* @param str Scanned string. |
* @param c Searched character (taken as one byte). |
* @return Pointer to the matched character or NULL if it is not |
* found in given string. |
*/ |
char *strrchr(const char *str, int c) |
{ |
char *retval = NULL; |
|
while (*str != '\0') { |
if (*str == (char) c) |
retval = (char *) str; |
str++; |
} |
|
return (char *) retval; |
} |
|
/** Convert string to a number. |
* Core of strtol and strtoul functions. |
* |
839,44 → 842,15 |
return (sgn ? -number : number); |
} |
|
char *strcpy(char *dest, const char *src) |
char *str_dup(const char *src) |
{ |
char *orig = dest; |
|
while ((*(dest++) = *(src++))) |
; |
return orig; |
} |
size_t size = str_size(src); |
void *dest = malloc(size + 1); |
|
char *strncpy(char *dest, const char *src, size_t n) |
{ |
char *orig = dest; |
|
while ((*(dest++) = *(src++)) && --n) |
; |
return orig; |
} |
|
char *strcat(char *dest, const char *src) |
{ |
char *orig = dest; |
while (*dest++) |
; |
--dest; |
while ((*dest++ = *src++)) |
; |
return orig; |
} |
|
char * strdup(const char *s1) |
{ |
size_t len = strlen(s1) + 1; |
void *ret = malloc(len); |
|
if (ret == NULL) |
if (dest == NULL) |
return (char *) NULL; |
|
return (char *) memcpy(ret, s1, len); |
return (char *) memcpy(dest, src, size + 1); |
} |
|
char *strtok(char *s, const char *delim) |
894,11 → 868,11 |
s = *next; |
|
/* Skip over leading delimiters. */ |
while (*s && (strchr(delim, *s) != NULL)) ++s; |
while (*s && (str_chr(delim, *s) != NULL)) ++s; |
start = s; |
|
/* Skip over token characters. */ |
while (*s && (strchr(delim, *s) == NULL)) ++s; |
while (*s && (str_chr(delim, *s) == NULL)) ++s; |
end = s; |
*next = (*s ? s + 1 : s); |
|