@@ -327,6 +327,35 @@ int sdsll2str(char *s, long long value) {
327327 return l ;
328328}
329329
330+ /* Identical sdsll2str(), but for unsigned long long type. */
331+ int sdsull2str (char * s , unsigned long long v ) {
332+ char * p , aux ;
333+ size_t l ;
334+
335+ /* Generate the string representation, this method produces
336+ * an reversed string. */
337+ p = s ;
338+ do {
339+ * p ++ = '0' + (v %10 );
340+ v /= 10 ;
341+ } while (v );
342+
343+ /* Compute length and add null term. */
344+ l = p - s ;
345+ * p = '\0' ;
346+
347+ /* Reverse the string. */
348+ p -- ;
349+ while (s < p ) {
350+ aux = * s ;
351+ * s = * p ;
352+ * p = aux ;
353+ s ++ ;
354+ p -- ;
355+ }
356+ return l ;
357+ }
358+
330359/* Create an sds string from a long long value. It is much faster than:
331360 *
332361 * sdscatprintf(sdsempty(),"%lld\n", value);
@@ -410,8 +439,10 @@ sds sdscatprintf(sds s, const char *fmt, ...) {
410439 *
411440 * %s - C String
412441 * %S - SDS string
413- * %i - signed integer
442+ * %i - signed int
414443 * %I - 64 bit signed integer (long long, int64_t)
444+ * %u - unsigned int
445+ * %U - 64 bit unsigned integer (unsigned long long, uint64_t)
415446 * %% - Verbatim "%" character.
416447 */
417448sds sdscatfmt (sds s , char const * fmt , ...) {
@@ -428,9 +459,13 @@ sds sdscatfmt(sds s, char const *fmt, ...) {
428459 char next , * str ;
429460 size_t l ;
430461 long long num ;
462+ unsigned long long unum ;
431463
432464 /* Make sure there is always space for at least 1 char. */
433- if (sh -> free == 0 ) s = sdsMakeRoomFor (s ,1 );
465+ if (sh -> free == 0 ) {
466+ s = sdsMakeRoomFor (s ,1 );
467+ sh = (void * ) (s - (sizeof (struct sdshdr )));
468+ }
434469
435470 switch (* f ) {
436471 case '%' :
@@ -441,7 +476,10 @@ sds sdscatfmt(sds s, char const *fmt, ...) {
441476 case 'S' :
442477 str = va_arg (ap ,char * );
443478 l = (next == 's' ) ? strlen (str ) : sdslen (str );
444- if (sh -> free < l ) s = sdsMakeRoomFor (s ,l );
479+ if (sh -> free < l ) {
480+ s = sdsMakeRoomFor (s ,l );
481+ sh = (void * ) (s - (sizeof (struct sdshdr )));
482+ }
445483 memcpy (s + i ,str ,l );
446484 sh -> len += l ;
447485 sh -> free -= l ;
@@ -456,7 +494,29 @@ sds sdscatfmt(sds s, char const *fmt, ...) {
456494 {
457495 char buf [SDS_LLSTR_SIZE ];
458496 l = sdsll2str (buf ,num );
459- if (sh -> free < l ) s = sdsMakeRoomFor (s ,l );
497+ if (sh -> free < l ) {
498+ s = sdsMakeRoomFor (s ,l );
499+ sh = (void * ) (s - (sizeof (struct sdshdr )));
500+ }
501+ memcpy (s + i ,buf ,l );
502+ sh -> len += l ;
503+ sh -> free -= l ;
504+ i += l ;
505+ }
506+ break ;
507+ case 'u' :
508+ case 'U' :
509+ if (next == 'u' )
510+ unum = va_arg (ap ,unsigned int );
511+ else
512+ unum = va_arg (ap ,unsigned long long);
513+ {
514+ char buf [SDS_LLSTR_SIZE ];
515+ l = sdsull2str (buf ,unum );
516+ if (sh -> free < l ) {
517+ s = sdsMakeRoomFor (s ,l );
518+ sh = (void * ) (s - (sizeof (struct sdshdr )));
519+ }
460520 memcpy (s + i ,buf ,l );
461521 sh -> len += l ;
462522 sh -> free -= l ;
@@ -943,6 +1003,13 @@ int main(void) {
9431003 memcmp (x ,"--Hello Hi! World -9223372036854775808,"
9441004 "9223372036854775807--" ,60 ) == 0 )
9451005
1006+ sdsfree (x );
1007+ x = sdsnew ("--" );
1008+ x = sdscatfmt (x , "%u,%U--" , UINT_MAX , ULLONG_MAX );
1009+ test_cond ("sdscatfmt() seems working with unsigned numbers" ,
1010+ sdslen (x ) == 35 &&
1011+ memcmp (x ,"--4294967295,18446744073709551615--" ,35 ) == 0 )
1012+
9461013 sdsfree (x );
9471014 x = sdsnew ("xxciaoyyy" );
9481015 sdstrim (x ,"xy" );
0 commit comments