From a4d914f0e45e62c94ed519fe6e63c595d6d7cc4b Mon Sep 17 00:00:00 2001 From: Julien Danjou Date: Wed, 3 Dec 2008 14:37:35 +0100 Subject: [PATCH] draw: fix UTF-8 string len computation upon conversion Signed-off-by: Julien Danjou --- draw.c | 29 ++++++++++++++++++----------- draw.h | 22 +++++++++++++++------- property.c | 9 +++++---- tag.c | 4 ++-- widgets/textbox.c | 9 +++++---- 5 files changed, 45 insertions(+), 28 deletions(-) diff --git a/draw.c b/draw.c index f0600f231..7e3aff4f0 100644 --- a/draw.c +++ b/draw.c @@ -39,13 +39,14 @@ extern awesome_t globalconf; /** Convert text from any charset to UTF-8 using iconv. * \param iso The ISO string to convert. * \param len The string size. - * \return NULL if error, otherwise pointer to the new converted string. + * \param dest The destination pointer. Memory will be allocated, up to you to + * free, like any char *. + * \param dlen The destination length, can be NULL. + * \return True if conversion was done. */ -char * -draw_iso2utf8(const char *iso, size_t len) +bool +draw_iso2utf8(const char *iso, size_t len, char **dest, ssize_t *dlen) { - size_t utf8len; - char *utf8, *utf8p; static iconv_t iso2utf8 = (iconv_t) -1; static int8_t dont_need_convert = -1; @@ -53,7 +54,7 @@ draw_iso2utf8(const char *iso, size_t len) dont_need_convert = !a_strcmp(nl_langinfo(CODESET), "UTF-8"); if(!len || dont_need_convert) - return NULL; + return false; if(iso2utf8 == (iconv_t) -1) { @@ -66,20 +67,26 @@ draw_iso2utf8(const char *iso, size_t len) else warn("unable to convert text: %s", strerror(errno)); - return NULL; + return false; } } - utf8len = 2 * len + 1; - utf8 = utf8p = p_new(char, utf8len); + size_t orig_utf8len, utf8len; + char *utf8; + + orig_utf8len = utf8len = 2 * len + 1; + utf8 = *dest = p_new(char, utf8len); if(iconv(iso2utf8, (char **) &iso, &len, &utf8, &utf8len) == (size_t) -1) { warn("text conversion failed: %s", strerror(errno)); - p_delete(&utf8p); + p_delete(dest); } - return utf8p; + if(dlen) + *dlen = orig_utf8len - utf8len; + + return true; } static xcb_visualtype_t * diff --git a/draw.h b/draw.h index 8cad50233..89c3ce252 100644 --- a/draw.h +++ b/draw.h @@ -141,18 +141,26 @@ draw_context_wipe(draw_context_t *ctx) font_t *draw_font_new(const char *); void draw_font_delete(font_t **); -char * draw_iso2utf8(const char *, size_t); +bool draw_iso2utf8(const char *, size_t, char **, ssize_t *); +/** Convert a string to UTF-8. + * \param str The string to convert. + * \param len The string length. + * \param dest The destination string that will be allocated. + * \param dlen The destination string length allocated, can be NULL. + * \return True if the conversion happened, false otherwise. In both case, dest + * and dlen will have value and dest have to be free(). + */ static inline bool -a_iso2utf8(char **dest, const char *str, ssize_t len) +a_iso2utf8(const char *str, ssize_t len, char **dest, ssize_t *dlen) { - char *utf8; - if((utf8 = draw_iso2utf8(str, len))) - { - *dest = utf8; + if(draw_iso2utf8(str, len, dest, dlen)) return true; - } + *dest = a_strdup(str); + if(dlen) + *dlen = len; + return false; } diff --git a/property.c b/property.c index 04a898d7b..6156f33a0 100644 --- a/property.c +++ b/property.c @@ -273,8 +273,9 @@ property_update_wm_name(client_t *c) p_delete(&c->name); - if((utf8 = draw_iso2utf8(name, len))) - c->name = utf8; + /* if no conversion needed, just point to name */ + if(draw_iso2utf8(name, len, &utf8, NULL)) + p_delete(&name); else c->name = name; @@ -298,8 +299,8 @@ property_update_wm_icon_name(client_t *c) p_delete(&c->icon_name); - if((utf8 = draw_iso2utf8(name, len))) - c->icon_name = utf8; + if(draw_iso2utf8(name, len, &utf8, NULL)) + p_delete(&name); else c->icon_name = name; diff --git a/tag.c b/tag.c index cf65a46ae..55f2b139a 100644 --- a/tag.c +++ b/tag.c @@ -54,7 +54,7 @@ tag_new(const char *name, ssize_t len) tag_t *tag; tag = p_new(tag_t, 1); - a_iso2utf8(&tag->name, name, len); + a_iso2utf8(name, len, &tag->name, NULL); /* to avoid error */ tag->screen = SCREEN_UNDEF; @@ -357,7 +357,7 @@ luaA_tag_newindex(lua_State *L) { const char *buf = luaL_checklstring(L, 3, &len); p_delete(&(*tag)->name); - a_iso2utf8(&(*tag)->name, buf, len); + a_iso2utf8(buf, len, &(*tag)->name, NULL); } break; case A_TK_SCREEN: diff --git a/widgets/textbox.c b/widgets/textbox.c index f5483a310..dd3236cc4 100644 --- a/widgets/textbox.c +++ b/widgets/textbox.c @@ -30,7 +30,7 @@ typedef struct /** Textbox text */ char *text; /** Textbox text length */ - size_t len; + ssize_t len; /** Textbox width */ int width; /** Extents */ @@ -244,15 +244,16 @@ luaA_textbox_newindex(lua_State *L, awesome_token_t token) draw_parser_data_init(&d->pdata); p_delete(&d->text); - /* re-init */ - d->len = len; if(buf) { - a_iso2utf8(&d->text, buf, len); + a_iso2utf8(buf, len, &d->text, &d->len); d->extents = draw_text_extents(globalconf.font, d->text, d->len, &d->pdata); } else + { + d->len = 0; p_clear(&d->extents, 1); + } } break; case A_TK_WIDTH: