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