Sophie

Sophie

distrib > Mandriva > 2009.0 > i586 > by-pkgid > 07e56ec36f5b6db53acae40086fcf8ad > files > 39

rpm-4.4.2.3-20mnb2.src.rpm

- Make the spec as follows
...
Summary: default summary
Summary(ja_JP.eucJP): [some strings encoded in euc-jp]
Name:hogefuga
...
- Show summary in each locale.
$ LANG=ja_JP.utf8 rpm -qp --qf "%{SUMMARY}\n" hogefuga.rpm
[some strings encoded in euc-jp]

do not display in UTF-8.

This patch improve the parser of spec-file which are written in multi-languages.
In case the language code is ja_JP , as you know ja_JP use some different encodings 
such as ja_JP.eucJP,ja_JP.sjis,ja_JP.utf8...
When the spec-file are written in eucJP but the local LANG environment is UTF-8, 
rpm will display encoded characters not same as LANG environment(a.k.a Mojibake).
So this patch will convert the data to a specific encoding which used in the selected locale.

--- rpm-4.4.2.3-rc1/rpmdb/header.c.toshi	2008-02-14 11:04:11.000000000 +0000
+++ rpm-4.4.2.3-rc1/rpmdb/header.c	2008-02-14 11:05:47.000000000 +0000
@@ -9,6 +9,8 @@
 /* network byte order and is converted on the fly to host order. */
 
 #include "system.h"
+#include <iconv.h>
+#include <langinfo.h>
 
 #define	__HEADER_PROTOTYPES__
 
@@ -1595,6 +1597,54 @@ static int headerMatchLocale(const char 
     return 0;
 }
 
+/** \ingroup header
+ * convert data to specific encoding used in the selected locale.
+ * @param td		header i18n table data, NUL terminated
+ * @param indata	original data
+ * @return		converted data(or original data if failed)
+ */
+static const char *headerIconv(const char *td,const char *indata)
+{
+  char *tcode=NULL;
+  char *fcode=NULL;
+
+  if( strstr(td,".") != NULL ){
+    fcode=strchr(td,'.')+1;
+    tcode=nl_langinfo(CODESET);
+    if( tcode!=NULL && *tcode != '\0' && strcasecmp(fcode,tcode) != 0 ){
+//      fprintf(stderr,"%s:fcode=%s,tcode=%s\n",__func__,fcode,tcode);
+      iconv_t conv = iconv_open(tcode,fcode);
+      if (conv != (iconv_t)-1) {
+        char *inp = indata;
+	char *outp,*outdata;
+	size_t inleft = strlen(indata);
+	size_t outleft;
+	size_t outdata_size = (inleft+1)*2;
+	outp = outdata = calloc(1,outdata_size);
+	outleft = outdata_size - 1;
+        int status = E2BIG;
+
+        while (inleft > 0 && status == E2BIG) {
+          iconv(conv, &inp, &inleft, &outp, &outleft);
+          status = errno;
+	  size_t used = outp-outdata;
+	  char *newdest;
+	  outdata_size *=2;
+	  newdest = realloc(outdata,outdata_size);
+	  if(newdest==NULL) break;
+	  outdata = newdest;
+	  outp = outdata+used;
+	  outleft = outdata_size - used - 1;
+          *outp = '\0';	
+        }
+        iconv_close(conv);
+	return outdata;
+      }
+    }
+  }
+  return strdup(indata);
+}
+
 /**
  * Return i18n string from header that matches locale.
  * @param h		header
@@ -1639,11 +1689,11 @@ headerFindI18NString(Header h, indexEntr
 	     langNum++, td += strlen(td) + 1, ed += strlen(ed) + 1) {
 
 	           int match = headerMatchLocale(td, l, le);
-		   if (match == 1) return ed;
+		   if (match == 1) return headerIconv(td,ed);
 		   else if (match == 2) ed_weak = ed;
 
 	}
-	if (ed_weak) return ed_weak;
+	if (ed_weak) return headerIconv(td,ed_weak);
     }
 /*@=boundsread@*/