head 1.14; access; symbols STR_0_9_12:1.14 LMTP2NNTP_1_4_1:1.14 LMTP2NNTP_1_4_0:1.14 STR_0_9_11:1.14 STR_0_9_10:1.14 LMTP2NNTP_1_3_0:1.12 LMTP2NNTP_1_3b2:1.12 LMTP2NNTP_1_3b1:1.12 LMTP2NNTP_1_3a3:1.12 LMTP2NNTP_1_3a2:1.12 STR_0_9_9:1.12 LMTP2NNTP_1_3a1:1.12 STR_0_9_8:1.12 LMTP2NNTP_1_2_0:1.12 LMTP2NNTP_1_2b4:1.12 LMTP2NNTP_1_2b3:1.12 LMTP2NNTP_1_2b2:1.12 LMTP2NNTP_1_2b1:1.12 LMTP2NNTP_1_2a8:1.12 LMTP2NNTP_1_2a7:1.12 LMTP2NNTP_1_2a6:1.11 LMTP2NNTP_1_2a5:1.11 STR_0_9_7:1.11 LMTP2NNTP_1_2a4:1.10 LMTP2NNTP_1_2a3:1.10 OSSP_RC_SPEC:1.10 LMTP2NNTP_1_2a1:1.8 LMTP2NNTP_1_1_1:1.8 LMTP2NNTP_1_1_0:1.8 LMTP2NNTP_1_1b4:1.8 LMTP2NNTP_1_1b3:1.8 LMTP2NNTP_1_1b2:1.8 LMTP2NNTP_1_1b1:1.8 STR_0_9_6:1.8 STR_0_9_5:1.8 STR_0_9_4:1.7 STR_0_9_3:1.5 STR_0_9_2:1.5 STR_0_9_1:1.4 STR_0_9_0:1.3; locks; strict; comment @ * @; 1.14 date 2005.01.24.15.30.04; author rse; state Exp; branches; next 1.13; 1.13 date 2005.01.24.15.22.19; author rse; state Exp; branches; next 1.12; 1.12 date 2003.01.06.19.13.47; author rse; state Exp; branches; next 1.11; 1.11 date 2002.04.01.08.32.54; author rse; state Exp; branches; next 1.10; 1.10 date 2002.01.31.13.34.13; author rse; state Exp; branches; next 1.9; 1.9 date 2002.01.02.17.09.13; author rse; state Exp; branches; next 1.8; 1.8 date 2001.08.16.13.21.22; author rse; state Exp; branches; next 1.7; 1.7 date 2000.05.25.13.04.22; author rse; state Exp; branches; next 1.6; 1.6 date 2000.03.01.11.08.48; author rse; state Exp; branches; next 1.5; 1.5 date 2000.01.20.20.42.10; author rse; state Exp; branches; next 1.4; 1.4 date 2000.01.09.19.11.43; author rse; state Exp; branches; next 1.3; 1.3 date 2000.01.01.13.05.17; author rse; state Exp; branches; next 1.2; 1.2 date 99.12.27.18.28.53; author rse; state Exp; branches; next 1.1; 1.1 date 99.12.27.13.43.05; author rse; state Exp; branches; next ; desc @@ 1.14 log @Add Autoconf detection for va_copy() existence and fallbacks. @ text @/* ** OSSP str - String Handling ** Copyright (c) 1999-2005 Ralf S. Engelschall ** Copyright (c) 1999-2005 The OSSP Project ** ** This file is part of OSSP str, a string handling and manipulation ** library which can be found at http://www.ossp.org/pkg/lib/str/. ** ** Permission to use, copy, modify, and distribute this software for ** any purpose with or without fee is hereby granted, provided that ** the above copyright notice and this permission notice appear in all ** copies. ** ** THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED ** WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF ** MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. ** IN NO EVENT SHALL THE AUTHORS AND COPYRIGHT HOLDERS AND THEIR ** CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, ** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT ** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF ** USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ** ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ** OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT ** OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF ** SUCH DAMAGE. ** ** str_handle.c: handling and manipulation functions */ #include "str_p.h" /* * str_len -- determine length of string. * This is exactly equal to POSIX strlen(3). */ str_size_t str_len(const char *s) { register const char *t; if (s == NULL) return 0; t = s; while (*t++ != NUL) /*nop*/; return (t-s-1); } /* * str_copy -- copy a string. * This is inspired by POSIX strncpy(3), but the source and target * and overlap and the the target is always NUL-terminated. */ char *str_copy(char *as, const char *at, str_size_t n) { register char *s; register const char *t; char *rv; if (as == NULL || at == NULL) return NULL; if (n == 0) n = str_len(at); t = at; s = as; rv = as; if (s > t) { /* must go high to low */ t += n - 1; s += n; rv = s; *s-- = NUL; while (n-- > 0) *s-- = *t--; } else if (s < t) { /* must go low to high */ while (n-- > 0) *s++ = *t++; *s = NUL; rv = s; } return rv; } /* * str_dup -- duplicate a string. * This is inspired by POSIX strdup(3), but provides * the ability to specify a maximum length. */ char *str_dup(const char *s, str_size_t n) { char *t; char *rv; if (s == NULL) return NULL; if (n == 0) n = str_len(s); if ((rv = str_mem_alloc(n+1)) == NULL) return NULL; t = rv; while (n-- > 0) *t++ = *s++; *t = NUL; return rv; } /* * str_concat -- concatenate one or more strings. * This function allows one to concatenate an arbitrary number of * strings and is inspired by Apache's ap_pstrcat() function. */ char *str_concat(char *s, ...) { va_list ap; char *rv; va_start(ap, s); rv = str_concat_va(s, ap); va_end(ap); return rv; } char *str_concat_va(char *s, va_list ap) { va_list ap_safe; int n; char *rv; char *cp; char *ds; if (s == NULL) return NULL; /* determine required target string length */ va_copy(ap_safe, ap); n = str_len(s); while ((cp = va_arg(ap, char *)) != NULL) n += str_len(cp); va_copy(ap, ap_safe); /* allocate target string */ if ((rv = str_mem_alloc(n+1)) == NULL) return NULL; /* concatenate the strings */ ds = rv; while ((*ds = *s++) != NUL) ds++; while ((cp = va_arg(ap, char *)) != NULL) { while ((*ds = *cp++) != NUL) ds++; } /* return target string */ return rv; } /* * str_splice -- splice one string into another. * This is inspired by Perl's splice() function and can be used * both for inplace movements, insert and cut-out operations. */ char *str_splice(char *s, str_size_t off, str_size_t n, char *t, str_size_t m) { int sl; /* check for invalid arguments */ if (s == NULL || t == NULL) return NULL; /* check for overlapping areas */ if (!((t+m) <= s || (s+off+n) <= t)) return NULL; sl = str_len(s); if ((t+m) < s || (s+sl) < t) { /* splice _external_ area into internal area */ if (m != n) str_mem_move(s+off+m, s+off+n, sl-off-n+1); str_mem_move(s+off, t, m); } else { /* splice _internal_ area into internal area */ if (t > s) { /* move t from larger to lower address of s */ str_mem_rev(s+off, (t+m)-(s+off)); str_mem_rev(s+off, m); str_mem_rev(s+off+m, t-(s+n)); str_mem_move(t+m-n, t+m, (s+sl)-(t+m)+1); } else { /* move t from lower to higher address of s */ str_mem_rev(t, (s+off)-t); str_mem_rev(t, (s+off)-t-m); str_mem_rev(s+off-m, m); str_mem_move(s+off, s+off+n, sl-off-n+1); } } return s; } /* * str_compare -- compare a two strings. * This is inspired by POSIX str[n][case]cmp(3), but * merges all functionality in a single function. */ int str_compare(const char *s1, const char *s2, str_size_t n, int mode) { int rv; int bWithLen; rv = 0; if (n == 0) bWithLen = FALSE; else bWithLen = TRUE; if (mode & STR_NOCASE) { /* compare case insensitive */ do { if (str_tolower(*s1) != str_tolower(*s2++)) { rv = ((str_tolower(*s1) - str_tolower(*(s2 - 1))) < 0 ? -1 : +1); break; } if (bWithLen) if (--n <= 0) break; } while (*s1++ != NUL); } else { /* compare case sensitive */ do { if (*s1 != *s2++) { rv = (((int)(*(const unsigned char *)s1) - (int)(*(const unsigned char *)(s2 - 1))) < 0 ? -1 : +1); break; } if (bWithLen) if (--n <= 0) break; } while (*s1++ != NUL); } return rv; } @ 1.13 log @Adjusted copyright messages for new year 2004/2005. @ text @d136 1 a136 1 ap_safe = ap; d140 1 a140 1 ap = ap_safe; @ 1.12 log @- adjust copyright messages for new year 2003 - strip trailing whitespaces - consistently use OSSP ASCII-art - add standard devtool.conf stuff from OSSP sa @ text @d3 2 a4 2 ** Copyright (c) 1999-2003 Ralf S. Engelschall ** Copyright (c) 1999-2003 The OSSP Project @ 1.11 log @finally switch to full OSSP branding @ text @d3 2 a4 2 ** Copyright (c) 1999-2002 Ralf S. Engelschall ** Copyright (c) 1999-2002 The OSSP Project d6 1 a6 1 ** This file is part of OSSP str, a string handling and manipulation d32 1 a32 1 /* d61 1 a61 1 if (n == 0) d66 1 a66 1 if (s > t) { d85 1 a85 1 /* d87 1 a87 1 * This is inspired by POSIX strdup(3), but provides d108 1 a108 1 /* d159 1 a159 1 /* d161 1 a161 1 * This is inspired by Perl's splice() function and can be used d202 1 a202 1 /* d221 1 a221 1 rv = ((str_tolower(*s1) - d234 1 a234 1 rv = (((int)(*(const unsigned char *)s1) - @ 1.10 log @str_concat included the terminating NUL in copy and added a useless NUL @ text @d2 1 a2 1 ** Str - String Library d4 1 d6 2 a7 2 ** This file is part of Str, a string handling and manipulation ** library which can be found at http://www.engelschall.com/sw/str/. @ 1.9 log @bump copyright year @ text @d147 6 a152 6 while ((*ds++ = *s++) != NUL) /*nop*/; while ((cp = va_arg(ap, char *)) != NULL) while ((*ds++ = *cp++) != NUL) /*nop*/; *ds = NUL; @ 1.8 log @Adjust copyright for year 2001. @ text @d3 1 a3 1 ** Copyright (c) 1999-2001 Ralf S. Engelschall @ 1.7 log @*** empty log message *** @ text @d3 1 a3 1 ** Copyright (c) 1999-2000 Ralf S. Engelschall @ 1.6 log @*** empty log message *** @ text @d221 1 a221 1 str_tolower(*--s2)) < 0 ? -1 : +1); @ 1.5 log @*** empty log message *** @ text @d37 1 a37 1 register char *t; d41 1 a41 1 t = (char *)s; @ 1.4 log @*** empty log message *** @ text @d115 10 a130 1 va_start(ap, s); a154 1 va_end(ap); @ 1.3 log @*** empty log message *** @ text @d35 1 a35 1 size_t str_len(const char *s) d52 1 a52 1 char *str_copy(char *as, const char *at, size_t n) d225 2 a226 2 rv = ((*(const unsigned char *)s1 - *(const unsigned char *)(s2 - 1)) < 0 ? -1 : +1); @ 1.2 log @*** empty log message *** @ text @d3 1 a3 1 ** Copyright (c) 1999 Ralf S. Engelschall @ 1.1 log @. @ text @d31 4 a34 1 /* determine length of string */ d47 5 a51 1 /* copy a string */ d84 5 a88 1 /* duplicate string */ d107 5 a111 1 /* concatenate one or more strings */ d150 5 a154 1 /* splice a string into another */ d193 5 a197 1 /* compare a two strings */ @