comparison sidinfo.c @ 157:8fc887cb56d0

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).
author Matti Hamalainen <ccr@tnsp.org>
date Thu, 26 Oct 2017 01:46:34 +0300
parents 717d143612e2
children a8c24f1f460f
comparison
equal deleted inserted replaced
156:717d143612e2 157:8fc887cb56d0
6 #include "th_args.h" 6 #include "th_args.h"
7 #include "th_string.h" 7 #include "th_string.h"
8 #include "th_file.h" 8 #include "th_file.h"
9 #include "sidlib.h" 9 #include "sidlib.h"
10 #ifdef HAVE_ICONV 10 #ifdef HAVE_ICONV
11 #include <iconv.h> 11 # include <iconv.h>
12 #endif 12 #endif
13 13
14 14
15 // Some constants 15 // Some constants
16 #define SET_DEF_CHARSET "utf-8" 16 #define SET_DEF_CHARSET "utf-8"
17 #define SET_SLDB_FILENAME "Songlengths.txt" 17 #define SET_SLDB_FILENAME "Songlengths.txt"
18 18
19 19
20 enum 20 enum
21 { 21 {
22 OFMT_QUOTED = 0x0001,
22 OFMT_FORMAT = 0x0002, 23 OFMT_FORMAT = 0x0002,
23 }; 24 };
24 25
25 26
26 enum 27 enum
274 275
275 return TRUE; 276 return TRUE;
276 } 277 }
277 278
278 279
280 #ifdef HAVE_ICONV
281 char *siConvertCharset(iconv_t ctx, const char *src)
282 {
283 size_t srcLeft = strlen(src) + 1;
284 size_t outLeft = srcLeft * 2;
285 char *outBuf, *outPtr;
286 char *srcPtr = (char *) src;
287
288 if ((outBuf = outPtr = th_malloc(outLeft + 1)) == NULL)
289 return NULL;
290
291 while (srcLeft > 0)
292 {
293 size_t ret = iconv(ctx, &srcPtr, &srcLeft, &outPtr, &outLeft);
294 if (ret == (size_t) -1)
295 break;
296 }
297
298 return outBuf;
299 }
300 #endif
301
302
279 int siItemFormatStrPutInt(th_vprintf_ctx *ctx, th_vprintf_putch vputch, 303 int siItemFormatStrPutInt(th_vprintf_ctx *ctx, th_vprintf_putch vputch,
280 const int value, const int f_radix, int f_flags, int f_width, int f_prec, 304 const int value, const int f_radix, int f_flags, int f_width, int f_prec,
281 const BOOL f_unsig, char *(f_alt)(const char *buf, const size_t blen, const int vret, const int flags)) 305 const BOOL f_unsig, char *(f_alt)(const char *buf, const size_t blen, const int vret, const int flags))
282 { 306 {
283 char buf[64]; 307 char buf[64];
692 if (optFieldOutput) 716 if (optFieldOutput)
693 fputs(optOneLine ? optFieldSep : "\n", outFile); 717 fputs(optOneLine ? optFieldSep : "\n", outFile);
694 } 718 }
695 719
696 720
697 static void siPrintPSIDInfoLine(FILE *outFile, BOOL *shown, const PSFStackItem *item, const char *d_str, const int d_int) 721 static void siPrintPSIDInfoLine(FILE *outFile, BOOL *shown, const PSFStackItem *item, const char *d_str, const int d_int, const BOOL useConv)
698 { 722 {
699 const PSFOption *opt = &optPSOptions[item->cmd]; 723 const PSFOption *opt = &optPSOptions[item->cmd];
700 char *fmt, *str; 724 char *fmt, *str;
701 725
702 switch (opt->type) 726 switch (opt->type)
719 return; 743 return;
720 } 744 }
721 745
722 siPrintFieldPrefix(outFile, opt); 746 siPrintFieldPrefix(outFile, opt);
723 747
748 #ifdef HAVE_ICONV
749 char *tmp;
750
751 if (setUseChConv && d_str != NULL && useConv)
752 tmp = siConvertCharset(setChConv, d_str);
753 else
754 tmp = th_strdup(d_str);
755
756 str = siItemFormatStrPrint(fmt, opt, tmp, d_int);
757 #else
758 (void) useConv;
724 str = siItemFormatStrPrint(fmt, opt, d_str, d_int); 759 str = siItemFormatStrPrint(fmt, opt, d_str, d_int);
760 #endif
761
725 if (str != NULL) 762 if (str != NULL)
726 fputs(str, outFile); 763 fputs(str, outFile);
727 764
728 siPrintFieldSeparator(outFile); 765 siPrintFieldSeparator(outFile);
729 th_free(str); 766 th_free(str);
730 767
768 #ifdef HAVE_ICONV
769 th_free(tmp);
770 #endif
771
731 *shown = TRUE; 772 *shown = TRUE;
732 } 773 }
733 774
734 775
735 #define PRS(d_str, d_conv) siPrintPSIDInfoLine(outFile, shown, item, d_str, -1) 776 #define PRS(d_str, d_conv) siPrintPSIDInfoLine(outFile, shown, item, d_str, -1, d_conv)
736 #define PRI(d_int) siPrintPSIDInfoLine(outFile, shown, item, NULL, d_int) 777 #define PRI(d_int) siPrintPSIDInfoLine(outFile, shown, item, NULL, d_int, FALSE)
737 778
738 779
739 static void siPrintPSIDInformationField(FILE *outFile, const char *filename, const PSIDHeader *psid, BOOL *shown, const PSFStackItem *item) 780 static void siPrintPSIDInformationField(FILE *outFile, const char *filename, const PSIDHeader *psid, BOOL *shown, const PSFStackItem *item)
740 { 781 {
741 const PSFOption *opt = &optPSOptions[item->cmd]; 782 const PSFOption *opt = &optPSOptions[item->cmd];