00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
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 == '+' )
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
00098 if ((o = strchr(digits, c)) == NULL) {
00099 *end = s;
00100 return (tmp);
00101 }
00102
00103 if ((o - digits) >= base) {
00104 *end = s;
00105 return (tmp);
00106 }
00107
00108 if (tmp > overflow) {
00109 *end = source;
00110 return (0);
00111 }
00112 tmp *= base;
00113
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
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
00254 if (n != 0U && --n != 0U) {
00255 do {
00256 if ((*d++ = *s++) == 0)
00257 break;
00258 } while (--n != 0U);
00259 }
00260
00261
00262 if (n == 0U) {
00263 if (size != 0U)
00264 *d = '\0';
00265 while (*s++)
00266 ;
00267 }
00268
00269 return(s - src - 1);
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
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));
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 }