|
/* $MirOS: src/lib/libc/string/strlfun.c,v 1.14 2007/01/07 02:11:40 tg Exp $ */ |
|
|
|
|
| 1 |
/*- |
/*- |
| 2 |
* Copyright (c) 2006 |
* Copyright (c) 2006, 2008 |
| 3 |
* Thorsten Glaser <tg@mirbsd.de> |
* Thorsten Glaser <tg@mirbsd.org> |
| 4 |
* |
* |
| 5 |
* Provided that these terms and disclaimer and all copyright notices |
* Provided that these terms and disclaimer and all copyright notices |
| 6 |
* are retained or reproduced in an accompanying document, permission |
* are retained or reproduced in an accompanying document, permission |
| 17 |
* damage or existence of a defect, except proven that it results out |
* damage or existence of a defect, except proven that it results out |
| 18 |
* of said person's immediate fault when using the work as intended. |
* of said person's immediate fault when using the work as intended. |
| 19 |
*- |
*- |
| 20 |
* The strlcat() code below has been written by Thorsten Glaser. Bodo |
* The original implementations of strlcpy(3) and strlcat(3) are from |
| 21 |
* Eggert suggested optimising the strlcpy() code, originally written |
* Todd C. Miller; the licence is reproduced below. However, this ap- |
| 22 |
* by Todd C. Miller (see below), which was carried out by Th. Glaser |
* plies only to the strlcpy(3) portion of the code, as Thorsten Gla- |
| 23 |
* as well as merging this code with strxfrm() for ISO-10646-only sy- |
* ser write the following strlcat(3) implementation according to the |
| 24 |
* stems and writing wcslcat(), wcslcpy() and wcsxfrm() equivalents. |
* spec. Both functions below have been optimised according to sugge- |
| 25 |
|
* stions from Bodo Eggert. Thorsten Glaser also has merged this code |
| 26 |
|
* with strxfrm(3) for ISO-10646-only systems and wrote the wide char |
| 27 |
|
* variants wcslcat(3), wcslcpy(3), and wcsxfrm(3) (see wcslfun.c). |
| 28 |
*/ |
*/ |
| 29 |
|
|
| 30 |
#ifdef STRXFRM |
#ifdef STRXFRM |
| 41 |
#undef HAVE_STRLCPY |
#undef HAVE_STRLCPY |
| 42 |
#undef HAVE_STRLCAT |
#undef HAVE_STRLCAT |
| 43 |
#else |
#else |
| 44 |
|
#include <stddef.h> /* for size_t in user space (SUSv3) */ |
| 45 |
#if defined(HAVE_CONFIG_H) && (HAVE_CONFIG_H != 0) |
#if defined(HAVE_CONFIG_H) && (HAVE_CONFIG_H != 0) |
| 46 |
/* usually when packaged with third-party software */ |
/* usually when packaged with third-party software */ |
| 47 |
#ifdef CONFIG_H_FILENAME |
#ifdef CONFIG_H_FILENAME |
| 50 |
#include "config.h" |
#include "config.h" |
| 51 |
#endif |
#endif |
| 52 |
#endif |
#endif |
| 53 |
|
/* do not include <string.h> to prevent redefinition warnings */ |
| 54 |
extern size_t strlen(const char *); |
extern size_t strlen(const char *); |
| 55 |
#endif |
#endif |
| 56 |
|
|
| 58 |
#undef __IDSTRING |
#undef __IDSTRING |
| 59 |
#undef __IDSTRING_CONCAT |
#undef __IDSTRING_CONCAT |
| 60 |
#undef __IDSTRING_EXPAND |
#undef __IDSTRING_EXPAND |
|
#if defined(__ELF__) && defined(__GNUC__) |
|
|
#define __IDSTRING(prefix, string) \ |
|
|
__asm__(".section .comment" \ |
|
|
"\n .ascii \"@(\"\"#)" #prefix ": \"" \ |
|
|
"\n .asciz \"" string "\"" \ |
|
|
"\n .previous") |
|
|
#else |
|
| 61 |
#define __IDSTRING_CONCAT(l,p) __LINTED__ ## l ## _ ## p |
#define __IDSTRING_CONCAT(l,p) __LINTED__ ## l ## _ ## p |
| 62 |
#define __IDSTRING_EXPAND(l,p) __IDSTRING_CONCAT(l,p) |
#define __IDSTRING_EXPAND(l,p) __IDSTRING_CONCAT(l,p) |
| 63 |
#define __IDSTRING(prefix, string) \ |
#define __IDSTRING(prefix, string) \ |
| 64 |
static const char __IDSTRING_EXPAND(__LINE__,prefix) [] \ |
static const char __IDSTRING_EXPAND(__LINE__,prefix) [] \ |
| 65 |
__attribute__((used)) = "@(""#)" #prefix ": " string |
__attribute__((used)) = "@(""#)" #prefix ": " string |
| 66 |
#endif |
#define __RCSID(x) __IDSTRING(rcsid,x) |
|
#define __RCSID(x) __IDSTRING(rcsid,x) |
|
| 67 |
#endif |
#endif |
| 68 |
|
|
| 69 |
#ifndef __predict_true |
#ifndef __predict_true |
| 74 |
#endif |
#endif |
| 75 |
|
|
| 76 |
#if !defined(_KERNEL) && !defined(_STANDALONE) |
#if !defined(_KERNEL) && !defined(_STANDALONE) |
| 77 |
__RCSID("$MirOS: src/lib/libc/string/strlfun.c,v 1.14 2007/01/07 02:11:40 tg Exp $"); |
__RCSID("$MirOS: src/lib/libc/string/strlfun.c,v 1.18 2008/08/01 12:26:17 tg Exp $"); |
| 78 |
#endif |
#endif |
| 79 |
|
|
| 80 |
#ifndef _STRLCPY_DEFNS |
/* (multibyte) string functions */ |
| 81 |
size_t strlcat(char *, const char *, size_t); |
#undef NUL |
| 82 |
size_t strlcpy(char *, const char *, size_t); |
#undef char_t |
| 83 |
#endif |
#define NUL '\0' |
| 84 |
|
#define char_t char |
| 85 |
|
|
| 86 |
|
size_t strlcat(char_t *, const char_t *, size_t); |
| 87 |
|
size_t strlcpy(char_t *, const char_t *, size_t); |
| 88 |
|
|
| 89 |
#if !defined(HAVE_STRLCAT) || (HAVE_STRLCAT == 0) |
#if !defined(HAVE_STRLCAT) || (HAVE_STRLCAT == 0) |
| 90 |
/* |
/* |
| 91 |
* Appends src to string dst of size siz (unlike strncat, siz is the |
* Appends src to string dst of size dlen (unlike strncat, dlen is the |
| 92 |
* full size of dst, not space left). At most siz-1 characters |
* full size of dst, not space left). At most dlen-1 characters |
| 93 |
* will be copied. Always NUL terminates (unless siz <= strlen(dst)). |
* will be copied. Always NUL terminates (unless dlen <= strlen(dst)). |
| 94 |
* Returns strlen(src) + MIN(siz, strlen(initial dst)). |
* Returns strlen(src) + MIN(dlen, strlen(initial dst)), without the |
| 95 |
* If retval >= siz, truncation occurred. |
* trailing NUL byte counted. If retval >= dlen, truncation occurred. |
| 96 |
*/ |
*/ |
| 97 |
size_t |
size_t |
| 98 |
strlcat(char *dst, const char *src, size_t dlen) |
strlcat(char_t *dst, const char_t *src, size_t dlen) |
| 99 |
{ |
{ |
| 100 |
size_t n = 0, slen; |
size_t n = 0, slen; |
| 101 |
|
|
| 102 |
slen = strlen(src); |
slen = strlen(src); |
| 103 |
while (__predict_true(n + 1 < dlen && dst[n] != '\0')) |
while (__predict_true(n + 1 < dlen && dst[n] != NUL)) |
| 104 |
++n; |
++n; |
| 105 |
if (__predict_false(dlen == 0 || dst[n] != '\0')) |
if (__predict_false(dlen == 0 || dst[n] != NUL)) |
| 106 |
return (dlen + slen); |
return (dlen + slen); |
| 107 |
while (__predict_true((slen > 0) && (n < (dlen - 1)))) { |
while (__predict_true((slen > 0) && (n < (dlen - 1)))) { |
| 108 |
dst[n++] = *src++; |
dst[n++] = *src++; |
| 109 |
--slen; |
--slen; |
| 110 |
} |
} |
| 111 |
dst[n] = '\0'; |
dst[n] = NUL; |
| 112 |
return (n + slen); |
return (n + slen); |
| 113 |
} |
} |
| 114 |
#endif /* !HAVE_STRLCAT */ |
#endif /* !HAVE_STRLCAT */ |
| 115 |
|
|
| 116 |
/* $OpenBSD: strlcpy.c,v 1.10 2005/08/08 08:05:37 espie Exp $ */ |
#if !defined(HAVE_STRLCPY) || (HAVE_STRLCPY == 0) |
| 117 |
|
/* $OpenBSD: strlcpy.c,v 1.11 2006/05/05 15:27:38 millert Exp $ */ |
| 118 |
|
|
| 119 |
/*- |
/*- |
| 120 |
* Copyright (c) 1998 Todd C. Miller <Todd.Miller@courtesan.com> |
* Copyright (c) 1998 Todd C. Miller <Todd.Miller@courtesan.com> |
| 122 |
* Permission to use, copy, modify, and distribute this software for any |
* Permission to use, copy, modify, and distribute this software for any |
| 123 |
* purpose with or without fee is hereby granted, provided that the above |
* purpose with or without fee is hereby granted, provided that the above |
| 124 |
* copyright notice and this permission notice appear in all copies. |
* copyright notice and this permission notice appear in all copies. |
| 125 |
|
* |
| 126 |
|
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES |
| 127 |
|
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF |
| 128 |
|
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR |
| 129 |
|
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES |
| 130 |
|
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN |
| 131 |
|
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF |
| 132 |
|
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. |
| 133 |
*/ |
*/ |
| 134 |
|
|
|
#if !defined(HAVE_STRLCPY) || (HAVE_STRLCPY == 0) |
|
| 135 |
/* |
/* |
| 136 |
* Copy src to string dst of size siz. At most siz-1 characters |
* Copy src to string dst of size siz. At most siz-1 characters |
| 137 |
* will be copied. Always NUL terminates (unless siz == 0). |
* will be copied. Always NUL terminates (unless siz == 0). |
| 138 |
* Returns strlen(src); if retval >= siz, truncation occurred. |
* Returns strlen(src); if retval >= siz, truncation occurred. |
| 139 |
*/ |
*/ |
| 140 |
size_t |
size_t |
| 141 |
strlcpy(char *dst, const char *src, size_t siz) |
strlcpy(char_t *dst, const char_t *src, size_t siz) |
| 142 |
{ |
{ |
| 143 |
const char *s = src; |
const char_t *s = src; |
| 144 |
|
|
| 145 |
if (__predict_false(siz == 0)) |
if (__predict_false(siz == 0)) |
| 146 |
goto traverse_src; |
goto traverse_src; |
| 152 |
/* not enough room in dst */ |
/* not enough room in dst */ |
| 153 |
if (__predict_false(siz == 0)) { |
if (__predict_false(siz == 0)) { |
| 154 |
/* safe to NUL-terminate dst since we copied <= siz-1 chars */ |
/* safe to NUL-terminate dst since we copied <= siz-1 chars */ |
| 155 |
*dst = '\0'; |
*dst = NUL; |
| 156 |
traverse_src: |
traverse_src: |
| 157 |
/* traverse rest of src */ |
/* traverse rest of src */ |
| 158 |
while (*s++) |
while (*s++) |
| 159 |
; |
; |
| 160 |
} |
} |
| 161 |
|
|
| 162 |
/* count doesn't include NUL */ |
/* count does not include NUL */ |
| 163 |
return (s - src - 1); |
return (s - src - 1); |
| 164 |
} |
} |
| 165 |
#endif /* !HAVE_STRLCPY */ |
#endif /* !HAVE_STRLCPY */ |