Sophie

Sophie

distrib > Mageia > 1 > i586 > media > core-updates-src > by-pkgid > 2d27fe3dff73e21c1aac97aebe0dff40 > files > 16

rpm-4.8.1-10.5.mga1.src.rpm

commit 72582cbd92b17b2bd1c1de3c0ee6d012470e4756
Author: unknown author <cooker@mandrivalinux.org>
Date:   Mon Jan 5 13:29:57 2009 +0000

    headerIconv
    
    - 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.

diff --git a/lib/header.c b/lib/header.c
index 77e2473..876a246 100644
--- a/lib/header.c
+++ b/lib/header.c
@@ -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>
 
 #include <rpm/rpmtypes.h>
 #include <rpm/rpmstring.h>
@@ -1214,6 +1216,54 @@ static int headerMatchLocale(const char *td, const char *l, const char *le)
     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
@@ -1246,6 +1296,7 @@ static int copyI18NEntry(Header h, indexEntry entry, rpmtd td,
     for (l = lang; *l != '\0'; l = le) {
 	const char *t;
 	char *ed, *ed_weak = NULL;
+	const char *t_weak = NULL;
 	int langNum;
 
 	while (*l && *l == ':')			/* skip leading colons */
@@ -1262,24 +1313,20 @@ static int copyI18NEntry(Header h, indexEntry entry, rpmtd td,
 
 	    int match = headerMatchLocale(t, l, le);
 	    if (match == 1) {
-		td->data = ed;
+	        td->data = headerIconv(t, ed);
 		goto exit;
 	    } else if (match == 2) { 
 		ed_weak = ed;
+	        t_weak = t;
 	    }
 	}
 	if (ed_weak) {
-	    td->data = ed_weak;
+	    td->data = headerIconv(t_weak, ed_weak);
 	    goto exit;
 	}
     }
 
 exit:
-    if (flags & HEADERGET_ALLOC) {
-	td->data = xstrdup(td->data);
-	td->flags |= RPMTD_ALLOCED;
-    }
-
     return 1;
 }