# HG changeset patch # User Matti Hamalainen # Date 1508971594 -10800 # Node ID 8fc887cb56d029270d806de9e9cc30b3ba0d68e2 # Parent 717d143612e2303cb7508a937c02a501d05f6b0c Implement iconv support for converting from PSID de-facto latin-1/ISO-8859-* to whatever we are using currently (default to UTF-8). Support for iconv can be turned off via compile-time define (see Makefile). diff -r 717d143612e2 -r 8fc887cb56d0 Makefile --- a/Makefile Thu Oct 26 01:45:02 2017 +0300 +++ b/Makefile Thu Oct 26 01:46:34 2017 +0300 @@ -11,6 +11,8 @@ CFLAGS += -DHAVE_CONFIG_H LDFLAGS += +CFLAGS += -DHAVE_ICONV + CFLAGS += -DHAVE_STRING_H CFLAGS += -DHAVE_STDINT_H #CFLAGS += -DHAVE_SYS_TYPES_H diff -r 717d143612e2 -r 8fc887cb56d0 README.txt --- a/README.txt Thu Oct 26 01:45:02 2017 +0300 +++ b/README.txt Thu Oct 26 01:46:34 2017 +0300 @@ -25,6 +25,11 @@ - th-libs library (included in the tar/zip packages, for building from mercurial repo, see "how to build") + - libiconv (optional, for converting ISO-8859/Latin-1 encoded + text used in HVSC SID files and STIL database to whatever + character set your system is using, like UTF-8.) + + For Linux -> Win32/64 cross-compilation I have used the standard MinGW packages from Debian Testing (wheezy): diff -r 717d143612e2 -r 8fc887cb56d0 sidinfo.c --- a/sidinfo.c Thu Oct 26 01:45:02 2017 +0300 +++ b/sidinfo.c Thu Oct 26 01:46:34 2017 +0300 @@ -8,7 +8,7 @@ #include "th_file.h" #include "sidlib.h" #ifdef HAVE_ICONV -#include +# include #endif @@ -19,6 +19,7 @@ enum { + OFMT_QUOTED = 0x0001, OFMT_FORMAT = 0x0002, }; @@ -276,6 +277,29 @@ } +#ifdef HAVE_ICONV +char *siConvertCharset(iconv_t ctx, const char *src) +{ + size_t srcLeft = strlen(src) + 1; + size_t outLeft = srcLeft * 2; + char *outBuf, *outPtr; + char *srcPtr = (char *) src; + + if ((outBuf = outPtr = th_malloc(outLeft + 1)) == NULL) + return NULL; + + while (srcLeft > 0) + { + size_t ret = iconv(ctx, &srcPtr, &srcLeft, &outPtr, &outLeft); + if (ret == (size_t) -1) + break; + } + + return outBuf; +} +#endif + + int siItemFormatStrPutInt(th_vprintf_ctx *ctx, th_vprintf_putch vputch, const int value, const int f_radix, int f_flags, int f_width, int f_prec, const BOOL f_unsig, char *(f_alt)(const char *buf, const size_t blen, const int vret, const int flags)) @@ -694,7 +718,7 @@ } -static void siPrintPSIDInfoLine(FILE *outFile, BOOL *shown, const PSFStackItem *item, const char *d_str, const int d_int) +static void siPrintPSIDInfoLine(FILE *outFile, BOOL *shown, const PSFStackItem *item, const char *d_str, const int d_int, const BOOL useConv) { const PSFOption *opt = &optPSOptions[item->cmd]; char *fmt, *str; @@ -721,19 +745,36 @@ siPrintFieldPrefix(outFile, opt); +#ifdef HAVE_ICONV + char *tmp; + + if (setUseChConv && d_str != NULL && useConv) + tmp = siConvertCharset(setChConv, d_str); + else + tmp = th_strdup(d_str); + + str = siItemFormatStrPrint(fmt, opt, tmp, d_int); +#else + (void) useConv; str = siItemFormatStrPrint(fmt, opt, d_str, d_int); +#endif + if (str != NULL) fputs(str, outFile); siPrintFieldSeparator(outFile); th_free(str); +#ifdef HAVE_ICONV + th_free(tmp); +#endif + *shown = TRUE; } -#define PRS(d_str, d_conv) siPrintPSIDInfoLine(outFile, shown, item, d_str, -1) -#define PRI(d_int) siPrintPSIDInfoLine(outFile, shown, item, NULL, d_int) +#define PRS(d_str, d_conv) siPrintPSIDInfoLine(outFile, shown, item, d_str, -1, d_conv) +#define PRI(d_int) siPrintPSIDInfoLine(outFile, shown, item, NULL, d_int, FALSE) static void siPrintPSIDInformationField(FILE *outFile, const char *filename, const PSIDHeader *psid, BOOL *shown, const PSFStackItem *item)