/contrib/bind9/lib/isc/string.c

https://bitbucket.org/freebsd/freebsd-head/ · C · 271 lines · 196 code · 49 blank · 26 comment · 68 complexity · fb035d01dfb3f49b7a947b469db06128 MD5 · raw file

  1. /*
  2. * Copyright (C) 2004-2007, 2011, 2012 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. /* $Id$ */
  18. /*! \file */
  19. #include <config.h>
  20. #include <ctype.h>
  21. #include <isc/mem.h>
  22. #include <isc/print.h>
  23. #include <isc/region.h>
  24. #include <isc/string.h>
  25. #include <isc/util.h>
  26. static char digits[] = "0123456789abcdefghijklmnoprstuvwxyz";
  27. isc_uint64_t
  28. isc_string_touint64(char *source, char **end, int base) {
  29. isc_uint64_t tmp;
  30. isc_uint64_t overflow;
  31. char *s = source;
  32. char *o;
  33. char c;
  34. if ((base < 0) || (base == 1) || (base > 36)) {
  35. *end = source;
  36. return (0);
  37. }
  38. while (*s != 0 && isascii(*s&0xff) && isspace(*s&0xff))
  39. s++;
  40. if (*s == '+' /* || *s == '-' */)
  41. s++;
  42. if (base == 0) {
  43. if (*s == '0' && (*(s+1) == 'X' || *(s+1) == 'x')) {
  44. s += 2;
  45. base = 16;
  46. } else if (*s == '0')
  47. base = 8;
  48. else
  49. base = 10;
  50. }
  51. if (*s == 0) {
  52. *end = source;
  53. return (0);
  54. }
  55. overflow = ~0;
  56. overflow /= base;
  57. tmp = 0;
  58. while ((c = *s) != 0) {
  59. c = tolower(c&0xff);
  60. /* end ? */
  61. if ((o = strchr(digits, c)) == NULL) {
  62. *end = s;
  63. return (tmp);
  64. }
  65. /* end ? */
  66. if ((o - digits) >= base) {
  67. *end = s;
  68. return (tmp);
  69. }
  70. /* overflow ? */
  71. if (tmp > overflow) {
  72. *end = source;
  73. return (0);
  74. }
  75. tmp *= base;
  76. /* overflow ? */
  77. if ((tmp + (o - digits)) < tmp) {
  78. *end = source;
  79. return (0);
  80. }
  81. tmp += o - digits;
  82. s++;
  83. }
  84. *end = s;
  85. return (tmp);
  86. }
  87. isc_result_t
  88. isc_string_copy(char *target, size_t size, const char *source) {
  89. REQUIRE(size > 0U);
  90. if (strlcpy(target, source, size) >= size) {
  91. memset(target, ISC_STRING_MAGIC, size);
  92. return (ISC_R_NOSPACE);
  93. }
  94. ENSURE(strlen(target) < size);
  95. return (ISC_R_SUCCESS);
  96. }
  97. void
  98. isc_string_copy_truncate(char *target, size_t size, const char *source) {
  99. REQUIRE(size > 0U);
  100. strlcpy(target, source, size);
  101. ENSURE(strlen(target) < size);
  102. }
  103. isc_result_t
  104. isc_string_append(char *target, size_t size, const char *source) {
  105. REQUIRE(size > 0U);
  106. REQUIRE(strlen(target) < size);
  107. if (strlcat(target, source, size) >= size) {
  108. memset(target, ISC_STRING_MAGIC, size);
  109. return (ISC_R_NOSPACE);
  110. }
  111. ENSURE(strlen(target) < size);
  112. return (ISC_R_SUCCESS);
  113. }
  114. void
  115. isc_string_append_truncate(char *target, size_t size, const char *source) {
  116. REQUIRE(size > 0U);
  117. REQUIRE(strlen(target) < size);
  118. strlcat(target, source, size);
  119. ENSURE(strlen(target) < size);
  120. }
  121. isc_result_t
  122. isc_string_printf(char *target, size_t size, const char *format, ...) {
  123. va_list args;
  124. size_t n;
  125. REQUIRE(size > 0U);
  126. va_start(args, format);
  127. n = vsnprintf(target, size, format, args);
  128. va_end(args);
  129. if (n >= size) {
  130. memset(target, ISC_STRING_MAGIC, size);
  131. return (ISC_R_NOSPACE);
  132. }
  133. ENSURE(strlen(target) < size);
  134. return (ISC_R_SUCCESS);
  135. }
  136. void
  137. isc_string_printf_truncate(char *target, size_t size, const char *format, ...)
  138. {
  139. va_list args;
  140. REQUIRE(size > 0U);
  141. va_start(args, format);
  142. /* check return code? */
  143. (void)vsnprintf(target, size, format, args);
  144. va_end(args);
  145. ENSURE(strlen(target) < size);
  146. }
  147. char *
  148. isc_string_regiondup(isc_mem_t *mctx, const isc_region_t *source) {
  149. char *target;
  150. REQUIRE(mctx != NULL);
  151. REQUIRE(source != NULL);
  152. target = (char *) isc_mem_allocate(mctx, source->length + 1);
  153. if (target != NULL) {
  154. memcpy(source->base, target, source->length);
  155. target[source->length] = '\0';
  156. }
  157. return (target);
  158. }
  159. char *
  160. isc_string_separate(char **stringp, const char *delim) {
  161. char *string = *stringp;
  162. char *s;
  163. const char *d;
  164. char sc, dc;
  165. if (string == NULL)
  166. return (NULL);
  167. for (s = string; (sc = *s) != '\0'; s++)
  168. for (d = delim; (dc = *d) != '\0'; d++)
  169. if (sc == dc) {
  170. *s++ = '\0';
  171. *stringp = s;
  172. return (string);
  173. }
  174. *stringp = NULL;
  175. return (string);
  176. }
  177. size_t
  178. isc_string_strlcpy(char *dst, const char *src, size_t size)
  179. {
  180. char *d = dst;
  181. const char *s = src;
  182. size_t n = size;
  183. /* Copy as many bytes as will fit */
  184. if (n != 0U && --n != 0U) {
  185. do {
  186. if ((*d++ = *s++) == 0)
  187. break;
  188. } while (--n != 0U);
  189. }
  190. /* Not enough room in dst, add NUL and traverse rest of src */
  191. if (n == 0U) {
  192. if (size != 0U)
  193. *d = '\0'; /* NUL-terminate dst */
  194. while (*s++)
  195. ;
  196. }
  197. return(s - src - 1); /* count does not include NUL */
  198. }
  199. size_t
  200. isc_string_strlcat(char *dst, const char *src, size_t size)
  201. {
  202. char *d = dst;
  203. const char *s = src;
  204. size_t n = size;
  205. size_t dlen;
  206. /* Find the end of dst and adjust bytes left but don't go past end */
  207. while (n-- != 0U && *d != '\0')
  208. d++;
  209. dlen = d - dst;
  210. n = size - dlen;
  211. if (n == 0U)
  212. return(dlen + strlen(s));
  213. while (*s != '\0') {
  214. if (n != 1U) {
  215. *d++ = *s;
  216. n--;
  217. }
  218. s++;
  219. }
  220. *d = '\0';
  221. return(dlen + (s - src)); /* count does not include NUL */
  222. }