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