poldek: poldek/pkgu.c - recoding utf8 if needed
mis
mis at pld-linux.org
Fri Jun 22 18:36:47 CEST 2007
Author: mis Date: Fri Jun 22 16:36:47 2007 GMT
Module: poldek Tag: HEAD
---- Log message:
- recoding utf8 if needed
---- Files affected:
poldek/poldek:
pkgu.c (1.32 -> 1.33)
---- Diffs:
================================================================
Index: poldek/poldek/pkgu.c
diff -u poldek/poldek/pkgu.c:1.32 poldek/poldek/pkgu.c:1.33
--- poldek/poldek/pkgu.c:1.32 Fri Jun 22 00:32:34 2007
+++ poldek/poldek/pkgu.c Fri Jun 22 18:36:42 2007
@@ -23,6 +23,8 @@
#include <trurl/nstream.h>
#include <trurl/nhash.h>
+#include <iconv.h>
+#include <langinfo.h>
#include "i18n.h"
#include "log.h"
@@ -30,14 +32,18 @@
#include "misc.h"
#include "pm/rpm/pm_rpm.h"
-#define NA_OWNED (1 << 0)
-
+#define NA_OWNED (1 << 0)
+#define RECODE_SUMMMARY (1 << 1) /* needs to be recoded */
+#define RECODE_DESCRIPTION (1 << 2)
+#define RECODED_SUMMMARY (1 << 3) /* already recoded */
+#define RECODED_DESCRIPTION (1 << 4)
struct pkguinf {
char *license;
char *url;
- char *summary;
- char *description;
+ char *_summary;
+ char *_description;
+ const char *_encoding; /* for iconv, NFY */
char *vendor;
char *buildhost;
char *distro;
@@ -57,6 +63,7 @@
char _buf[0];
};
+
static
struct pkguinf_i18n *pkguinf_i18n_new(tn_alloc *na, const char *summary,
const char *description)
@@ -98,8 +105,8 @@
pkgu->license = NULL;
pkgu->url = NULL;
- pkgu->summary = NULL;
- pkgu->description = NULL;
+ pkgu->_summary = NULL;
+ pkgu->_description = NULL;
pkgu->vendor = NULL;
pkgu->buildhost = NULL;
@@ -117,11 +124,17 @@
return;
}
- if (pkgu->summary)
- pkgu->summary = NULL;
-
- if (pkgu->description)
- pkgu->description = NULL;
+ if (pkgu->_summary) {
+ if (pkgu->_flags & RECODED_SUMMMARY)
+ free(pkgu->_summary);
+ pkgu->_summary = NULL;
+ }
+
+ if (pkgu->_description) {
+ if (pkgu->_flags & RECODED_DESCRIPTION)
+ free(pkgu->_description);
+ pkgu->_description = NULL;
+ }
if (pkgu->_langs)
n_array_free(pkgu->_langs);
@@ -140,6 +153,82 @@
n_alloc_free(pkgu->_na);
}
+/*
+ Set recodable pkgu member, set _flags accordinggly to trigger
+ recoding in pkguinf_get()
+ */
+static void pkgu_set_recodable(struct pkguinf *pkgu, int tag, char *val,
+ const char *lang)
+{
+ char **member = NULL;
+ unsigned flag = 0, needflag = 0;
+ char *usrencoding = NULL;
+
+ switch (tag) {
+ case PKGUINF_SUMMARY:
+ member = &pkgu->_summary;
+ flag = RECODED_SUMMMARY;
+ needflag = RECODE_SUMMMARY;
+ break;
+
+ case PKGUINF_DESCRIPTION:
+ member = &pkgu->_description;
+ flag = RECODED_DESCRIPTION;
+ needflag = RECODE_SUMMMARY;
+ break;
+
+ default:
+ n_assert(0);
+ break;
+ }
+
+ if (*member && (pkgu->_flags & flag)) {
+ free((char*)*member);
+ *member = NULL;
+ }
+
+ *member = val;
+ pkgu->_flags &= ~needflag;
+
+ if (strstr(lang, "UTF-8") == NULL) {
+ *member = val;
+ return;
+ }
+
+ usrencoding = nl_langinfo(CODESET);
+ DBGF("CODE %s\n", usrencoding);
+
+ if (usrencoding && n_str_ne(usrencoding, "UTF-8"))
+ pkgu->_flags |= needflag;
+}
+
+
+static char *recode(const char *val, const char *valencoding)
+{
+ char *p, *val_utf8, *usrencoding;
+ size_t vlen, u_vlen;
+ iconv_t cd;
+
+ usrencoding = nl_langinfo(CODESET);
+ if (usrencoding == NULL)
+ return (char*)val;
+
+ valencoding = "UTF-8"; /* XXX, support for others needed? */
+
+ u_vlen = vlen = strlen(val);
+ p = val_utf8 = n_malloc(u_vlen + 1);
+
+ cd = iconv_open(usrencoding, valencoding);
+ if (iconv(cd, (char**)&val, &vlen, &p, &u_vlen) == (size_t)-1) {
+ iconv_close(cd);
+ free(val_utf8);
+ return (char*)val;
+ }
+ iconv_close(cd);
+ *p = '\0';
+ return val_utf8;
+}
+
struct pkguinf *pkguinf_link(struct pkguinf *pkgu)
{
pkgu->_refcnt++;
@@ -232,8 +321,8 @@
inf = n_hash_get(pkgu->_ht, sl_lang);
n_assert(inf);
- pkgu->summary = inf->summary;
- pkgu->description = inf->description;
+ pkgu_set_recodable(pkgu, PKGUINF_SUMMARY, inf->summary, sl_lang);
+ pkgu_set_recodable(pkgu, PKGUINF_DESCRIPTION, inf->description, sl_lang);
}
n_array_free(avlangs);
@@ -357,6 +446,8 @@
return nbuf;
}
+
+
struct pkguinf *pkguinf_restore(tn_alloc *na, tn_buf_it *it, const char *lang)
{
struct pkguinf *pkgu;
@@ -407,6 +498,7 @@
return pkgu;
}
+
int pkguinf_restore_i18n(struct pkguinf *pkgu, tn_buf_it *it, const char *lang)
{
struct pkguinf_i18n *inf;
@@ -433,15 +525,17 @@
inf = pkguinf_i18n_new(pkgu->_na, summary, description);
n_hash_insert(pkgu->_ht, lang, inf);
-
- pkgu->summary = inf->summary;
- pkgu->description = inf->description;
-
+
+ pkgu_set_recodable(pkgu, PKGUINF_SUMMARY, summary, lang);
+ pkgu_set_recodable(pkgu, PKGUINF_DESCRIPTION, description, lang);
return 1;
}
const char *pkguinf_get(const struct pkguinf *pkgu, int tag)
{
+ char **val = NULL; /* for summary, description recoding */
+ unsigned flag = 0, needflag = 0;
+
switch (tag) {
case PKGUINF_LICENSE:
return pkgu->license;
@@ -457,24 +551,47 @@
case PKGUINF_DISTRO:
return pkgu->distro;
-
+
case PKGUINF_SUMMARY:
- return pkgu->summary;
+ val = (char**)&pkgu->_summary;
+ flag = RECODED_SUMMMARY;
+ needflag = RECODE_SUMMMARY;
+ break;
case PKGUINF_DESCRIPTION:
- return pkgu->description;
-
+ val = (char**)&pkgu->_description;
+ flag = RECODED_DESCRIPTION;
+ needflag = RECODE_DESCRIPTION;
+ break;
+
default:
if (poldek_VERBOSE > 2)
logn(LOGERR, "%d: unknown tag", tag);
break;
}
+ if (val) { /* something to recode? */
+ char *recoded = NULL;
+
+ /* already recoded or no recoding needed */
+ if ((pkgu->_flags & needflag) == 0)
+ return *val;
+
+ recoded = recode(*val, NULL);
+ if (recoded && recoded != *val) {
+ ((struct pkguinf *)(pkgu))->_flags &= ~needflag; /* XXX ugly */
+ ((struct pkguinf *)(pkgu))->_flags |= ~flag;
+ *val = recoded;
+ }
+
+ return *val;
+ }
+
return NULL;
}
int pkguinf_set(struct pkguinf *pkgu, int tag, const char *val,
- const char *lang)
+ const char *lang)
{
int len;
@@ -519,11 +636,12 @@
if (tag == PKGUINF_SUMMARY) {
inf->summary = na_strdup(pkgu->_na, val, len);
- pkgu->summary = inf->summary;
+ pkgu_set_recodable(pkgu, PKGUINF_SUMMARY, inf->summary, lang);
} else {
inf->description = na_strdup(pkgu->_na, val, len);
- pkgu->description = inf->description;
+ pkgu_set_recodable(pkgu, PKGUINF_DESCRIPTION, inf->description,
+ lang);
}
}
================================================================
---- CVS-web:
http://cvs.pld-linux.org/poldek/poldek/pkgu.c?r1=1.32&r2=1.33&f=u
More information about the pld-cvs-commit
mailing list