utstring cloning

18 views
Skip to first unread message

Silvio Clecio

unread,
Feb 16, 2018, 3:41:17 PM2/16/18
to uthash
Hello dudes.

What is the proper way to clone a utstring? I'm using:

utstring_clear(dst);
utstring_concat
(src, dst);

but I'm not sure if it is the "elegant" way to do that. :-/ 

Thank you!

--
Silvio Clecio

Arthur O'Dwyer

unread,
Feb 16, 2018, 3:51:38 PM2/16/18
to uth...@googlegroups.com
It appears to me that there is no such way, at the moment. Sounds like there would be a good case for adding something like `dst = utstring_clone(src)` — although I haven't looked closely at it.
Notice that the standard name for this operation is `strdup`; but `utstring_dup` seems like a worse name than `utstring_clone` just in terms of readability.


--
You received this message because you are subscribed to the Google Groups "uthash" group.
To unsubscribe from this group and stop receiving emails from it, send an email to uthash+unsubscribe@googlegroups.com.
To post to this group, send email to uth...@googlegroups.com.
Visit this group at https://groups.google.com/group/uthash.
For more options, visit https://groups.google.com/d/optout.

silvioprog

unread,
Feb 16, 2018, 4:15:47 PM2/16/18
to uth...@googlegroups.com
+1 for utstring_clone(). :-)

Would it be nice to open a feature request at Github?
--
Silvio Clécio

silvioprog

unread,
Feb 16, 2018, 5:11:29 PM2/16/18
to uth...@googlegroups.com
Possible macro?:

#define utstring_clone(dst, src)          \
do { \
if ((src)->d != NULL) { \
utstring_new(dst); \
(dst)->n = (src)->n; \
(dst)->i = (src)->i; \
memcpy((dst)->d, (src)->d, (src)->n); \
} else { \
(dst) = NULL; \
} \
} while (0)

---

#include <stdio.h>
#include <string.h>
#include "utstring.h"

int main() {
UT_string *s, *c;
utstring_new(s);
utstring_printf(s, "hello world!");
printf("source -> %s\n", utstring_body(s));
utstring_clone(c, s);
printf("cloned -> %s\n", utstring_body(c));
utstring_free(s);
utstring_free(c);
return 0;
}
./a.out
source -> hello world!
cloned -> hello world!

(tested only on GCC)


I'm not sure if MSVC  allows macro returning. 🤔 But I'm going to test it in MSVC 15 2017:

#define utstring_clone(src)               \
({ \
UT_string *dst = NULL; \
if ((src)->d != NULL) { \
utstring_new(dst); \
(dst)->n = (src)->n; \
(dst)->i = (src)->i; \
memcpy((dst)->d, (src)->d, (src)->n); \
} \
dst; \
})

it allows to use as:

#include <stdio.h>
#include <string.h>
#include "utstring.h"

int main() {
UT_string *s, *c;
utstring_new(s);
utstring_printf(s, "hello world!");
printf("source -> %s\n", utstring_body(s));
c = utstring_clone(s);
printf("cloned -> %s\n", utstring_body(c));
utstring_free(s);
utstring_free(c);
return 0;
}
./a.out
source -> hello world!
cloned -> hello world!

--
Silvio Clécio

silvioprog

unread,
Feb 16, 2018, 5:33:06 PM2/16/18
to uth...@googlegroups.com
Hm... the ({ }) construct is a GCC/Clang extension, so:

#ifdef __GNUC__

#define utstring_clone(src) \
({ \
UT_string *dst = NULL; \
if ((src)->d != NULL) { \
utstring_new(dst); \
(dst)->n = (src)->n; \
(dst)->i = (src)->i; \
memcpy((dst)->d, (src)->d, (src)->n); \
} \
dst; \
})
#else
UT_string *utstring_clone(UT_string *src) {
UT_string *dst = NULL;
if (src->d != NULL) {
utstring_new(dst);
dst->n = src->n;
dst->i = src->i;
memcpy(dst->d, src->d, src->n);
}
return dst;
}
#endif
(successfully tested on GCC/Clang and MSVC)

What do you thing about this implementation?

On Fri, Feb 16, 2018 at 7:10 PM, silvioprog <silvi...@gmail.com> wrote:
[...]

I'm not sure if MSVC  allows macro returning. 🤔 But I'm going to test it in MSVC 15 2017:

--
Silvio Clécio
Reply all
Reply to author
Forward
0 new messages