Return to string.c CVS log | Up to [ELWIX - Embedded LightWeight unIX -] / embedaddon / ntp / lib / isc |
1.1 ! misho 1: /* ! 2: * Copyright (C) 2004-2007 Internet Systems Consortium, Inc. ("ISC") ! 3: * Copyright (C) 1999-2001, 2003 Internet Software Consortium. ! 4: * ! 5: * Permission to use, copy, modify, and/or distribute this software for any ! 6: * purpose with or without fee is hereby granted, provided that the above ! 7: * copyright notice and this permission notice appear in all copies. ! 8: * ! 9: * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH ! 10: * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY ! 11: * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, ! 12: * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM ! 13: * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE ! 14: * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR ! 15: * PERFORMANCE OF THIS SOFTWARE. ! 16: */ ! 17: ! 18: /* $Id: string.c,v 1.20 2007/06/19 23:47:17 tbox Exp $ */ ! 19: ! 20: /*! \file */ ! 21: ! 22: #include <config.h> ! 23: ! 24: #include <ctype.h> ! 25: ! 26: #include <isc/mem.h> ! 27: #include <isc/print.h> ! 28: #include <isc/region.h> ! 29: #include <isc/string.h> ! 30: #include <isc/util.h> ! 31: ! 32: static char digits[] = "0123456789abcdefghijklmnoprstuvwxyz"; ! 33: ! 34: isc_uint64_t ! 35: isc_string_touint64(char *source, char **end, int base) { ! 36: isc_uint64_t tmp; ! 37: isc_uint64_t overflow; ! 38: char *s = source; ! 39: char *o; ! 40: char c; ! 41: ! 42: if ((base < 0) || (base == 1) || (base > 36)) { ! 43: *end = source; ! 44: return (0); ! 45: } ! 46: ! 47: while (*s != 0 && isascii(*s&0xff) && isspace(*s&0xff)) ! 48: s++; ! 49: if (*s == '+' /* || *s == '-' */) ! 50: s++; ! 51: if (base == 0) { ! 52: if (*s == '0' && (*(s+1) == 'X' || *(s+1) == 'x')) { ! 53: s += 2; ! 54: base = 16; ! 55: } else if (*s == '0') ! 56: base = 8; ! 57: else ! 58: base = 10; ! 59: } ! 60: if (*s == 0) { ! 61: *end = source; ! 62: return (0); ! 63: } ! 64: overflow = ~0; ! 65: overflow /= base; ! 66: tmp = 0; ! 67: ! 68: while ((c = *s) != 0) { ! 69: c = tolower(c&0xff); ! 70: /* end ? */ ! 71: if ((o = strchr(digits, c)) == NULL) { ! 72: *end = s; ! 73: return (tmp); ! 74: } ! 75: /* end ? */ ! 76: if ((o - digits) >= base) { ! 77: *end = s; ! 78: return (tmp); ! 79: } ! 80: /* overflow ? */ ! 81: if (tmp > overflow) { ! 82: *end = source; ! 83: return (0); ! 84: } ! 85: tmp *= base; ! 86: /* overflow ? */ ! 87: if ((tmp + (o - digits)) < tmp) { ! 88: *end = source; ! 89: return (0); ! 90: } ! 91: tmp += o - digits; ! 92: s++; ! 93: } ! 94: *end = s; ! 95: return (tmp); ! 96: } ! 97: ! 98: isc_result_t ! 99: isc_string_copy(char *target, size_t size, const char *source) { ! 100: REQUIRE(size > 0U); ! 101: ! 102: if (strlcpy(target, source, size) >= size) { ! 103: memset(target, ISC_STRING_MAGIC, size); ! 104: return (ISC_R_NOSPACE); ! 105: } ! 106: ! 107: ENSURE(strlen(target) < size); ! 108: ! 109: return (ISC_R_SUCCESS); ! 110: } ! 111: ! 112: void ! 113: isc_string_copy_truncate(char *target, size_t size, const char *source) { ! 114: REQUIRE(size > 0U); ! 115: ! 116: strlcpy(target, source, size); ! 117: ! 118: ENSURE(strlen(target) < size); ! 119: } ! 120: ! 121: isc_result_t ! 122: isc_string_append(char *target, size_t size, const char *source) { ! 123: REQUIRE(size > 0U); ! 124: REQUIRE(strlen(target) < size); ! 125: ! 126: if (strlcat(target, source, size) >= size) { ! 127: memset(target, ISC_STRING_MAGIC, size); ! 128: return (ISC_R_NOSPACE); ! 129: } ! 130: ! 131: ENSURE(strlen(target) < size); ! 132: ! 133: return (ISC_R_SUCCESS); ! 134: } ! 135: ! 136: void ! 137: isc_string_append_truncate(char *target, size_t size, const char *source) { ! 138: REQUIRE(size > 0U); ! 139: REQUIRE(strlen(target) < size); ! 140: ! 141: strlcat(target, source, size); ! 142: ! 143: ENSURE(strlen(target) < size); ! 144: } ! 145: ! 146: isc_result_t ! 147: isc_string_printf(char *target, size_t size, const char *format, ...) { ! 148: va_list args; ! 149: size_t n; ! 150: ! 151: REQUIRE(size > 0U); ! 152: ! 153: va_start(args, format); ! 154: n = vsnprintf(target, size, format, args); ! 155: va_end(args); ! 156: ! 157: if (n >= size) { ! 158: memset(target, ISC_STRING_MAGIC, size); ! 159: return (ISC_R_NOSPACE); ! 160: } ! 161: ! 162: ENSURE(strlen(target) < size); ! 163: ! 164: return (ISC_R_SUCCESS); ! 165: } ! 166: ! 167: void ! 168: isc_string_printf_truncate(char *target, size_t size, const char *format, ...) { ! 169: va_list args; ! 170: size_t n; ! 171: ! 172: REQUIRE(size > 0U); ! 173: ! 174: va_start(args, format); ! 175: n = vsnprintf(target, size, format, args); ! 176: va_end(args); ! 177: ! 178: ENSURE(strlen(target) < size); ! 179: } ! 180: ! 181: char * ! 182: isc_string_regiondup(isc_mem_t *mctx, const isc_region_t *source) { ! 183: char *target; ! 184: ! 185: REQUIRE(mctx != NULL); ! 186: REQUIRE(source != NULL); ! 187: ! 188: target = (char *) isc_mem_allocate(mctx, source->length + 1); ! 189: if (target != NULL) { ! 190: memcpy(source->base, target, source->length); ! 191: target[source->length] = '\0'; ! 192: } ! 193: ! 194: return (target); ! 195: } ! 196: ! 197: char * ! 198: isc_string_separate(char **stringp, const char *delim) { ! 199: char *string = *stringp; ! 200: char *s; ! 201: const char *d; ! 202: char sc, dc; ! 203: ! 204: if (string == NULL) ! 205: return (NULL); ! 206: ! 207: for (s = string; (sc = *s) != '\0'; s++) ! 208: for (d = delim; (dc = *d) != '\0'; d++) ! 209: if (sc == dc) { ! 210: *s++ = '\0'; ! 211: *stringp = s; ! 212: return (string); ! 213: } ! 214: *stringp = NULL; ! 215: return (string); ! 216: } ! 217: ! 218: size_t ! 219: isc_string_strlcpy(char *dst, const char *src, size_t size) ! 220: { ! 221: char *d = dst; ! 222: const char *s = src; ! 223: size_t n = size; ! 224: ! 225: /* Copy as many bytes as will fit */ ! 226: if (n != 0U && --n != 0U) { ! 227: do { ! 228: if ((*d++ = *s++) == 0) ! 229: break; ! 230: } while (--n != 0U); ! 231: } ! 232: ! 233: /* Not enough room in dst, add NUL and traverse rest of src */ ! 234: if (n == 0U) { ! 235: if (size != 0U) ! 236: *d = '\0'; /* NUL-terminate dst */ ! 237: while (*s++) ! 238: ; ! 239: } ! 240: ! 241: return(s - src - 1); /* count does not include NUL */ ! 242: } ! 243: ! 244: size_t ! 245: isc_string_strlcat(char *dst, const char *src, size_t size) ! 246: { ! 247: char *d = dst; ! 248: const char *s = src; ! 249: size_t n = size; ! 250: size_t dlen; ! 251: ! 252: /* Find the end of dst and adjust bytes left but don't go past end */ ! 253: while (n-- != 0U && *d != '\0') ! 254: d++; ! 255: dlen = d - dst; ! 256: n = size - dlen; ! 257: ! 258: if (n == 0U) ! 259: return(dlen + strlen(s)); ! 260: while (*s != '\0') { ! 261: if (n != 1U) { ! 262: *d++ = *s; ! 263: n--; ! 264: } ! 265: s++; ! 266: } ! 267: *d = '\0'; ! 268: ! 269: return(dlen + (s - src)); /* count does not include NUL */ ! 270: }