1 |
From 6e46b147b462a226c833e055fc0368eb86766a1a Mon Sep 17 00:00:00 2001 |
2 |
From: unknown author <cooker@mandrivalinux.org> |
3 |
Date: Mon, 5 Jan 2009 13:29:57 +0000 |
4 |
Subject: [PATCH 20/35] headerIconv |
5 |
|
6 |
- Make the spec as follows |
7 |
... |
8 |
Summary: default summary |
9 |
Summary(ja_JP.eucJP): [some strings encoded in euc-jp] |
10 |
Name:hogefuga |
11 |
... |
12 |
- Show summary in each locale. |
13 |
$ LANG=ja_JP.utf8 rpm -qp --qf "%{SUMMARY}\n" hogefuga.rpm |
14 |
[some strings encoded in euc-jp] |
15 |
|
16 |
do not display in UTF-8. |
17 |
|
18 |
This patch improve the parser of spec-file which are written in multi-languages. |
19 |
In case the language code is ja_JP , as you know ja_JP use some different encodings |
20 |
such as ja_JP.eucJP,ja_JP.sjis,ja_JP.utf8... |
21 |
When the spec-file are written in eucJP but the local LANG environment is UTF-8, |
22 |
rpm will display encoded characters not same as LANG environment(a.k.a Mojibake). |
23 |
So this patch will convert the data to a specific encoding which used in the selected locale. |
24 |
--- |
25 |
lib/header.c | 62 ++++++++++++++++++++++++++++++++++++++++++++++++++------- |
26 |
1 files changed, 54 insertions(+), 8 deletions(-) |
27 |
|
28 |
diff --git a/lib/header.c b/lib/header.c |
29 |
index fb9602b..42d017d 100644 |
30 |
--- a/lib/header.c |
31 |
+++ b/lib/header.c |
32 |
@@ -9,6 +9,8 @@ |
33 |
/* network byte order and is converted on the fly to host order. */ |
34 |
|
35 |
#include "system.h" |
36 |
+#include <iconv.h> |
37 |
+#include <langinfo.h> |
38 |
|
39 |
#include <rpm/rpmtypes.h> |
40 |
#include <rpm/rpmstring.h> |
41 |
@@ -1293,6 +1295,54 @@ static int headerMatchLocale(const char *td, const char *l, const char *le) |
42 |
return 0; |
43 |
} |
44 |
|
45 |
+/** \ingroup header |
46 |
+ * convert data to specific encoding used in the selected locale. |
47 |
+ * @param td header i18n table data, NUL terminated |
48 |
+ * @param indata original data |
49 |
+ * @return converted data(or original data if failed) |
50 |
+ */ |
51 |
+static const char *headerIconv(const char *td,const char *indata) |
52 |
+{ |
53 |
+ char *tcode=NULL; |
54 |
+ char *fcode=NULL; |
55 |
+ |
56 |
+ if( strstr(td,".") != NULL ){ |
57 |
+ fcode=strchr(td,'.')+1; |
58 |
+ tcode=nl_langinfo(CODESET); |
59 |
+ if( tcode!=NULL && *tcode != '\0' && strcasecmp(fcode,tcode) != 0 ){ |
60 |
+// fprintf(stderr,"%s:fcode=%s,tcode=%s\n",__func__,fcode,tcode); |
61 |
+ iconv_t conv = iconv_open(tcode,fcode); |
62 |
+ if (conv != (iconv_t)-1) { |
63 |
+ char *inp = indata; |
64 |
+ char *outp,*outdata; |
65 |
+ size_t inleft = strlen(indata); |
66 |
+ size_t outleft; |
67 |
+ size_t outdata_size = (inleft+1)*2; |
68 |
+ outp = outdata = calloc(1,outdata_size); |
69 |
+ outleft = outdata_size - 1; |
70 |
+ int status = E2BIG; |
71 |
+ |
72 |
+ while (inleft > 0 && status == E2BIG) { |
73 |
+ iconv(conv, &inp, &inleft, &outp, &outleft); |
74 |
+ status = errno; |
75 |
+ size_t used = outp-outdata; |
76 |
+ char *newdest; |
77 |
+ outdata_size *=2; |
78 |
+ newdest = realloc(outdata,outdata_size); |
79 |
+ if(newdest==NULL) break; |
80 |
+ outdata = newdest; |
81 |
+ outp = outdata+used; |
82 |
+ outleft = outdata_size - used - 1; |
83 |
+ *outp = '\0'; |
84 |
+ } |
85 |
+ iconv_close(conv); |
86 |
+ return outdata; |
87 |
+ } |
88 |
+ } |
89 |
+ } |
90 |
+ return strdup(indata); |
91 |
+} |
92 |
+ |
93 |
/** |
94 |
* Return i18n string from header that matches locale. |
95 |
* @param h header |
96 |
@@ -1324,7 +1374,7 @@ static int copyI18NEntry(Header h, indexEntry entry, rpmtd td, |
97 |
|
98 |
for (l = lang; *l != '\0'; l = le) { |
99 |
const char *t; |
100 |
- char *ed, *ed_weak = NULL; |
101 |
+ char *ed, *ed_weak = NULL, *t_weak = NULL; |
102 |
int langNum; |
103 |
|
104 |
while (*l && *l == ':') /* skip leading colons */ |
105 |
@@ -1341,24 +1391,20 @@ static int copyI18NEntry(Header h, indexEntry entry, rpmtd td, |
106 |
|
107 |
int match = headerMatchLocale(t, l, le); |
108 |
if (match == 1) { |
109 |
- td->data = ed; |
110 |
+ td->data = headerIconv(t, ed); |
111 |
goto exit; |
112 |
} else if (match == 2) { |
113 |
ed_weak = ed; |
114 |
+ t_weak = t; |
115 |
} |
116 |
} |
117 |
if (ed_weak) { |
118 |
- td->data = ed_weak; |
119 |
+ td->data = headerIconv(t_weak, ed_weak); |
120 |
goto exit; |
121 |
} |
122 |
} |
123 |
|
124 |
exit: |
125 |
- if (flags & HEADERGET_ALLOC) { |
126 |
- td->data = xstrdup(td->data); |
127 |
- td->flags |= RPMTD_ALLOCED; |
128 |
- } |
129 |
- |
130 |
return 1; |
131 |
} |
132 |
|
133 |
-- |
134 |
1.6.1.3 |
135 |
|