string.c

Go to the documentation of this file.
00001 /*
00002  * Copyright (C) 2004-2007, 2011, 2012, 2014  Internet Systems Consortium, Inc. ("ISC")
00003  * Copyright (C) 1999-2001, 2003  Internet Software Consortium.
00004  *
00005  * Permission to use, copy, modify, and/or distribute this software for any
00006  * purpose with or without fee is hereby granted, provided that the above
00007  * copyright notice and this permission notice appear in all copies.
00008  *
00009  * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
00010  * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
00011  * AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
00012  * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
00013  * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
00014  * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
00015  * PERFORMANCE OF THIS SOFTWARE.
00016  */
00017 
00018 /*
00019  * Copyright (c) 1990, 1993
00020  *      The Regents of the University of California.  All rights reserved.
00021  *
00022  * Redistribution and use in source and binary forms, with or without
00023  * modification, are permitted provided that the following conditions
00024  * are met:
00025  * 1. Redistributions of source code must retain the above copyright
00026  *    notice, this list of conditions and the following disclaimer.
00027  * 2. Redistributions in binary form must reproduce the above copyright
00028  *    notice, this list of conditions and the following disclaimer in the
00029  *    documentation and/or other materials provided with the distribution.
00030  * 3. Neither the name of the University nor the names of its contributors
00031  *    may be used to endorse or promote products derived from this software
00032  *    without specific prior written permission.
00033  *
00034  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
00035  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00036  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00037  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
00038  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
00039  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
00040  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
00041  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
00042  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
00043  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
00044  * SUCH DAMAGE.
00045  */
00046 
00047 /*! \file */
00048 
00049 #include <config.h>
00050 
00051 #include <ctype.h>
00052 
00053 #include <isc/mem.h>
00054 #include <isc/print.h>
00055 #include <isc/region.h>
00056 #include <isc/string.h>
00057 #include <isc/util.h>
00058 
00059 static char digits[] = "0123456789abcdefghijklmnoprstuvwxyz";
00060 
00061 isc_uint64_t
00062 isc_string_touint64(char *source, char **end, int base) {
00063         isc_uint64_t tmp;
00064         isc_uint64_t overflow;
00065         char *s = source;
00066         char *o;
00067         char c;
00068 
00069         if ((base < 0) || (base == 1) || (base > 36)) {
00070                 *end = source;
00071                 return (0);
00072         }
00073 
00074         while (*s != 0 && isascii(*s&0xff) && isspace(*s&0xff))
00075                 s++;
00076         if (*s == '+' /* || *s == '-' */)
00077                 s++;
00078         if (base == 0) {
00079                 if (*s == '0' && (*(s+1) == 'X' || *(s+1) == 'x')) {
00080                         s += 2;
00081                         base = 16;
00082                 } else if (*s == '0')
00083                         base = 8;
00084                 else
00085                         base = 10;
00086         }
00087         if (*s == 0) {
00088                 *end = source;
00089                 return (0);
00090         }
00091         overflow = ~0;
00092         overflow /= base;
00093         tmp = 0;
00094 
00095         while ((c = *s) != 0) {
00096                 c = tolower(c&0xff);
00097                 /* end ? */
00098                 if ((o = strchr(digits, c)) == NULL) {
00099                         *end = s;
00100                         return (tmp);
00101                 }
00102                 /* end ? */
00103                 if ((o - digits) >= base) {
00104                         *end = s;
00105                         return (tmp);
00106                 }
00107                 /* overflow ? */
00108                 if (tmp > overflow) {
00109                         *end = source;
00110                         return (0);
00111                 }
00112                 tmp *= base;
00113                 /* overflow ? */
00114                 if ((tmp + (o - digits)) < tmp) {
00115                         *end = source;
00116                         return (0);
00117                 }
00118                 tmp += o - digits;
00119                 s++;
00120         }
00121         *end = s;
00122         return (tmp);
00123 }
00124 
00125 isc_result_t
00126 isc_string_copy(char *target, size_t size, const char *source) {
00127         REQUIRE(size > 0U);
00128 
00129         if (strlcpy(target, source, size) >= size) {
00130                 memset(target, ISC_STRING_MAGIC, size);
00131                 return (ISC_R_NOSPACE);
00132         }
00133 
00134         ENSURE(strlen(target) < size);
00135 
00136         return (ISC_R_SUCCESS);
00137 }
00138 
00139 void
00140 isc_string_copy_truncate(char *target, size_t size, const char *source) {
00141         REQUIRE(size > 0U);
00142 
00143         strlcpy(target, source, size);
00144 
00145         ENSURE(strlen(target) < size);
00146 }
00147 
00148 isc_result_t
00149 isc_string_append(char *target, size_t size, const char *source) {
00150         REQUIRE(size > 0U);
00151         REQUIRE(strlen(target) < size);
00152 
00153         if (strlcat(target, source, size) >= size) {
00154                 memset(target, ISC_STRING_MAGIC, size);
00155                 return (ISC_R_NOSPACE);
00156         }
00157 
00158         ENSURE(strlen(target) < size);
00159 
00160         return (ISC_R_SUCCESS);
00161 }
00162 
00163 void
00164 isc_string_append_truncate(char *target, size_t size, const char *source) {
00165         REQUIRE(size > 0U);
00166         REQUIRE(strlen(target) < size);
00167 
00168         strlcat(target, source, size);
00169 
00170         ENSURE(strlen(target) < size);
00171 }
00172 
00173 isc_result_t
00174 isc_string_printf(char *target, size_t size, const char *format, ...) {
00175         va_list args;
00176         size_t n;
00177 
00178         REQUIRE(size > 0U);
00179 
00180         va_start(args, format);
00181         n = vsnprintf(target, size, format, args);
00182         va_end(args);
00183 
00184         if (n >= size) {
00185                 memset(target, ISC_STRING_MAGIC, size);
00186                 return (ISC_R_NOSPACE);
00187         }
00188 
00189         ENSURE(strlen(target) < size);
00190 
00191         return (ISC_R_SUCCESS);
00192 }
00193 
00194 void
00195 isc_string_printf_truncate(char *target, size_t size, const char *format, ...)
00196 {
00197         va_list args;
00198 
00199         REQUIRE(size > 0U);
00200 
00201         va_start(args, format);
00202         /* check return code? */
00203         (void)vsnprintf(target, size, format, args);
00204         va_end(args);
00205 
00206         ENSURE(strlen(target) < size);
00207 }
00208 
00209 char *
00210 isc_string_regiondup(isc_mem_t *mctx, const isc_region_t *source) {
00211         char *target;
00212 
00213         REQUIRE(mctx != NULL);
00214         REQUIRE(source != NULL);
00215 
00216         target = (char *) isc_mem_allocate(mctx, source->length + 1);
00217         if (target != NULL) {
00218                 memmove(source->base, target, source->length);
00219                 target[source->length] = '\0';
00220         }
00221 
00222         return (target);
00223 }
00224 
00225 char *
00226 isc_string_separate(char **stringp, const char *delim) {
00227         char *string = *stringp;
00228         char *s;
00229         const char *d;
00230         char sc, dc;
00231 
00232         if (string == NULL)
00233                 return (NULL);
00234 
00235         for (s = string; (sc = *s) != '\0'; s++)
00236                 for (d = delim; (dc = *d) != '\0'; d++)
00237                         if (sc == dc) {
00238                                 *s++ = '\0';
00239                                 *stringp = s;
00240                                 return (string);
00241                         }
00242         *stringp = NULL;
00243         return (string);
00244 }
00245 
00246 size_t
00247 isc_string_strlcpy(char *dst, const char *src, size_t size)
00248 {
00249         char *d = dst;
00250         const char *s = src;
00251         size_t n = size;
00252 
00253         /* Copy as many bytes as will fit */
00254         if (n != 0U && --n != 0U) {
00255                 do {
00256                         if ((*d++ = *s++) == 0)
00257                                 break;
00258                 } while (--n != 0U);
00259         }
00260 
00261         /* Not enough room in dst, add NUL and traverse rest of src */
00262         if (n == 0U) {
00263                 if (size != 0U)
00264                         *d = '\0';              /* NUL-terminate dst */
00265                 while (*s++)
00266                         ;
00267         }
00268 
00269         return(s - src - 1);    /* count does not include NUL */
00270 }
00271 
00272 size_t
00273 isc_string_strlcat(char *dst, const char *src, size_t size)
00274 {
00275         char *d = dst;
00276         const char *s = src;
00277         size_t n = size;
00278         size_t dlen;
00279 
00280         /* Find the end of dst and adjust bytes left but don't go past end */
00281         while (n-- != 0U && *d != '\0')
00282                 d++;
00283         dlen = d - dst;
00284         n = size - dlen;
00285 
00286         if (n == 0U)
00287                 return(dlen + strlen(s));
00288         while (*s != '\0') {
00289                 if (n != 1U) {
00290                         *d++ = *s;
00291                         n--;
00292                 }
00293                 s++;
00294         }
00295         *d = '\0';
00296 
00297         return(dlen + (s - src));       /* count does not include NUL */
00298 }
00299 
00300 char *
00301 isc_string_strcasestr(const char *str, const char *search) {
00302         char c, sc, *s;
00303         size_t len;
00304 
00305         if ((c = *search++) != 0) {
00306                 c = tolower((unsigned char) c);
00307                 len = strlen(search);
00308                 do {
00309                         do {
00310                                 if ((sc = *str++) == 0)
00311                                         return (NULL);
00312                         } while ((char) tolower((unsigned char) sc) != c);
00313                 } while (strncasecmp(str, search, len) != 0);
00314                 str--;
00315         }
00316         DE_CONST(str, s);
00317         return (s);
00318 
00319 }

Generated on Tue Apr 28 17:41:05 2015 by Doxygen 1.5.4 for BIND9 Internals 9.11.0pre-alpha