Host library for controlling a WiConnect enabled Wi-Fi module.

Dependents:   wiconnect-ota_example wiconnect-web_setup_example wiconnect-test-console wiconnect-tcp_server_example ... more

Committer:
dan_ackme
Date:
Mon Aug 11 09:58:24 2014 +0000
Revision:
0:ea85c4bb5e1f
Child:
1:6ec9998427ad
initial check-in

Who changed what in which revision?

UserRevisionLine numberNew contents of line
dan_ackme 0:ea85c4bb5e1f 1 /*
dan_ackme 0:ea85c4bb5e1f 2 * Copyright 2014, ACKme Networks
dan_ackme 0:ea85c4bb5e1f 3 * All Rights Reserved.
dan_ackme 0:ea85c4bb5e1f 4 *
dan_ackme 0:ea85c4bb5e1f 5 * This is UNPUBLISHED PROPRIETARY SOURCE CODE of ACKme Networks;
dan_ackme 0:ea85c4bb5e1f 6 * the contents of this file may not be disclosed to third parties, copied
dan_ackme 0:ea85c4bb5e1f 7 * or duplicated in any form, in whole or in part, without the prior
dan_ackme 0:ea85c4bb5e1f 8 * written permission of ACKme Networks.
dan_ackme 0:ea85c4bb5e1f 9 */
dan_ackme 0:ea85c4bb5e1f 10
dan_ackme 0:ea85c4bb5e1f 11 #pragma once
dan_ackme 0:ea85c4bb5e1f 12
dan_ackme 0:ea85c4bb5e1f 13
dan_ackme 0:ea85c4bb5e1f 14 #include <string.h>
dan_ackme 0:ea85c4bb5e1f 15 #include <ctype.h>
dan_ackme 0:ea85c4bb5e1f 16 #include <stdint.h>
dan_ackme 0:ea85c4bb5e1f 17 #include <limits.h>
dan_ackme 0:ea85c4bb5e1f 18
dan_ackme 0:ea85c4bb5e1f 19
dan_ackme 0:ea85c4bb5e1f 20 #ifdef WICONNECT_USE_STRTOLL
dan_ackme 0:ea85c4bb5e1f 21 // Necessary to get strtoll in C99 mode.
dan_ackme 0:ea85c4bb5e1f 22 // http://sourceware.org/ml/newlib/2012/msg00425.html
dan_ackme 0:ea85c4bb5e1f 23 extern long long strtoll(const char *__n, char **__end_PTR, int __base);
dan_ackme 0:ea85c4bb5e1f 24 #endif
dan_ackme 0:ea85c4bb5e1f 25
dan_ackme 0:ea85c4bb5e1f 26
dan_ackme 0:ea85c4bb5e1f 27 class StringUtil
dan_ackme 0:ea85c4bb5e1f 28 {
dan_ackme 0:ea85c4bb5e1f 29
dan_ackme 0:ea85c4bb5e1f 30 public:
dan_ackme 0:ea85c4bb5e1f 31 /*************************************************************************************************/
dan_ackme 0:ea85c4bb5e1f 32 // Helper to find an occurrence of a delimiter string,
dan_ackme 0:ea85c4bb5e1f 33 // insert '\0' in its place and return string after
dan_ackme 0:ea85c4bb5e1f 34 // the delimiter e.g.
dan_ackme 0:ea85c4bb5e1f 35 // if char s[] = "foo://bar";
dan_ackme 0:ea85c4bb5e1f 36 // - strchop(s, "://") returns "bar"
dan_ackme 0:ea85c4bb5e1f 37 // - s becomes "foo"
dan_ackme 0:ea85c4bb5e1f 38 static char *chop(char *haystack, const char *needle)
dan_ackme 0:ea85c4bb5e1f 39 {
dan_ackme 0:ea85c4bb5e1f 40 if (!haystack)
dan_ackme 0:ea85c4bb5e1f 41 {
dan_ackme 0:ea85c4bb5e1f 42 return NULL;
dan_ackme 0:ea85c4bb5e1f 43 }
dan_ackme 0:ea85c4bb5e1f 44 char *end = strstr(haystack, needle);
dan_ackme 0:ea85c4bb5e1f 45 if (end)
dan_ackme 0:ea85c4bb5e1f 46 {
dan_ackme 0:ea85c4bb5e1f 47 *end = '\0';
dan_ackme 0:ea85c4bb5e1f 48 return end + strlen(needle);
dan_ackme 0:ea85c4bb5e1f 49 }
dan_ackme 0:ea85c4bb5e1f 50 return NULL;
dan_ackme 0:ea85c4bb5e1f 51 }
dan_ackme 0:ea85c4bb5e1f 52
dan_ackme 0:ea85c4bb5e1f 53 /*************************************************************************************************/
dan_ackme 0:ea85c4bb5e1f 54 // Check if string is non-null and non-empty.
dan_ackme 0:ea85c4bb5e1f 55 static bool empty(const char *s)
dan_ackme 0:ea85c4bb5e1f 56 {
dan_ackme 0:ea85c4bb5e1f 57 return !(s && *s);
dan_ackme 0:ea85c4bb5e1f 58 }
dan_ackme 0:ea85c4bb5e1f 59
dan_ackme 0:ea85c4bb5e1f 60 /*************************************************************************************************/
dan_ackme 0:ea85c4bb5e1f 61 static bool isSpace(const char *s)
dan_ackme 0:ea85c4bb5e1f 62 {
dan_ackme 0:ea85c4bb5e1f 63 while(*s != 0)
dan_ackme 0:ea85c4bb5e1f 64 {
dan_ackme 0:ea85c4bb5e1f 65 if(!isspace((uint8_t)*s++))
dan_ackme 0:ea85c4bb5e1f 66 return false;
dan_ackme 0:ea85c4bb5e1f 67 }
dan_ackme 0:ea85c4bb5e1f 68 return true;
dan_ackme 0:ea85c4bb5e1f 69 }
dan_ackme 0:ea85c4bb5e1f 70
dan_ackme 0:ea85c4bb5e1f 71 /*************************************************************************************************/
dan_ackme 0:ea85c4bb5e1f 72 // Convert null-terminated string to lower case.
dan_ackme 0:ea85c4bb5e1f 73 // ASCII charset only.
dan_ackme 0:ea85c4bb5e1f 74 static void toLower(char *s)
dan_ackme 0:ea85c4bb5e1f 75 {
dan_ackme 0:ea85c4bb5e1f 76 for (; *s; ++s)
dan_ackme 0:ea85c4bb5e1f 77 {
dan_ackme 0:ea85c4bb5e1f 78 *s = tolower((int) * s);
dan_ackme 0:ea85c4bb5e1f 79 }
dan_ackme 0:ea85c4bb5e1f 80 }
dan_ackme 0:ea85c4bb5e1f 81
dan_ackme 0:ea85c4bb5e1f 82 /*************************************************************************************************/
dan_ackme 0:ea85c4bb5e1f 83 // Combination of strip left + right.
dan_ackme 0:ea85c4bb5e1f 84 static char *strip(char *s, const char *chars)
dan_ackme 0:ea85c4bb5e1f 85 {
dan_ackme 0:ea85c4bb5e1f 86 return rightStrip(leftStrip(s, chars), chars);
dan_ackme 0:ea85c4bb5e1f 87 }
dan_ackme 0:ea85c4bb5e1f 88
dan_ackme 0:ea85c4bb5e1f 89 /*************************************************************************************************/
dan_ackme 0:ea85c4bb5e1f 90 // Strip string from the left.
dan_ackme 0:ea85c4bb5e1f 91 // Returns pointer into the input string.
dan_ackme 0:ea85c4bb5e1f 92 static char *leftStrip(char *s, const char *chars)
dan_ackme 0:ea85c4bb5e1f 93 {
dan_ackme 0:ea85c4bb5e1f 94 return s + strspn(s, chars);
dan_ackme 0:ea85c4bb5e1f 95 }
dan_ackme 0:ea85c4bb5e1f 96
dan_ackme 0:ea85c4bb5e1f 97 /*************************************************************************************************/
dan_ackme 0:ea85c4bb5e1f 98 // Strip string from the right.
dan_ackme 0:ea85c4bb5e1f 99 // Modified in place.
dan_ackme 0:ea85c4bb5e1f 100 static char *rightStrip(char *s, const char *chars)
dan_ackme 0:ea85c4bb5e1f 101 {
dan_ackme 0:ea85c4bb5e1f 102 char *end = s + strlen(s) - 1;
dan_ackme 0:ea85c4bb5e1f 103 while (end > s && strstr(chars, end))
dan_ackme 0:ea85c4bb5e1f 104 {
dan_ackme 0:ea85c4bb5e1f 105 *end-- = '\0';
dan_ackme 0:ea85c4bb5e1f 106 }
dan_ackme 0:ea85c4bb5e1f 107 return s;
dan_ackme 0:ea85c4bb5e1f 108 }
dan_ackme 0:ea85c4bb5e1f 109
dan_ackme 0:ea85c4bb5e1f 110 /*************************************************************************************************/
dan_ackme 0:ea85c4bb5e1f 111 // Parse decimal integer and check if it's in bounds [min, max].
dan_ackme 0:ea85c4bb5e1f 112 static bool parseInt(const char *s, intmax_t *result, intmax_t min, intmax_t max)
dan_ackme 0:ea85c4bb5e1f 113 {
dan_ackme 0:ea85c4bb5e1f 114 return parseBase(s, result, min, max, 10);
dan_ackme 0:ea85c4bb5e1f 115 }
dan_ackme 0:ea85c4bb5e1f 116
dan_ackme 0:ea85c4bb5e1f 117 // Parse hexadecimal integer and check if it's in bounds [min, max].
dan_ackme 0:ea85c4bb5e1f 118 static bool parseHex(const char *s, intmax_t *result, intmax_t min, intmax_t max)
dan_ackme 0:ea85c4bb5e1f 119 {
dan_ackme 0:ea85c4bb5e1f 120 return parseBase(s, result, min, max, 16);
dan_ackme 0:ea85c4bb5e1f 121 }
dan_ackme 0:ea85c4bb5e1f 122
dan_ackme 0:ea85c4bb5e1f 123 /*************************************************************************************************/
dan_ackme 0:ea85c4bb5e1f 124 static bool parseBase(const char *s, intmax_t *result, intmax_t min, intmax_t max, int base)
dan_ackme 0:ea85c4bb5e1f 125 {
dan_ackme 0:ea85c4bb5e1f 126 if (!s)
dan_ackme 0:ea85c4bb5e1f 127 {
dan_ackme 0:ea85c4bb5e1f 128 return false;
dan_ackme 0:ea85c4bb5e1f 129 }
dan_ackme 0:ea85c4bb5e1f 130 char *end;
dan_ackme 0:ea85c4bb5e1f 131 #ifdef WICONNECT_USE_STRTOLL
dan_ackme 0:ea85c4bb5e1f 132 intmax_t value = strtoll(s, &end, base);
dan_ackme 0:ea85c4bb5e1f 133 #else
dan_ackme 0:ea85c4bb5e1f 134 intmax_t value = strtol(s, &end, base);
dan_ackme 0:ea85c4bb5e1f 135 #endif
dan_ackme 0:ea85c4bb5e1f 136 if (*end || value < min || value > max)
dan_ackme 0:ea85c4bb5e1f 137 {
dan_ackme 0:ea85c4bb5e1f 138 return false;
dan_ackme 0:ea85c4bb5e1f 139 }
dan_ackme 0:ea85c4bb5e1f 140 *result = value;
dan_ackme 0:ea85c4bb5e1f 141 return true;
dan_ackme 0:ea85c4bb5e1f 142 }
dan_ackme 0:ea85c4bb5e1f 143
dan_ackme 0:ea85c4bb5e1f 144 /*************************************************************************************************/
dan_ackme 0:ea85c4bb5e1f 145 // Parse an long long integer.
dan_ackme 0:ea85c4bb5e1f 146 static bool parseBool(const char *onoff, bool *var)
dan_ackme 0:ea85c4bb5e1f 147 {
dan_ackme 0:ea85c4bb5e1f 148 const char* const on_vals[] =
dan_ackme 0:ea85c4bb5e1f 149 {
dan_ackme 0:ea85c4bb5e1f 150 "1",
dan_ackme 0:ea85c4bb5e1f 151 "on",
dan_ackme 0:ea85c4bb5e1f 152 "true",
dan_ackme 0:ea85c4bb5e1f 153 "yes",
dan_ackme 0:ea85c4bb5e1f 154 };
dan_ackme 0:ea85c4bb5e1f 155
dan_ackme 0:ea85c4bb5e1f 156 for(uint8_t i = 0; i < ARRAY_COUNT(on_vals); ++i)
dan_ackme 0:ea85c4bb5e1f 157 {
dan_ackme 0:ea85c4bb5e1f 158 if(strcasecmp(on_vals[i], onoff) == 0)
dan_ackme 0:ea85c4bb5e1f 159 {
dan_ackme 0:ea85c4bb5e1f 160 *var = true;
dan_ackme 0:ea85c4bb5e1f 161 return true;
dan_ackme 0:ea85c4bb5e1f 162 }
dan_ackme 0:ea85c4bb5e1f 163 }
dan_ackme 0:ea85c4bb5e1f 164
dan_ackme 0:ea85c4bb5e1f 165 const char* const off_vals[] =
dan_ackme 0:ea85c4bb5e1f 166 {
dan_ackme 0:ea85c4bb5e1f 167 "0",
dan_ackme 0:ea85c4bb5e1f 168 "false",
dan_ackme 0:ea85c4bb5e1f 169 "no",
dan_ackme 0:ea85c4bb5e1f 170 "off",
dan_ackme 0:ea85c4bb5e1f 171 NULL
dan_ackme 0:ea85c4bb5e1f 172 };
dan_ackme 0:ea85c4bb5e1f 173 for(uint8_t i = 0; i < ARRAY_COUNT(off_vals); ++i)
dan_ackme 0:ea85c4bb5e1f 174 {
dan_ackme 0:ea85c4bb5e1f 175 if(strcasecmp(off_vals[i], onoff) == 0)
dan_ackme 0:ea85c4bb5e1f 176 {
dan_ackme 0:ea85c4bb5e1f 177 *var = false;
dan_ackme 0:ea85c4bb5e1f 178 return true;
dan_ackme 0:ea85c4bb5e1f 179 }
dan_ackme 0:ea85c4bb5e1f 180 }
dan_ackme 0:ea85c4bb5e1f 181
dan_ackme 0:ea85c4bb5e1f 182 return false;
dan_ackme 0:ea85c4bb5e1f 183 }
dan_ackme 0:ea85c4bb5e1f 184
dan_ackme 0:ea85c4bb5e1f 185 /*************************************************************************************************/
dan_ackme 0:ea85c4bb5e1f 186 // convert binary data to hex string
dan_ackme 0:ea85c4bb5e1f 187 static void binToHex(char *dst, int max_dst, const void *data, int data_len)
dan_ackme 0:ea85c4bb5e1f 188 {
dan_ackme 0:ea85c4bb5e1f 189 char *end = dst + max_dst - 1;
dan_ackme 0:ea85c4bb5e1f 190 for (int i = 0; i < data_len; ++i)
dan_ackme 0:ea85c4bb5e1f 191 {
dan_ackme 0:ea85c4bb5e1f 192 if (dst < end)
dan_ackme 0:ea85c4bb5e1f 193 {
dan_ackme 0:ea85c4bb5e1f 194 dst += sprintf(dst, "%2.2x", ((uint8_t *)data)[i]);
dan_ackme 0:ea85c4bb5e1f 195 }
dan_ackme 0:ea85c4bb5e1f 196 }
dan_ackme 0:ea85c4bb5e1f 197 }
dan_ackme 0:ea85c4bb5e1f 198
dan_ackme 0:ea85c4bb5e1f 199
dan_ackme 0:ea85c4bb5e1f 200 /*************************************************************************************************/
dan_ackme 0:ea85c4bb5e1f 201 // Parse binary data into hex string
dan_ackme 0:ea85c4bb5e1f 202 // the input buffer MUST be len*2 long
dan_ackme 0:ea85c4bb5e1f 203 // as the parsing is destructive and done in-place
dan_ackme 0:ea85c4bb5e1f 204 static void binToHex(void *h, int len)
dan_ackme 0:ea85c4bb5e1f 205 {
dan_ackme 0:ea85c4bb5e1f 206 char *dst = (char*)h;
dan_ackme 0:ea85c4bb5e1f 207 char *src= (char*)h+len;
dan_ackme 0:ea85c4bb5e1f 208
dan_ackme 0:ea85c4bb5e1f 209 memmove(src, dst, len);
dan_ackme 0:ea85c4bb5e1f 210
dan_ackme 0:ea85c4bb5e1f 211 while(len--)
dan_ackme 0:ea85c4bb5e1f 212 {
dan_ackme 0:ea85c4bb5e1f 213 sprintf(dst, "%2.2X", (unsigned int)(*src & 0xff));
dan_ackme 0:ea85c4bb5e1f 214 dst += 2;
dan_ackme 0:ea85c4bb5e1f 215 ++src;
dan_ackme 0:ea85c4bb5e1f 216 }
dan_ackme 0:ea85c4bb5e1f 217 }
dan_ackme 0:ea85c4bb5e1f 218
dan_ackme 0:ea85c4bb5e1f 219
dan_ackme 0:ea85c4bb5e1f 220 /*************************************************************************************************/
dan_ackme 0:ea85c4bb5e1f 221 // Parses hex representation of binary data destructively.
dan_ackme 0:ea85c4bb5e1f 222 // Returns number of bytes parsed or -1 on error.
dan_ackme 0:ea85c4bb5e1f 223 static int hexToBin(char *s)
dan_ackme 0:ea85c4bb5e1f 224 {
dan_ackme 0:ea85c4bb5e1f 225 int len, i, j;
dan_ackme 0:ea85c4bb5e1f 226 len = strlen(s);
dan_ackme 0:ea85c4bb5e1f 227 if (len % 2)
dan_ackme 0:ea85c4bb5e1f 228 {
dan_ackme 0:ea85c4bb5e1f 229 return -1;
dan_ackme 0:ea85c4bb5e1f 230 }
dan_ackme 0:ea85c4bb5e1f 231 for (i = j = 0; i < len; i += 2, j++)
dan_ackme 0:ea85c4bb5e1f 232 {
dan_ackme 0:ea85c4bb5e1f 233 const int num = hexToInt(&s[i]);
dan_ackme 0:ea85c4bb5e1f 234 if(num == -1)
dan_ackme 0:ea85c4bb5e1f 235 return -1;
dan_ackme 0:ea85c4bb5e1f 236 s[j] = (char)num;
dan_ackme 0:ea85c4bb5e1f 237 }
dan_ackme 0:ea85c4bb5e1f 238 return j;
dan_ackme 0:ea85c4bb5e1f 239 }
dan_ackme 0:ea85c4bb5e1f 240
dan_ackme 0:ea85c4bb5e1f 241 /*************************************************************************************************/
dan_ackme 0:ea85c4bb5e1f 242 // hex string to integer, returns -1 on error
dan_ackme 0:ea85c4bb5e1f 243 static int hexToInt(const char *hex_str)
dan_ackme 0:ea85c4bb5e1f 244 {
dan_ackme 0:ea85c4bb5e1f 245 int hi = hexToNibble(*hex_str);
dan_ackme 0:ea85c4bb5e1f 246 int lo = hexToNibble(*(hex_str+1));
dan_ackme 0:ea85c4bb5e1f 247 if (hi == -1 || lo == -1)
dan_ackme 0:ea85c4bb5e1f 248 {
dan_ackme 0:ea85c4bb5e1f 249 return -1;
dan_ackme 0:ea85c4bb5e1f 250 }
dan_ackme 0:ea85c4bb5e1f 251 return (hi << 4) | lo;
dan_ackme 0:ea85c4bb5e1f 252 }
dan_ackme 0:ea85c4bb5e1f 253
dan_ackme 0:ea85c4bb5e1f 254 /*************************************************************************************************/
dan_ackme 0:ea85c4bb5e1f 255 static int hexToNibble(char c)
dan_ackme 0:ea85c4bb5e1f 256 {
dan_ackme 0:ea85c4bb5e1f 257 if (c >= '0' && c <= '9')
dan_ackme 0:ea85c4bb5e1f 258 {
dan_ackme 0:ea85c4bb5e1f 259 return c - '0';
dan_ackme 0:ea85c4bb5e1f 260 }
dan_ackme 0:ea85c4bb5e1f 261 if (c >= 'a' && c <= 'f')
dan_ackme 0:ea85c4bb5e1f 262 {
dan_ackme 0:ea85c4bb5e1f 263 return 10 + (c - 'a');
dan_ackme 0:ea85c4bb5e1f 264 }
dan_ackme 0:ea85c4bb5e1f 265 if (c >= 'A' && c <= 'F')
dan_ackme 0:ea85c4bb5e1f 266 {
dan_ackme 0:ea85c4bb5e1f 267 return 10 + (c - 'A');
dan_ackme 0:ea85c4bb5e1f 268 }
dan_ackme 0:ea85c4bb5e1f 269 return -1;
dan_ackme 0:ea85c4bb5e1f 270 }
dan_ackme 0:ea85c4bb5e1f 271
dan_ackme 0:ea85c4bb5e1f 272 /*************************************************************************************************/
dan_ackme 0:ea85c4bb5e1f 273 static const char* uint32ToStr(char* intStrBuffer, int integer)
dan_ackme 0:ea85c4bb5e1f 274 {
dan_ackme 0:ea85c4bb5e1f 275 sprintf(intStrBuffer, "%u", integer);
dan_ackme 0:ea85c4bb5e1f 276 return intStrBuffer;
dan_ackme 0:ea85c4bb5e1f 277 }
dan_ackme 0:ea85c4bb5e1f 278
dan_ackme 0:ea85c4bb5e1f 279 /*************************************************************************************************/
dan_ackme 0:ea85c4bb5e1f 280 static bool strToUint32(const char *str, uint32_t *uint32Ptr)
dan_ackme 0:ea85c4bb5e1f 281 {
dan_ackme 0:ea85c4bb5e1f 282 intmax_t r;
dan_ackme 0:ea85c4bb5e1f 283 bool result = StringUtil::parseInt(str, &r, 0, UINT_MAX);
dan_ackme 0:ea85c4bb5e1f 284 *uint32Ptr = (uint32_t)r;
dan_ackme 0:ea85c4bb5e1f 285 return result;
dan_ackme 0:ea85c4bb5e1f 286 }
dan_ackme 0:ea85c4bb5e1f 287
dan_ackme 0:ea85c4bb5e1f 288 /*************************************************************************************************/
dan_ackme 0:ea85c4bb5e1f 289 static bool strToInt32(const char *str, int32_t *int32Ptr)
dan_ackme 0:ea85c4bb5e1f 290 {
dan_ackme 0:ea85c4bb5e1f 291 intmax_t r;
dan_ackme 0:ea85c4bb5e1f 292 bool result = StringUtil::parseInt(str, &r, INT_MIN, INT_MAX);
dan_ackme 0:ea85c4bb5e1f 293 *int32Ptr = (int32_t)r;
dan_ackme 0:ea85c4bb5e1f 294 return result;
dan_ackme 0:ea85c4bb5e1f 295 }
dan_ackme 0:ea85c4bb5e1f 296
dan_ackme 0:ea85c4bb5e1f 297 /*************************************************************************************************/
dan_ackme 0:ea85c4bb5e1f 298 // uint32 hex string to uint32
dan_ackme 0:ea85c4bb5e1f 299 static bool strHexToUint32(const char *strHex, uint32_t *uint32Ptr)
dan_ackme 0:ea85c4bb5e1f 300 {
dan_ackme 0:ea85c4bb5e1f 301 intmax_t r;
dan_ackme 0:ea85c4bb5e1f 302 bool result = StringUtil::parseHex(strHex, &r, 0, UINT_MAX);
dan_ackme 0:ea85c4bb5e1f 303 *uint32Ptr = (uint32_t)r;
dan_ackme 0:ea85c4bb5e1f 304 return result;
dan_ackme 0:ea85c4bb5e1f 305 }
dan_ackme 0:ea85c4bb5e1f 306
dan_ackme 0:ea85c4bb5e1f 307 /*************************************************************************************************/
dan_ackme 0:ea85c4bb5e1f 308 static char *strtok_r(char *str, const char *delim, char **nextp)
dan_ackme 0:ea85c4bb5e1f 309 {
dan_ackme 0:ea85c4bb5e1f 310 char *ret;
dan_ackme 0:ea85c4bb5e1f 311
dan_ackme 0:ea85c4bb5e1f 312 if (str == NULL)
dan_ackme 0:ea85c4bb5e1f 313 {
dan_ackme 0:ea85c4bb5e1f 314 str = *nextp;
dan_ackme 0:ea85c4bb5e1f 315 }
dan_ackme 0:ea85c4bb5e1f 316
dan_ackme 0:ea85c4bb5e1f 317 str += strspn(str, delim);
dan_ackme 0:ea85c4bb5e1f 318
dan_ackme 0:ea85c4bb5e1f 319 if (*str == '\0')
dan_ackme 0:ea85c4bb5e1f 320 {
dan_ackme 0:ea85c4bb5e1f 321 return NULL;
dan_ackme 0:ea85c4bb5e1f 322 }
dan_ackme 0:ea85c4bb5e1f 323
dan_ackme 0:ea85c4bb5e1f 324 ret = str;
dan_ackme 0:ea85c4bb5e1f 325
dan_ackme 0:ea85c4bb5e1f 326 str += strcspn(str, delim);
dan_ackme 0:ea85c4bb5e1f 327
dan_ackme 0:ea85c4bb5e1f 328 if (*str)
dan_ackme 0:ea85c4bb5e1f 329 {
dan_ackme 0:ea85c4bb5e1f 330 *str++ = '\0';
dan_ackme 0:ea85c4bb5e1f 331 }
dan_ackme 0:ea85c4bb5e1f 332
dan_ackme 0:ea85c4bb5e1f 333 *nextp = str;
dan_ackme 0:ea85c4bb5e1f 334
dan_ackme 0:ea85c4bb5e1f 335 return ret;
dan_ackme 0:ea85c4bb5e1f 336 }
dan_ackme 0:ea85c4bb5e1f 337
dan_ackme 0:ea85c4bb5e1f 338 /*************************************************************************************************/
dan_ackme 0:ea85c4bb5e1f 339 static int strncasecmp(const char *s1, const char *s2, int n)
dan_ackme 0:ea85c4bb5e1f 340 {
dan_ackme 0:ea85c4bb5e1f 341 if (n == 0)
dan_ackme 0:ea85c4bb5e1f 342 return 0;
dan_ackme 0:ea85c4bb5e1f 343
dan_ackme 0:ea85c4bb5e1f 344 while (n-- != 0 && tolower(*s1) == tolower(*s2))
dan_ackme 0:ea85c4bb5e1f 345 {
dan_ackme 0:ea85c4bb5e1f 346 if (n == 0 || *s1 == '\0' || *s2 == '\0')
dan_ackme 0:ea85c4bb5e1f 347 break;
dan_ackme 0:ea85c4bb5e1f 348 s1++;
dan_ackme 0:ea85c4bb5e1f 349 s2++;
dan_ackme 0:ea85c4bb5e1f 350 }
dan_ackme 0:ea85c4bb5e1f 351
dan_ackme 0:ea85c4bb5e1f 352 return tolower(*(unsigned char *) s1) - tolower(*(unsigned char *) s2);
dan_ackme 0:ea85c4bb5e1f 353 }
dan_ackme 0:ea85c4bb5e1f 354
dan_ackme 0:ea85c4bb5e1f 355 /*************************************************************************************************/
dan_ackme 0:ea85c4bb5e1f 356 static int strcasecmp(const char *s1, const char *s2)
dan_ackme 0:ea85c4bb5e1f 357 {
dan_ackme 0:ea85c4bb5e1f 358 register const unsigned char *p1 = (const unsigned char *) s1;
dan_ackme 0:ea85c4bb5e1f 359 register const unsigned char *p2 = (const unsigned char *) s2;
dan_ackme 0:ea85c4bb5e1f 360 unsigned char c1, c2;
dan_ackme 0:ea85c4bb5e1f 361
dan_ackme 0:ea85c4bb5e1f 362 if (p1 == p2)
dan_ackme 0:ea85c4bb5e1f 363 return 0;
dan_ackme 0:ea85c4bb5e1f 364
dan_ackme 0:ea85c4bb5e1f 365 do
dan_ackme 0:ea85c4bb5e1f 366 {
dan_ackme 0:ea85c4bb5e1f 367 c1 = tolower (*p1);
dan_ackme 0:ea85c4bb5e1f 368 c2 = tolower (*p2);
dan_ackme 0:ea85c4bb5e1f 369
dan_ackme 0:ea85c4bb5e1f 370 if (c1 == '\0')
dan_ackme 0:ea85c4bb5e1f 371 break;
dan_ackme 0:ea85c4bb5e1f 372
dan_ackme 0:ea85c4bb5e1f 373 ++p1;
dan_ackme 0:ea85c4bb5e1f 374 ++p2;
dan_ackme 0:ea85c4bb5e1f 375 }
dan_ackme 0:ea85c4bb5e1f 376 while (c1 == c2);
dan_ackme 0:ea85c4bb5e1f 377
dan_ackme 0:ea85c4bb5e1f 378 if (UCHAR_MAX <= INT_MAX)
dan_ackme 0:ea85c4bb5e1f 379 return c1 - c2;
dan_ackme 0:ea85c4bb5e1f 380 else
dan_ackme 0:ea85c4bb5e1f 381 /* On machines where 'char' and 'int' are types of the same size, the
dan_ackme 0:ea85c4bb5e1f 382 difference of two 'unsigned char' values - including the sign bit -
dan_ackme 0:ea85c4bb5e1f 383 doesn't fit in an 'int'. */
dan_ackme 0:ea85c4bb5e1f 384 return (c1 > c2 ? 1 : c1 < c2 ? -1 : 0);
dan_ackme 0:ea85c4bb5e1f 385 }
dan_ackme 0:ea85c4bb5e1f 386 };
dan_ackme 0:ea85c4bb5e1f 387