about summary refs log tree commit diff
path: root/intl/dcigettext.c
diff options
context:
space:
mode:
Diffstat (limited to 'intl/dcigettext.c')
-rw-r--r--intl/dcigettext.c34
1 files changed, 19 insertions, 15 deletions
diff --git a/intl/dcigettext.c b/intl/dcigettext.c
index a2cd8014c3..7004cd49cf 100644
--- a/intl/dcigettext.c
+++ b/intl/dcigettext.c
@@ -203,7 +203,12 @@ struct known_translation_t
   size_t translation_length;
 
   /* Pointer to the string in question.  */
-  char msgid[ZERO];
+  union
+    {
+      char appended[ZERO];  /* used if domain != NULL */
+      const char *ptr;      /* used if domain == NULL */
+    }
+  msgid;
 };
 
 /* Root of the search tree with known translations.  We can use this
@@ -231,7 +236,8 @@ transcmp (p1, p2)
   s1 = (const struct known_translation_t *) p1;
   s2 = (const struct known_translation_t *) p2;
 
-  result = strcmp (s1->msgid, s2->msgid);
+  result = strcmp (s1->domain != NULL ? s1->msgid.appended : s1->msgid.ptr,
+		   s2->domain != NULL ? s2->msgid.appended : s2->msgid.ptr);
   if (result == 0)
     {
       result = strcmp (s1->domainname, s2->domainname);
@@ -422,9 +428,8 @@ DCIGETTEXT (domainname, msgid1, msgid2, plural, n, category)
   size_t retlen;
   int saved_errno;
 #if defined HAVE_TSEARCH || defined _LIBC
-  struct known_translation_t *search;
+  struct known_translation_t search;
   struct known_translation_t **foundp = NULL;
-  size_t msgid_len;
 # ifdef HAVE_PER_THREAD_LOCALE
   const char *localename;
 # endif
@@ -453,20 +458,17 @@ DCIGETTEXT (domainname, msgid1, msgid2, plural, n, category)
     domainname = _nl_current_default_domain;
 
 #if defined HAVE_TSEARCH || defined _LIBC
-  msgid_len = strlen (msgid1) + 1;
-
   /* Try to find the translation among those which we found at
      some time.  */
-  search = (struct known_translation_t *)
-	   alloca (offsetof (struct known_translation_t, msgid) + msgid_len);
-  memcpy (search->msgid, msgid1, msgid_len);
-  search->domainname = domainname;
-  search->category = category;
+  search.domain = NULL;
+  search.msgid.ptr = msgid1;
+  search.domainname = domainname;
+  search.category = category;
 # ifdef HAVE_PER_THREAD_LOCALE
 #  ifdef _LIBC
   localename = __current_locale_name (category);
 #  endif
-  search->localename = localename;
+  search.localename = localename;
 # endif
 
   /* Since tfind/tsearch manage a balanced tree, concurrent tfind and
@@ -474,11 +476,10 @@ DCIGETTEXT (domainname, msgid1, msgid2, plural, n, category)
   __libc_rwlock_define_initialized (static, tree_lock);
   __libc_rwlock_rdlock (tree_lock);
 
-  foundp = (struct known_translation_t **) tfind (search, &root, transcmp);
+  foundp = (struct known_translation_t **) tfind (&search, &root, transcmp);
 
   __libc_rwlock_unlock (tree_lock);
 
-  freea (search);
   if (foundp != NULL && (*foundp)->counter == _nl_msg_cat_cntr)
     {
       /* Now deal with plural.  */
@@ -662,9 +663,11 @@ DCIGETTEXT (domainname, msgid1, msgid2, plural, n, category)
 	      if (foundp == NULL)
 		{
 		  /* Create a new entry and add it to the search tree.  */
+		  size_t msgid_len;
 		  size_t size;
 		  struct known_translation_t *newp;
 
+		  msgid_len = strlen (msgid1) + 1;
 		  size = offsetof (struct known_translation_t, msgid)
 			 + msgid_len + domainname_len + 1;
 # ifdef HAVE_PER_THREAD_LOCALE
@@ -678,7 +681,8 @@ DCIGETTEXT (domainname, msgid1, msgid2, plural, n, category)
 		      char *new_localename;
 # endif
 
-		      new_domainname = mempcpy (newp->msgid, msgid1, msgid_len);
+		      new_domainname =
+			mempcpy (newp->msgid.appended, msgid1, msgid_len);
 		      memcpy (new_domainname, domainname, domainname_len + 1);
 # ifdef HAVE_PER_THREAD_LOCALE
 		      new_localename = new_domainname + domainname_len + 1;