Mercurial > hg > sidinfo
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]; |