methodmissing_hiredis 0.4.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,47 @@
1
+ /* Extracted from anet.c to work properly with Hiredis error reporting.
2
+ *
3
+ * Copyright (c) 2006-2011, Salvatore Sanfilippo <antirez at gmail dot com>
4
+ * Copyright (c) 2010-2011, Pieter Noordhuis <pcnoordhuis at gmail dot com>
5
+ *
6
+ * All rights reserved.
7
+ *
8
+ * Redistribution and use in source and binary forms, with or without
9
+ * modification, are permitted provided that the following conditions are met:
10
+ *
11
+ * * Redistributions of source code must retain the above copyright notice,
12
+ * this list of conditions and the following disclaimer.
13
+ * * Redistributions in binary form must reproduce the above copyright
14
+ * notice, this list of conditions and the following disclaimer in the
15
+ * documentation and/or other materials provided with the distribution.
16
+ * * Neither the name of Redis nor the names of its contributors may be used
17
+ * to endorse or promote products derived from this software without
18
+ * specific prior written permission.
19
+ *
20
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
24
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
26
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
27
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30
+ * POSSIBILITY OF SUCH DAMAGE.
31
+ */
32
+
33
+ #ifndef __NET_H
34
+ #define __NET_H
35
+
36
+ #include "hiredis.h"
37
+
38
+ #if defined(__sun)
39
+ #define AF_LOCAL AF_UNIX
40
+ #endif
41
+
42
+ int redisCheckSocketError(redisContext *c, int fd);
43
+ int redisContextSetTimeout(redisContext *c, struct timeval tv);
44
+ int redisContextConnectTcp(redisContext *c, const char *addr, int port, struct timeval *timeout);
45
+ int redisContextConnectUnix(redisContext *c, const char *path, struct timeval *timeout);
46
+
47
+ #endif
@@ -0,0 +1,605 @@
1
+ /* SDSLib, A C dynamic strings library
2
+ *
3
+ * Copyright (c) 2006-2010, Salvatore Sanfilippo <antirez at gmail dot com>
4
+ * All rights reserved.
5
+ *
6
+ * Redistribution and use in source and binary forms, with or without
7
+ * modification, are permitted provided that the following conditions are met:
8
+ *
9
+ * * Redistributions of source code must retain the above copyright notice,
10
+ * this list of conditions and the following disclaimer.
11
+ * * Redistributions in binary form must reproduce the above copyright
12
+ * notice, this list of conditions and the following disclaimer in the
13
+ * documentation and/or other materials provided with the distribution.
14
+ * * Neither the name of Redis nor the names of its contributors may be used
15
+ * to endorse or promote products derived from this software without
16
+ * specific prior written permission.
17
+ *
18
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
22
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
23
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
24
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
25
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
26
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
27
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
28
+ * POSSIBILITY OF SUCH DAMAGE.
29
+ */
30
+
31
+ #include <stdio.h>
32
+ #include <stdlib.h>
33
+ #include <string.h>
34
+ #include <ctype.h>
35
+ #include "sds.h"
36
+
37
+ #ifdef SDS_ABORT_ON_OOM
38
+ static void sdsOomAbort(void) {
39
+ fprintf(stderr,"SDS: Out Of Memory (SDS_ABORT_ON_OOM defined)\n");
40
+ abort();
41
+ }
42
+ #endif
43
+
44
+ sds sdsnewlen(const void *init, size_t initlen) {
45
+ struct sdshdr *sh;
46
+
47
+ sh = malloc(sizeof(struct sdshdr)+initlen+1);
48
+ #ifdef SDS_ABORT_ON_OOM
49
+ if (sh == NULL) sdsOomAbort();
50
+ #else
51
+ if (sh == NULL) return NULL;
52
+ #endif
53
+ sh->len = initlen;
54
+ sh->free = 0;
55
+ if (initlen) {
56
+ if (init) memcpy(sh->buf, init, initlen);
57
+ else memset(sh->buf,0,initlen);
58
+ }
59
+ sh->buf[initlen] = '\0';
60
+ return (char*)sh->buf;
61
+ }
62
+
63
+ sds sdsempty(void) {
64
+ return sdsnewlen("",0);
65
+ }
66
+
67
+ sds sdsnew(const char *init) {
68
+ size_t initlen = (init == NULL) ? 0 : strlen(init);
69
+ return sdsnewlen(init, initlen);
70
+ }
71
+
72
+ sds sdsdup(const sds s) {
73
+ return sdsnewlen(s, sdslen(s));
74
+ }
75
+
76
+ void sdsfree(sds s) {
77
+ if (s == NULL) return;
78
+ free(s-sizeof(struct sdshdr));
79
+ }
80
+
81
+ void sdsupdatelen(sds s) {
82
+ struct sdshdr *sh = (void*) (s-(sizeof(struct sdshdr)));
83
+ int reallen = strlen(s);
84
+ sh->free += (sh->len-reallen);
85
+ sh->len = reallen;
86
+ }
87
+
88
+ static sds sdsMakeRoomFor(sds s, size_t addlen) {
89
+ struct sdshdr *sh, *newsh;
90
+ size_t free = sdsavail(s);
91
+ size_t len, newlen;
92
+
93
+ if (free >= addlen) return s;
94
+ len = sdslen(s);
95
+ sh = (void*) (s-(sizeof(struct sdshdr)));
96
+ newlen = (len+addlen)*2;
97
+ newsh = realloc(sh, sizeof(struct sdshdr)+newlen+1);
98
+ #ifdef SDS_ABORT_ON_OOM
99
+ if (newsh == NULL) sdsOomAbort();
100
+ #else
101
+ if (newsh == NULL) return NULL;
102
+ #endif
103
+
104
+ newsh->free = newlen - len;
105
+ return newsh->buf;
106
+ }
107
+
108
+ /* Grow the sds to have the specified length. Bytes that were not part of
109
+ * the original length of the sds will be set to zero. */
110
+ sds sdsgrowzero(sds s, size_t len) {
111
+ struct sdshdr *sh = (void*)(s-(sizeof(struct sdshdr)));
112
+ size_t totlen, curlen = sh->len;
113
+
114
+ if (len <= curlen) return s;
115
+ s = sdsMakeRoomFor(s,len-curlen);
116
+ if (s == NULL) return NULL;
117
+
118
+ /* Make sure added region doesn't contain garbage */
119
+ sh = (void*)(s-(sizeof(struct sdshdr)));
120
+ memset(s+curlen,0,(len-curlen+1)); /* also set trailing \0 byte */
121
+ totlen = sh->len+sh->free;
122
+ sh->len = len;
123
+ sh->free = totlen-sh->len;
124
+ return s;
125
+ }
126
+
127
+ sds sdscatlen(sds s, const void *t, size_t len) {
128
+ struct sdshdr *sh;
129
+ size_t curlen = sdslen(s);
130
+
131
+ s = sdsMakeRoomFor(s,len);
132
+ if (s == NULL) return NULL;
133
+ sh = (void*) (s-(sizeof(struct sdshdr)));
134
+ memcpy(s+curlen, t, len);
135
+ sh->len = curlen+len;
136
+ sh->free = sh->free-len;
137
+ s[curlen+len] = '\0';
138
+ return s;
139
+ }
140
+
141
+ sds sdscat(sds s, const char *t) {
142
+ return sdscatlen(s, t, strlen(t));
143
+ }
144
+
145
+ sds sdscpylen(sds s, char *t, size_t len) {
146
+ struct sdshdr *sh = (void*) (s-(sizeof(struct sdshdr)));
147
+ size_t totlen = sh->free+sh->len;
148
+
149
+ if (totlen < len) {
150
+ s = sdsMakeRoomFor(s,len-sh->len);
151
+ if (s == NULL) return NULL;
152
+ sh = (void*) (s-(sizeof(struct sdshdr)));
153
+ totlen = sh->free+sh->len;
154
+ }
155
+ memcpy(s, t, len);
156
+ s[len] = '\0';
157
+ sh->len = len;
158
+ sh->free = totlen-len;
159
+ return s;
160
+ }
161
+
162
+ sds sdscpy(sds s, char *t) {
163
+ return sdscpylen(s, t, strlen(t));
164
+ }
165
+
166
+ sds sdscatvprintf(sds s, const char *fmt, va_list ap) {
167
+ va_list cpy;
168
+ char *buf, *t;
169
+ size_t buflen = 16;
170
+
171
+ while(1) {
172
+ buf = malloc(buflen);
173
+ #ifdef SDS_ABORT_ON_OOM
174
+ if (buf == NULL) sdsOomAbort();
175
+ #else
176
+ if (buf == NULL) return NULL;
177
+ #endif
178
+ buf[buflen-2] = '\0';
179
+ va_copy(cpy,ap);
180
+ vsnprintf(buf, buflen, fmt, cpy);
181
+ if (buf[buflen-2] != '\0') {
182
+ free(buf);
183
+ buflen *= 2;
184
+ continue;
185
+ }
186
+ break;
187
+ }
188
+ t = sdscat(s, buf);
189
+ free(buf);
190
+ return t;
191
+ }
192
+
193
+ sds sdscatprintf(sds s, const char *fmt, ...) {
194
+ va_list ap;
195
+ char *t;
196
+ va_start(ap, fmt);
197
+ t = sdscatvprintf(s,fmt,ap);
198
+ va_end(ap);
199
+ return t;
200
+ }
201
+
202
+ sds sdstrim(sds s, const char *cset) {
203
+ struct sdshdr *sh = (void*) (s-(sizeof(struct sdshdr)));
204
+ char *start, *end, *sp, *ep;
205
+ size_t len;
206
+
207
+ sp = start = s;
208
+ ep = end = s+sdslen(s)-1;
209
+ while(sp <= end && strchr(cset, *sp)) sp++;
210
+ while(ep > start && strchr(cset, *ep)) ep--;
211
+ len = (sp > ep) ? 0 : ((ep-sp)+1);
212
+ if (sh->buf != sp) memmove(sh->buf, sp, len);
213
+ sh->buf[len] = '\0';
214
+ sh->free = sh->free+(sh->len-len);
215
+ sh->len = len;
216
+ return s;
217
+ }
218
+
219
+ sds sdsrange(sds s, int start, int end) {
220
+ struct sdshdr *sh = (void*) (s-(sizeof(struct sdshdr)));
221
+ size_t newlen, len = sdslen(s);
222
+
223
+ if (len == 0) return s;
224
+ if (start < 0) {
225
+ start = len+start;
226
+ if (start < 0) start = 0;
227
+ }
228
+ if (end < 0) {
229
+ end = len+end;
230
+ if (end < 0) end = 0;
231
+ }
232
+ newlen = (start > end) ? 0 : (end-start)+1;
233
+ if (newlen != 0) {
234
+ if (start >= (signed)len) {
235
+ newlen = 0;
236
+ } else if (end >= (signed)len) {
237
+ end = len-1;
238
+ newlen = (start > end) ? 0 : (end-start)+1;
239
+ }
240
+ } else {
241
+ start = 0;
242
+ }
243
+ if (start && newlen) memmove(sh->buf, sh->buf+start, newlen);
244
+ sh->buf[newlen] = 0;
245
+ sh->free = sh->free+(sh->len-newlen);
246
+ sh->len = newlen;
247
+ return s;
248
+ }
249
+
250
+ void sdstolower(sds s) {
251
+ int len = sdslen(s), j;
252
+
253
+ for (j = 0; j < len; j++) s[j] = tolower(s[j]);
254
+ }
255
+
256
+ void sdstoupper(sds s) {
257
+ int len = sdslen(s), j;
258
+
259
+ for (j = 0; j < len; j++) s[j] = toupper(s[j]);
260
+ }
261
+
262
+ int sdscmp(sds s1, sds s2) {
263
+ size_t l1, l2, minlen;
264
+ int cmp;
265
+
266
+ l1 = sdslen(s1);
267
+ l2 = sdslen(s2);
268
+ minlen = (l1 < l2) ? l1 : l2;
269
+ cmp = memcmp(s1,s2,minlen);
270
+ if (cmp == 0) return l1-l2;
271
+ return cmp;
272
+ }
273
+
274
+ /* Split 's' with separator in 'sep'. An array
275
+ * of sds strings is returned. *count will be set
276
+ * by reference to the number of tokens returned.
277
+ *
278
+ * On out of memory, zero length string, zero length
279
+ * separator, NULL is returned.
280
+ *
281
+ * Note that 'sep' is able to split a string using
282
+ * a multi-character separator. For example
283
+ * sdssplit("foo_-_bar","_-_"); will return two
284
+ * elements "foo" and "bar".
285
+ *
286
+ * This version of the function is binary-safe but
287
+ * requires length arguments. sdssplit() is just the
288
+ * same function but for zero-terminated strings.
289
+ */
290
+ sds *sdssplitlen(char *s, int len, char *sep, int seplen, int *count) {
291
+ int elements = 0, slots = 5, start = 0, j;
292
+
293
+ sds *tokens = malloc(sizeof(sds)*slots);
294
+ #ifdef SDS_ABORT_ON_OOM
295
+ if (tokens == NULL) sdsOomAbort();
296
+ #endif
297
+ if (seplen < 1 || len < 0 || tokens == NULL) return NULL;
298
+ if (len == 0) {
299
+ *count = 0;
300
+ return tokens;
301
+ }
302
+ for (j = 0; j < (len-(seplen-1)); j++) {
303
+ /* make sure there is room for the next element and the final one */
304
+ if (slots < elements+2) {
305
+ sds *newtokens;
306
+
307
+ slots *= 2;
308
+ newtokens = realloc(tokens,sizeof(sds)*slots);
309
+ if (newtokens == NULL) {
310
+ #ifdef SDS_ABORT_ON_OOM
311
+ sdsOomAbort();
312
+ #else
313
+ goto cleanup;
314
+ #endif
315
+ }
316
+ tokens = newtokens;
317
+ }
318
+ /* search the separator */
319
+ if ((seplen == 1 && *(s+j) == sep[0]) || (memcmp(s+j,sep,seplen) == 0)) {
320
+ tokens[elements] = sdsnewlen(s+start,j-start);
321
+ if (tokens[elements] == NULL) {
322
+ #ifdef SDS_ABORT_ON_OOM
323
+ sdsOomAbort();
324
+ #else
325
+ goto cleanup;
326
+ #endif
327
+ }
328
+ elements++;
329
+ start = j+seplen;
330
+ j = j+seplen-1; /* skip the separator */
331
+ }
332
+ }
333
+ /* Add the final element. We are sure there is room in the tokens array. */
334
+ tokens[elements] = sdsnewlen(s+start,len-start);
335
+ if (tokens[elements] == NULL) {
336
+ #ifdef SDS_ABORT_ON_OOM
337
+ sdsOomAbort();
338
+ #else
339
+ goto cleanup;
340
+ #endif
341
+ }
342
+ elements++;
343
+ *count = elements;
344
+ return tokens;
345
+
346
+ #ifndef SDS_ABORT_ON_OOM
347
+ cleanup:
348
+ {
349
+ int i;
350
+ for (i = 0; i < elements; i++) sdsfree(tokens[i]);
351
+ free(tokens);
352
+ return NULL;
353
+ }
354
+ #endif
355
+ }
356
+
357
+ void sdsfreesplitres(sds *tokens, int count) {
358
+ if (!tokens) return;
359
+ while(count--)
360
+ sdsfree(tokens[count]);
361
+ free(tokens);
362
+ }
363
+
364
+ sds sdsfromlonglong(long long value) {
365
+ char buf[32], *p;
366
+ unsigned long long v;
367
+
368
+ v = (value < 0) ? -value : value;
369
+ p = buf+31; /* point to the last character */
370
+ do {
371
+ *p-- = '0'+(v%10);
372
+ v /= 10;
373
+ } while(v);
374
+ if (value < 0) *p-- = '-';
375
+ p++;
376
+ return sdsnewlen(p,32-(p-buf));
377
+ }
378
+
379
+ sds sdscatrepr(sds s, char *p, size_t len) {
380
+ s = sdscatlen(s,"\"",1);
381
+ if (s == NULL) return NULL;
382
+
383
+ while(len--) {
384
+ switch(*p) {
385
+ case '\\':
386
+ case '"':
387
+ s = sdscatprintf(s,"\\%c",*p);
388
+ break;
389
+ case '\n': s = sdscatlen(s,"\\n",2); break;
390
+ case '\r': s = sdscatlen(s,"\\r",2); break;
391
+ case '\t': s = sdscatlen(s,"\\t",2); break;
392
+ case '\a': s = sdscatlen(s,"\\a",2); break;
393
+ case '\b': s = sdscatlen(s,"\\b",2); break;
394
+ default:
395
+ if (isprint(*p))
396
+ s = sdscatprintf(s,"%c",*p);
397
+ else
398
+ s = sdscatprintf(s,"\\x%02x",(unsigned char)*p);
399
+ break;
400
+ }
401
+ p++;
402
+ if (s == NULL) return NULL;
403
+ }
404
+ return sdscatlen(s,"\"",1);
405
+ }
406
+
407
+ /* Split a line into arguments, where every argument can be in the
408
+ * following programming-language REPL-alike form:
409
+ *
410
+ * foo bar "newline are supported\n" and "\xff\x00otherstuff"
411
+ *
412
+ * The number of arguments is stored into *argc, and an array
413
+ * of sds is returned. The caller should sdsfree() all the returned
414
+ * strings and finally free() the array itself.
415
+ *
416
+ * Note that sdscatrepr() is able to convert back a string into
417
+ * a quoted string in the same format sdssplitargs() is able to parse.
418
+ */
419
+ sds *sdssplitargs(char *line, int *argc) {
420
+ char *p = line;
421
+ char *current = NULL;
422
+ char **vector = NULL, **_vector = NULL;
423
+
424
+ *argc = 0;
425
+ while(1) {
426
+ /* skip blanks */
427
+ while(*p && isspace(*p)) p++;
428
+ if (*p) {
429
+ /* get a token */
430
+ int inq=0; /* set to 1 if we are in "quotes" */
431
+ int done=0;
432
+
433
+ if (current == NULL) {
434
+ current = sdsempty();
435
+ if (current == NULL) goto err;
436
+ }
437
+
438
+ while(!done) {
439
+ if (inq) {
440
+ if (*p == '\\' && *(p+1)) {
441
+ char c;
442
+
443
+ p++;
444
+ switch(*p) {
445
+ case 'n': c = '\n'; break;
446
+ case 'r': c = '\r'; break;
447
+ case 't': c = '\t'; break;
448
+ case 'b': c = '\b'; break;
449
+ case 'a': c = '\a'; break;
450
+ default: c = *p; break;
451
+ }
452
+ current = sdscatlen(current,&c,1);
453
+ } else if (*p == '"') {
454
+ /* closing quote must be followed by a space */
455
+ if (*(p+1) && !isspace(*(p+1))) goto err;
456
+ done=1;
457
+ } else if (!*p) {
458
+ /* unterminated quotes */
459
+ goto err;
460
+ } else {
461
+ current = sdscatlen(current,p,1);
462
+ }
463
+ } else {
464
+ switch(*p) {
465
+ case ' ':
466
+ case '\n':
467
+ case '\r':
468
+ case '\t':
469
+ case '\0':
470
+ done=1;
471
+ break;
472
+ case '"':
473
+ inq=1;
474
+ break;
475
+ default:
476
+ current = sdscatlen(current,p,1);
477
+ break;
478
+ }
479
+ }
480
+ if (*p) p++;
481
+ if (current == NULL) goto err;
482
+ }
483
+ /* add the token to the vector */
484
+ _vector = realloc(vector,((*argc)+1)*sizeof(char*));
485
+ if (_vector == NULL) goto err;
486
+
487
+ vector = _vector;
488
+ vector[*argc] = current;
489
+ (*argc)++;
490
+ current = NULL;
491
+ } else {
492
+ return vector;
493
+ }
494
+ }
495
+
496
+ err:
497
+ while((*argc)--)
498
+ sdsfree(vector[*argc]);
499
+ if (vector != NULL) free(vector);
500
+ if (current != NULL) sdsfree(current);
501
+ return NULL;
502
+ }
503
+
504
+ #ifdef SDS_TEST_MAIN
505
+ #include <stdio.h>
506
+
507
+ int __failed_tests = 0;
508
+ int __test_num = 0;
509
+ #define test_cond(descr,_c) do { \
510
+ __test_num++; printf("%d - %s: ", __test_num, descr); \
511
+ if(_c) printf("PASSED\n"); else {printf("FAILED\n"); __failed_tests++;} \
512
+ } while(0);
513
+ #define test_report() do { \
514
+ printf("%d tests, %d passed, %d failed\n", __test_num, \
515
+ __test_num-__failed_tests, __failed_tests); \
516
+ if (__failed_tests) { \
517
+ printf("=== WARNING === We have failed tests here...\n"); \
518
+ } \
519
+ } while(0);
520
+
521
+ int main(void) {
522
+ {
523
+ sds x = sdsnew("foo"), y;
524
+
525
+ test_cond("Create a string and obtain the length",
526
+ sdslen(x) == 3 && memcmp(x,"foo\0",4) == 0)
527
+
528
+ sdsfree(x);
529
+ x = sdsnewlen("foo",2);
530
+ test_cond("Create a string with specified length",
531
+ sdslen(x) == 2 && memcmp(x,"fo\0",3) == 0)
532
+
533
+ x = sdscat(x,"bar");
534
+ test_cond("Strings concatenation",
535
+ sdslen(x) == 5 && memcmp(x,"fobar\0",6) == 0);
536
+
537
+ x = sdscpy(x,"a");
538
+ test_cond("sdscpy() against an originally longer string",
539
+ sdslen(x) == 1 && memcmp(x,"a\0",2) == 0)
540
+
541
+ x = sdscpy(x,"xyzxxxxxxxxxxyyyyyyyyyykkkkkkkkkk");
542
+ test_cond("sdscpy() against an originally shorter string",
543
+ sdslen(x) == 33 &&
544
+ memcmp(x,"xyzxxxxxxxxxxyyyyyyyyyykkkkkkkkkk\0",33) == 0)
545
+
546
+ sdsfree(x);
547
+ x = sdscatprintf(sdsempty(),"%d",123);
548
+ test_cond("sdscatprintf() seems working in the base case",
549
+ sdslen(x) == 3 && memcmp(x,"123\0",4) ==0)
550
+
551
+ sdsfree(x);
552
+ x = sdstrim(sdsnew("xxciaoyyy"),"xy");
553
+ test_cond("sdstrim() correctly trims characters",
554
+ sdslen(x) == 4 && memcmp(x,"ciao\0",5) == 0)
555
+
556
+ y = sdsrange(sdsdup(x),1,1);
557
+ test_cond("sdsrange(...,1,1)",
558
+ sdslen(y) == 1 && memcmp(y,"i\0",2) == 0)
559
+
560
+ sdsfree(y);
561
+ y = sdsrange(sdsdup(x),1,-1);
562
+ test_cond("sdsrange(...,1,-1)",
563
+ sdslen(y) == 3 && memcmp(y,"iao\0",4) == 0)
564
+
565
+ sdsfree(y);
566
+ y = sdsrange(sdsdup(x),-2,-1);
567
+ test_cond("sdsrange(...,-2,-1)",
568
+ sdslen(y) == 2 && memcmp(y,"ao\0",3) == 0)
569
+
570
+ sdsfree(y);
571
+ y = sdsrange(sdsdup(x),2,1);
572
+ test_cond("sdsrange(...,2,1)",
573
+ sdslen(y) == 0 && memcmp(y,"\0",1) == 0)
574
+
575
+ sdsfree(y);
576
+ y = sdsrange(sdsdup(x),1,100);
577
+ test_cond("sdsrange(...,1,100)",
578
+ sdslen(y) == 3 && memcmp(y,"iao\0",4) == 0)
579
+
580
+ sdsfree(y);
581
+ y = sdsrange(sdsdup(x),100,100);
582
+ test_cond("sdsrange(...,100,100)",
583
+ sdslen(y) == 0 && memcmp(y,"\0",1) == 0)
584
+
585
+ sdsfree(y);
586
+ sdsfree(x);
587
+ x = sdsnew("foo");
588
+ y = sdsnew("foa");
589
+ test_cond("sdscmp(foo,foa)", sdscmp(x,y) > 0)
590
+
591
+ sdsfree(y);
592
+ sdsfree(x);
593
+ x = sdsnew("bar");
594
+ y = sdsnew("bar");
595
+ test_cond("sdscmp(bar,bar)", sdscmp(x,y) == 0)
596
+
597
+ sdsfree(y);
598
+ sdsfree(x);
599
+ x = sdsnew("aar");
600
+ y = sdsnew("bar");
601
+ test_cond("sdscmp(bar,bar)", sdscmp(x,y) < 0)
602
+ }
603
+ test_report()
604
+ }
605
+ #endif