ee1605c52900e915aaafdb5c0649eca3fa19c166
[awesomized/libmemcached] / memcached / util.c
1 #include <config.h>
2
3 #include <stdio.h>
4 #include <assert.h>
5 #include <ctype.h>
6 #include <errno.h>
7 #include <string.h>
8 #include <stdlib.h>
9 #include <stdarg.h>
10
11 #include "memcached.h"
12
13 /* Avoid warnings on solaris, where isspace() is an index into an array, and gcc uses signed chars */
14 #define xisspace(c) isspace((unsigned char)c)
15
16 bool safe_strtoull(const char *str, uint64_t *out) {
17 assert(out != NULL);
18 errno = 0;
19 *out = 0;
20 char *endptr;
21 unsigned long long ull = strtoull(str, &endptr, 10);
22 if ((errno == ERANGE) || (str == endptr)) {
23 return false;
24 }
25
26 if (xisspace(*endptr) || (*endptr == '\0' && endptr != str)) {
27 if ((long long) ull < 0) {
28 /* only check for negative signs in the uncommon case when
29 * the unsigned number is so big that it's negative as a
30 * signed number. */
31 if (strchr(str, '-') != NULL) {
32 return false;
33 }
34 }
35 *out = ull;
36 return true;
37 }
38 return false;
39 }
40
41 bool safe_strtoll(const char *str, int64_t *out) {
42 assert(out != NULL);
43 errno = 0;
44 *out = 0;
45 char *endptr;
46 long long ll = strtoll(str, &endptr, 10);
47 if ((errno == ERANGE) || (str == endptr)) {
48 return false;
49 }
50
51 if (xisspace(*endptr) || (*endptr == '\0' && endptr != str)) {
52 *out = ll;
53 return true;
54 }
55 return false;
56 }
57
58 bool safe_strtoul(const char *str, uint32_t *out) {
59 char *endptr = NULL;
60 unsigned long l = 0;
61 assert(out);
62 assert(str);
63 *out = 0;
64 errno = 0;
65
66 l = strtoul(str, &endptr, 10);
67 if ((errno == ERANGE) || (str == endptr)) {
68 return false;
69 }
70
71 if (xisspace(*endptr) || (*endptr == '\0' && endptr != str)) {
72 if ((long) l < 0) {
73 /* only check for negative signs in the uncommon case when
74 * the unsigned number is so big that it's negative as a
75 * signed number. */
76 if (strchr(str, '-') != NULL) {
77 return false;
78 }
79 }
80 *out = l;
81 return true;
82 }
83
84 return false;
85 }
86
87 bool safe_strtol(const char *str, int32_t *out) {
88 assert(out != NULL);
89 errno = 0;
90 *out = 0;
91 char *endptr;
92 long l = strtol(str, &endptr, 10);
93 if ((errno == ERANGE) || (str == endptr)) {
94 return false;
95 }
96
97 if (xisspace(*endptr) || (*endptr == '\0' && endptr != str)) {
98 *out = l;
99 return true;
100 }
101 return false;
102 }
103
104 void vperror(const char *fmt, ...) {
105 int old_errno = errno;
106 char buf[1024];
107 va_list ap;
108
109 va_start(ap, fmt);
110 if (vsnprintf(buf, sizeof(buf), fmt, ap) == -1) {
111 buf[sizeof(buf) - 1] = '\0';
112 }
113 va_end(ap);
114
115 errno = old_errno;
116
117 perror(buf);
118 }
119
120 #ifndef HAVE_HTONLL
121 static uint64_t mc_swap64(uint64_t in) {
122 #ifdef ENDIAN_LITTLE
123 /* Little endian, flip the bytes around until someone makes a faster/better
124 * way to do this. */
125 int64_t rv = 0;
126 int i = 0;
127 for(i = 0; i<8; i++) {
128 rv = (rv << 8) | (in & 0xff);
129 in >>= 8;
130 }
131 return rv;
132 #else
133 /* big-endian machines don't need byte swapping */
134 return in;
135 #endif
136 }
137
138 uint64_t ntohll(uint64_t val) {
139 return mc_swap64(val);
140 }
141
142 uint64_t htonll(uint64_t val) {
143 return mc_swap64(val);
144 }
145 #endif
146