|
Bernhard M. Wiedemann |
1250f9 |
Convert output to the current locale. Assumes utf8 input if the
|
|
Bernhard M. Wiedemann |
1250f9 |
decoding works, otherwise iso-8859-1.
|
|
Bernhard M. Wiedemann |
1250f9 |
|
|
Bernhard M. Wiedemann |
1250f9 |
--- ./lib/tagexts.c.orig 2016-10-21 09:44:00.309962086 +0000
|
|
Bernhard M. Wiedemann |
1250f9 |
+++ ./lib/tagexts.c 2017-01-19 10:27:57.243832208 +0000
|
|
Bernhard M. Wiedemann |
1250f9 |
@@ -2,6 +2,7 @@
|
|
Bernhard M. Wiedemann |
1250f9 |
* \file lib/formats.c
|
|
Bernhard M. Wiedemann |
1250f9 |
*/
|
|
Bernhard M. Wiedemann |
1250f9 |
|
|
Bernhard M. Wiedemann |
1250f9 |
+#include <wchar.h>
|
|
Bernhard M. Wiedemann |
1250f9 |
#include "system.h"
|
|
Bernhard M. Wiedemann |
1250f9 |
|
|
Bernhard M. Wiedemann |
1250f9 |
#include <rpm/rpmtypes.h>
|
|
Bernhard M. Wiedemann |
1250f9 |
@@ -197,6 +198,114 @@ typedef enum tMode_e {
|
|
Bernhard M. Wiedemann |
1250f9 |
TRANSFILETRIGGER = 2,
|
|
Bernhard M. Wiedemann |
1250f9 |
} tMode;
|
|
Bernhard M. Wiedemann |
1250f9 |
|
|
Bernhard M. Wiedemann |
1250f9 |
+static char * strtolocale(char *str)
|
|
Bernhard M. Wiedemann |
1250f9 |
+{
|
|
Bernhard M. Wiedemann |
1250f9 |
+ wchar_t *wstr, *wp;
|
|
Bernhard M. Wiedemann |
1250f9 |
+ const unsigned char *cp;
|
|
Bernhard M. Wiedemann |
1250f9 |
+ char *cc;
|
|
Bernhard M. Wiedemann |
1250f9 |
+ int state = 0;
|
|
Bernhard M. Wiedemann |
1250f9 |
+ int c;
|
|
Bernhard M. Wiedemann |
1250f9 |
+ int ccl, cca, mb_cur_max;
|
|
Bernhard M. Wiedemann |
1250f9 |
+ size_t l;
|
|
Bernhard M. Wiedemann |
1250f9 |
+ mbstate_t ps;
|
|
Bernhard M. Wiedemann |
1250f9 |
+ int strisutf8 = 1;
|
|
Bernhard M. Wiedemann |
1250f9 |
+ int locisutf8 = 1;
|
|
Bernhard M. Wiedemann |
1250f9 |
+
|
|
Bernhard M. Wiedemann |
1250f9 |
+ if (!str)
|
|
Bernhard M. Wiedemann |
1250f9 |
+ return 0;
|
|
Bernhard M. Wiedemann |
1250f9 |
+ if (!*str)
|
|
Bernhard M. Wiedemann |
1250f9 |
+ return str;
|
|
Bernhard M. Wiedemann |
1250f9 |
+ wstr = (wchar_t *)xmalloc((strlen(str) + 1) * sizeof(*wstr));
|
|
Bernhard M. Wiedemann |
1250f9 |
+ wp = wstr;
|
|
Bernhard M. Wiedemann |
1250f9 |
+ cp = (const unsigned char *)str;
|
|
Bernhard M. Wiedemann |
1250f9 |
+ while ((c = *cp++) != 0) {
|
|
Bernhard M. Wiedemann |
1250f9 |
+ if (state) {
|
|
Bernhard M. Wiedemann |
1250f9 |
+ if ((c & 0xc0) != 0x80) {
|
|
Bernhard M. Wiedemann |
1250f9 |
+ /* encoding error */
|
|
Bernhard M. Wiedemann |
1250f9 |
+ break;
|
|
Bernhard M. Wiedemann |
1250f9 |
+ }
|
|
Bernhard M. Wiedemann |
1250f9 |
+ c = (c & 0x3f) | (state << 6);
|
|
Bernhard M. Wiedemann |
1250f9 |
+ if (!(state & 0x40000000)) {
|
|
Bernhard M. Wiedemann |
1250f9 |
+ /* check for overlong sequences */
|
|
Bernhard M. Wiedemann |
1250f9 |
+ if ((c & 0x820823e0) == 0x80000000)
|
|
Bernhard M. Wiedemann |
1250f9 |
+ c = 0xfdffffff;
|
|
Bernhard M. Wiedemann |
1250f9 |
+ else if ((c & 0x020821f0) == 0x02000000)
|
|
Bernhard M. Wiedemann |
1250f9 |
+ c = 0xfff7ffff;
|
|
Bernhard M. Wiedemann |
1250f9 |
+ else if ((c & 0x000820f8) == 0x00080000)
|
|
Bernhard M. Wiedemann |
1250f9 |
+ c = 0xffffd000;
|
|
Bernhard M. Wiedemann |
1250f9 |
+ else if ((c & 0x0000207c) == 0x00002000)
|
|
Bernhard M. Wiedemann |
1250f9 |
+ c = 0xffffff70;
|
|
Bernhard M. Wiedemann |
1250f9 |
+ }
|
|
Bernhard M. Wiedemann |
1250f9 |
+ } else {
|
|
Bernhard M. Wiedemann |
1250f9 |
+ /* new sequence */
|
|
Bernhard M. Wiedemann |
1250f9 |
+ if (c >= 0xfe)
|
|
Bernhard M. Wiedemann |
1250f9 |
+ c = 0xfffd;
|
|
Bernhard M. Wiedemann |
1250f9 |
+ else if (c >= 0xfc)
|
|
Bernhard M. Wiedemann |
1250f9 |
+ c = (c & 0x01) | 0xbffffffc; /* 5 bytes to follow */
|
|
Bernhard M. Wiedemann |
1250f9 |
+ else if (c >= 0xf8)
|
|
Bernhard M. Wiedemann |
1250f9 |
+ c = (c & 0x03) | 0xbfffff00; /* 4 */
|
|
Bernhard M. Wiedemann |
1250f9 |
+ else if (c >= 0xf0)
|
|
Bernhard M. Wiedemann |
1250f9 |
+ c = (c & 0x07) | 0xbfffc000; /* 3 */
|
|
Bernhard M. Wiedemann |
1250f9 |
+ else if (c >= 0xe0)
|
|
Bernhard M. Wiedemann |
1250f9 |
+ c = (c & 0x0f) | 0xbff00000; /* 2 */
|
|
Bernhard M. Wiedemann |
1250f9 |
+ else if (c >= 0xc2)
|
|
Bernhard M. Wiedemann |
1250f9 |
+ c = (c & 0x1f) | 0xfc000000; /* 1 */
|
|
Bernhard M. Wiedemann |
1250f9 |
+ else if (c >= 0xc0)
|
|
Bernhard M. Wiedemann |
1250f9 |
+ c = 0xfdffffff; /* overlong */
|
|
Bernhard M. Wiedemann |
1250f9 |
+ else if (c >= 0x80)
|
|
Bernhard M. Wiedemann |
1250f9 |
+ c = 0xfffd;
|
|
Bernhard M. Wiedemann |
1250f9 |
+ }
|
|
Bernhard M. Wiedemann |
1250f9 |
+ state = (c & 0x80000000) ? c : 0;
|
|
Bernhard M. Wiedemann |
1250f9 |
+ if (state)
|
|
Bernhard M. Wiedemann |
1250f9 |
+ continue;
|
|
Bernhard M. Wiedemann |
1250f9 |
+ *wp++ = (wchar_t)c;
|
|
Bernhard M. Wiedemann |
1250f9 |
+ }
|
|
Bernhard M. Wiedemann |
1250f9 |
+ if (state) {
|
|
Bernhard M. Wiedemann |
1250f9 |
+ /* encoding error, assume latin1 */
|
|
Bernhard M. Wiedemann |
1250f9 |
+ strisutf8 = 0;
|
|
Bernhard M. Wiedemann |
1250f9 |
+ cp = (const unsigned char *)str;
|
|
Bernhard M. Wiedemann |
1250f9 |
+ wp = wstr;
|
|
Bernhard M. Wiedemann |
1250f9 |
+ while ((c = *cp++) != 0) {
|
|
Bernhard M. Wiedemann |
1250f9 |
+ *wp++ = (wchar_t)c;
|
|
Bernhard M. Wiedemann |
1250f9 |
+ }
|
|
Bernhard M. Wiedemann |
1250f9 |
+ }
|
|
Bernhard M. Wiedemann |
1250f9 |
+ *wp = 0;
|
|
Bernhard M. Wiedemann |
1250f9 |
+ mb_cur_max = MB_CUR_MAX;
|
|
Bernhard M. Wiedemann |
1250f9 |
+ memset(&ps, 0, sizeof(ps));
|
|
Bernhard M. Wiedemann |
1250f9 |
+ cc = xmalloc(mb_cur_max);
|
|
Bernhard M. Wiedemann |
1250f9 |
+ /* test locale encoding */
|
|
Bernhard M. Wiedemann |
1250f9 |
+ if (wcrtomb(cc, 0x20ac, &ps) != 3 || memcmp(cc, "\342\202\254", 3))
|
|
Bernhard M. Wiedemann |
1250f9 |
+ locisutf8 = 0;
|
|
Bernhard M. Wiedemann |
1250f9 |
+ if (locisutf8 == strisutf8) {
|
|
Bernhard M. Wiedemann |
1250f9 |
+ wstr = _free(wstr);
|
|
Bernhard M. Wiedemann |
1250f9 |
+ return str;
|
|
Bernhard M. Wiedemann |
1250f9 |
+ }
|
|
Bernhard M. Wiedemann |
1250f9 |
+ str = _free((char *)str);
|
|
Bernhard M. Wiedemann |
1250f9 |
+ memset(&ps, 0, sizeof(ps));
|
|
Bernhard M. Wiedemann |
1250f9 |
+ ccl = cca = 0;
|
|
Bernhard M. Wiedemann |
1250f9 |
+ for (wp = wstr; ; wp++) {
|
|
Bernhard M. Wiedemann |
1250f9 |
+ l = wcrtomb(cc + ccl, *wp, &ps);
|
|
Bernhard M. Wiedemann |
1250f9 |
+ if (*wp == 0)
|
|
Bernhard M. Wiedemann |
1250f9 |
+ break;
|
|
Bernhard M. Wiedemann |
1250f9 |
+ if (l == (size_t)-1) {
|
|
Bernhard M. Wiedemann |
1250f9 |
+ if (*wp < (wchar_t)256 && mbsinit(&ps)) {
|
|
Bernhard M. Wiedemann |
1250f9 |
+ cc[ccl] = *wp;
|
|
Bernhard M. Wiedemann |
1250f9 |
+ l = 1;
|
|
Bernhard M. Wiedemann |
1250f9 |
+ } else
|
|
Bernhard M. Wiedemann |
1250f9 |
+ l = wcrtomb(cc + ccl, (wchar_t)'?', &ps);
|
|
Bernhard M. Wiedemann |
1250f9 |
+ }
|
|
Bernhard M. Wiedemann |
1250f9 |
+ if (l == 0 || l == (size_t)-1)
|
|
Bernhard M. Wiedemann |
1250f9 |
+ continue;
|
|
Bernhard M. Wiedemann |
1250f9 |
+ ccl += l;
|
|
Bernhard M. Wiedemann |
1250f9 |
+ if (ccl > cca) {
|
|
Bernhard M. Wiedemann |
1250f9 |
+ cca = ccl + 16;
|
|
Bernhard M. Wiedemann |
1250f9 |
+ cc = xrealloc(cc, cca + mb_cur_max);
|
|
Bernhard M. Wiedemann |
1250f9 |
+ }
|
|
Bernhard M. Wiedemann |
1250f9 |
+ }
|
|
Bernhard M. Wiedemann |
1250f9 |
+ wstr = _free(wstr);
|
|
Bernhard M. Wiedemann |
1250f9 |
+ return (char *)cc;
|
|
Bernhard M. Wiedemann |
1250f9 |
+}
|
|
Bernhard M. Wiedemann |
1250f9 |
+
|
|
Bernhard M. Wiedemann |
1250f9 |
/**
|
|
Bernhard M. Wiedemann |
1250f9 |
* Retrieve trigger info.
|
|
Bernhard M. Wiedemann |
1250f9 |
* @param mode type of trigger (see tMode_e)
|
|
Bernhard M. Wiedemann |
1250f9 |
@@ -607,10 +716,41 @@ static int i18nTag(Header h, rpmTag tag,
|
|
Bernhard M. Wiedemann |
1250f9 |
#endif
|
|
Bernhard M. Wiedemann |
1250f9 |
|
|
Bernhard M. Wiedemann |
1250f9 |
rc = headerGet(h, tag, td, HEADERGET_ALLOC);
|
|
Bernhard M. Wiedemann |
1250f9 |
+ if (rc && td->data) {
|
|
Bernhard M. Wiedemann |
1250f9 |
+ td->data = strtolocale(td->data);
|
|
Bernhard M. Wiedemann |
1250f9 |
+ }
|
|
Bernhard M. Wiedemann |
1250f9 |
return rc;
|
|
Bernhard M. Wiedemann |
1250f9 |
}
|
|
Bernhard M. Wiedemann |
1250f9 |
|
|
Bernhard M. Wiedemann |
1250f9 |
/**
|
|
Bernhard M. Wiedemann |
1250f9 |
+ * Retrieve text and convert to locale.
|
|
Bernhard M. Wiedemann |
1250f9 |
+ */
|
|
Bernhard M. Wiedemann |
1250f9 |
+static int localeTag(Header h, rpmTag tag, rpmtd td)
|
|
Bernhard M. Wiedemann |
1250f9 |
+{
|
|
Bernhard M. Wiedemann |
1250f9 |
+ int rc;
|
|
Bernhard M. Wiedemann |
1250f9 |
+ rc = headerGet(h, tag, td, HEADERGET_ALLOC);
|
|
Bernhard M. Wiedemann |
1250f9 |
+ if (!rc)
|
|
Bernhard M. Wiedemann |
1250f9 |
+ return 0;
|
|
Bernhard M. Wiedemann |
1250f9 |
+ if (td->type == RPM_STRING_TYPE) {
|
|
Bernhard M. Wiedemann |
1250f9 |
+ td->data = strtolocale(td->data);
|
|
Bernhard M. Wiedemann |
1250f9 |
+ td->count = 1;
|
|
Bernhard M. Wiedemann |
1250f9 |
+ } else if (td->type == RPM_STRING_ARRAY_TYPE) {
|
|
Bernhard M. Wiedemann |
1250f9 |
+ char **arr;
|
|
Bernhard M. Wiedemann |
1250f9 |
+ int i;
|
|
Bernhard M. Wiedemann |
1250f9 |
+ arr = xmalloc(td->count * sizeof(*arr));
|
|
Bernhard M. Wiedemann |
1250f9 |
+ for (i = 0; i < td->count; i++) {
|
|
Bernhard M. Wiedemann |
1250f9 |
+ arr[i] = xstrdup(((char **)td->data)[i]);
|
|
Bernhard M. Wiedemann |
1250f9 |
+ arr[i] = strtolocale(arr[i]);
|
|
Bernhard M. Wiedemann |
1250f9 |
+ }
|
|
Bernhard M. Wiedemann |
1250f9 |
+ _free(td->data);
|
|
Bernhard M. Wiedemann |
1250f9 |
+ td->data = arr;
|
|
Bernhard M. Wiedemann |
1250f9 |
+ td->flags = RPMTD_ALLOCED | RPMTD_PTR_ALLOCED;
|
|
Bernhard M. Wiedemann |
1250f9 |
+ }
|
|
Bernhard M. Wiedemann |
1250f9 |
+ return rc;
|
|
Bernhard M. Wiedemann |
1250f9 |
+}
|
|
Bernhard M. Wiedemann |
1250f9 |
+
|
|
Bernhard M. Wiedemann |
1250f9 |
+
|
|
Bernhard M. Wiedemann |
1250f9 |
+/**
|
|
Bernhard M. Wiedemann |
1250f9 |
* Retrieve summary text.
|
|
Bernhard M. Wiedemann |
1250f9 |
* @param h header
|
|
Bernhard M. Wiedemann |
1250f9 |
* @retval td tag data container
|
|
Bernhard M. Wiedemann |
1250f9 |
@@ -634,6 +774,16 @@ static int descriptionTag(Header h, rpmt
|
|
Bernhard M. Wiedemann |
1250f9 |
return i18nTag(h, RPMTAG_DESCRIPTION, td, hgflags);
|
|
Bernhard M. Wiedemann |
1250f9 |
}
|
|
Bernhard M. Wiedemann |
1250f9 |
|
|
Bernhard M. Wiedemann |
1250f9 |
+static int changelognameTag(Header h, rpmtd td)
|
|
Bernhard M. Wiedemann |
1250f9 |
+{
|
|
Bernhard M. Wiedemann |
1250f9 |
+ return localeTag(h, RPMTAG_CHANGELOGNAME, td);
|
|
Bernhard M. Wiedemann |
1250f9 |
+}
|
|
Bernhard M. Wiedemann |
1250f9 |
+
|
|
Bernhard M. Wiedemann |
1250f9 |
+static int changelogtextTag(Header h, rpmtd td)
|
|
Bernhard M. Wiedemann |
1250f9 |
+{
|
|
Bernhard M. Wiedemann |
1250f9 |
+ return localeTag(h, RPMTAG_CHANGELOGTEXT, td);
|
|
Bernhard M. Wiedemann |
1250f9 |
+}
|
|
Bernhard M. Wiedemann |
1250f9 |
+
|
|
Bernhard M. Wiedemann |
1250f9 |
/**
|
|
Bernhard M. Wiedemann |
1250f9 |
* Retrieve group text.
|
|
Bernhard M. Wiedemann |
1250f9 |
* @param h header
|
|
Bernhard M. Wiedemann |
1250f9 |
@@ -971,6 +1121,8 @@ static const struct headerTagFunc_s rpmH
|
|
Bernhard M. Wiedemann |
1250f9 |
{ RPMTAG_LONGARCHIVESIZE, longarchivesizeTag },
|
|
Bernhard M. Wiedemann |
1250f9 |
{ RPMTAG_LONGSIZE, longsizeTag },
|
|
Bernhard M. Wiedemann |
1250f9 |
{ RPMTAG_LONGSIGSIZE, longsigsizeTag },
|
|
Bernhard M. Wiedemann |
1250f9 |
+ { RPMTAG_CHANGELOGNAME, changelognameTag },
|
|
Bernhard M. Wiedemann |
1250f9 |
+ { RPMTAG_CHANGELOGTEXT, changelogtextTag },
|
|
Bernhard M. Wiedemann |
1250f9 |
{ RPMTAG_DBINSTANCE, dbinstanceTag },
|
|
Bernhard M. Wiedemann |
1250f9 |
{ RPMTAG_EVR, evrTag },
|
|
Bernhard M. Wiedemann |
1250f9 |
{ RPMTAG_NVR, nvrTag },
|