File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / ntp / lib / isc / string.c
Revision 1.1.1.1 (vendor branch): download - view: text, annotated - select for diffs - revision graph
Tue May 29 12:08:38 2012 UTC (12 years, 1 month ago) by misho
Branches: ntp, MAIN
CVS tags: v4_2_6p5p0, v4_2_6p5, HEAD
ntp 4.2.6p5

    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.1.1.1 2012/05/29 12:08:38 misho 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: }

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>